aboutsummaryrefslogtreecommitdiffstats
path: root/python/exploration/curve_trades.py
blob: c80a41d5d8880a2da537d322977ef1585d27ad69 (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
96
97
98
99
100
101
102
103
104
105
106
107
108
from index_data import get_index_quotes, index_returns
import pandas as pd
import math
from scipy.stats.mstats import zscore

import matplotlib.pyplot as plt

index = 'IG'
on_the_run = 28

def curve_spread_diff(index = 'IG', on_the_run = 28):
    ## look at spreads
    df = get_index_quotes(index, list(range(on_the_run-6,on_the_run+1)), tenor=['3yr', '5yr', '7yr', '10yr'])
    spreads = df.groupby(level=['date', 'tenor']).nth(-1)['closespread'].unstack(-1)
    # remove 'yr'
    spreads.columns = [int(col[:-2]) for col in spreads.columns]
    spreads = spreads.sort_index(1)
    spreads_diff = spreads.diff(axis=1)
    spreads_diff = spreads_diff.filter([5, 7, 10])
    spreads_diff['5-10'] = spreads_diff[7] + spreads_diff[10]
    spreads_diff.columns = ['3-5', '5-7', '7-10', '5-10']
    return spreads_diff

def spreads_diff_table(spreads_diff):
    df = pd.DataFrame()
    df['min'] = spreads_diff.min()
    df['max'] = spreads_diff.max()
    df['average'] = spreads_diff.mean()
    df['current'] = spreads_diff.iloc[-1]
    df['zscore'] = pd.Series(zscore(spreads_diff)[-1], index = df.index)
    pd.DataFrame(zscore(spreads_diff), index=spreads_diff.index, columns=spreads_diff.columns).plot()
    return df

def theta_matrix(index = 'IG', on_the_run = 28):
    df = get_index_quotes(index, list(range(on_the_run-6,on_the_run+1)), tenor=['3yr', '5yr', '7yr', '10yr'])
    df['theta_per_dur'] = df.theta2/df.duration2
    theta_matrix = df.groupby(level=['date', 'tenor','series']).nth(-1)['theta_per_dur']
    theta_matrix_1 = theta_matrix.xs(theta_matrix.index.max()[0], level = 0).unstack(0)
    return theta_matrix_1[['3yr', '5yr', '7yr', '10yr']]

def on_the_run_theta(index = 'IG', on_the_run = 28):
    df = get_index_quotes(index, list(range(on_the_run-6,on_the_run+1)), tenor=['3yr', '5yr', '7yr', '10yr'])
    df['theta_per_dur'] = df.theta2/df.duration2
    theta_matrix = df.groupby(level=['date', 'tenor']).nth(-1)['theta_per_dur']
    theta_matrix.unstack(-1).plot()

def curve_returns(index = 'IG', on_the_run = 28):
    ## look at returns
    df = index_returns(index= index, series=list(range(on_the_run-6,on_the_run+1)), tenor=['3yr', '5yr', '7yr', '10yr'])
    ## on-the-run returns
    returns = df.price_return.unstack(-1).dropna().groupby(level='date').nth(-1)

    strategy = ['510', '710', '3510']

    strategies_return = pd.DataFrame()
    strategies_return[strategy[0]] = 1.78 * returns['5yr'] - returns['10yr']
    strategies_return[strategy[1]] = 1.33 * returns['7yr'] - returns['10yr']
    strategies_return[strategy[2]] = -2 * returns['3yr']+ 3 * returns['5yr'] - 1 * returns['10yr']

    strategies_return_monthly = pd.DataFrame()
    for strat in strategy:
        strategies_return_monthly[strat] = strategies_return[strat].groupby(pd.TimeGrouper(freq='M')).agg(lambda df:(1+df).prod()-1)

    sharpe = {}
    monthly_sharpe = {}
    for strat in strategy:
        sharpe[strat] = strategies_return[strat].mean()/strategies_return[strat].std()*math.sqrt(252)
        monthly_sharpe[strat] = strategies_return_monthly[strat].mean()/strategies_return_monthly[strat].std()*math.sqrt(12)

    worst_drawdown = {}
    for strat in strategy:
        worst_drawdown[strat] = strategies_return[strat].nsmallest(10)

    return (sharpe, monthly_sharpe, worst_drawdown)

def cross_series_curve(index = 'IG', on_the_run = 28):

    df = index_returns(index= index, series=list(range(on_the_run-6,on_the_run+1)), tenor=['3yr', '5yr', '7yr', '10yr'])
    ## look cross series
    returns1 = df.xs(['5yr','IG'], level = ['tenor','index']).price_return.unstack(-1)
    price_diff = pd.DataFrame()
    for ind in [28,27,26]:
        price_diff[ind] = returns1[ind] - 1.55* returns1[ind - 4]

    price_diff = price_diff.stack().groupby(level = 'date').nth(-1)
    monthly_returns_cross_series = price_diff.groupby(pd.TimeGrouper(freq='M')).agg(lambda df:(1+df).prod()-1)
    monthly_returns_cross_series.plot()


def forward_loss():
    from db import dbengine, dbconn
    serenitasdb = dbengine('serenitasdb')
    index = 'IG'
    start_date = (pd.Timestamp.now() - pd.DateOffset(years=3)).date()

    df = pd.read_sql_query("SELECT date, index, series, tenor, duration, closespread, closespread*duration/100 as indexel " \
                           "FROM index_quotes WHERE index=%s AND date >= %s " \
                           "ORDER BY date DESC, series ASC, duration ASC",
                           serenitasdb, parse_dates=['date'], params=[index, start_date])
    df1 = pd.read_sql_query("select index, series, tenor, maturity from index_maturity", serenitasdb, parse_dates=['maturity'])

    df = df.merge(df1, on=['index','series','tenor'])
    df = df.set_index(['date','index', 'maturity']).dropna()
    df = df.groupby(level=['date','index', 'maturity']).nth(-1)
    # annual change, to take out some noise
    df['fwd_loss_rate'] = df.indexel.diff(2)/df.duration.diff(2)