aboutsummaryrefslogtreecommitdiffstats
path: root/python/yieldcurve.py
blob: bdd3676803cca0787616340b9a9d5e28ef6730ce (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
from common import root
import os
import requests, zipfile
from io import BytesIO
import xml.etree.ElementTree as ET
import datetime
from quantlib.time.api import Calendar, Period, Days, Schedule, today, Actual360, calendar_from_name
from quantlib.time import imm
from quantlib.util.converter import qldate_to_pydate, pydate_to_qldate
from quantlib.market.market import libor_market, next_imm_date
import numpy as np
import matplotlib.pyplot as plt

def getMarkitIRData(date = datetime.date.today()):
    basedir = os.path.join(root, "data", "Yield Curves")
    datestr = date.strftime("%Y%m%d")
    filename = "InterestRates_USD_{0}.xml".format(datestr)
    if not os.path.exists(os.path.join(basedir, filename)):
        r = requests.get('http://www.markit.com/news/InterestRates_USD_{0}.zip'.format(datestr))
        if "x-zip" in r.headers['content-type']:
            with zipfile.ZipFile(BytesIO(r.content)) as z:
                z.extractall(path = os.path.join(root, "data", "Yield Curves"))
        else:
            return getMarkitIRData(date-datetime.timedelta(days=1))

    tree = ET.parse(os.path.join(root, "data", "Yield Curves", filename))
    deposits = {tenor: rate for tenor, rate in \
                zip([e.text for e in tree.findall('./deposits/*/tenor')],
                    [float(e.text) for e in tree.findall('./deposits/*/parrate')])}
    swaps = {tenor: rate for tenor, rate in \
             zip([e.text for e in tree.findall('./swaps/*/tenor')],
                 [float(e.text) for e in tree.findall('./swaps/*/parrate')])}
    effectiveasof = tree.find('./effectiveasof').text
    MarkitData = {'deposits': deposits,
                  'swaps': swaps,
                  'effectiveasof': datetime.datetime.strptime(effectiveasof, "%Y-%m-%d").date()}
    return MarkitData

def get_futures_data(date = datetime.date.today()):
    futures_file = os.path.join(root, "data", "Yield Curves",
                                "futures-{0}.csv".format(date.strftime("%Y-%m-%d")))
    with open(futures_file) as fh:
        quotes = [float(line.split(",")[1]) for line in fh]
    return quotes

def YC(date = datetime.date.today(), MarkitData=None, futures = None):
    if not MarkitData:
        MarkitData = getMarkitIRData(date)
    if not futures:
        futures = get_futures_data(date)
    m = libor_market('USD(NY)')
    cal = calendar_from_name('GBR')
    # m.settle_date is not available until we set_quotes, so we compute it again
    # need a better way to do this
    settle_date = cal.advance(pydate_to_qldate(date), 2, Days)
    quotes = [('ED',i+1, v) for i, v in enumerate(futures)]
    if next_imm_date(date, 9) == settle_date + Period('2Yr'):
        quotes.pop(7)
    quotes += [('SWAP', k, v) for k, v in MarkitData['swaps'].items()]
    m.set_quotes(date, quotes)
    ts = m.bootstrap_term_structure()
    return ts

if __name__=="__main__":
    date = datetime.date(2014, 4, 29)
    ts = YC(date)
    cal = calendar_from_name('USA')
    p1 = Period('1Mo')
    p2 = Period('2Mo')
    p3 = Period('3Mo')
    p6 = Period('6Mo')
    p12 = Period('12Mo')
    sched = Schedule(ts.reference_date, ts.reference_date+Period('5Yr'), Period('3Mo'), cal)
    days = [qldate_to_pydate(day) for day in sched]
    f3 = [ts.forward_rate(d, d+p3, Actual360()).rate for d in sched]
    f6 = [ts.forward_rate(d, d+p6, Actual360()).rate for d in sched]
    f2 = [ts.forward_rate(d, d+p2, Actual360()).rate for d in sched]

    plt.plot(days, f2, days, f3, days, f6)
    plt.show()