【问题标题】:QuantLib: Swap to zero-coupon curve bootstrappingQuantLib:交换到零息曲线自举
【发布时间】:2020-05-13 12:31:23
【问题描述】:

我正在尝试将美国掉期曲线引导成零息曲线(参见彭博屏幕截图)。我有从 1996 年 6 月 21 日到今天的 3M、1Y、2Y、5Y、7Y、10Y 到期日的每日数据(有些日子不见了,请参阅 DataFrame 屏幕截图)。我想为从 3M 到 10Y 的所有期限获得相应的零利率。

Bloomberg Screenshot of the 5Y US Swap

Swap curve data

这是我写的一段代码:

zero_rates = {}
helpers_mat =[]
# loop over time
for t in range(irs.shape[0]):
    # date of pricing (= DataFrame index line by line)
    pricing_date = ql.DateParser.parseFormatted(str(irs.index[t]),'%Y-%m-%d')
    # define evaluation date
    ql.Settings.instance().evaluationDate = pricing_date
    # list of maturities and corresponding swap rates
    for m in irs.columns:
        helpers_mat.append([(m, ql.Months), irs[m][t]])

    # helper function to intput details
    helpers = [ql.SwapRateHelper(
                           ql.QuoteHandle(ql.SimpleQuote(rate/100.0)),
                           ql.Period(*tenor),
                           ql.TARGET(),
                           ql.Semiannual,
                           ql.ModifiedFollowing,
                           ql.Thirty360(),
                           ql.Euribor3M())
                           for tenor, rate in helpers_mat]

    # build zero-coupon curve (cubic spline interpolation)
    zc_curve = ql.PiecewiseCubicZero(pricing_date, helpers, ql.Actual360())
    # pre-allocate
    zero_rate = []
    tenors = []
    # loop over wanted maturities
    for n in np.arange(3, 120+1, 3):
        # maturities
        yrs = n/12.0
        tenors.append(yrs)
        # extract zero-coupon rate
        zc_rate = zc_curve.zeroRate(yrs, ql.Compounded, ql.Annual).rate()
        zero_rate.append(zc_rate*100)
        # pandas export
        zero_rates[t] = pd.DataFrame(np.transpose(list(zip(zero_rate))), columns = list(zip(tenors)), 
        index = [irs.index[t]])

zero_rates = pd.concat(zero_rates, axis=0)

使用该代码,我得到以下错误:

RuntimeError: more than one instrument with Pillar 1996 年 7 月 25 日

所以我想我对日期有疑问。我的理解是 SwapRateHelper 具有掉期固定腿的特征。 但是我在哪里输入浮动腿的?

【问题讨论】:

    标签: python quantlib


    【解决方案1】:

    浮动腿参数来自索引。在您的情况下,您似乎正在使用 ql.Euribor3M() ,它与您真正想要的 USD Libor 3M 足够接近。区别基本上是错误的日历。

    但是,不知道数据的形状很难找出问题所在。

    有许多不同的方法可以构建辅助函数,对于美元曲线,您不妨将 USDLibor 指数用于存款,将 ql.UsdLiborSwapIsdaFixAm 用于掉期。

    检查我根据您的数据制作的这个例子是否有帮助......

    import pandas as pd
    import QuantLib as ql
    
    data = [
        {'Date': '1996-06-21 00:00:00', '3M': 5.57813, '1Y': 6.19, '2Y': 6.55, '5Y': 7.02, '7Y': 7.17, '10Y': 7.31},
        {'Date': '1996-06-24 00:00:00', '3M': 5.56641, '1Y': 6.18, '2Y': 6.54, '5Y': 6.99, '7Y': 7.14, '10Y': 7.31},
        {'Date': '1996-06-25 00:00:00', '3M': 5.5625, '1Y': 6.155, '2Y': 6.52, '5Y': 6.99, '7Y': 7.15, '10Y': 7.31},
        {'Date': '1996-06-26 00:00:00', '3M': 5.57031, '1Y': 6.14, '2Y': 6.52, '5Y': 6.94, '7Y': 7.1, '10Y': 7.27},
        {'Date': '1996-06-27 00:00:00', '3M': 5.59766, '1Y': 6.16, '2Y': 6.5, '5Y': 6.93, '7Y': 7.09, '10Y': 7.26},
        {'Date': '1996-06-28 00:00:00', '3M': 5.58203, '1Y': 6.075, '2Y': 6.44, '5Y': 6.87, '7Y': 7.03, '10Y': 7.2},
        {'Date': '1996-07-01 00:00:00', '3M': 5.5625, '1Y': 6.03, '2Y': 6.33, '5Y': 6.75, '7Y': 6.92, '10Y': 7.09},
        {'Date': '1996-07-02 00:00:00', '3M': 5.5625, '1Y': 6.05, '2Y': 6.36, '5Y': 6.77, '7Y': 6.93, '10Y': 7.11},
        {'Date': '1996-07-03 00:00:00', '3M': 5.59766, '1Y': 6.11, '2Y': 6.43, '5Y': 6.84, '7Y': 7.0, '10Y': 7.17},
        {'Date': '1996-07-04 00:00:00', '3M': 5.57031, '1Y': 6.07, '2Y': 6.37, '5Y': 6.79, '7Y': 6.95, '10Y': 7.13},
        {'Date': '1996-07-05 00:00:00', '3M': 5.57422, '1Y': 6.075, '2Y': 6.4, '5Y': 6.8, '7Y': 6.96, '10Y': 7.13},
        {'Date': '1996-07-08 00:00:00', '3M': 5.6875, '1Y': 6.33, '2Y': 6.69, '5Y': 7.11, '7Y': 7.27, '10Y': 7.44},
        {'Date': '1996-07-09 00:00:00', '3M': 5.6875, '1Y': 6.31, '2Y': 6.64, '5Y': 7.07, '7Y': 7.23, '10Y': 7.41},
        {'Date': '1996-07-10 00:00:00', '3M': 5.6875, '1Y': 6.28, '2Y': 6.545, '5Y': 6.985, '7Y': 7.145, '10Y': 7.325},
        {'Date': '1996-07-11 00:00:00', '3M': 5.6875, '1Y': 6.22, '2Y': 6.465, '5Y': 6.925, '7Y': 7.085, '10Y': 7.255},
        {'Date': '1996-07-12 00:00:00', '3M': 5.67578, '1Y': 6.17, '2Y': 6.465, '5Y': 6.905, '7Y': 7.055, '10Y': 7.225},
        {'Date': '1996-07-15 00:00:00', '3M': 5.67578, '1Y': 6.19, '2Y': 6.485, '5Y': 6.925, '7Y': 7.075, '10Y': 7.245},
        {'Date': '1996-07-16 00:00:00', '3M': 5.68359, '1Y': 6.22, '2Y': 6.425, '5Y': 6.855, '7Y': 7.025, '10Y': 7.205}
    ]
    
    calendar = ql.UnitedStates()
    zeros = []
    deposits = ['3M']
    swaps = ['1Y', '2Y', '5Y', '7Y', '10Y']
    for row in data:
        # Build Curve for the date
        curve_date = ql.Date(row['Date'][:10], '%Y-%m-%d')
        ql.Settings.instance().evaluationDate = curve_date
        spot_date = calendar.advance(curve_date, 2, ql.Days)
        helpers = ql.RateHelperVector()
        for tenor in deposits:
            index = ql.USDLibor(ql.Period(tenor))
            helpers.append(
                ql.DepositRateHelper(row[tenor] / 100, index)
            )
        for tenor in swaps:
            swap_index = ql.UsdLiborSwapIsdaFixAm(ql.Period(tenor))
            helpers.append(
                ql.SwapRateHelper(row[tenor] / 100, swap_index)
            )
        curve = ql.PiecewiseCubicZero(curve_date, helpers, ql.Actual360())
    
        # Get Zero Rates
        for tenor in deposits + swaps:
            date = calendar.advance(spot_date, ql.Period(tenor))
            rate = curve.zeroRate(date, ql.Actual360(), ql.Compounded, ql.Annual).rate()
            zeros.append({ 'curve_date': curve_date, 'tenor': tenor, 'zero_rate': rate})
    
    pd.DataFrame(zeros)
    

    【讨论】:

      【解决方案2】:

      在定义存款助手时,您有多种选择。

      假设您有以下参数:

      tenor = ql.Period('6M')
      fixingDays = 2
      calendar = ql.SouthAfrica()
      convention = ql.ModifiedFollowing
      endOfMonth = False
      dayCounter = ql.Actual365Fixed()
      

      (i) 创建自定义索引而不是使用可用模板。在这里你必须给它相关的参数。

      myindex = ql.IborIndex('MyIndex', tenor, fixingDays, currency, calendar, convention, endOfMonth, dayCounter)
      helper = ql.DepositRateHelper(rate, myindex)
      

      (ii) 或者在 DepositHelper 中定义所有这些参数:

      helper = ql.DepositRateHelper(rate, tenor, fixingDays, calendar, convention, endOfMonth, dayCounter)
      

      【讨论】:

      • 太好了,谢谢。我发现了以下与理论计算相匹配的通用属性:calendar = ql.NullCalendar() fixedLegDayCounter = ql.SimpleDayCounter()。最后一个问题:如果在其他参数中指定了所有内容,那么 ql.IborIndex 中货币的用途是什么?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多