【问题标题】:Runtime error - Forward Rates Calculation运行时错误 - 远期汇率计算
【发布时间】:2021-02-17 10:23:53
【问题描述】:

我正在尝试构建一个远期年度 EONIA 远期曲线,其中输入的期限从 1 周到 50 年不等。

到目前为止,我已经成功编写了代码:

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 专家,但这一行:tenor = ql.Period(ql.Weeks)。 QL 参考建议您应该有几个星期......应该是 ql.Period(terms[i],ql.Weeks) 等?
  • 在 tenor = ql.Period(ql.Weeks) 行中,我的猜测是 ql.Period 试图将 ql.Weeks 解释为频率。在 C++ 枚举中,ql.Weeks = 1,months 为 2,years 为 3。因此 ql.Period(n) 被解释为频率,1 = Annual,2=Semiannual,3=EveryFourthMonth。线索是,当您使用 ql.Years 时,您实际上使用的是 ql.Period(3),它正在成为 EveryFourthMonth ...给您(假设您的现货结算时间是 21 年 2 月 18 日)许多到期为 18 的工具-Jun-21。由于这是你的集合中最短的日期,这是 QL 首先抱怨的。欢迎使用 Python 类型安全!

标签: python pandas quantitative-finance quantlib


【解决方案1】:

首先,对任何不优雅的 Python 表示歉意,因为我来自 C++:

原始问题的主要问题是 ql.Period() 在与整数周期数一起使用时采用两个参数:例如 ql.Period(3,ql.Years)。相反,如果您使用 Tenor 的字符串表示形式构造输入数组,例如“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']))

【讨论】:

  • 谢谢,我终于设法让它工作了。我必须将 OIS 助手与术语索引进行分类。
猜你喜欢
  • 1970-01-01
  • 2014-11-17
  • 2018-12-10
  • 1970-01-01
  • 1970-01-01
  • 2015-11-27
  • 2018-03-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多