aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--python/yieldcurve.py93
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:]]