aboutsummaryrefslogtreecommitdiffstats
path: root/python
diff options
context:
space:
mode:
Diffstat (limited to 'python')
-rw-r--r--python/option_trades.py106
1 files changed, 82 insertions, 24 deletions
diff --git a/python/option_trades.py b/python/option_trades.py
index 1b4f18d3..15b16efa 100644
--- a/python/option_trades.py
+++ b/python/option_trades.py
@@ -1,9 +1,13 @@
+import datetime
+import math
+import numpy as np
import pandas as pd
+
+from pandas.tseries.offsets import BDay
from arch import arch_model
-import math
from db import dbengine
-import numpy as np
from scipy.interpolate import interp1d
+from analytics import Index
serenitasdb = dbengine('serenitasdb')
@@ -49,7 +53,8 @@ def index_returns(date=None, years=3, index="IG", tenor="5yr"):
def realized_vol(index, series, tenor, date=None, years=None):
"""computes the realized spread volatility"""
- if date is no
+ if date is None:
+ date = (pd.Timestamp.now() - pd.DateOffset(years=years)).date()
returns = daily_spreads(index, series, tenor)
am = arch_model(returns)
res = am.fit(update_freq=0, disp='off')
@@ -122,25 +127,78 @@ def lr_var(res):
var = res.params.omega/(1 - res.params['alpha[1]'] - res.params['beta[1]'])
return math.sqrt(var) * math.sqrt(252)
-if __name__ == "__main__":
- series = 23
- rv, res = realized_vol("ig", series, "5yr")
- rv = pd.DataFrame(rv)
- rv = rv.reset_index()
- df_vol = atm_vol("ig", series)
- df_vol = rolling_vol(df_vol, term=[1, 2, 3])
- realized_vs_atm = pd.merge_asof(rv, df_vol, on='date')
- realized_vs_atm.set_index('date', inplace=True)
- fig = realized_vs_atm[['cond_vol', '1m', '2m', '3m']].plot()
+def index_rolling_returns(date=None, years=3, index="IG", tenor="5yr"):
+ """computes on the run returns"""
+ if date is None:
+ date = (pd.Timestamp.now() - pd.DateOffset(years=years)).date()
+ sql_str = "SELECT date, series, closespread AS spread FROM index_quotes " \
+ "WHERE index=%s and date>=%s and tenor = %s"
+ df = pd.read_sql_query(sql_str, serenitasdb, parse_dates=['date'], index_col=['date', 'series'],
+ params=(index.upper(), date, tenor))
+ df.sort_index(inplace=True)
+ return df
+
+def get_index_spread(index, series, date, conn):
+ with conn.cursor() as c:
+ c.execute("SELECT closespread from index_quotes " \
+ "WHERE index=%s and series=%s and date=%s and tenor='5yr'",
+ (index, series, date))
+ try:
+ spread, = c.fetchone()
+ except TypeError:
+ spread = None
+ conn.commit()
+ return spread
- #compute series
- top10 = pd.DataFrame()
- for series in [23, 24, 25, 26, 27]:
- df_vol = atm_vol("ig", series)
- df_vol = rolling_vol(df_vol, term=[1, 2, 3])
- df_vol.set_index('date', inplace=True)
- daily_vol = df_vol.resample('D').last()
- daily_vol['series'] = series
- daily_vol = pd.DataFrame(daily_vol['3m'].diff().abs().nlargest(10))
- daily_vol['series'] = series
- top10 = top10.append(daily_vol)
+def get_option_pnl(strike, expiry, index, series, engine):
+ start_date = BDay().rollback(expiry - pd.DateOffset(months=1))
+ df = pd.read_sql_query("SELECT quotedate, (pay_bid+pay_offer)/2 AS pay_mid, " \
+ "(rec_bid+rec_offer)/2 AS rec_mid FROM swaption_quotes " \
+ "WHERE strike=%s and expiry=%s and index=%s and series=%s" \
+ "and quotedate>=%s", engine,
+ params=(strike, expiry, index, series, start_date),
+ index_col='quotedate', parse_dates=['quotedate'])
+ df = df.groupby(df.index.normalize()).last()
+ if expiry < datetime.date.today():
+ spread = get_index_spread(index, series, expiry, engine.raw_connection())
+ underlying = Index.from_name(index, series, "5yr", expiry, 1e4)
+ underlying.spread = spread
+ pv = underlying.pv
+ underlying.spread = strike
+ if spread > strike:
+ pay_mid, rec_mid = pv-underlying.pv, 0
+ else:
+ pay_mid, rec_mid = 0, underlying.pv - pv
+ pv = underlying.pv
+ df = df.append(pd.DataFrame([[pay_mid, rec_mid]],
+ columns=['pay_mid', 'rec_mid'],
+ index=[pd.Timestamp(expiry)]))
+ return df
+
+
+def sell_vol_strategy(index="IG"):
+ engine = dbengine('serenitasdb')
+ conn = engine.raw_connection()
+ d = pd.Series()
+ with conn.cursor() as c:
+ c.execute("SELECT DISTINCT ON (expiry) series, expiry FROM " \
+ "swaption_quotes GROUP BY series, expiry ORDER BY expiry, series desc")
+ for series, expiry in c:
+ start_date = BDay().rollback(expiry - pd.DateOffset(months=1)).date()
+ if start_date > datetime.date.today():
+ break
+ index_spread = get_index_spread(index, series, start_date, conn)
+ if index_spread is None:
+ series -=1
+ index_spread = get_index_spread(index, series, start_date, conn)
+ strike = round(index_spread/2.5) * 2.5 ##round to the closest higher 2.5 increment
+ df = get_option_pnl(strike, expiry, index, series, engine)
+ if d.empty:
+ d = -df.sum(1).diff().dropna()
+ else:
+ d = d.add(-df.sum(1).diff().dropna(),fill_value=0)
+ conn.commit()
+ return d
+
+if __name__ == "__main__":
+ d = sell_vol_strategy()