Python
使用 QuantLib Python 計算 Swap DV01
我想使用 QuantLib Python 來計算利率掉期的 DV01。
最初我想分別計算固定腿 DV01 和浮動腿 DV01,然後將兩條腿 DV01 相加得到交換 DV01。但是,我不知道如何使用 QuantLib Python 計算浮動腿 DV01。
最後,我使用以下程式碼採用了不同的方法來計算利率掉期 DV01:
from QuantLib import * # global data calendar = TARGET() todaysDate = Date(6,November,2001); Settings.instance().evaluationDate = todaysDate settlementDate = Date(8,November,2001); # market quotes deposits = { (1,Weeks): 0.0382, (1,Months): 0.0372, (3,Months): 0.0363, (6,Months): 0.0353, (9,Months): 0.0348, (1,Years): 0.0345 } swaps = { (2,Years): 0.037125, (3,Years): 0.0398, (5,Years): 0.0443, (10,Years): 0.05165, (15,Years): 0.055175 } # convert them to Quote objects for n,unit in deposits.keys(): deposits[(n,unit)] = SimpleQuote(deposits[(n,unit)]) for n,unit in swaps.keys(): swaps[(n,unit)] = SimpleQuote(swaps[(n,unit)]) # build rate helpers dayCounter = Actual360() settlementDays = 2 depositHelpers = [ DepositRateHelper(QuoteHandle(deposits[(n,unit)]), Period(n,unit), settlementDays, calendar, ModifiedFollowing, False, dayCounter) for n, unit in [(1,Weeks),(1,Months),(3,Months), (6,Months),(9,Months),(1,Years)] ] fixedLegFrequency = Annual fixedLegTenor = Period(1,Years) fixedLegAdjustment = Unadjusted fixedLegDayCounter = Thirty360() floatingLegFrequency = Semiannual floatingLegTenor = Period(6,Months) floatingLegAdjustment = ModifiedFollowing swapHelpers = [ SwapRateHelper(QuoteHandle(swaps[(n,unit)]), Period(n,unit), calendar, fixedLegFrequency, fixedLegAdjustment, fixedLegDayCounter, Euribor6M()) for n, unit in swaps.keys() ] # term structure handles discountTermStructure = RelinkableYieldTermStructureHandle() forecastTermStructure = RelinkableYieldTermStructureHandle() # term-structure construction helpers = depositHelpers + swapHelpers depoSwapCurve = PiecewiseFlatForward(settlementDate, helpers, Actual360()) swapEngine = DiscountingSwapEngine(discountTermStructure) # 5Y Swap nominal = 1000000 maturity = calendar.advance(settlementDate,5,Years) fixedLegFrequency = Annual fixedLegAdjustment = Unadjusted fixedLegDayCounter = Thirty360() fixedRate = 0.04 floatingLegFrequency = Semiannual spread = 0.0 fixingDays = 2 index = Euribor6M(forecastTermStructure) floatingLegAdjustment = ModifiedFollowing floatingLegDayCounter = index.dayCounter() fixedSchedule = Schedule(settlementDate, maturity, fixedLegTenor, calendar, fixedLegAdjustment, fixedLegAdjustment, DateGeneration.Forward, False) floatingSchedule = Schedule(settlementDate, maturity, floatingLegTenor, calendar, floatingLegAdjustment, floatingLegAdjustment, DateGeneration.Forward, False) swap = VanillaSwap(VanillaSwap.Receiver, nominal, fixedSchedule, fixedRate, fixedLegDayCounter, floatingSchedule, index, spread, floatingLegDayCounter) swap.setPricingEngine(swapEngine) discountTermStructure.linkTo(depoSwapCurve) forecastTermStructure.linkTo(depoSwapCurve) print('Fixed Leg DV01') print(swap.fixedLegBPS()) shift = 0.0001 temp_fyc_handle = YieldTermStructureHandle(depoSwapCurve) temp_dyc_handle = YieldTermStructureHandle(depoSwapCurve) shiftedForwardCurve = ZeroSpreadedTermStructure(temp_fyc_handle, QuoteHandle(SimpleQuote(shift))) shiftedDiscountCurve = ZeroSpreadedTermStructure(temp_dyc_handle, QuoteHandle(SimpleQuote(shift))) discountTermStructure.linkTo(shiftedDiscountCurve) forecastTermStructure.linkTo(shiftedForwardCurve) P_p = swap.NPV() temp_fyc_handle = YieldTermStructureHandle(depoSwapCurve) temp_dyc_handle = YieldTermStructureHandle(depoSwapCurve) shiftedForwardCurve = ZeroSpreadedTermStructure(temp_fyc_handle, QuoteHandle(SimpleQuote(-shift))) shiftedDiscountCurve = ZeroSpreadedTermStructure(temp_dyc_handle, QuoteHandle(SimpleQuote(-shift))) discountTermStructure.linkTo(shiftedDiscountCurve) forecastTermStructure.linkTo(shiftedForwardCurve) P_m = swap.NPV() dv01 = (P_m - P_p) / 2.0 print('Swap DV01') print(dv01)
我在如何使用 QuantLib Python 計算利率掉期 DV01 方面是否正確?上面程式碼的輸出顯示固定支路 DV01 小於整個交換的 DV01。那正確嗎?
不,恐怕你是在比較蘋果和橙子。您對掉期 DV01 的計算是正確的(需要注意的是,見下文),但返回的數字
swap.fixedLegBPS
不可比較。DV01 告訴您如果利率曲線發生變化,NPV 會發生什麼變化;在固定腿的情況下,這會影響用於貼現票面金額的貼現因子,但不會影響固定金額本身。
BPS 告訴您如果固定息票的利率增加 1 個基點而利率(以及貼現因子)保持不變,NPV 會發生什麼變化。計算公平利率很有用,或者在您定義交易時,但一旦建立交換並且其利率固定,可能就不那麼有用了。所以:不同的東西。
如果你想單獨計算固定腿的 DV01,你可以這樣做:
shift = 0.0001 temp_dyc_handle = YieldTermStructureHandle(depoSwapCurve) shiftedDiscountCurve = ZeroSpreadedTermStructure(temp_dyc_handle, QuoteHandle(SimpleQuote(shift))) discountTermStructure.linkTo(shiftedDiscountCurve) P_p = CashFlows.npv(swap.fixedLeg(), discountTermStructure, False, settlementDate) temp_dyc_handle = YieldTermStructureHandle(depoSwapCurve) shiftedDiscountCurve = ZeroSpreadedTermStructure(temp_dyc_handle, QuoteHandle(SimpleQuote(-shift))) discountTermStructure.linkTo(shiftedDiscountCurve) P_m = CashFlows.npv(swap.fixedLeg(), discountTermStructure, False, settlementDate) dv01 = (P_m - P_p) / 2.0 print('Fixed Leg DV01') print(dv01)
關於我上面提到的警告:你正在做
discountTermStructure.linkTo(depoSwapCurve) forecastTermStructure.linkTo(depoSwapCurve)
也就是說,您使用相同的曲線來預測浮動利率固定和現金流貼現,這就是我們在 QuantLib 版本中包含的範例中所做的。我們真的應該更新它;如今,實踐是使用兩條不同的曲線進行預測和貼現。在這種情況下,當您像現在一樣移動兩條曲線時,將 DV01 定義為 NPV 的變化可能仍然有意義;但請確保這是您想要的。