当尝试从数据框中的财务数据计算指数移动平均线(EMA)时,似乎Pandas' ewm方法不正确。
以下链接详细说明了基础知识: http://stockcharts.com/school/doku.php?id=chart_school:technical_indicators:moving_averages
当谈到Pandas的解释时,所采取的方法如下(使用" adjust"参数为False):
weighted_average[0] = arg[0];
weighted_average[i] = (1-alpha) * weighted_average[i-1] + alpha * arg[i]
我认为这是不正确的。 " arg"应该是(例如)结束值,但是,arg [0]是第一个平均值(即所选周期长度的第一系列数据的简单平均值),而不是第一个结束值。因此,arg [0]和arg [i]永远不会来自相同的数据。使用" min_periods"参数似乎没有解决这个问题。
任何人都可以解释一下(如果)Pandas如何用于正确计算数据的EMA?
答案 0 :(得分:7)
有几种方法可以初始化指数移动平均线,所以我不会说大熊猫做错了,只是不同。
这是一种计算它的方法:
In [20]: s.head()
Out[20]:
0 22.27
1 22.19
2 22.08
3 22.17
4 22.18
Name: Price, dtype: float64
In [21]: span = 10
In [22]: sma = s.rolling(window=span, min_periods=span).mean()[:span]
In [24]: rest = s[span:]
In [25]: pd.concat([sma, rest]).ewm(span=span, adjust=False).mean()
Out[25]:
0 NaN
1 NaN
2 NaN
3 NaN
4 NaN
5 NaN
6 NaN
7 NaN
8 NaN
9 22.221000
10 22.208091
11 22.241165
12 22.266408
13 22.328879
14 22.516356
15 22.795200
16 22.968800
17 23.125382
18 23.275312
19 23.339801
20 23.427110
21 23.507635
22 23.533520
23 23.471062
24 23.403596
25 23.390215
26 23.261085
27 23.231797
28 23.080561
29 22.915004
Name: Price, dtype: float64
答案 1 :(得分:6)
您可以在Pandas span
函数中使用alpha或系数(ewm
)计算EWMA。
使用alpha的公式:(1 - alpha) * previous_val + alpha * current_val
其中alpha = 1 / period
使用coeff的公式:((current_val - previous_val) * coeff) + previous_val
其中coeff = 2 / (period + 1)
以下是如何使用Pandas计算上述公式:
con = pd.concat([df[:period][base].rolling(window=period).mean(), df[period:][base]])
if (alpha == True):
df[target] = con.ewm(alpha=1 / period, adjust=False).mean()
else:
df[target] = con.ewm(span=period, adjust=False).mean()
答案 2 :(得分:3)
以下是Pandas如何计算调整和未调整ewm的示例:
name = 'closing'
series = pd.Series([1, 2, 3, 5, 8, 13, 21, 34], name=name).to_frame()
period = 4
alpha = 2/(1+period)
series[name+'_ewma'] = np.nan
series.loc[0, name+'_ewma'] = series[name].iloc[0]
series[name+'_ewma_adjust'] = np.nan
series.loc[0, name+'_ewma_adjust'] = series[name].iloc[0]
for i in range(1, len(series)):
series.loc[i, name+'_ewma'] = (1-alpha) * series.loc[i-1, name+'_ewma'] + alpha * series.loc[i, name]
ajusted_weights = np.array([(1-alpha)**(i-t) for t in range(i+1)])
series.loc[i, name+'_ewma_adjust'] = np.sum(series.iloc[0:i+1][name].values * ajusted_weights) / ajusted_weights.sum()
print(series)
print("diff adjusted=False -> ", np.sum(series[name+'_ewma'] - series[name].ewm(span=period, adjust=False).mean()))
print("diff adjusted=True -> ", np.sum(series[name+'_ewma_adjust'] - series[name].ewm(span=period, adjust=True).mean()))
找到
答案 3 :(得分:0)
如果您正在计算ewm的ewm(如MACD公式),则结果会很糟糕,因为第二个及之后的ewm将使用从0开始并以句号结尾的索引。我使用以下解决方案。
use strict;
use warning;
my $dirname = "../../../experiment/";
my $keyword = "Book";
my @result;
my $find_file = sub {
my $F = $File::Find::name;
if ($F =~ /txt$/) {
open my $in, "<", $F or die $!;
while(<$in>) {
if (/\Q$keyword\E/){
next;
}else{
push @result, $F;
return;
}
}
}
};
find ({ wanted => $find_file, no_chdir=>1}, $dirname );
foreach my $result (@result){
chomp $result;
$result =~ s{.*/}{};
print "$result\n";
}