Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/276.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用python更快地计算指数移动平均值?_Python_Pandas_Numpy_Finance_Quantitative Finance - Fatal编程技术网

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

如何使用python更快地计算指数移动平均值?,python,pandas,numpy,finance,quantitative-finance,Python,Pandas,Numpy,Finance,Quantitative Finance,我正忙于构建回溯测试软件,但我在创建指数移动平均线时遇到了麻烦。我使用for循环成功地创建了它,但每个要测试的符号运行大约需要20秒(太长) 如果有人有任何建议,我正试图找到一个更快的解决方案 我当前的代码看起来像这样,但它不会产生正确的结果 def exponential_moving_average(df, period): # Create a copy of original dataframe to work with. dataframe = df.copy()

我正忙于构建回溯测试软件,但我在创建指数移动平均线时遇到了麻烦。我使用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']
此方法位于Indicators类中,输入采用以下内容

  • df
    是每天的
    开盘价、高价、低价
    收盘价
    以及任何其他用于回溯测试和预测的指标
  • 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\u ma
(10天期间)的预期结果


我更改了第一个数据帧的值,以便它显示用于计算
slow\u ma
值的数字

这是我在Stackoverflow上的第一篇文章,所以问问是否有什么不清楚的地方

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

在旧的2.6[GHz]i5设备上,在
<50[us]
下为您的大小数据/周期提供的速度可实现


第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
        ]
      )
与上面第一个表中的值(即低于LSD的2个数量级)相比,存在一些数值表示差异

第1步:调整(QA确认)处理以提高速度 在这个阶段,很大程度上取决于使用的外部环境

从cythonize()
可以预期最佳结果,但评测可能会在运行中显示一些惊喜

无需将处理移到cython代码中,您就可以在全球使用
float64
-s而不是
float32
-s(在类似EMA深度上被削掉了一些
110~200[us]
),矢量化就地分配(约2倍加速,从
~100[us]
~50[us]
在更好地结合矢量内存分配(结果矢量及其矢量化值处理)和最佳情况下,如果数学重新公式化可以帮助跳过一些纯粹的“机械”操作

然而,所有的加速技巧都依赖于使用的工具——如果是纯的
,或者
numpy+numba
(这可能会对EMA这类毫无疑问的琐碎处理产生负面影响——对“杰克逊博士”来说,没有多少数学上的)或者是cython的优化解决方案,因此如果要获得最佳结果,必须在目标CPU环境中进行评测


正在尝试找到更快的解决方案

在给定的
[SPACE]
-域数据规模(
window==10
aPriceVECTOR.shape[0]~15
)上,更新您的帖子,说明您的预期目标加速比,或者更好地说明所述问题的
[TIME]
-域中的每次呼叫处理成本,如果目标代码执行平台有一些硬件/CPU/缓存层次结构组合约束或没有,因为构建backtester平台实际上非常强调任何和所有代码设计+代码执行效率低下


鉴于EMA相当有效,工具可能会获得约4倍的加速 QuantFX的故事已经从
~42000[美国]
下降到
~21000[美国]
,没有
numba
/JIT工具,只需重新制定和优化内存向量处理(使用人工大小的工作负载,处理
aPV[:10000]块)

接下来,运行时间下降到
~10600[us]
,使用原样的Cpython代码库,只要有自动Cythonise的权限,就可以使用
pyximport导入
-ed代码:

pass;        import pyximport
pass;               pyximport.install( pyimport = True )
from QuantFX import numba_EMA_fromPrice2
...
因此,可以获得速度
~45~47[美国]
在普通2.6[GHz]i5设备上,针对您的大小数据
aPV[:15]
,周期=10



如果坚持使用pandas
数据框架工具和方法,您的表现主要掌握在pandas团队手中,在设计折衷方面没有太多需要做,这必须在速度和普遍性之间的两难境地中完成。

你能分享一个结果错误的数据帧片段吗(也不确定输入中的
span=period
是否有意义)根据我的理解,span是公式α=2/(span+1),它是加权均线的乘数,span是我想要计算的时段。例如,它也可以写为(2/(选定时间段+1))=(2/(10+1))=0.1818(18.18%)。对于您提供的样本,
slow\u ma
的值是多少您在
期间使用的值是多少?我已经更改了第一个数据帧的值,以显示用于计算慢速的值,第二个数据帧包含预期结果。我用来缩短数据帧的时间是10天
|>>> ( 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
         ]
        )
pass;        import pyximport
pass;               pyximport.install( pyimport = True )
from QuantFX import numba_EMA_fromPrice2
...