|
From: Aaron De la R. <aar...@gm...> - 2025-10-27 15:14:36
|
Could you share the entire code. So, I can fix it.
Regard
Aaron
________________________________
From: Kenji Ogawa <for...@gm...>
Sent: Sunday, October 26, 2025 6:34 PM
To: Qua...@li... <Qua...@li...>
Subject: [Quantlib-users] Asset Swap Calculation Error with IBM 1.25 1/29/27 (Settlement Days Issue)
Below is the code that calculates the asset swap for IBM 1.25 1/29/27, traded on April 25, 2024, at a price of 93.95.
When using settleDS = 3, the results are correct:
legNPV1 = 95.179 and fairSPD = 0.359%.
However, when using settleDS = 2, the calculation produces abnormal results:
legNPV1 = 100.926 and fairSPD = -1.81%.
Since the bond should settle on T+2, this discrepancy is problematic.
Could someone please help fix this error?
# =====================================================
# Asset swaps - IBM 1.25, Jan 2027
import QuantLib as ql; import pandas as pd; import numpy as np
settleDS = 2
tradeDT = ql.Date(25,4,2024)
settleDT = ql.TARGET().advance(tradeDT, settleDS, ql.Days)
ql.Settings.instance().evaluationDate = tradeDT
# my abbreviation
calEU = ql.TARGET()
dc30 = ql.Thirty360(ql.Thirty360.BondBasis)
dcAAb = ql.ActualActual(ql.ActualActual.Bond)
unADJ = ql.Unadjusted
dtGENb = ql.DateGeneration.Backward
EoMf = False
def sqHDL(xx): return ql.QuoteHandle(ql.SimpleQuote(xx))
# Euribor curve data
crvDATA = [('depo', '6m', 3.825), ('asOBJ', '1y', 3.7), ('asOBJ', '18m', 3.512),
('asOBJ', '2y', 3.378), ('asOBJ', '3y', 3.186), ('asOBJ', '4y', 3.067)]
# Euribor Index
ebCrvHDL = ql.RelinkableYieldTermStructureHandle()
ebrIX = ql.Euribor(ql.Period("6M"), ebCrvHDL)
# Swap Curve
cHelper, ebParRT = [], []
for knd, tnr, rt in crvDATA:
if knd == 'depo': cHelper.append(ql.DepositRateHelper(sqHDL(rt/100),ebrIX))
if knd == 'asOBJ': cHelper.append(ql.SwapRateHelper( sqHDL(rt/100),
ql.Period(tnr), calEU, ql.Annual, ql.ModifiedFollowing, dc30, ebrIX))
ebCrvOBJ = ql.PiecewiseLogLinearDiscount(2, calEU, cHelper, ql.Actual360())
ebCrvHDL.linkTo(ebCrvOBJ)
# bond
effDT, matDT = ql.Date(31,1,2019), ql.Date(29,1,2027)
faceAMT, cpnLST, clnPRC = 100.0, [0.0125], 93.95
bondSCD = ql.Schedule(effDT, matDT, ql.Period(ql.Annual), calEU, unADJ,unADJ, dtGENb, EoMf)
bondOBJ = ql.FixedRateBond(settleDS, faceAMT, bondSCD, cpnLST, dcAAb)
# asset swap
payFix, isPar = True, True
crdSPRD, fltSCH = 35/10000, ql.Schedule()
asOBJ = ql.AssetSwap(payFix,bondOBJ,clnPRC,ebrIX,crdSPRD,fltSCH,ebrIX.dayCounter(),isPar)
asOBJ.setPricingEngine(ql.DiscountingSwapEngine(ebCrvHDL))
print(f' NPV:{asOBJ.NPV(): 10.6f} \n'
f'legNPV0:{asOBJ.legNPV(0): 10.6f} \n'
f'legNPV1:{asOBJ.legNPV(1): 10.6f} \n'
f'fairSPD:{asOBJ.fairSpread(): 10.6%}')
# =====================================================
|