diff options
Diffstat (limited to 'python')
| -rw-r--r-- | python/option_trades.py | 54 |
1 files changed, 29 insertions, 25 deletions
diff --git a/python/option_trades.py b/python/option_trades.py index 3010b5c4..0b1c76dd 100644 --- a/python/option_trades.py +++ b/python/option_trades.py @@ -6,7 +6,7 @@ import pandas as pd from pandas.tseries.offsets import BDay from arch import arch_model -from db import dbengine +from db import dbengine, dbconn from scipy.interpolate import interp1d from analytics import Index @@ -55,6 +55,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 None: + if years is None: + raise ValueError("need to provide at least one of date or years") date = (pd.Timestamp.now() - pd.DateOffset(years=years)).date() returns = daily_spreads(index, series, tenor) am = arch_model(returns) @@ -179,18 +181,22 @@ def get_strike(index, series, date, expiry, conn): return ref, fwdspread def get_option_pnl(strike, expiry, index, series, start_date, engine): - for s in [strike, strike+2.5]: + for s in [strike, strike+2.5, strike-2.5, strike+5]: 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=(s, expiry, index, series, start_date), - index_col='quotedate', parse_dates=['quotedate']) - if not df.empty and df.index[0] == start_date: + index_col='quotedate', + parse_dates=['quotedate']) + if not df.empty and df.index[0].date() == start_date: strike = s break else: - raise ValueError("Something wrong") + raise ValueError("Couldn't find data starting from that date") + + if not pd.api.types.is_datetime64tz_dtype(df.index): + df.index = df.index.tz_localize('utc') df = df.groupby(df.index.normalize()).last() if expiry < datetime.date.today(): @@ -206,37 +212,32 @@ def get_option_pnl(strike, expiry, index, series, start_date, engine): pv = underlying.pv df = df.append(pd.DataFrame([[pay_mid, rec_mid]], columns=['pay_mid', 'rec_mid'], - index=[pd.Timestamp(expiry)])) + index=[pd.Timestamp(expiry, tz='UTC')])) return df, strike def sell_vol_strategy(index="IG", months=3): engine = dbengine('serenitasdb') conn = engine.raw_connection() - 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") + with conn.cursor() as c1, conn.cursor() as c2: + c1.execute("SELECT DISTINCT series, expiry FROM " \ + "swaption_quotes ORDER BY expiry, series desc") d = {} - for series, expiry in c: + for series, expiry in c1: start_date = BDay().rollback(expiry - pd.DateOffset(months=months)).date() - if start_date == datetime.date(2016, 1, 15): - start_date = datetime.date(2016, 1, 14) - elif start_date == datetime.date(2014, 7, 18): - start_date = datetime.date(2014, 7, 17) - elif start_date == datetime.date(2014, 11, 17): - start_date = datetime.date(2014, 11, 14) - elif start_date == datetime.date(2015, 3, 13): - start_date = datetime.date(2015, 3, 12) if start_date > datetime.date.today(): break - for s in [series, series - 1]: - ref, fwdspread = get_index_ref(index, s, start_date, expiry, conn) - if fwdspread is not None: - break - else: + c2.execute("SELECT max(quotedate::date) FROM swaption_quotes WHERE " \ + "index=%s AND series=%s AND expiry=%s AND quotedate<=%s", + (index, series, expiry, start_date)) + actual_start_date, = c2.fetchone() + if actual_start_date is None or (start_date - actual_start_date).days > 5: continue + ref, fwdspread = get_index_ref(index, series, actual_start_date, expiry, conn) + if fwdspread is None: + fwdspread = ref + months / 50 #TODO: use actual values strike = round(fwdspread/2.5) * 2.5 - pnl, strike = get_option_pnl(strike, expiry, index, s, start_date, engine) - d[(s, strike, expiry)] = pnl + pnl, strike = get_option_pnl(strike, expiry, index, series, actual_start_date, engine) + d[(series, strike, expiry)] = pnl conn.commit() return d @@ -277,3 +278,6 @@ if __name__ == "__main__": d3 = sell_vol_strategy(months=3) all_tenors = pd.concat([aggregate_trades(d) for d in [d1, d2, d3]], axis=1) all_tenors.columns = ['1m', '2m', '3m'] + all_tenors['optimal'] = ((1.2*all_tenors['1m']). + sub(1.2*all_tenors['2m'], fill_value=0). + add(all_tenors['3m'], fill_value=0)) |
