He estado tratando de obtener las tasas cero de la curva del Swap chileno con Quantlib en Python, pero no he podido configurar los parámetros correctamente. Este es mi código:
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)
Y estoy obteniendo los siguientes resultados:
>>> 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
Los tipos cero son erróneos según Bloomberg boostrap (dejando de lado pequeñas diferencias en los tipos y fechas). Estoy utilizando el índice Euribor3M en el Swap Helpers pero supongo que está mal. ¿Cómo podría configurar un índice personalizado en python? Además, los niveles de los ceros parecen ser un poco altos en comparación con los ceros reales:
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