DMA移动均线的算法求解,多谢


(189) #1

dma是动态移动平均线:用dma(x,a)表示。

若y=dma(x,a) ,则y=a*x+(1-a)*y'。其中y'表示上一周期y值,a必须小于1.
它与sma是一家的,看:y=m/n*x+(n-m)/n*y';y=a*x+(1-a)*y';
前者说n必须大于m,后者说a必须小于1.然后两者就一样了
:a=m/n.a要取小数才行.dma在第一根k线就开始起算,sma要到第二根k线开始起算.

(iQuant) #2

dma的计算如你所说,其实和指数移动平均线类似。但是,talib默认的ema函数不能调整a这个系数,因此您可以参考下面代码:

克隆策略
In [9]:
def get_EMA(df,a):  
    for i in range(len(df)):  
        if i==0:  
            df.ix[i,'ema']=df.ix[i,'close']  
        if i>0:  
            df.ix[i,'ema']=(1-a)*df.ix[i-1,'close']+a*df.ix[i,'close']  
    return df  
In [14]:
df = D.history_data(['000001.SZA'], '2017-01-01', '2017-10-01',['open','low','close'])
In [16]:
get_EMA(df,0.7).plot()
Out[16]:
<matplotlib.axes._subplots.AxesSubplot at 0x7fd027aa6cc0>

(189) #3

请问如果我有一堆股票,比如股票池的数据dateframe,
df = D.history_data([‘000300.SHA’], start_date, end_date, fields=[‘close’,‘low’,‘high’,‘open’])

怎样才能逐个求得每个股票的get_EMA??并且把它合并到df的最后一列


(iQuant) #4

您可以参考下面的例子,主要用了groupby和apply两函数,我们只选取前十只股票,缩短了运行的时间,您可改为全市场。

克隆策略
In [16]:
def get_EMA(df,a=0.7):  
    df['ema'] = range(len(df))
    for i in range(len(df)): 
        df.index = range(len(df))
        if i==0:  
            df.ix[i,'ema']=df.ix[i,'close']  
        if i>0:  
            df.ix[i,'ema']=(1-a)*df.ix[i-1,'close']+a*df.ix[i,'close']  
    return df  
In [17]:
df = D.history_data(D.instruments()[:10], '2017-01-01', '2017-10-01',['open','high','low','close'])
In [19]:
result = df.groupby('instrument').apply(get_EMA)
print(result)
                      open         low  instrument       date         high  \
instrument                                                                   
000001.SZA 0    954.347656  952.252502  000001.SZA 2017-01-03   961.680786   
           1    958.538025  957.490417  000001.SZA 2017-01-04   961.680786   
           2    960.633179  958.538025  000001.SZA 2017-01-05   961.680786   
           3    960.633179  954.347656  000001.SZA 2017-01-06   960.633179   
           4    956.442871  954.347656  000001.SZA 2017-01-09   960.633179   
           5    958.538025  957.490417  000001.SZA 2017-01-10   959.585571   
           6    957.490417  956.442871  000001.SZA 2017-01-11   960.633179   
           7    956.442871  956.442871  000001.SZA 2017-01-12   960.633179   
           8    957.490417  955.395264  000001.SZA 2017-01-13   962.728333   
           9    958.538025  950.157349  000001.SZA 2017-01-16   959.585571   
           10   955.395264  953.300110  000001.SZA 2017-01-17   959.585571   
           11   957.490417  956.442871  000001.SZA 2017-01-18   962.728333   
           12   958.538025  958.538025  000001.SZA 2017-01-19   967.966248   
           13   960.633179  960.633179  000001.SZA 2017-01-20   966.918701   
           14   965.871094  963.775940  000001.SZA 2017-01-23   970.061401   
           15   966.918701  963.775940  000001.SZA 2017-01-24   972.156616   
           16   971.109009  969.013855  000001.SZA 2017-01-25   972.156616   
           17   971.109009  970.061401  000001.SZA 2017-01-26   978.442078   
           18   978.442078  966.918701  000001.SZA 2017-02-03   980.537231   
           19   970.061401  970.061401  000001.SZA 2017-02-06   976.346924   
           20   975.299316  971.109009  000001.SZA 2017-02-07   976.346924   
           21   973.204163  967.966248  000001.SZA 2017-02-08   974.251770   
           22   974.251770  972.156616  000001.SZA 2017-02-09   977.394470   
           23   976.346924  975.299316  000001.SZA 2017-02-10   980.537231   
           24   978.442078  977.394470  000001.SZA 2017-02-13   988.917908   
           25   985.775146  981.584839  000001.SZA 2017-02-14   986.822754   
           26   984.727600  983.679993  000001.SZA 2017-02-15   999.393738   
           27   989.965515  986.822754  000001.SZA 2017-02-16   995.203430   
           28   991.013062  981.584839  000001.SZA 2017-02-17   994.155823   
           29   984.727600  984.727600  000001.SZA 2017-02-20  1003.584045   
...                    ...         ...         ...        ...          ...   
000011.SZA 154   64.563461   64.120552  000011.SZA 2017-08-21    65.278946   
           155   65.074524   64.733818  000011.SZA 2017-08-22    66.232918   
           156   65.040451   64.052406  000011.SZA 2017-08-23    65.040451   
           157   64.018341   63.030296  000011.SZA 2017-08-24    64.699745   
           158   63.507282   63.132507  000011.SZA 2017-08-25    64.495323   
           159   63.916126   63.916126  000011.SZA 2017-08-28    65.415222   
           160   67.800156   65.858139  000011.SZA 2017-08-29    69.265182   
           161   66.709900   66.505478  000011.SZA 2017-08-30    70.798355   
           162   68.822266   67.459450  000011.SZA 2017-08-31    68.822266   
           163   67.766083   66.437340  000011.SZA 2017-09-01    68.072716   
           164   66.743973   66.028496  000011.SZA 2017-09-04    67.936440   
           165   67.527596   67.118744  000011.SZA 2017-09-05    69.231117   
           166   67.527596   66.505478  000011.SZA 2017-09-06    67.732018   
           167   67.357239   66.607689  000011.SZA 2017-09-07    68.447495   
           168   67.016533   66.471413  000011.SZA 2017-09-08    74.307610   
           169   71.547905   70.900566  000011.SZA 2017-09-11    74.069115   
           170   71.207199   70.696144  000011.SZA 2017-09-12    72.195244   
           171   71.309410   69.912521  000011.SZA 2017-09-13    71.377548   
           172   70.253227   69.946594  000011.SZA 2017-09-14    72.535942   
           173   70.764282   70.219154  000011.SZA 2017-09-15    72.535942   
           174   71.207199   70.934639  000011.SZA 2017-09-18    74.205399   
           175   71.002777   71.002777  000011.SZA 2017-09-19    75.704498   
           176   72.058960   70.185089  000011.SZA 2017-09-20    72.399666   
           177   70.627998   69.435539  000011.SZA 2017-09-21    71.377548   
           178   69.162971   67.732018  000011.SZA 2017-09-22    69.367393   
           179   67.459450   64.733818  000011.SZA 2017-09-25    67.459450   
           180   65.006378   65.006378  000011.SZA 2017-09-26    66.028496   
           181   65.755928   65.449295  000011.SZA 2017-09-27    66.505478   
           182   66.096634   65.176735  000011.SZA 2017-09-28    66.096634   
           183   65.347084   65.347084  000011.SZA 2017-09-29    66.232918   

                      close         ema  
instrument                               
000001.SZA 0     959.585571  959.585571  
           1     959.585571  959.585571  
           2     960.633179  960.318909  
           3     956.442871  957.699951  
           4     958.538025  957.909485  
           5     958.538025  958.538025  
           6     957.490417  957.804688  
           7     958.538025  958.223755  
           8     959.585571  959.271301  
           9     957.490417  958.118958  
           10    958.538025  958.223755  
           11    960.633179  960.004639  
           12    961.680786  961.366516  
           13    965.871094  964.614014  
           14    965.871094  965.871094  
           15    971.109009  969.537659  
           16    970.061401  970.375671  
           17    977.394470  975.194580  
           18    970.061401  972.261353  
           19    975.299316  973.727966  
           20    974.251770  974.566040  
           21    974.251770  974.251770  
           22    975.299316  974.985046  
           23    977.394470  976.765930  
           24    985.775146  983.260925  
           25    984.727600  985.041870  
           26    989.965515  988.394165  
           27    991.013062  990.698792  
           28    983.679993  985.879883  
           29   1001.488892  996.146240  
...                     ...         ...  
000011.SZA 154    64.563461   64.645233  
           155    65.244873   65.040451  
           156    64.120552   64.457848  
           157    63.507282   63.691261  
           158    64.154617   63.960419  
           159    65.142662   64.846252  
           160    66.266983   65.929688  
           161    69.094833   68.246475  
           162    67.732018   68.140862  
           163    66.914322   67.159630  
           164    67.936440   67.629807  
           165    67.220955   67.435600  
           166    67.220955   67.220955  
           167    67.561661   67.459450  
           168    74.307610   72.283829  
           169    72.808510   73.258240  
           170    71.888611   72.164581  
           171    70.662071   71.030029  
           172    71.343483   71.139061  
           173    70.355438   70.651855  
           174    71.547905   71.190163  
           175    73.251427   72.740372  
           176    71.411621   71.963562  
           177    69.571815   70.123756  
           178    67.766083   68.307800  
           179    65.006378   65.834290  
           180    65.687790   65.483368  
           181    66.164772   66.021675  
           182    65.176735   65.473145  
           183    66.096634   65.820663  

[1840 rows x 7 columns]


(189) #5

多谢!其实我发现我的问题还要复杂一点点,即a=0.7这里,我的a值是DF其中一列,可以说是一个小于1的因子
考虑到这样我就算出新的一列ema值,但是
这样我在用apply函数时就会出错,说是好像a不能是变量?汗!
改用map函数好像也不行


(189) #6

另外在你们的后台崩溃以后,我测试时出现一个之前没有过的奇怪错误,Q群主叫我分享这里

TypeError Traceback (most recent call last)
in ()
3 bm_price = D.history_data([‘000300.SHA’], start_date, end_date, fields=[‘close’,‘low’,‘high’,‘open’,‘amount’])
4 df = D.history_data(D.instruments(),start_date,end_date,fields=[‘in_csi800’])
----> 5 instruments = list(set(df[df[‘in_csi800’]==1][‘instrument’]))
6 stock_raw_data = D.history_data(instruments, start_date, end_date,fields=[‘list_date’,‘open’, ‘high’, ‘low’, ‘close’, ‘amount’])
7 bm_price[‘sma_c’] =(bm_price[‘close’].rolling(10).mean()//bm_price[‘close’])

TypeError: ‘Series’ object is not callable


(hugo) #7

你好,我这里如果要求10天的收益率

def stock_return(df):
    df['stock_return']=df['close']/df['close'].shift(10)-1
    return df

在执行data.groupby('instrument').apply(stock_return)这一步是数据一直跑不出来,是因为计算过大么?
有什么其他方法吗?


(小Q) #8

是不是你时间跨度很长,我拿一年的数据计算,时间是6秒。

克隆策略
In [19]:
t = datetime.datetime.now()
df = D.history_data(D.instruments(),'2016-05-01','2017-05-01',['close'])

def calcu(df):
    df['ret_10'] = df['close']/df['close'].shift(10)-1
    return df
result = df.groupby('instrument').apply(calcu)
print('一年数据计算运行时间:%s 秒'%(datetime.datetime.now() -t).seconds)
一年数据计算运行时间:6 秒
In [17]:
result.tail()
Out[17]:
instrument close date ret_10
957294 603993.SHA 14.108046 2017-04-28 -0.111111
957295 603996.SHA 26.739563 2017-04-28 -0.134086
957296 603997.SHA 26.249878 2017-04-28 0.008152
957297 603998.SHA 58.263962 2017-04-28 -0.077114
957298 603999.SHA 28.452599 2017-04-28 -0.105602


(hugo) #10

D.history_data(D.instruments(),'2016-05-01','2017-05-01',['close']).set_index('date')这样之后会影响计算么?去掉这个后计算就跟你一样了