Sharpe ratio - A deep dive

Sharpe Ratio

Primer

Sharpe Ratio is the most common metric used to measure risk in finance.

The formula is

(return on portfolio - risk free rate)/standard deviation of the excess return on the portfolio

There are tons of resources on the internet about sharpe ratio.

This investopedia page is a good introduction.

We assume the risk free rate to be zero, then the formula simply becomes mean returns divided by the standard deviation of returns.

In [1]:
import numpy as np
import pandas as pd
import empyrical as ep
import matplotlib.pyplot as plt
import seaborn as sns
sns.set()

Single stock

Let us create a set of 5 stocks with same monthly returns but with different standard deviation for a period of 20 years. Stocks are named a to e with a being the stock with least volatility e with the highest volatility

In [2]:
mu = 0.01 #monthly returns
# Express sigma in relation to mean
multipliers = (0.5,1,2,5,10)
collect = {}
for s,m in zip(list('abcde'), multipliers):
    collect[s] = np.random.normal(loc=mu, scale=m*mu, size=240)
df = pd.DataFrame(collect)
axes = df.plot(kind='kde', title='Distribution of returns', subplots=True, figsize=(8,8))
for ax in axes:
    ax.axvline(0.01, color='red')
ep.cum_returns(df).plot(title='Cumulative returns')
s = df.describe().round(4)
s = s.append(pd.Series(df.mean()/df.std(), name='sharpe'))
s = s.append(pd.Series((df.mean()/df.std())*np.sqrt(12), name='sharpe_annual'))
s
Out[2]:
a b c d e
count 240.000000 240.000000 240.000000 240.000000 240.000000
mean 0.010000 0.010500 0.010000 0.008800 0.007300
std 0.004900 0.010200 0.019400 0.044800 0.098500
min -0.003200 -0.014600 -0.042700 -0.106500 -0.264700
25% 0.006600 0.003400 -0.002800 -0.022400 -0.063300
50% 0.010400 0.010100 0.009500 0.009100 0.002000
75% 0.013100 0.017300 0.022600 0.039500 0.074300
max 0.023400 0.040400 0.079400 0.134300 0.339900
sharpe 2.029252 1.031875 0.513276 0.197086 0.074137
sharpe_annual 7.029536 3.574519 1.778041 0.682726 0.256819

Although all values are generated from the normal distribution with a fixed mean of 0.01, we could see a stark difference.

The first plot shows the distribution or the spread of returns where a and b are close to the mean of 0.01 (the red line) while e is just nowhere. You can also look at the table where the minimum and maximum returns for a are much closer while for e they are much wider. This implies this is very difficult to infer the mean returns of e as they wildly swing from one extreme to other while on the other hand we could be fairly confident with our estimates for a. From a risk perspective, it is very difficult to differentiate the actual mean value of stock e due to its high volatility. A look at the sharpe ratio for the instruments also follow this pattern.

A look at the cumulative returns suggests that stock e has left everybody behind and despite wild swings, it is way above; it seems that volatility helps in the long run. But this is only a single simulation of how prices would behave for a given risk/return profile.

Read more... 9 minute read

Sharpe ratio

Sharpe Ratio - Introduction

Sharpe Ratio is the most common metric used to measure risk in finance.

The formula is

(return on portfolio - risk free rate)/standard deviation of the excess return on the portfolio

There are tons of resources on the internet about sharpe ratio.

This investopedia page is a good introduction.

In this series of articles, we take a deep dive into the sharpe ratio and its variations and usage.

We assume the risk free rate to be zero, then the formula simply becomes mean returns divided by the standard deviation of returns. The following terms are used interchangebly throughout this article

  • mean returns/average returns/mu
  • standard deviation of returns/deviation/sigma

We would be working on the NSE Nifty 50 index data

In [1]:
import numpy as np
import pandas as pd
import empyrical as ep
from typing import Tuple
import seaborn as sns
sns.set()
In [2]:
# Parameters 
# useful when running as a papermill notebook

filename:str = '/tmp/nifty.csv'
periods:Tuple[str] = ('W','M','Y')
In [3]:
df = pd.read_csv(filename, index_col=['date'], parse_dates=['date'])
df['daily_return'] = df.close.pct_change()
df.head()
Out[3]:
open high low close daily_return
date
2000-01-03 1482.15 1592.90 1482.15 1592.2 NaN
2000-01-04 1594.40 1641.95 1594.40 1638.7 0.029205
2000-01-05 1634.55 1635.50 1555.05 1595.8 -0.026179
2000-01-06 1595.80 1639.00 1595.80 1617.6 0.013661
2000-01-07 1616.60 1628.25 1597.20 1613.3 -0.002658
In [4]:
mu,sigma = df.daily_return.mean(), df.daily_return.std()
print(f"Daily mean return = {mu :.4f}")
print(f"Deviation of daily returns = {sigma :.4f}")
print(f"Sharpe ratio = {mu/sigma :.4f}")
Daily mean return = 0.0005
Deviation of daily returns = 0.0144
Sharpe ratio = 0.0381

Sharpe ratio - converting to various periods

The sharpe ratio calculated here is based on daily return. To calculate it for other periods, multiply this by the square root of the period.

sharpe ratio * √n

To get the weekly sharpe ratio, multiply by √5 since there are 5 trading days in a week, √20 for a month and so on. Most of the literature and news display the annualized sharpe ratio, sharpe ratio per annum

Read more... 4 minute read