我在尝试用熊猫计算指数加权移动平均线 (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
应该始终正确,因为df
和df_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