在C ++中实现指数移动平均 [英] Implementing Exponential Moving Average in 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屋!