Skip to content

Instantly share code, notes, and snippets.

@mlblogger
Created January 21, 2023 11:18
Show Gist options
  • Save mlblogger/fb9552b434e9e2217caf961d01f61321 to your computer and use it in GitHub Desktop.
Save mlblogger/fb9552b434e9e2217caf961d01f61321 to your computer and use it in GitHub Desktop.
import pandas as pd
import pandas_datareader.data as web
import numpy as np
class Metrics():
def __init__(self, returns, risk_free_rate=2, period='daily'):
self.returns = returns
self.period = {
'monthly' : 12,
'weekly' : 52,
'daily' : 252
}
self.frequency = self.period[period]
self.risk_free_rate = np.power(1+risk_free_rate*0.01,1/self.frequency) - 1
def annualized_sharpe_ratio(self):
return round(
( (self.returns.mean() - self.risk_free_rate) / (self.returns.std()) )\
* ( np.sqrt(self.frequency) ), 2
)
def annualized_volatility(self):
return round(
self.returns.std()*np.sqrt(self.frequency)*100, 2
)
def max_draw_down(self):
cum_returns = self.returns.add(1).cumprod()
draw_down = cum_returns.div(cum_returns.cummax()).sub(1)
max_draw_down = draw_down.min()*100
return round( max_draw_down, 2 )
def cumulative_rets(self):
return (self.returns+1).prod()
def annualized_returns(self):
num_years = len(self.returns) / self.frequency
ending_value = self.cumulative_rets()
return (ending_value **(1 / num_years) - 1)*100
def calmar_ratio(self):
return round(self.annualized_returns()/abs(self.max_draw_down()), 2)
def downside_risk(self):
df = pd.DataFrame()
df['Returns'] = self.returns
df['downside_returns'] = 0
df.loc[df['Returns'] < 0, 'downside_returns'] = df['Returns']**2
down_risk = np.sqrt(df['downside_returns'].mean())*np.sqrt(self.frequency)
return down_risk
def sortino_ratio(self):
average_annual_return = np.nanmean(self.returns, axis=0) * self.frequency
return round(
(average_annual_return - self.risk_free_rate)/self.downside_risk(), 2
)
def beta(self,index):
return round(self.returns.cov(index)/index.var(), 2)
if __name__ == '__main__':
stock = 'LMT.US'
index = '^DJI'
start = '2022-01-01'
end = '2023-01-01'
lmt = web.DataReader(stock, 'stooq')
lmt = lmt.sort_values(by='Date')
lmt = lmt['Close'].pct_change()
mask = ( start <= lmt.index ) & ( lmt.index <= end )
lmt = lmt[mask]
dji = web.DataReader(index, 'stooq')
dji = dji.sort_values(by='Date')
dji = dji['Close'].pct_change()
mask = ( start <= dji.index ) & ( dji.index <= end )
dji = dji[mask]
metrics = Metrics(lmt)
print('Sharpe Ratio ', metrics.annualized_sharpe_ratio())
print('Calmar Ratio ', metrics.calmar_ratio())
print('Sortino Ratio ', metrics.sortino_ratio())
print('Max Draw Down ', metrics.max_draw_down())
print('Volatility ', metrics.annualized_volatility())
print('Beta ', metrics.beta(dji))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment