Python

使用 quantlib 交換引導

  • November 6, 2017

我一直試圖在 Python 中使用 Quantlib 獲得智利互換曲線的零利率,但我無法正確設置參數。這是我的程式碼:

import QuantLib as ql
import pandas as pd

#Custom Calendar with Chilean Holidays
def create_calendar_chile(start_year,n_years):
   Chile = ql.WeekendsOnly()
   days = [1,14,15,1,21,26,2,16,15,18,19,9,27,1,19,8,17,25,31]
   months = [1,4,4,5,5,6,8,9,9,10,10,11,12,12,12,12]
   name = ['Año Nuevo','Viernes Santo','Sabado Santo','Dia del Trabajo','Dia de las Glorias Navales','San Pedro y San Pablo','Elecciones Primarias','Dia de la Virgen del Carmen','Asuncion de la Virgen','Independencia Nacional','Glorias del Ejercito','Encuentro de dos mundos','Día de las Iglesias Evangélicas y Protestantes','Día de todos los Santos','Elecciones Presidenciales y Parlamentarias','Inmaculada Concepción','Segunda vuelta Presidenciales','Navidad','Feriado Bancario']
   for i in range(n_years+1):
       for x,y in zip(days,months):
           date = ql.Date(x,y,start_year+i)
           Chile.addHoliday(date)

   return Chile



today = ql.Date(25, 10, 2017)
ql.Settings.instance().evaluationDate = today

swap_clp = [2.46, 2.40, 2.40, 2.41, 2.54, 2.68, 3.01, 3.3, 3.53, 3.69, 3.87, 4.02, 4.13, 4.23, 4.38, 4.38, 4.56]
terms = [3,6,9,12,18,2,3,4,5,6,7,8,9,10,12,15,20]
## SWAP Parameters ##
calendar = create_calendar_chile(2001,50)
bussiness_convention = ql.Following
day_count = ql.Actual360()

#Overnigth Rate
TPM = 2.5
depo_helper = [ql.DepositRateHelper(ql.QuoteHandle(ql.SimpleQuote(TPM/100)),ql.Period(1,ql.Days),1,calendar,ql.Unadjusted,False,ql.Actual360())]

#Swap Rates
swap_helpers = []
for i in range(len(terms)):
   if i < 4:
       coupon_frequency = ql.Once
       tenor = ql.Period(terms[i],ql.Months)
       rate = swap_clp[i]
       swap_helpers.append(ql.SwapRateHelper(ql.QuoteHandle(ql.SimpleQuote(rate/100.0)),tenor, calendar,coupon_frequency, bussiness_convention,day_count,ql.Euribor3M()))
   else:
       coupon_frequency = ql.Semiannual
       tenor = ql.Period(terms[i],ql.Years)
       rate = swap_clp[i]
       swap_helpers.append(ql.SwapRateHelper(ql.QuoteHandle(ql.SimpleQuote(rate/100.0)),tenor, calendar,coupon_frequency, bussiness_convention,day_count,ql.Euribor3M()))

#Yield Curve
rate_helpers = depo_helper + swap_helpers
yieldcurve = ql.PiecewiseLinearZero(today,rate_helpers,day_count)

spots = []
tenors = []
for d in yieldcurve.dates():
   yrs = day_count.yearFraction(today, d)
   compounding = ql.Simple
   freq = ql.Annual
   zero_rate = yieldcurve.zeroRate(yrs, compounding, freq)
   tenors.append(yrs)
   eq_rate = zero_rate.equivalentRate(day_count,compounding,freq,today,d).rate()
   spots.append(100*eq_rate)

datatable = {'Dates':yieldcurve.dates(),'Tenors':tenors,'spots':spots}
df = pd.DataFrame.from_dict(datatable)

我得到以下結果:

>>> df
                Dates     Tenors     spots
0   October 25th, 2017   0.000000  0.000000
1   October 27th, 2017   0.005556  2.500087
2   January 29th, 2018   0.266667  2.461170
3     April 27th, 2018   0.511111  2.401418
4      July 27th, 2018   0.763889  2.401059
5   October 29th, 2018   1.025000  2.410821
6   October 28th, 2019   2.036111  2.739493
7   October 27th, 2020   3.050000  3.141727
8   October 27th, 2021   4.063889  3.529495
9   October 27th, 2022   5.077778  3.875600
10  October 27th, 2023   6.091667  4.157661
11  October 28th, 2024   7.111111  4.495323
12  October 27th, 2025   8.122222  4.817217
13  October 27th, 2026   9.136111  5.100542
14  October 27th, 2027  10.150000  5.390948
15  October 29th, 2029  12.186111  5.945168
16  October 27th, 2032  15.225000  6.352031
17  October 29th, 2035  18.272222  2.707640
18  October 27th, 2037  20.297222  8.655828

根據 Bloomberg boostrap 的說法,零利率是錯誤的(撇開利率和日期的微小差異不談)。我在交換助手中使用 Euribor3M 索引,但我認為那是錯誤的。如何在 python 中設置自定義索引?此外,與實際零相比,零水平似乎有點高:

Bloomberg:
Date    Days    Term    InstType    Mid Zero
26-10-2017  1   O/N CASH    2,500   2,500
30-01-2018  97  3 MO    CASH    2,460   2,460
30-04-2018  187 6 MO    CASH    2,400   2,400
30-07-2018  278 9 MO    CASH    2,400   2,400
30-10-2018  370 1 YR    CASH    2,410   2,410
30-04-2019  552 18 MO   CASH    2,540   2,540
30-10-2019  735 2 YR    SWAP    2,680   2,684
30-10-2020  1101    3 YR    SWAP    3,010   3,024
29-10-2021  1465    4 YR    SWAP    3,300   3,327
28-10-2022  1829    5 YR    SWAP    3,540   3,582
30-10-2023  2196    6 YR    SWAP    3,700   3,752
30-10-2024  2562    7 YR    SWAP    3,870   3,939
30-10-2025  2927    8 YR    SWAP    4,030   4,119
30-10-2026  3292    9 YR    SWAP    4,140   4,243
29-10-2027  3656    10 YR   SWAP    4,230   4,346
30-10-2032  5484    15 YR   SWAP    4,380   4,502
30-10-2037  7310    20 YR   SWAP    4,560   4,742

您可能已經想到了這一點,因為您在評論中提到彭博利率每半年復利一次。但是,較高的利率與您選擇的複利慣例有關。您要求使用簡單複利的利率,這會覆蓋您通過的年度頻率,並導致利率高於您的預期。使用CompoundedSemiannual返回更接近您引用的值。

對於您在第 18 年獲得的 2.707,您的程式碼中有一個錯誤。18 個月期限載入為 18 年

#Swap Rates
swap_helpers = []
for i in range(len(terms)):
   if i < 4:  # should be i < 5!!! 
       ...

不過,不知道彭博費率使用的慣例來評論差異。

引用自:https://quant.stackexchange.com/questions/36602