diff options
Diffstat (limited to 'python/yieldcurve.py')
| -rw-r--r-- | python/yieldcurve.py | 68 |
1 files changed, 42 insertions, 26 deletions
diff --git a/python/yieldcurve.py b/python/yieldcurve.py index 7ef24a59..6e0cc3bf 100644 --- a/python/yieldcurve.py +++ b/python/yieldcurve.py @@ -23,12 +23,13 @@ from pyisda.curve import YieldCurve from pyisda.date import BadDay import warnings + def load_curves(currency="USD", date=None): """load the prebuilt curves from the database""" + sql_str = f"SELECT * FROM {currency}_curves" if date: - sql_str = "SELECT curve FROM {}_curves WHERE effective_date=%s".format(currency) - else: - sql_str = "SELECT * FROM {}_curves".format(currency) + sql_str += " WHERE effective_date=%s" + with closing(dbconn('serenitasdb')) as conn: with conn.cursor() as c: if date: @@ -42,6 +43,7 @@ def load_curves(currency="USD", date=None): (d, YieldCurve.from_bytes(lz4.block.decompress(curve))) for d, curve in c]) + def get_curve(effective_date, currency="USD"): if f'_{currency}_curves' in globals(): curves = globals()[f'_{currency}_curves'] @@ -64,6 +66,7 @@ def get_curve(effective_date, currency="USD"): curves[effective_date] = jp_yc return jp_yc + def getMarkitIRData(effective_date=datetime.date.today(), currency="USD"): conn = dbconn("serenitasdb") @@ -80,6 +83,7 @@ def getMarkitIRData(effective_date=datetime.date.today(), if rate is not None]} return MarkitData + def get_futures_data(date=datetime.date.today()): futures_file = os.path.join(os.environ['DATA_DIR'], "Yield Curves", "futures-{0:%Y-%m-%d}.csv".format(date)) @@ -87,6 +91,7 @@ def get_futures_data(date=datetime.date.today()): quotes = [float(line.split(",")[1]) for line in fh] return quotes + def rate_helpers(currency="USD", MarkitData=None, evaluation_date=None): """Utility function to build a list of RateHelpers @@ -108,7 +113,7 @@ def rate_helpers(currency="USD", MarkitData=None, evaluation_date=None): if not MarkitData: MarkitData = getMarkitIRData(evaluation_date, currency) if MarkitData['effectiveasof'] != evaluation_date: - warnings.warn("Yield curve effective date: {0} doesn't " \ + warnings.warn("Yield curve effective date: {0} doesn't " "match the evaluation date: {1}".format( MarkitData['effectiveasof'], evaluation_date), @@ -116,21 +121,23 @@ def rate_helpers(currency="USD", MarkitData=None, evaluation_date=None): settings.evaluation_date = Date.from_datetime(MarkitData['effectiveasof']) calendar = WeekendsOnly() if currency == "USD": - isda_ibor = IborIndex("IsdaIbor", Period(3, Months), 2, USDCurrency(), calendar, - ModifiedFollowing, False, Actual360()) + 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()) + isda_ibor = IborIndex("IsdaIbor", Period(6, Months), 2, EURCurrency(), + calendar, ModifiedFollowing, False, Actual360()) fix_freq = Annual # we use SimpleQuotes, rather than just float to make it updateable - deps = [DepositRateHelper(SimpleQuote(q), Period(t), 2, calendar, ModifiedFollowing, False, Actual360()) + 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(SimpleQuote(q), Period(t), calendar, fix_freq, ModifiedFollowing, Thirty360(), isda_ibor) for t, q in MarkitData['swaps']] return deps + swaps + def get_dates(date, currency="USD"): """computes the list of curve dates on a given date""" if currency == "USD": @@ -139,20 +146,22 @@ def get_dates(date, currency="USD"): calendar = WeekendsOnly() settle_date = calendar.advance(Date.from_datetime(date), 2, 0) deposit_dates = [calendar.advance(settle_date, period=Period(m, Months), - convention=ModifiedFollowing) \ + convention=ModifiedFollowing) for m in month_periods] swap_dates = [calendar.advance(settle_date, period=Period(y, Years), - convention=ModifiedFollowing) \ - for y in year_periods] + 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 = [d for d in yc.dates if d >= forward_date] dfs = np.array([yc.discount_factor(d, forward_date) for d in dates]) return YieldCurve.from_discount_factors(forward_date, dates, dfs, 'ACT/365F') + def YC(helpers=None, currency="USD", MarkitData=None, evaluation_date=None): if helpers is None: helpers = rate_helpers(currency, MarkitData, evaluation_date) @@ -163,25 +172,27 @@ def YC(helpers=None, currency="USD", MarkitData=None, evaluation_date=None): return PiecewiseYieldCurve(BootstrapTrait.Discount, Interpolator.LogLinear, 0, calendar, helpers, Actual365Fixed()) + def jpYC(effective_date, currency="USD", MarkitData=None): if MarkitData is None: markit_data = getMarkitIRData(effective_date, currency) periods, rates = zip(*markit_data['deposits']) - periods_swaps, rate_swaps = zip(*markit_data['swaps']) + periods_swaps, rates_swaps = zip(*markit_data['swaps']) types = 'M'*len(periods) + 'S'*len(periods_swaps) rates = np.array(rates + rates_swaps) - periods = list(period + periods_swaps) + periods = list(periods + periods_swaps) if currency == "USD": fixed_period = '6M' float_period = '3M' elif currency == 'EUR': fixed_period = '12M' float_period = '6M' - return YieldCurve(effective_date, types, periods, rates, 'ACT/360',\ + return YieldCurve(effective_date, types, periods, rates, 'ACT/360', fixed_period, float_period, '30/360', 'ACT/360', BadDay.MODIFIED) + def ql_to_jp(ql_yc): """convert a QuantLib yield curve to a JP's one""" if ql_yc._trait == BootstrapTrait.Discount: @@ -190,21 +201,23 @@ def ql_to_jp(ql_yc): trade_date = pydate_from_qldate(ql_yc.dates[0]) return YieldCurve.from_discount_factors(trade_date, dates, dfs, 'ACT/365F') else: - raise RuntimeErrror('QuantLib curve needs to use Discount trait') + raise RuntimeError('QuantLib curve needs to use Discount trait') + def build_curves(currency="USD"): settings = Settings() calendar = WeekendsOnly() if currency == "USD": - isda_ibor = IborIndex("IsdaIbor", Period(3, Months), 2, USDCurrency(), calendar, - ModifiedFollowing, False, Actual360()) + 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()) + isda_ibor = IborIndex("IsdaIbor", Period(6, Months), 2, EURCurrency(), + calendar, ModifiedFollowing, False, Actual360()) fix_freq = Annual engine = dbengine('serenitasdb') - rates = pd.read_sql_table('{}_rates'.format(currency.lower()), engine, index_col='effective_date') + rates = pd.read_sql_table('{}_rates'.format(currency.lower()), engine, + index_col='effective_date') quotes = [SimpleQuote() for c in rates.columns] gen = zip(quotes, rates.columns) deps = [DepositRateHelper(q, Period(t), 2, calendar, ModifiedFollowing, @@ -212,7 +225,7 @@ def build_curves(currency="USD"): swaps = [SwapRateHelper.from_tenor(q, Period(t), calendar, fix_freq, ModifiedFollowing, Thirty360(), isda_ibor) for q, t in gen] - sql_str = "INSERT INTO {}_curves VALUES(%s, %s) ON CONFLICT DO NOTHING".format(currency) + sql_str = f"INSERT INTO {currency}_curves VALUES(%s, %s) ON CONFLICT DO NOTHING" conn = dbconn('serenitasdb') for effective_date, curve_data in rates.iterrows(): print(effective_date) @@ -221,15 +234,18 @@ def build_curves(currency="USD"): q.value = val valid_deps = [d for d in deps if not np.isnan(d.quote)] valid_swaps = [s for s in swaps if not np.isnan(s.quote)] - ql_yc = PiecewiseYieldCurve(BootstrapTrait.Discount, Interpolator.LogLinear, - 0, calendar, valid_deps + valid_swaps, Actual365Fixed()) + ql_yc = PiecewiseYieldCurve(BootstrapTrait.Discount, + Interpolator.LogLinear, + 0, calendar, valid_deps + valid_swaps, + Actual365Fixed()) jp_yc = ql_to_jp(ql_yc) with conn.cursor() as c: c.execute(sql_str, (effective_date, lz4.block.compress(jp_yc.__getstate__()))) conn.commit() -if __name__=="__main__": - #evaluation_date = Date(29, 4, 2014) + +if __name__ == "__main__": + # evaluation_date = Date(29, 4, 2014) Settings.instance().evaluation_date = today() import matplotlib.pyplot as plt |
