熊猫指数加权移动平均线的问题



我在尝试用熊猫计算指数加权移动平均线 (ewma) 时遇到了一个小问题:

在这里,我使用熊猫函数来计算我价格的 9 周期 ewma:

df = m1["open"].ewm(min_periods=9,span=9).mean()

用于计算 ewma 的公式如下:

ewm(t+1) = alpha * price + (1-alpha) * ewm(t) 

alpha = 2/(period+1)

熊猫函数给我的结果似乎不正确,所以我试图验证它:

df = m1["open"].ewm(min_periods=9,span=9).mean()
alpha = 2/(9+1)
df_bis = alpha*m1["open"].shift(1) + (1-alpha)*df.shift(1)
bol_array = df == df_bis

df是熊猫函数返回的数据帧,df_bis使用来自 df 的数据和价格的公式的数据帧。

bol_array应该始终正确,因为dfdf_bis都应该是平等的。

但是,事实并非如此,在这里我随机选择了bol_array的一部分:

2015-01-09 21:32:00    False
2015-01-09 21:33:00    False
2015-01-09 21:34:00     True
2015-01-09 21:35:00    False
2015-01-09 21:36:00    False
2015-01-09 21:37:00    False
2015-01-09 21:38:00    False
2015-01-09 21:39:00    False
2015-01-09 21:40:00    False
2015-01-09 21:41:00    False
2015-01-09 21:42:00    False
2015-01-09 21:43:00     True
2015-01-09 21:44:00    False
2015-01-09 21:45:00    False

有时,它们是平等的,有时不是。

我在特定时间检查了一下,看看它是否可能是舍入问题:

m1["open"][15]*alpha + df[15]*(1-alpha)
Out[7]: 1.1931468623934722
df[16]
Out[8]: 1.1930652375329887

结果真的很不同,这不是舍入问题(我需要 5 位的精度)。

有谁知道这里有什么问题? 我似乎找不到这里的问题所在。

编辑:为了看看这是否可能是一个舍入问题,我添加了一个数组来衡量熊猫之间的差异

diff_array = df-df_bis

我需要 5 位数的精度,所以我将这个数组乘以 10^5 以更好地可视化差异的大小:

diff_array*10**5
Out[16]: 
DateTime
2015-01-04 22:00:00          NaN
2015-01-04 22:01:00          NaN
2015-01-04 22:02:00          NaN
2015-01-04 22:03:00          NaN
2015-01-04 22:04:00          NaN
2015-01-04 22:05:00          NaN
2015-01-04 22:06:00          NaN
2015-01-04 22:07:00          NaN
2015-01-04 22:08:00          NaN
2015-01-04 22:09:00    -2.610024
2015-01-04 22:10:00   -60.325142
2015-01-04 22:11:00    27.044649
2015-01-04 22:12:00    32.072310
2015-01-04 22:13:00   -25.944314
2015-01-04 22:14:00     8.201273
2015-01-04 22:15:00     8.358418
2015-01-04 22:16:00    -8.162486
2015-01-04 22:17:00   -11.381701
2015-01-04 22:18:00     8.610419
2015-01-04 22:19:00     4.862610
2015-01-04 22:20:00     3.875236
2015-01-04 22:21:00     1.659843

差异的大小有时非常大。 即使我正在寻找 5 位数字的精度,对我来说可以有 10^(-5) 的差异,或者两倍,但我在第一个值中相差高达 60*(10^-5),这太大了。

编辑 2:我查看了 emw 的每个参数,我得到了相同的结果,直接指定了对应于 9 周期 ewma 的 alpha 参数,这意味着我的参数确实是正确的。

默认情况下,adjust 参数设置为 True,查看 pandas 文档:

当调整为 False 时,加权平均值以递归方式计算如下: weighted_average[0] = 参数[0];weighted_average[i] = (1-alpha)*weighted_average[i-1] + alpha*arg[i]。

我将调整参数转换为 False,这应该可以解决问题:

df = m1["open"].ewm(min_periods=9,alpha=0.2,adjust=False).mean()
alpha = 2/(9+1)
df_bis = alpha*m1["open"].shift(1) + (1-alpha)*df.shift(1)
diff_array = df-df_bis
diff_array*10**5
Out[11]: 
DateTime
2015-01-04 22:09:00    -5.6
2015-01-04 22:10:00   -56.8
2015-01-04 22:11:00    27.2
2015-01-04 22:12:00    30.4
2015-01-04 22:13:00   -25.8
2015-01-04 22:14:00     8.0
2015-01-04 22:15:00     8.0
2015-01-04 22:16:00    -8.2
2015-01-04 22:17:00   -11.2
2015-01-04 22:18:00     8.6
2015-01-04 22:19:00     4.8

但它并不能解决我在这里的问题。 我找不到任何可以解释这种差异的东西,有人知道为什么会有差异吗?

以下是熊猫关于该主题的文档,我之前使用的公式来自:http://pandas.pydata.org/pandas-docs/stable/computation.html#exponentially-weighted-windows

我使用的数据非常大,这里有一个示例:

m1["open"]
Out[10]: 
DateTime
2015-01-04 22:00:00    1.19548
2015-01-04 22:01:00    1.19388
2015-01-04 22:02:00    1.19102
2015-01-04 22:03:00    1.18826
2015-01-04 22:04:00    1.19085
2015-01-04 22:05:00    1.19257
2015-01-04 22:06:00    1.19270
2015-01-04 22:07:00    1.19350
2015-01-04 22:08:00    1.19427
2015-01-04 22:09:00    1.19399
2015-01-04 22:10:00    1.19115
2015-01-04 22:11:00    1.19251
2015-01-04 22:12:00    1.19403
2015-01-04 22:13:00    1.19274
2015-01-04 22:14:00    1.19314
2015-01-04 22:15:00    1.19354
2015-01-04 22:16:00    1.19313
2015-01-04 22:17:00    1.19257
2015-01-04 22:18:00    1.19300
2015-01-04 22:19:00    1.19324
2015-01-04 22:20:00    1.19343
2015-01-04 22:21:00    1.19351
2015-01-04 22:22:00    1.19353
2015-01-04 22:23:00    1.19376
2015-01-04 22:24:00    1.19408
2015-01-04 22:25:00    1.19370
2015-01-04 22:26:00    1.19381
2015-01-04 22:27:00    1.19439
2015-01-04 22:28:00    1.19435
2015-01-04 22:29:00    1.19419

解决了这个问题,我只是一个白痴。

我使用了公式:df_bis = alpha*m1["open"].shift(1) + (1-alpha)*df.shift(1)

但是价格不应该在这里移动,正确的计算是:

df_bis = alpha*m1["open"] + (1-alpha)*df.shift(1)

这会产生:

diff_array
Out[24]: 
DateTime
2015-01-04 22:09:00    0.0
2015-01-04 22:10:00    0.0
2015-01-04 22:11:00    0.0
2015-01-04 22:12:00    0.0
2015-01-04 22:13:00    0.0
2015-01-04 22:14:00    0.0
2015-01-04 22:15:00    0.0
2015-01-04 22:16:00    0.0
2015-01-04 22:17:00    0.0
2015-01-04 22:18:00    0.0
2015-01-04 22:19:00    0.0
2015-01-04 22:20:00    0.0

最新更新