Skip to content

Instantly share code, notes, and snippets.

@beatmadsen
Created March 3, 2021 08:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save beatmadsen/d396d1eef03410b42dddc8a3e386cef0 to your computer and use it in GitHub Desktop.
Save beatmadsen/d396d1eef03410b42dddc8a3e386cef0 to your computer and use it in GitHub Desktop.
Calculate (European option) gamma pr dollar spent on premium
import yfinance as yf
import pandas as pd
import numpy as np
from scipy.stats import norm
'''
Calculate realised volatility of stock
:ticker: yfinance ticker
:window: trading days in rolling window
:dpy: trading days per year
'''
def realised_vol(ticker, window, dpy):
ann_factor = dpy / window
df = ticker.history(period='100d', interval='1d')
df['log_rtn'] = np.log(df['Close']).diff()
df['real_var'] = df['log_rtn'].rolling(window).var() * ann_factor
df['real_vol'] = np.sqrt(df['real_var'])
return df['real_vol'][-1]
'''
Calculate European Option gamma
:s: price of underlying
:x: strike
:t: time to expiry in (trading) years
:r: risk free rate
:vol: realised vol
'''
def gamma(s, x, t, r, vol):
if t > 0.6:
return 0
sqrt_t = np.sqrt(t)
d1 = (np.log(s / x) + (r + np.square(vol) / 2) * t) / (vol * sqrt_t)
return norm.pdf(d1) / (s * vol * sqrt_t)
ticker = yf.Ticker("RKT")
dates = ticker.options
todays_price_df = ticker.history(period='10m', interval='1m')
timestamp = todays_price_df.index[-1]
underlying = todays_price_df['Close'][-1]
_r_fixed = 0.05
_dpy = 252 # trading days per year
real_vol = realised_vol(ticker, 21, _dpy)
print("Real vol: " + str(real_vol))
was_merged = False
merged_df = None
for date in dates:
chain = ticker.option_chain(date)
expiration_date = pd.Timestamp(date + 'T17', tz='America/New_York')
t_years = (expiration_date - timestamp).total_seconds() / 60 / 60 / 24 / _dpy
def gamma_applied(x):
return gamma(underlying, x, t_years, _r_fixed, real_vol) * 100
for (df, kind) in ((chain.puts, 'put'), (chain.calls, 'call')):
df['gamma'] = df.apply(lambda x: gamma_applied(x['strike']), axis=1)
selection = df[['strike', 'gamma']][df.gamma.gt(0.00001)]
selection['kind'] = kind
selection['expiration_date'] = expiration_date
selection['gammaPerDollarBid'] = df['gamma'] / df['bid']
selection['gammaPerDollarAsk'] = df['gamma'] / df['ask']
selection['gammaPerDollarLastPrice'] = df['gamma'] / df['lastPrice']
if was_merged:
merged_df = pd.concat([merged_df, selection], ignore_index=True)
else:
merged_df = selection
was_merged = True
sorted = merged_df.sort_values(by='gammaPerDollarLastPrice', ascending=False)
print(sorted.head(20))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment