首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何用python更快地计算指数移动平均?

如何用python更快地计算指数移动平均?
EN

Stack Overflow用户
提问于 2018-05-23 04:27:24
回答 1查看 3.8K关注 0票数 2

我正忙着构建反测试软件,我在创建指数移动平均线时遇到了麻烦。我成功地使用了for循环创建了它,但是我想测试的每个符号运行时间大约是20秒(太长了)。

如果有人有任何建议的话,我正试图找到一个更快的解决方案。

我的当前代码如下所示,但它不会产生正确的结果。

代码语言:javascript
复制
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, LowClose价格以及将用于回溯测试的任何其他指标。
  • period是必须计算的指数移动平均值的“窗口”或天数。

下面是一个具有df值的片段:

代码语言:javascript
复制
            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天)

代码语言:javascript
复制
            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的文章,所以只需问一问是否有什么不清楚。

EN

回答 1

Stack Overflow用户

发布于 2018-05-25 08:24:24

如何用python 更快地计算指数移动平均?

速度在< 50 [us]下的为您的大小的数据/期间在一个旧的2.6 GHz i5设备上可以实现.

步骤0:获得结果(过程)通过质量保证

快速但错误的数据会带来负面的附加值,对吗?

如果您使用的是“硬连线”.ewm()方法,那么您可以重新读取它的参数化选项,如果可以使用不同的dataframe['Close']列处理模式的话。

作为快速检查:

代码语言:javascript
复制
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个阶)。

代码语言:javascript
复制
|>>> ( 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 == 10aPriceVECTOR.shape[0] ~ 15 )上,在[TIME]-domain中更新您的帖子,说明您期望的目标加速,或者更好的目标每调用处理成本,这将是很有趣的。

如果EMA是合理有效的,工具可能得到~4倍的加速比

通过重新构造和内存优化的向量处理(使用人工大小的工作负载,处理一个aPV[:10000]块),QuantFX的故事已经从~ 42000 [us]发展到没有numba/JIT工具的~ 21000[us]

接下来,运行时下降到使用as-is Cpython代码库的~ 10600 [us],,只要允许在可能的情况下使用pyximportimport-ed代码自动Cythonise。

代码语言:javascript
复制
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的数据工具和方法,你的表现主要掌握在熊猫团队的手中,在设计妥协方面没有什么可做的,这必须在速度和普遍性之间一直处于两难境地。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50479789

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档