QuantLib:交换到零优惠券曲线引导

2024-05-19 02:50:06 发布

您现在位置:Python中文网/ 问答频道 /正文

我正试图将美国掉期曲线引导成零息票曲线(见彭博社截图)。我有从1996年6月21日到今天的3M、1Y、2Y、5Y、7Y、10Y到期日的每日数据(缺少一些天数,请参见数据框屏幕截图)。我希望获得从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)

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

运行时错误:超过一台带有支柱的仪器1996年7月25日

所以我想我对日期有意见。我的理解是,掉期辅助工具具有掉期固定分支的特征但在哪里输入浮动支腿的值?


Tags: ofinfordateindexratezchelpers
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)或在文件中定义所有这些参数:

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

浮动支腿参数来自索引。在您的例子中,似乎您使用的是ql.Euribor3M(),它与您真正想要的美元伦敦银行同业拆借利率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)

相关问题 更多 >

    热门问题