diff options
| author | Guillaume Horel <guillaume.horel@serenitascapital.com> | 2016-07-12 15:38:43 -0400 |
|---|---|---|
| committer | Guillaume Horel <guillaume.horel@serenitascapital.com> | 2016-07-12 15:38:43 -0400 |
| commit | d9254a14b0964305f011e416965c9c42d4b2e49d (patch) | |
| tree | 219bd42361ee996281807e29467e079890e9ac30 | |
| parent | 10e9385b9dce32513d865f75003c0eccff75faa0 (diff) | |
| download | pyisda-d9254a14b0964305f011e416965c9c42d4b2e49d.tar.gz | |
add functions to import Markit yieldcurves
| -rw-r--r-- | pyisda/utils.py | 92 |
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 |
