问题描述
我正在尝试使用从 1 周到 50 年的期限输入来构建远期年度 EONIA 远期曲线。
到目前为止,我已经设法编写代码:
data
maturity spot rate
0 1 -0.529
1 2 -0.529
2 3 -0.529
3 1 -0.504
4 2 -0.505
5 3 -0.506
6 4 -0.508
7 5 -0.509
8 6 -0.510
9 7 -0.512
10 8 -0.514
11 9 -0.515
12 10 -0.517
13 11 -0.518
14 1 -0.520
15 15 -0.524
16 18 -0.526
17 21 -0.527
18 2 -0.528
19 3 -0.519
20 4 -0.501
21 5 -0.476
22 6 -0.441
23 7 -0.402
24 8 -0.358
25 9 -0.313
26 10 -0.265
27 11 -0.219
28 12 -0.174
29 15 -0.062
30 20 0.034
31 25 0.054
32 30 0.039
33 40 -0.001
34 50 -0.037
terms= data["maturity"].tolist()
rates= data['spot rate'].tolist()
calendar = ql.TARGET()
business_convention = ql.ModifiedFollowing
day_count = ql.Actual360()
settlement_days_EONIA = 2
EONIA = ql.OvernightIndex("EONIA",settlement_days_EONIA,ql.EURCurrency(),calendar,day_count)
# Deposit Helper
depo_facility = -0.50
depo_helper = [ql.DepositRateHelper(ql.QuoteHandle(ql.SimpleQuote(depo_facility/100)),ql.Period(1,ql.Days),1,ql.Unadjusted,False,day_count)]
# OIS Helper
OIS_helpers = []
for i in range(len(terms)):
if i < 3:
tenor = ql.Period(ql.Weeks)
eon_rate = rates[i]
OIS_helpers.append(ql.OISRateHelper(settlement_days_EONIA,tenor,ql.QuoteHandle(ql.SimpleQuote(eon_rate/100)),EONIA))
elif i < 12:
tenor = ql.Period(ql.Months)
eon_rate = rates[i]
OIS_helpers.append(ql.OISRateHelper(settlement_days_EONIA,EONIA))
else:
tenor = ql.Period(ql.Years)
eon_rate = rates[i]
OIS_helpers.append(ql.OISRateHelper(settlement_days_EONIA,EONIA))
rate_helpers = depo_helper + OIS_helpers
eonia_curve_c = ql.PiecewiseLogCubicdiscount(0,ql.TARGET(),rate_helpers,day_count)
#This doesn't give me a daily grid of rates,but only the rates at the tenors of my input
eonia_curve_c.enableExtrapolation()
days = ql.MakeSchedule(eonia_curve_c.referenceDate(),eonia_curve_c.maxDate(),ql.Period('1Y'))
rates_fwd = [
eonia_curve_c.forwardrate(d,calendar.advance(d,365,day_count,ql.Simple).rate()*100
for d in days
]
RuntimeError: more than one instrument with pillar June 18th,2021
OIS 帮助程序的代码中某处可能存在错误,其中存在重叠,但我不确定我做错了什么。有人知道问题出在哪里吗?
解决方法
首先,为任何不优雅的 Python 道歉,因为我来自 C++:
原始问题的主要问题是 ql.Period() 在与整数个周期一起使用时采用两个参数:例如 ql.Period(3,ql.Years)。相反,如果您使用 Tenors 的字符串表示来构造输入数组,例如“3y”,您可以将此字符串传递给 ql.Period()。所以 ql.Period(3,ql.Years) 和 ql.Period('3y') 给出相同的结果。
import QuantLib as ql
import numpy as np
import pandas as pd
curve = [ ['1w',-0.529],['2w',['3w',['1m',-0.504],['2m',-0.505],['3m',-0.506],['4m',-0.508],['5m',-0.509],['6m',-0.510],['7m',-0.512],['8m',-0.514],['9m',-0.515],['10m',-0.517],['11m',-0.518],['1y',-0.520],['15m',-0.524],['18m',-0.526],['21m',-0.527],['2y',-0.528],['3y',-0.519],['4y',-0.501],['5y',-0.476],['6y',-0.441],['7y',-0.402],['8y',-0.358],['9y',-0.313],['10y',-0.265],['11y',-0.219],['12y',-0.174],['15y',-0.062],['20y',0.034],['25y',0.054],['30y',0.039],['40y',-0.001],['50y',-0.037] ]
data = pd.DataFrame(curve,columns = ['maturity','spot rate'])
print('Input curve\n',data)
terms= data["maturity"].tolist()
rates= data['spot rate'].tolist()
calendar = ql.TARGET()
day_count = ql.Actual360()
settlement_days_EONIA = 2
EONIA = ql.OvernightIndex("EONIA",settlement_days_EONIA,ql.EURCurrency(),calendar,day_count)
# Deposit Helper
depo_facility = -0.50
depo_helper = [ql.DepositRateHelper(ql.QuoteHandle(ql.SimpleQuote(depo_facility/100)),ql.Period(1,ql.Days),1,ql.Unadjusted,False,day_count)]
# OIS Helper
OIS_helpers = []
for i in range(len(terms)):
tenor = ql.Period(terms[i])
eon_rate = rates[i]
OIS_helpers.append(ql.OISRateHelper(settlement_days_EONIA,tenor,ql.QuoteHandle(ql.SimpleQuote(eon_rate/100)),EONIA))
rate_helpers = depo_helper + OIS_helpers
eonia_curve_c = ql.PiecewiseLogCubicDiscount(0,ql.TARGET(),rate_helpers,day_count)
#This doesn't give me a daily grid of rates,but only the rates at the tenors of my input
eonia_curve_c.enableExtrapolation()
days = ql.MakeSchedule(eonia_curve_c.referenceDate(),eonia_curve_c.maxDate(),ql.Period('1Y'))
rates_fwd = [
eonia_curve_c.forwardRate(d,calendar.advance(d,365,day_count,ql.Simple).rate()*100
for d in days
]
print('Output\n',pd.DataFrame(rates_fwd,columns=['Fwd rate']))