aboutsummaryrefslogtreecommitdiffstats
path: root/python/mark_swaptions.py
blob: dda1e856b1785c73765a2a920e7f215bc1dc8b00 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
import argparse
import datetime
import logging
import os
import pandas as pd
from pandas.tseries.offsets import BDay

from analytics import Index, Swaption
from db import dbengine
from sqlalchemy import exc

logging.basicConfig(filename=os.path.join(os.getenv("LOG_DIR"), 'swaption_marks.log'),
                    level=logging.WARNING,
                    format='%(asctime)s %(message)s')

def get_trades(date, engine):
    return pd.read_sql_query(
        "SELECT dealid, buysell, swaption_type, notional, strike, " \
        "expiration_date, index, series FROM swaptions " \
	"JOIN index_version ON (swaptions.security_id = index_version.redindexcode) " \
        "WHERE termination_date is NULL AND expiration_date > %s AND trade_date <= %s",
        engine, 'dealid', params=(date, date), parse_dates=['expiration_date'])


def get_swaptionvol(index, series, strike, expiry, date, engine):
    r = engine.execute(
        "SELECT ref, vol_payer AS payer, vol_receiver AS receiver, " \
        "vol_payer_black AS payer_black, vol_receiver_black AS receiver_black " \
        "FROM swaption_calib JOIN swaption_ref_quotes " \
        "USING (quotedate, expiry, index, series) WHERE index = %s " \
        "AND series = %s AND strike=%s AND expiry = %s AND quotedate::date=%s " \
        "ORDER BY quotedate desc",
        (index, series, strike, expiry, date))
    try:
        return r.fetchone()
    except exc.DataError as e:
        logging.error(e)
        return None
    except TypeError:
        logging.error("No data for {}{} {}K on date {}".format(index, series, strike, date))
        return None

def mark_trades(date, engine):
    df = get_trades(date, engine)
    result = []
    for trade in df.itertuples():
        try:
            r = engine.execute("SELECT closespread, closeprice FROM index_quotes " \
                               "WHERE index=%s AND series=%s AND tenor='5yr' AND date=%s",
                               (trade.index, trade.series, date))
            closespread, closeprice = r.fetchone()
        except exc.DataError as e:
            logging.eror(e)
        except TypeError:
            logging.error("no quote for {}{} {} on date {}".format(
                trade.index, trade.series, '5yr', date))
        underlying = Index.from_name(trade.index, trade.series, '5yr', date,
                                     trade.notional)
        sigma = get_swaptionvol(trade.index, trade.series, trade.strike, trade.expiration_date.date(),
                                date, serenitas_engine)
        if trade.index == "IG":
            underlying.spread = sigma.ref
        elif trade.index == "HY":
            underlying.price = sigma.ref
        swaption = Swaption(underlying, trade.expiration_date.date(),
                            trade.strike, trade.swaption_type.lower())
        swaption.sigma = getattr(sigma, swaption.option_type)
        direction = 1. if trade.buysell else -1.
        market_value = swaption.pv * trade.notional * direction
        market_value += swaption.DV01 * (closespread-sigma.ref) * trade.notional * direction
        #compute the greeks at index mark
        swaption.index.spread = closespread
        swaption._update()

        try:
            test = (trade.Index, date, market_value, swaption.delta, swaption.gamma,
                    swaption.vega)
            engine.execute("INSERT INTO swaption_marks VALUES(%s, %s, %s, %s, %s, %s)",
                           (trade.Index, date, market_value, swaption.delta, swaption.gamma,
                            swaption.vega))
        except exc.DataError as e:
            logging.error(e)
    return result

if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument('workdate', nargs='?', type = lambda s: pd.datetime.strptime(s, "%Y-%m-%d").date())
    dawn_engine = dbengine('dawndb')
    serenitas_engine = dbengine('serenitasdb')
    args = parser.parse_args()
    if args.workdate is None:
        workdate = (pd.Timestamp.today()-BDay()).date()
    else:
        workdate = args.workdate
    r = mark_trades(workdate, dawn_engine)