diff options
Diffstat (limited to 'python')
| -rw-r--r-- | python/yieldcurve.py | 93 |
1 files changed, 49 insertions, 44 deletions
diff --git a/python/yieldcurve.py b/python/yieldcurve.py index c865c9bb..8c5431e3 100644 --- a/python/yieldcurve.py +++ b/python/yieldcurve.py @@ -1,13 +1,11 @@ from common import root import os -import requests, zipfile -from io import BytesIO -import xml.etree.ElementTree as ET import datetime from quantlib.settings import Settings from quantlib.time.api import (WeekendsOnly, Date, Period, Days, Schedule, Annual, - Semiannual, today, Actual360, Months, ModifiedFollowing, - Thirty360, Actual365Fixed, calendar_from_name) + Semiannual, today, Actual360, Months, Years, + ModifiedFollowing, Thirty360, Actual365Fixed, + calendar_from_name) from quantlib.currency.api import USDCurrency, EURCurrency from quantlib.indexes.ibor_index import IborIndex from quantlib.termstructures.yields.api import ( @@ -24,47 +22,16 @@ import array def getMarkitIRData(effective_date = datetime.date.today(), currency = "USD"): - download_date = effective_date - datetime.timedelta(days = 1) conn = dbconn("serenitasdb") sql_str = "SELECT * FROM {}_rates WHERE effective_date = %s".format(currency) with conn.cursor() as c: c.execute(sql_str, (effective_date,)) col_names = [c[0] for c in c.description] r = c.fetchone() - if r: - MarkitData = {'effectiveasof': r[0], - 'deposits': [(t, r[i]) for i, t in \ - enumerate(col_names[1:7], 1) if r[i] is not None], - 'swaps': [(t, r[i]) for i, t in enumerate(col_names[7:], 7)]} - else: - basedir = os.path.join(root, "data", "Yield Curves") - filename = "InterestRates_{0}_{1:%Y%m%d}".format(currency, download_date) - if not os.path.exists(os.path.join(basedir, filename + '.xml')): - r = requests.get('http://www.markit.com/news/{0}.zip'.format(filename)) - if "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(download_date-datetime.timedelta(days=1)) - - tree = ET.parse(os.path.join(root, "data", "Yield Curves", filename + '.xml')) - deposits = zip([e.text for e in tree.findall('./deposits/*/tenor')], - [float(e.text) for e in tree.findall('./deposits/*/parrate')]) - swaps = 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': list(deposits), - 'swaps': list(swaps), - 'effectiveasof': pd.Timestamp(effectiveasof).date()} - instruments = MarkitData['deposits'] + MarkitData['swaps'] - names = ",".join(['"{}"'.format(r[0]) for r in instruments]) - values = ",".join(["%s"] * (len(instruments) + 1)) # +1 for effective_date - insert_str = ("INSERT INTO {0}_rates(effective_date, {1}) VALUES({2})". - format(currency, names, values)) - with conn.cursor() as c: - c.execute(insert_str, [MarkitData['effectiveasof']] +[r[1] for r in instruments]) - conn.commit() - conn.close() + MarkitData = {'effectiveasof': r[0], + 'deposits': [(t, r[i]) for i, t in \ + enumerate(col_names[1:7], 1) if r[i] is not None], + 'swaps': [(t, r[i]) for i, t in enumerate(col_names[7:], 7)]} return MarkitData def get_futures_data(date = datetime.date.today()): @@ -75,6 +42,20 @@ def get_futures_data(date = datetime.date.today()): return quotes def rate_helpers(currency="USD", MarkitData=None): + """Util function to build a list of RateHelpers + + Parameters + ---------- + currency : str, optional + One of `USD`, `EUR` at the moment, defaults to `USD` + MarkitData : dict, optional + MarkitData for the current evaluation_date + + Returns + ------- + helpers : list + List of QuantLib RateHelpers + """ settings = Settings() if not MarkitData: MarkitData = getMarkitIRData(pydate_from_qldate(settings.evaluation_date), currency) @@ -92,21 +73,45 @@ def rate_helpers(currency="USD", MarkitData=None): isda_ibor = IborIndex("IsdaIbor", Period(6, Months), 2, EURCurrency(), calendar, ModifiedFollowing, False, Actual360()) fix_freq = Annual - deps = [DepositRateHelper(q, Period(t), 2, calendar, ModifiedFollowing, False, Actual360()) + # we use SimpleQuotes, rather than just float to make it updateable + deps = [DepositRateHelper(SimpleQuote(q), Period(t), 2, calendar, ModifiedFollowing, False, Actual360()) for t, q in MarkitData['deposits']] # this matches with bloomberg, but according to Markit, maturity should be unadjusted - swaps = [SwapRateHelper.from_tenor(q, Period(t), calendar, fix_freq, ModifiedFollowing, + swaps = [SwapRateHelper.from_tenor(SimpleQuote(q), Period(t), calendar, fix_freq, ModifiedFollowing, Thirty360(), isda_ibor) for t, q in MarkitData['swaps']] return deps + swaps -def YC(currency="USD", helpers = None, MarkitData=None): +def get_dates(date, currency="USD"): + """computes the list of curve dates on a given date""" + if currency == "USD": + month_periods = [1, 2, 3, 6, 12] + year_periods = [2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 15, 20, 25, 30] + calendar = WeekendsOnly() + settle_date = calendar.advance(Date.from_datetime(date), 2, 0) + deposit_dates = [calendar.advance(settle_date, period = Period(m, Months), + convention=ModifiedFollowing) \ + for m in month_periods] + swap_dates = [calendar.advance(settle_date, period = Period(y, Years), + convention=ModifiedFollowing) \ + for y in year_periods] + dates = deposit_dates + swap_dates + return [pydate_from_qldate(d) for d in dates] + +def roll_yc(yc, forward_date): + """returns the expected forward yield cuve on a forward_date""" + dates = get_dates(forward_date) + df0 = yc.discount_factor(forward_date) + dfs = array.array('d', [yc.discount_factor(d)/df0 for d in dates]) + return YieldCurve.from_discount_factors(forward_date, dates, array.array('d', dfs), 'ACT/365F') + +def YC(helpers = None, currency="USD", MarkitData=None): if helpers is None: helpers = rate_helpers(currency, MarkitData) calendar = WeekendsOnly() return PiecewiseYieldCurve(BootstrapTrait.Discount, Interpolator.LogLinear, 0, calendar, helpers, Actual365Fixed()) def ql_to_jp(ql_yc): - """ convert a QuantLib yield curve to a JP's one""" + """convert a QuantLib yield curve to a JP's one""" if ql_yc._trait == BootstrapTrait.Discount: dfs = array.array('d', ql_yc.data[1:]) dates = [pydate_from_qldate(d) for d in ql_yc.dates[1:]] |
