在python中通过pandas系列滚动自定义函数

时间:2016-11-14 18:55:20

标签: python pandas dataframe series finance

我有一个熊猫系列

Date
2016-11-01    100000.000000
2016-11-02    100500.648302
2016-11-03    100481.450478
2016-11-04     99550.193742
2016-11-07    101913.648567

我正在尝试计算此系列的滚动锐利率。锐化率的公式是

sharpe = np.sqrt(252)*(average_daily_returns/volatility)

我们可以将每日报表计算为

daily_returns = (series/series.shift(1))-1
daily_returns = daily_returns[1:]

然后平均_daily_returns变为

average_daily_returns = daily_returns.mean()

并且波动性变为

volatility = daily_returns.std()

我正在尝试在系列中滚动锐化比率。所以我想计算第1天的锐化比率,然后是第1天和第2天,然后是第1天,第2天和第3天,然后是第1天和第2天,以及......和第n天,其中n是系列中的最后一个日期。 / p>

我创建了以下功能:

def sharpe(s): 
    daily_returns = (s/s.shift(1))-1
    daily_returns = daily_returns[1:]
    average_daily_returns = daily_returns.mean()
    volatility = daily_returns.std()
    sharpe = np.sqrt(252)*(average_daily_returns/volatility)

上面这个函数将计算传入的每个系列的锐化率。我想在这个系列上滚动这个函数。因此,在(2016-11-01)然后(2016-11-01和2016-11-02)然后(2016-11-01和2016-11-02和2016-01-03)上滚动此功能。 ..

我查看了pandas.rolling_apply和doccumentation(http://pandas.pydata.org/pandas-docs/version/0.17.0/generated/pandas.rolling_apply.html),但我无法使用我的函数。看起来rolling_apply只在我执行诸如求和,平均值或简单计算之类的函数时才起作用。我已经尝试了很多这方面的变化,但迄今为止没有任何工作。例如使用

(pv.rolling(2)).apply(#I am not sure how I can fit the sharpe ratio function in here)

1 个答案:

答案 0 :(得分:0)

考虑使用Date索引构建pandas系列的列表理解。每个元素都是按日期传递到sharpe()函数的过滤系列:

import numpy as np
import pandas as pd

data = pd.Series([100000.000000, 100500.648302, 100481.450478, 99550.193742, 101913.648567],
                 index=pd.DatetimeIndex(['2016-11-01', '2016-11-02', '2016-11-03',
                                         '2016-11-04', '2016-11-07'], name='Date'))
print(data)
# Date
# 2016-11-01    100000.000000
# 2016-11-02    100500.648302
# 2016-11-03    100481.450478
# 2016-11-04     99550.193742
# 2016-11-07    101913.648567
# dtype: float64

def sharpe(s): 
    daily_returns = (s/s.shift(1))-1
    daily_returns = daily_returns[1:]
    average_daily_returns = daily_returns.mean()
    volatility = daily_returns.std()
    sharpe = np.sqrt(252)*(average_daily_returns/volatility)
    return(sharpe)

newdata = pd.Series([sharpe(data[data.index <= d]) for d in data.index.values],
                   index=pd.DatetimeIndex(data.index.values, name='Date'))    
print(newdata)
# Date
# 2016-11-01          NaN
# 2016-11-02          NaN
# 2016-11-03    10.399878
# 2016-11-04    -3.261154
# 2016-11-07     5.497725
# dtype: float64