我正忙着构建反测试软件,我在创建指数移动平均线时遇到了麻烦。我成功地使用了for循环创建了它,但是我想测试的每个符号运行时间大约是20秒(太长了)。
如果有人有任何建议的话,我正试图找到一个更快的解决方案。
我的当前代码如下所示,但它不会产生正确的结果。
def exponential_moving_average(df, period):
# Create a copy of original dataframe to work with.
dataframe = df.copy()
dataframe['EMA'] = dataframe['Close'].ewm( span = period,
adjust = False,
min_periods = period,
ignore_na = True
).mean()
return dataframe['EMA']此方法属于Indicator类,输入如下所示。
df是指每日Open, High, Low和Close价格以及将用于回溯测试的任何其他指标。period是必须计算的指数移动平均值的“窗口”或天数。下面是一个具有df值的片段:
symbol Open High Low Close ATR slow_ma
Date
2010-01-03 EURUSD 1.43075 1.43369 1.43065 1.43247 NaN NaN
2010-01-04 EURUSD 1.43020 1.44560 1.42570 1.44120 NaN NaN
2010-01-05 EURUSD 1.44130 1.44840 1.43460 1.43650 NaN NaN
2010-01-06 EURUSD 1.43660 1.44350 1.42820 1.44060 NaN NaN
2010-01-07 EURUSD 1.44070 1.44470 1.42990 1.43070 NaN NaN
2010-01-08 EURUSD 1.43080 1.44380 1.42630 1.44160 NaN NaN
2010-01-10 EURUSD 1.44245 1.44252 1.44074 1.44110 NaN NaN
2010-01-11 EURUSD 1.44280 1.45560 1.44080 1.45120 NaN NaN
2010-01-12 EURUSD 1.45120 1.45450 1.44530 1.44840 NaN NaN
2010-01-13 EURUSD 1.44850 1.45790 1.44570 1.45100 NaN 1.442916
2010-01-14 EURUSD 1.45090 1.45550 1.44460 1.44990 NaN 1.444186
2010-01-15 EURUSD 1.45000 1.45110 1.43360 1.43790 NaN 1.443043
2010-01-17 EURUSD 1.43597 1.43655 1.43445 1.43480 NaN 1.441544
2010-01-18 EURUSD 1.43550 1.44000 1.43340 1.43830 NaN 1.440954
2010-01-19 EURUSD 1.43820 1.44130 1.42520 1.42870 NaN 1.438726以下是slow_ma的预期结果(10天)
symbol Open High Low Close ATR slow_ma
Date
2010-01-03 EURUSD 1.43075 1.43369 1.43065 1.43247 NaN NaN
2010-01-04 EURUSD 1.43020 1.44560 1.42570 1.44120 NaN NaN
2010-01-05 EURUSD 1.44130 1.44840 1.43460 1.43650 NaN NaN
2010-01-06 EURUSD 1.43660 1.44350 1.42820 1.44060 NaN NaN
2010-01-07 EURUSD 1.44070 1.44470 1.42990 1.43070 NaN NaN
2010-01-08 EURUSD 1.43080 1.44380 1.42630 1.44160 NaN NaN
2010-01-10 EURUSD 1.44245 1.44252 1.44074 1.44110 NaN NaN
2010-01-11 EURUSD 1.44280 1.45560 1.44080 1.45120 NaN NaN
2010-01-12 EURUSD 1.45120 1.45450 1.44530 1.44840 NaN NaN
2010-01-13 EURUSD 1.44850 1.45790 1.44570 1.45100 NaN 1.44351
2010-01-14 EURUSD 1.45090 1.45550 1.44460 1.44990 NaN 1.44467
2010-01-15 EURUSD 1.45000 1.45110 1.43360 1.43790 NaN 1.44344
2010-01-17 EURUSD 1.43597 1.43655 1.43445 1.43480 NaN 1.44187
2010-01-18 EURUSD 1.43550 1.44000 1.43340 1.43830 NaN 1.44122
2010-01-19 EURUSD 1.43820 1.44130 1.42520 1.42870 NaN 1.43894我已经更改了第一个dataframe的值,以便它显示用于计算slow_ma值的数字。
这是我第一篇关于Stackoverflow的文章,所以只需问一问是否有什么不清楚。
发布于 2018-05-25 08:24:24
如何用python 更快地计算指数移动平均?
速度在< 50 [us]下的为您的大小的数据/期间在一个旧的2.6 GHz i5设备上可以实现.
步骤0:获得结果(过程)通过质量保证
快速但错误的数据会带来负面的附加值,对吗?
如果您使用的是“硬连线”.ewm()方法,那么您可以重新读取它的参数化选项,如果可以使用不同的dataframe['Close']列处理模式的话。
作为快速检查:
aPV = [ 1.43247, # borrowed from dataframe['Close']
1.44120,
1.43650,
1.44060, 1.43070, 1.44160, 1.44110, 1.45120, 1.44840,
1.45100, 1.44990, 1.43790, 1.43480, 1.43830, 1.42870,
]
|>>> QuantFX.numba_EMA_fromPrice2( N_period = 10,
aPriceVECTOR = QuantFX.np.array( aPV )
)
array([
1.43247 ,
1.43405727,
1.4345014 ,
1.43561024,
1.43471747,
1.43596884,
1.43690178,
1.43950145,
1.44111937,
1.44291585,
1.44418569,
1.44304284,
1.44154414,
1.4409543 ,
1.43872624
]
)其中有一些~ +/- 3E-7数值表示的差异,与第一个表中的值(即低于LSD的2个阶)。
|>>> ( QuantFX.numba_EMA_fromPrice2( 10,
QuantFX.np.array( aPV )
)
- QuantFX.np.array( slow_EMA_1 )# values borrowed from Table 1 above
)
array([ nan,
nan,
nan,
nan,
nan,
nan,
nan,
nan,
nan,
-1.50656152e-07,
-3.05082306e-07,
-1.58703705e-07,
1.42878787e-07,
2.98719007e-07,
2.44406460e-07
]
)步骤1:调整(QA确认的)处理以提高速度
在这个阶段,很大程度上取决于使用的外部环境。
最好的结果可以期待从cythonize(),,但剖析可能会显示出一些意外的动态。
如果不将处理转移到cython代码中,就可以在全球范围内使用float64-s而不是float32-s (在类似的EMA深度上去除了一些110 ~ 200 [us] )、向量化的位置分配(~ 2x加速比,从~ 100 [us]到~ 50 [us],以更好的组合向量--结果向量的内存分配及其向量值处理)获得有趣的加速,而且最好的情况是,数学重构可以帮助完全跳过一些“机械”操作。
然而,所有的加速技巧都取决于已使用的工具--如果一个纯粹的numpy,或numpy + numba (这可能会对像EMA这样琐碎的处理产生负面影响)或cython-optimised解决方案没有太多的数学“ for Dr.Jackson”,或者cython-optimised解决方案,那么,如果要交付最好的结果,就必须在目标CPU上下文中进行分析。
试图找到一个更快的解决方案.
如果目标代码执行平台具有某种硬件/ CPU /cache层次结构的组合约束,或者构建一个backtester-platform实际上在很大程度上强调了设计+代码执行inefficiencies.,那么在给定的[SPACE]-domain数据规模( window == 10,aPriceVECTOR.shape[0] ~ 15 )上,在[TIME]-domain中更新您的帖子,说明您期望的目标加速,或者更好的目标每调用处理成本,这将是很有趣的。
如果EMA是合理有效的,工具可能得到~4倍的加速比
通过重新构造和内存优化的向量处理(使用人工大小的工作负载,处理一个aPV[:10000]块),QuantFX的故事已经从~ 42000 [us]发展到没有numba/JIT工具的~ 21000[us]。
接下来,运行时下降到使用as-is Cpython代码库的~ 10600 [us],,只要允许在可能的情况下使用pyximport的import-ed代码自动Cythonise。
pass; import pyximport
pass; pyximport.install( pyimport = True )
from QuantFX import numba_EMA_fromPrice2
...所以,可以得到速度
对于大小为~ 45 ~ 47 [us]的数据aPV[:15],在普通的2.6 GHz i5设备上,句号= 10。
如果坚持使用pandas的数据工具和方法,你的表现主要掌握在熊猫团队的手中,在设计妥协方面没有什么可做的,这必须在速度和普遍性之间一直处于两难境地。
https://stackoverflow.com/questions/50479789
复制相似问题