运行时错误 - 远期利率计算

Runtime error - Forward Rates Calculation

我正在尝试使用 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, calendar, 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, tenor, ql.QuoteHandle(ql.SimpleQuote(eon_rate/100)), EONIA)) 
    else:
        tenor = ql.Period(ql.Years)
        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,ql.Days), 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)。相反,如果您使用男高音的字符串表示形式构造输入数组,例如“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',     -0.529],
        ['3w',     -0.529],
        ['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, calendar, 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,ql.Days), day_count, ql.Simple).rate()*100
    for d in days
]

print('Output\n',pd.DataFrame(rates_fwd,columns=['Fwd rate']))