summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuillaume Horel <guillaume.horel@serenitascapital.com>2016-07-12 15:38:43 -0400
committerGuillaume Horel <guillaume.horel@serenitascapital.com>2016-07-12 15:38:43 -0400
commitd9254a14b0964305f011e416965c9c42d4b2e49d (patch)
tree219bd42361ee996281807e29467e079890e9ac30
parent10e9385b9dce32513d865f75003c0eccff75faa0 (diff)
downloadpyisda-d9254a14b0964305f011e416965c9c42d4b2e49d.tar.gz
add functions to import Markit yieldcurves
-rw-r--r--pyisda/utils.py92
1 files changed, 92 insertions, 0 deletions
diff --git a/pyisda/utils.py b/pyisda/utils.py
new file mode 100644
index 0000000..38196f0
--- /dev/null
+++ b/pyisda/utils.py
@@ -0,0 +1,92 @@
+from quantlib.settings import Settings
+from quantlib.time.api import ( Date, pydate_from_qldate, WeekendsOnly,
+ Period, Months, ModifiedFollowing, Actual360,
+ Semiannual, Thirty360, Actual365Fixed )
+from quantlib.indexes.ibor_index import IborIndex
+from quantlib.currency.api import USDCurrency, EURCurrency
+from quantlib.indexes.ibor_index import IborIndex
+from quantlib.termstructures.yields.api import (
+ PiecewiseYieldCurve, DepositRateHelper, SwapRateHelper)
+import array
+import datetime
+import requests
+import zipfile
+from io import BytesIO
+import xml.etree.ElementTree as ET
+from pyisda.curve import YieldCurve
+
+def getMarkitIRData(date = datetime.date.today() - datetime.timedelta(days = 1),
+ currency="USD"):
+ filename = "InterestRates_{0}_{1:%Y%m%d}".format(currency, date)
+ r = requests.get('http://www.markit.com/news/{0}.zip'.format(filename))
+ if "x-zip" in r.headers['content-type']:
+ with zipfile.ZipFile(BytesIO(r.content)) as z:
+ fh = z.open(filename + '.xml')
+ tree = ET.parse(fh)
+ 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': datetime.datetime.strptime(effectiveasof, "%Y-%m-%d").date()}
+ return MarkitData
+ else:
+ return getMarkitIRData(date-datetime.timedelta(days=1))
+
+def rate_helpers(currency="USD", MarkitData=None):
+ settings = Settings()
+ if not MarkitData:
+ MarkitData = getMarkitIRData(pydate_from_qldate(settings.evaluation_date-1), currency)
+ if MarkitData['effectiveasof'] != pydate_from_qldate(settings.evaluation_date):
+ raise RuntimeError("Yield curve effective date: {0} doesn't " \
+ "match the evaluation date: {1}".format(
+ MarkitData['effectiveasof'],
+ pydate_from_qldate(settings.evaluation_date)))
+ calendar = WeekendsOnly()
+ if currency == "USD":
+ isda_ibor = IborIndex("IsdaIbor", Period(3, Months), 2, USDCurrency(), calendar,
+ ModifiedFollowing, False, Actual360())
+ fix_freq = Semiannual
+ elif currency == "EUR":
+ 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())
+ 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,
+ Thirty360(), isda_ibor) for t, q in MarkitData['swaps']]
+ return deps + swaps
+
+def YC(currency="USD", helpers = None, MarkitData=None):
+ settings = Settings()
+ if helpers is None:
+ helpers = rate_helpers(currency, MarkitData)
+ curve = PiecewiseYieldCurve("discount", "loglinear", settings.evaluation_date,
+ helpers, Actual365Fixed())
+ return curve
+
+def build_yc(trade_date, ql_curve = False):
+ markit_data = getMarkitIRData(trade_date-datetime.timedelta(days=1))
+ if ql_curve:
+ settings = Settings()
+ settings.evaluation_date = Date.from_datetime(trade_date)
+ yield_helpers = rate_helpers(MarkitData = markit_data)
+ ql_yc = YC(helpers = yield_helpers)
+ dfs = array.array('d', [ql_yc.discount(yh.latest_date) for yh in yield_helpers])
+ dates = [pydate_from_qldate(yh.latest_date) for yh in yield_helpers]
+ yc = YieldCurve.from_discount_factors(trade_date, dates, dfs, 'ACT/365F')
+ else:
+ periods, rates = zip(*markit_data['deposits'])
+ periods = list(periods)
+ rates = list(rates)
+ periods_swaps, rates_swaps = zip(*markit_data['swaps'])
+ types = 'M' * len(periods) + 'S' * len(periods_swaps)
+ rates = array.array('d', rates)
+ periods.extend(periods_swaps)
+ rates.extend(rates_swaps)
+ yc = YieldCurve(trade_date, types, periods, rates, 'ACT/360', '6M',
+ '3M', '30/360', 'ACT/360', BadDay.MODIFIED)
+ return yc