程式
使用 quantlib 定價攤銷可贖回丹麥抵押債券
我正在嘗試為可贖回固定利率攤銷丹麥抵押債券定價。因為 QuantLib 只有
CallableFixedRateBond
我創建了一個名為的派生類CallableAmortizedBond
,它看起來像AmortizingFixedRateBond
:class CallableAmortizedBond : public CallableFixedRateBond { public: CallableAmortizedBond( Natural settlementDays, Real faceAmount, const Schedule &schedule, const vector<Rate> &coupons, const DayCounter &accrualDayCounter, BusinessDayConvention paymentConvention, Real redemption, const Date &issueDate, const vector<Rate> ¬ionals, const CallabilitySchedule &putCallSchedule) : CallableFixedRateBond(settlementDays, faceAmount, schedule, coupons, accrualDayCounter, paymentConvention, redemption, issueDate, putCallSchedule) { cashflows_ = FixedRateLeg(schedule) .withNotionals(notionals) .withCouponRates(coupons, accrualDayCounter) .withPaymentAdjustment(paymentConvention); } };
我添加了一些概念,靈感來自:
Schedule sinkingSchedule(const Date& startDate, const Period& maturityTenor, const Frequency& sinkingFrequency, const Calendar& paymentCalendar)
對於不同的債券,它看起來像這樣:
對於沒有攤銷的債券,它將是一個面值向量,例如,
[100.0 .. 100.0]
對於部分攤銷的債券,它將與面值一起,直到攤銷開始然後完全攤銷:[100.0, 100.0 .. 99.0 97.0 .. 0.0]
對於完全攤銷的債券,它將是[100.0, 99.0 .. 0.0]
我使用 swaprates 創建
YieldTermStructure
具有以下值的 a:2Y -> -0.13 3Y -> -0.09 4Y -> -0.03 5Y -> -0.03 6Y -> 0.1 7Y -> 0.18 8Y -> 0.25 9Y -> 0.32 10Y -> 0.39 12Y -> 0.51 15Y -> 0.65
像這樣:
Handle<YieldTermStructure> calculateTermStructure(rust::Vec<SwapRates> swapRates, RustDate now) { Calendar calendar = TARGET(); Date settlementDate(now.day, getMonthFromInt(now.month), now.year); Frequency swFixedLegFrequency = Annual; BusinessDayConvention swFixedLegConvention = Unadjusted; DayCounter swFixedLegDayCounter = dayCounter; DayCounter termStructureDayCounter = dayCounter; ext::shared_ptr<IborIndex> swFloatingLegIndex(new Euribor1Y); const Period forwardStart(1 * Days); std::vector<ext::shared_ptr<RateHelper>> swapInstruments; for (auto const &swapRate : swapRates) { ext::shared_ptr<Quote> simpleQuote(new SimpleQuote(swapRate.rate)); ext::shared_ptr<RateHelper> swapRateHelper(new SwapRateHelper( Handle<Quote>(simpleQuote), swapRate.maturity * Years, calendar, swFixedLegFrequency, swFixedLegConvention, swFixedLegDayCounter, swFloatingLegIndex, Handle<Quote>(), forwardStart)); swapInstruments.push_back(swapRateHelper); } ext::shared_ptr<YieldTermStructure> swapTermStructure( new PiecewiseYieldCurve<Discount, LogLinear>( settlementDate, swapInstruments, termStructureDayCounter)); Handle<YieldTermStructure> termStructure(swapTermStructure); termStructure->enableExtrapolation(); return termStructure; }
我
CallabilitySchedule
使用以下函式創建:CallabilitySchedule getCallSchedule(rust::Vec<RustDate> callSchedule) { CallabilitySchedule callabilitySchedule; Real callPrice = 100.; for (auto const &callRustRate : callSchedule) { Bond::Price bondCallPrice(callPrice, Bond::Price::Clean); Date callDate(callRustRate.day, getMonthFromInt(callRustRate.month), callRustRate.year); callabilitySchedule.push_back( ext::make_shared<Callability>( bondCallPrice, Callability::Call, callDate)); } return callabilitySchedule; }
然後我用它來為可贖回抵押債券定價:
Integer gridIntervals = 40; Real reversionParameter = .03; // output price/yield results for varying volatility parameter Real sigma = QL_EPSILON; // core dumps if zero on Cygwin ext::shared_ptr<ShortRateModel> hw0( new HullWhite(termStructure, reversionParameter, sigma)); ext::shared_ptr<PricingEngine> engine0( new TreeCallableFixedRateBondEngine(hw0, gridIntervals)); ext::shared_ptr<PricingEngine> bondEngine( new DiscountingBondEngine(termStructure)); vector<Rate> notionalRates; for (auto const ¬ional : notionals) { notionalRates.push_back(notional); } CallableAmortizedBond callableAmortizedBond(settlementDays, faceAmount, schedule, vector<Rate>(1, coupon), dayCounter, paymentConvention, redemption, datedDate, notionalRates, callabilitySchedule); callableAmortizedBond.setPricingEngine(engine0); return callableAmortizedBond.cleanPrice();
使用返回的價格
.cleanPrice()
遠低於納斯達克的價格。例如,該債券的最後價格為 ,91.210
但我使用目前掉期利率的價格88.542
沒有攤銷。另一個問題是,通過攤銷,我得到的價格比沒有攤銷低。這與現實世界中發生的事情相反。那麼,這是為可贖回攤銷抵押債券定價的正確方法嗎?它是為可贖回債券類別添加攤銷的正確方法嗎?