diff options
Diffstat (limited to 'python')
| -rw-r--r-- | python/option_trades.py | 106 |
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() |
