Price Return
The price return on an asset over some period, between time and is given by .
Code for getting returns from prices
import pandas as pd
def returns1(prices):
return prices.pct_change()
def returns2(prices):
return prices/prices.shift(1) - 1
def returns3(prices):
return prices.iloc[1:].values/prices.iloc[:-1] - 1
Total Return
If the asset pays a dividend during the time period to the total return is given by .
Multiperiod Return
If is the return in the time period to and is the return for the time period to . The total compounded return over the period to is given by .
Comparing return across time periods
Returns across different time periods can be compared using a process called annualization.
If is the return for a given period and there are such periods in a year then the annualized return is given by .
If are the returns over months and there are such time periods in a year, the annualized return is given by
Code for calculating Annualized return
def annualize_rets(r, periods_per_year):
compounded_growth = (1+r).prod()
n_periods = r.shape[0]
return compounded_growth**(periods_per_year/n_periods)-1
Measures of Volatility
Standard deviation
If is the random variable of the returns, the volatility is given by .
If are a series of returns, then the volatility is given by the standard deviation of the returns
Here we are computing standard deviation assuming the returns are a sample from an unknown distribution.
Code for calculating volatility
def volatility(returns):
return returns.std()
Annualized volatility
If there are periods in a year and the volatility during a given period is given by . The annualized volatility is given by .
Code for calculating Annualized volatility
def annualize_vol(r, periods_per_year):
return r.std()*(periods_per_year**0.5)
Comparing returns with different volatility
The Sharpe ratio is the excess return per unit of volatility and is given by .
Code for calculating Sharpe ratio
def sharpe_ratio(monthly_returns, riskfree_rate):
annualized_vol = monthly_returns.std()*np.sqrt(12)
n_months = len(monthly_returns)
annualized_return = (monthly_returns+1).prod()**(12/n_months) - 1
return (annualized_return - riskfree_rate)/annualized_vol
Drawdowns
A very popular measure of risk is called the maximum drawdown. Maximum drawdown is the maximum loss that you could have experienced, it is the worst return of the peak to trough that you could have experienced over the time that the return series are being analyzed.
Algorithm for computing drawdowns
- Convert the time series of returns to a time series that represents a wealth index. A wealth index is just the current amount of wealth what would have happened if I had taken letβs say a dollar or a \$1,000, and invested it over time. Just buy and hold. Just kept it in that asset all the way through that period.
- Compute a time series of the previous peaks.
- Compute the Drawdown as the difference between the previous peak and the current value.
- Compute the maximum of all drawdowns.
Code for computing drawdowns
def drawdown(return_series: pd.Series):
"""Takes a time series of asset returns.
returns a DataFrame with columns for
the wealth index,
the previous peaks, and
the percentage drawdown
"""
wealth_index = 1000*(1+return_series).cumprod()
previous_peaks = wealth_index.cummax()
drawdowns = (wealth_index - previous_peaks)/previous_peaks
return pd.DataFrame({"Wealth": wealth_index,
"Previous Peak": previous_peaks,
"Drawdown": drawdowns})
max_drawdown = drawdown(return_series)["Drawdown"].max()
Problems with drawdowns
Max Drawdown is essentially dependent on two data points, and you donβt want to use statistics that are dependent on essentially two data points.
The other problem to watch out for in terms of drawdowns calculation is, drawdown on a daily basis is very different from drawdown on a weekly basis. If you look at drawdown on a daily basis, youβre going to see the worst worst-case. If you look at it on a weekly basis, the worst-case would have essentially disappeared because you are only looking at weekly data. If you read monthly data, itβs even less. So itβs very very sensitive to the granularity of the data.
Calmar ratio
The Calmar ratio is a risk adjusted return measure where the average annual rate of return for the last 36 months divided by the maximum drawdown for the last 36 months.