在C ++中实现指数移动平均 [英] Implementing Exponential Moving Average in C++

查看:60
本文介绍了在C ++中实现指数移动平均的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am developing a small trading robot as an exercise. He receives stock prices day after day (represented as iterations).

这是我的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
};

从我的后两个属性可以看到,我希望实现指数移动平均作为趋势跟踪算法的一部分.

As you can see from my last two attributes, I wish to implement an Exponential Moving Average as part of a Trend Following Algorithm.

但是我认为我不太了解如何实现它.这是我的calcEMA函数,可以简单地计算EMA:

But I think I didn't quite understand how to implement it; here's my calcEMA function that simply calculates the EMA:

int     Trade::calcEMA()
{
  return ((this->currentStock_ - this->lastEMA_
           * (2/(this->daysInTrading_ + 1)))
          + this->lastEMA_);
}

但是当我的股票价值(传递到文件中)像这样时:

But when my stock values (passed in a file) are like such:

1000, 1100, 1200, 1300, 1400, 1500, 1400, 1300, 1200, 1100, 1000

为确保我的EMA有意义,嗯...那不行!

As to make sure my EMA makes sense, and well... it does not !

我在哪里做错了手术?

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

Aditionally, what value should I give lastEMA if it's the first time I call calcEMA?

推荐答案

我相信您在calcEMA函数中缺少括号.可以使用临时变量将表达式分解为更小的表达式,以保存中间结果.

I believe you are missing a parentheses in you calcEMA function. It helps to break the expression up into smaller expressions with temporary variables to hold intermediate results.

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

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

Also, as PaulMcKenzie pointed out in the comments, you are using ints to do floating point math. You should consider using floats or doubles to avoid truncation.

像您这样的EMA被定义了一个时间段,在上面称为timePeriod_.当daysInTrading_小于或等于timePeriod_时,lastEMA_应该仅设置为正常平均值.当daysInTrading_大于timePeriod_时,您可以使用正确初始化的lastEMA_开始调用calcEMA函数.请记住在每次调用calcEMA之后更新lastEMA_.这是一个可能的实现:

An EMA like yours is defined for a time period, called timePeriod_ above. While daysInTrading_ is less or equal to timePeriod_, lastEMA_ should just be set to a normal average. Once daysInTrading_ is greater than your timePeriod_ you can start calling your calcEMA function with lastEMA_ properly initialized. Remember to update lastEMA_ after each call to calcEMA. Here is a possible implementation:

#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 ++中实现指数移动平均的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆