简体   繁体   中英

Rolling a custom function over pandas series in python

I have a pandas series

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

I am trying to calculate a rolling sharpe ratio on this series. The formula for the sharpe ratio is

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

where we can calculate daily returns as

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

then average _daily_returns becomes

average_daily_returns = daily_returns.mean()

and volatility becomes

volatility = daily_returns.std()

I am trying to roll the sharpe ratio over the series. So I want to calculate the sharpe ratio for day 1 then day 1 and day 2 then day 1 and day 2 and day 3 then day 1 and day 2 and ... and day n where n is the last date in the series.

I have created the following function:

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)

This above function will calculate the sharpe ratio for each series passed in. I want to roll this function over the series. So, roll this function on (2016-11-01) then on (2016-11-01 and 2016-11-02) then on (2016-11-01 and 2016-11-02 and 2016-01-03) ...

I have looked at pandas.rolling_apply and the doccumentation ( http://pandas.pydata.org/pandas-docs/version/0.17.0/generated/pandas.rolling_apply.html ) but I can not get this to work with my function. It seems that the rolling_apply is only working when I do a function such as a sum, mean, or simple calculation like that. I have tried many variations of this but nothing has worked so far. For instance using

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

Consider a list comprehension using the Date index to build a pandas Series. Each element is a filtered series by dates passed into the sharpe() function:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM