我正在开发一个小型交易机器人作为练习。他日复一日地接收股票价格(表示为迭代)。

这是我的 Trade 类的样子:

class   Trade
{
private:
  int                   capital_;
  int                   days_; // Total number of days of available stock prices
  int                   daysInTrading_; // Increments as days go by.
  std::list<int>        stockPrices_; // Contains stock prices day after day.
  int                   currentStock_; // Current stock we are dealing with.
  int                   lastStock_; // Last stock dealt with
  int                   trend_; // Either {-1; 0; 1} depending on the trend.
  int                   numOfStocks_; // Number of stocks in our possession
  int                   EMA_; // Exponential Moving Average
  int                   lastEMA_; // Last EMA

public:
    // functions
};

正如您从我的最后两个属性中看到的,我希望将指数移动平均线作为趋势跟踪算法的一部分。

但我想我不太明白如何实现它;这是我的 calcEMA 函数,它只是计算 EMA :
int     Trade::calcEMA()
{
  return ((this->currentStock_ - this->lastEMA_
           * (2/(this->daysInTrading_ + 1)))
          + this->lastEMA_);
}

但是当我的股票值(value)(在文件中传递)是这样的:
1000, 1100, 1200, 1300, 1400, 1500, 1400, 1300, 1200, 1100, 1000

至于确保我的 EMA 有意义,嗯……它没有!

我在手术中哪里出错了?

另外,如果这是我第一次调用 lastEMA ,我应该给 calcEMA 什么值?

最佳答案

我相信您在 calcEMA 函数中缺少括号。它有助于将表达式分解为带有临时变量的较小表达式以保存中间结果。

int Trade::calcEMA()
{
   auto mult = 2/(timePeriod_ + 1);
   auto rslt = (currentStock_ - lastEMA_) * mult + lastEMA_;
   return rslt;
}

此外,正如 PaulMcKenzie 在评论中指出的那样,您正在使用整数进行浮点数学运算。您应该考虑使用浮点数或 double 数来避免截断。

像您这样的 EMA 定义了一个时间段,上面称为 timePeriod_。当 daysInTrading_ 小于或等于 timePeriod_ 时,lastEMA_ 应设置为正常平均值。一旦 daysInTrading_ 大于您的 timePeriod_,您就可以在正确初始化 lastEMA_ 的情况下开始调用您的 calcEMA 函数。请记住在每次调用 calcEMA 后更新 lastEMA_。这是一个可能的实现:
#include <vector>
#include <list>
#include <iostream>

// calculate a moving average
double calcMA(double previousAverage, unsigned int previousNumDays, double newStock)
{
   auto rslt = previousNumDays * previousAverage + newStock;
   return rslt / (previousNumDays + 1.0);
}

// calculate an exponential moving average
double calcEMA(double previousAverage, int timePeriod, double newStock)
{
   auto mult = 2.0 / (timePeriod + 1.0);
   auto rslt = (newStock - previousAverage) * mult + previousAverage;
   return rslt;
}

class Trade
{
   unsigned int timePeriod_ = 5;
   double lastMA_ = 0.0;
   std::list<double> stockPrices_;

public:

   void addStock(double newStock)
   {
      stockPrices_.push_back(newStock);
      auto num_days = stockPrices_.size();

      if (num_days <= timePeriod_)
         lastMA_ = calcMA(lastMA_, num_days - 1, newStock);
      else
         lastMA_ = calcEMA(lastMA_, num_days - 1, newStock);
   }

   double getAverage() const { return lastMA_; }
};

int main()
{
   std::vector<double> stocks =
     {1000, 1100, 1200, 1300, 1400, 1500, 1400, 1300, 1200, 1100, 1000};

   Trade trade;
   for (auto stock : stocks)
      trade.addStock(stock);

   std::cout << "Average: " << trade.getAverage() << std::endl;

   return 0;
}

关于c++ - 用 C++ 实现指数移动平均线,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/37300684/

10-12 03:07