使用1个月和12个月的延迟计算python中的动量信号

时间:2019-03-17 02:20:24

标签: python pandas finance

我想计算一个简单的动量信号。我采用的方法是1个月滞后的cumret除以12个月滞后的cumret减1。

date开始于1/5/14,结束于1/5/16。由于需要12个月的延迟,因此第一个mom信号必须在date开始后的12个月内开始。因此,为什么第一个mom信号从1/5/15开始。

以下是使用的数据:

import pandas as pd

data = {'date':['1/5/14','1/6/14','1/7/14','1/8/14','1/9/14','1/10/14','1/11/14','1/12/14' .,'1/1/15','1/2/15','1/3/15','1/4/15','1/5/15','1/6/15','1/7/15','1/8/15','1/9/15','1/10/15','1/11/15','1/12/15','1/1/16','1/2/16','1/3/16','1/4/16','1/5/16'],
'id': ['a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a' ],
'ret':[0.01, 0.02, 0.03, 0.04, 0.05, 0.06, 0.07, 0.08, 0.09, 0.10, 0.11, 0.12, 0.13, 0.14, 0.15, 0.16, 0.17, 0.18, 0.19, 0.20, 0.21, 0.22, 0.23, 0.24, 0.25],
'cumret':[1.01,1.03,    1.06,1.1    ,1.15,1.21,1.28,    1.36,1.45,1.55,1.66,    1.78,1.91,2.05,2.2,2.36,    2.53,2.71,2.9,3.1,3.31,3.53,    3.76,4,4.25]}

df = pd.DataFrame(data).set_index(['date', 'id'])

所需的输出

           ret  cumret  mom
date    id          
1/5/14  a   .01 1.01    
1/6/14  a   .02 1.03    
1/7/14  a   .03 1.06    
1/8/14  a   .04 1.1 
1/9/14  a   .05 1.15    
1/10/14 a   .06 1.21    
1/11/14 a   .07 1.28    
1/12/14 a   .08 1.36    
1/1/15  a   .09 1.45    
1/2/15  a   .1  1.55    
1/3/15  a   .11 1.66    
1/4/15  a   .12 1.78    
1/5/15  a   .13 1.91    .8
1/6/15  a   .14 2.05    .9
1/7/15  a   .15 2.2     .9
1/8/15  a   .16 2.36    1
1/9/15  a   .17 2.53    1.1
1/10/15 a   .18 2.71    1.1
1/11/15 a   .19 2.9     1.1
1/12/15 a   .2  3.1     1.1
1/1/16  a   .21 3.31    1.1
1/2/16  a   .22 3.53    1.1
1/3/16  a   .23 3.76    1.1
1/4/16  a   .24 4       1.1
1/5/16  a   .25 4.25    1.1

这是试图计算mom

的代码
df['mom'] = ((df['cumret'].shift(-1) / (df['cumret'].shift(-12))) - 1).groupby(level = ['id'])

整个数据集有更多id,例如a,b,c在此示例中仅包含1个变量。

任何帮助都会很棒! :)

1 个答案:

答案 0 :(得分:2)

据我所知,动量只是变化率。熊猫对此有内置方法:

df['mom'] = df['ret'].pct_change(12) # 12 month change

此外,我不确定您为什么要使用“ cumret”而不是“ ret”来计算动量。

更新:如果您需要使用多个ID,我建议:

for i in df.index.levels[1]:
    temp = df.loc[(slice(None), i), "ret"].pct_change(11) 
    df.loc[(slice(None), i), "mom"] = temp
    # or df.loc[(slice(None), i), "mom"] = df.loc[(slice(None), i), "ret"].pct_change(11) for short

输出:

             ret    cumret  mom
date    id          
1/5/14  a   0.01    1.01    NaN
1/6/14  a   0.02    1.03    NaN
1/7/14  a   0.03    1.06    NaN
1/8/14  a   0.04    1.10    NaN
1/9/14  a   0.05    1.15    NaN
1/10/14 a   0.06    1.21    NaN
1/11/14 a   0.07    1.28    NaN
1/12/14 a   0.08    1.36    NaN
1/1/15  a   0.09    1.45    NaN
1/2/15  a   0.10    1.55    NaN
1/3/15  a   0.11    1.66    NaN
1/4/15  a   0.12    1.78    11.000000
1/5/15  a   0.13    1.91    5.500000
1/6/15  a   0.14    2.05    3.666667
1/7/15  a   0.15    2.20    2.750000
1/8/15  a   0.16    2.36    2.200000
1/9/15  a   0.17    2.53    1.833333
1/10/15 a   0.18    2.71    1.571429
1/11/15 a   0.19    2.90    1.375000
1/12/15 a   0.20    3.10    1.222222
1/1/16  a   0.21    3.31    1.100000
1/2/16  a   0.22    3.53    1.000000
1/3/16  a   0.23    3.76    0.916667
1/4/16  a   0.24    4.00    0.846154
1/5/16  a   0.25    4.25    0.785714
1/5/14  b   0.01    1.01    NaN
1/6/14  b   0.02    1.03    NaN
1/7/14  b   0.03    1.06    NaN
1/8/14  b   0.04    1.10    NaN
1/9/14  b   0.05    1.15    NaN
1/10/14 b   0.06    1.21    NaN
1/11/14 b   0.07    1.28    NaN
1/12/14 b   0.08    1.36    NaN
1/1/15  b   0.09    1.45    NaN
1/2/15  b   0.10    1.55    NaN
1/3/15  b   0.11    1.66    NaN
1/4/15  b   0.12    1.78    11.000000
1/5/15  b   0.13    1.91    5.500000
1/6/15  b   0.14    2.05    3.666667
1/7/15  b   0.15    2.20    2.750000
1/8/15  b   0.16    2.36    2.200000
1/9/15  b   0.17    2.53    1.833333
1/10/15 b   0.18    2.71    1.571429
1/11/15 b   0.19    2.90    1.375000
1/12/15 b   0.20    3.10    1.222222
1/1/16  b   0.21    3.31    1.100000
1/2/16  b   0.22    3.53    1.000000
1/3/16  b   0.23    3.76    0.916667
1/4/16  b   0.24    4.00    0.846154
1/5/16  b   0.25    4.25    0.785714