Closed vfilimonov closed 9 years ago
Hey Vlad,
Another good idea - the implementation looks good to me.
My only question/concern is the annualization of returns & rates. Since we are currently annualizing the return component as such
daily_mean = r.mean() * 252
monthly_mean = mr.mean() * 12
should we not be doing something similar for the risk-free rate
_daily_rf = _yearly_rf / 252.
_monthly_rf = _yearly_rf / 12.
for sake of consistency? Or alternatively, maybe we should be using geometric compounding to annualize the daily and monthly returns?
The reason I initially used simple returns return * n
is because this is how the Sharpe ratio is typically annualized mean(r) * std(r) * sqrt(252)
. I am aware that this method is not perfect (for example Andrew Lo's paper http://www.edge-fund.com/Lo02.pdf) but it is still the most commonly used way to annualize the Sharpe ratio.
What do you think?
My logic was the following: if we're given the yearly rate _yearly_rf
, then monthly rate should be calculated from the compounding rule P0 * (1+_yearly_rf) = P0 * (1+_monthly_rf) ** 12
, i.e:
_monthly_rf = np.power(1+_yearly_rf, 1./12.) - 1.
Here _yearly_rf / 12.
gives indeed a first order approximation.
When it is calculated in this way, _monthly_rf
is consistent with monthly returns that are calculated via resampled price series (price.resample('M', 'last').to_returns().mean()
).
Now, since we have annualized returns and volatility:
self.monthly_mean = mr.mean() * 12
self.monthly_vol = mr.std() * np.sqrt(12)
self.monthly_sharpe = self.monthly_mean / self.monthly_vol
then we need to subtract from monthly_mean
value, which is annualized in the same way:
_monthly_rf = (np.power(1+_yearly_rf, 1./12.) - 1.) * 12
I think it's OK to keep both average returns and rates annualized as long as it is documented - then daily/monthly/yearly returns, volatilities and Sharpe ratios could be directly compared.
Hey Vlad,
The more I think about it, the more I think your approach was fine to begin with. Thanks again for the pull request!
So far Sharpe ratio was calculated implying rf=0%. Added functionality to change rf both for individual object and "system-wide": for entire class.
TODO later: extent to possibility of having time-series of risk-free ratios
P.S. As I understand from this, daily and monthly returns are annualized? I have
_monthly_rf
and_daily_rf
annualized as well: Phil, please check.