Class MBSFixedRateBond
- Namespace
- NanoQL.Extensions.Instruments
- Assembly
- NanoQL.Extensions.dll
A fixed-rate mortgage pass-through with prepayment: a pool of level-payment mortgages at a weighted-average coupon (WAC), whose expected principal and pass-through interest reach the holder each period, the prepayments as a model gives them.
public sealed class MBSFixedRateBond : Bond
- Inheritance
-
MBSFixedRateBond
- Inherited Members
Remarks
Each period pays a FixedRateCoupon at the pass-through rate on the pool's balance at the period's start, its scheduled principal (AmortizingPayment), the level-payment schedule's at the WAC scaled to the balance, and its prepayment (VoluntaryPrepay), the balance after the scheduled principal times the period's single monthly mortality (SMM); the bond's leg holds them in that order on each date, as a bond's redemptions follow its coupons. The model reads the pool's age: a date of the bond's schedule plus the original length less the remaining one, so a seasoned pool starts its PSA ramp part way.
Ported from QLNet, which derives it from its AmortizingFixedRateBond; here it builds on Bond,
its schedule and the level-payment notionals from AmortizingFixedRateBondFunctions. Its departures
from QLNet: the notional schedule and the redemptions are the pool's expected ones, so the yields price the pool's
balance at the settlement, where QLNet's read the level-payment schedule's; the flows pay on the period ends
adjusted by the payment convention on the calendar, which QLNet ignores; a period of a frequency other than monthly
survives the product of its months' prepayments (or, for a period counted in weeks or days, its share of a month's),
where QLNet applies one month's SMM a period; the monthly yield's bracket widens past QLNet's [0, 1]% a month when
that doesn't hold the root; and the yields refuse a pool fully paid off at the settlement, where QLNet's throw on
its stale notional, and price the settlement date's flows as paid whatever the context's settings, where QLNet's
read them. MonthlyYield(EvaluationContext) keeps QLNet's whole periods with no delay;
Yield(double, int, EvaluationContext, Date?) and Price(double, int, EvaluationContext, Date?) are SIFMA's standard yield and
price.
Constructors
MBSFixedRateBond(int, Calendar?, double, Date, Period, Period, Frequency, double, double, DayCounter, IPrepayModel?, BusinessDayConvention, Date?)
Initializes a new instance of the MBSFixedRateBond class.
public MBSFixedRateBond(int settlementDays, Calendar? calendar, double faceAmount, Date startDate, Period bondTenor, Period originalLength, Frequency sinkingFrequency, double wacRate, double passThroughRate, DayCounter accrualDayCounter, IPrepayModel? prepayModel, BusinessDayConvention paymentConvention = BusinessDayConvention.Following, Date? issueDate = null)
Parameters
settlementDaysintThe settlement days.
calendarCalendarThe calendar of the settlement and the payment dates, or null, QuantLib's empty calendar, which takes only an Unadjusted payment convention.
faceAmountdoubleThe pool's balance at the start date.
startDateDateThe start date of the bond's first period.
bondTenorPeriodThe remaining term, the bond's length.
originalLengthPeriodThe loans' original term: the pool's age is it less the remaining term.
sinkingFrequencyFrequencyThe payment frequency.
wacRatedoubleThe weighted-average coupon of the loans, which sets the scheduled principal.
passThroughRatedoubleThe rate paid to the holder on the pool's balance.
accrualDayCounterDayCounterThe pass-through coupons' day counter.
prepayModelIPrepayModelThe prepayment model, or null for none.
paymentConventionBusinessDayConventionThe convention adjusting the payment dates on the calendar.
issueDateDate?The issue date, or null for none.
Exceptions
- ArgumentNullException
accrualDayCounteris null.- ArgumentOutOfRangeException
settlementDaysis negative, orpaymentConventionisn't a member of its type.- ArgumentException
The frequency or the tenor isn't one the level-payment schedule takes (SinkingNotionals(Period, Frequency, double, double)).
- NanoQLException
The calendar is null and the payment convention adjusts.
Properties
BondFactors
Gets the level-payment schedule's factors: its notionals over the first, one a date of the bond's schedule, the last 0.
public ImmutableArray<double> BondFactors { get; }
Property Value
DayCounter
Gets the pass-through coupons' day counter.
public DayCounter DayCounter { get; }
Property Value
ExpectedCashflows
Gets the expected cash flows: each period's pass-through coupon, scheduled principal and prepayment, the bond's own leg.
public ImmutableArray<CashFlow> ExpectedCashflows { get; }
Property Value
Frequency
Gets the payment frequency.
public Frequency Frequency { get; }
Property Value
Methods
BondEquivalentYield(EvaluationContext)
The bond-equivalent yield of MonthlyYield(EvaluationContext), its semi-annual equivalent, as SIFMA converts a monthly
yield: 2 ((1 + y)^6 − 1), or for a pool of another frequency 2 ((1 + y)^(f/2) − 1) on its yield
per period.
public double BondEquivalentYield(EvaluationContext context)
Parameters
contextEvaluationContextThe evaluation context, whose evaluation date sets the settlement date.
Returns
- double
The yield, a fraction a year, compounded semi-annually.
Exceptions
- ArgumentNullException
contextis null.- ArgumentException
The pool is fully paid off at the settlement date.
- NanoQLException
The solver finds no root.
MonthlyYield(EvaluationContext)
The monthly yield at par, QLNet's: the rate per month at which the expected flows after the settlement date, discounted by whole periods per payment date with no delay, are worth the pool's balance at the settlement date.
public double MonthlyYield(EvaluationContext context)
Parameters
contextEvaluationContextThe evaluation context, whose evaluation date sets the settlement date.
Returns
- double
The yield per month, a fraction.
Remarks
The solve is QLNet's: Brent from a guess of 0.02% a month over [0, 1]% a month, to 1e-10, in 100 evaluations; where that range doesn't bracket the root, Brent's step search from the same guess, above −100% a month. On a pool of another frequency the root is a yield per period, and the result its monthly equivalent. The settlement date's flows count as paid, as the balance takes them, whatever the context's IncludeReferenceDateEvents and IncludeTodaysCashFlows.
Exceptions
- ArgumentNullException
contextis null.- ArgumentException
The pool is fully paid off at the settlement date.
- NanoQLException
The solver finds no root.
Price(double, int, EvaluationContext, Date?)
SIFMA's standard price at a yield (Uniform Practices, Chapter SF, SF-48): the expected flows' value at the bond-equivalent yield, less the accrued interest, per 100 of the balance at the start of the period holding the settlement, as Yield(double, int, EvaluationContext, Date?) reads them.
public double Price(double yield, int delayDays, EvaluationContext context, Date? settlementDate = null)
Parameters
yielddoubleThe bond-equivalent yield, a fraction a year, compounded semi-annually.
delayDaysintThe actual delay, in days from each period's end to its payment (SF-44).
contextEvaluationContextThe evaluation context, whose evaluation date sets the settlement date.
settlementDateDate?The settlement date; the bond's when null.
Returns
- double
The clean price per 100 of the current balance.
Exceptions
- ArgumentNullException
contextis null.- ArgumentOutOfRangeException
delayDaysis negative.- ArgumentException
The pool is fully paid off at the settlement date.
SMM(Date)
The prepayment model's single monthly mortality at a date plus the pool's age, QLNet's function. It isn't always a period's SMM: the flows read the model at the start's anniversaries, the start plus the age plus the months before the period, which a schedule date plus the age misses by a month from a start after the 28th, and a period of another frequency survives the product of its months' prepayments.
public double SMM(Date d)
Parameters
dDateThe date, before the pool's age is added.
Returns
- double
The model's SMM at
dplus the pool's age; 0 with no model.
Yield(double, int, EvaluationContext, Date?)
SIFMA's standard yield (Uniform Practices, Chapter SF, SF-48): the bond-equivalent yield Y at which the expected
flows due after the settlement, each discounted by (1 + Y/2)^(−2T), are worth the dollar price.
public double Yield(double cleanPrice, int delayDays, EvaluationContext context, Date? settlementDate = null)
Parameters
cleanPricedoubleThe price per 100 of the current balance, without accrued interest.
delayDaysintThe actual delay, in days from each period's end to its payment (SF-44).
contextEvaluationContextThe evaluation context, whose evaluation date sets the settlement date.
settlementDateDate?The settlement date; the bond's when null.
Returns
- double
The yield, a fraction a year, compounded semi-annually.
Remarks
The dollar price is the clean price per 100 of the balance at the start of the period holding the settlement, times that balance, plus the interest accrued at the pass-through rate from that period's start (SF-46). T is in years on SIFMA's 30/360 (SF-44), from the settlement to each period's unadjusted end, plus the delay days, so the payment convention doesn't enter; SIFMA's yield is semi-annual whatever the pool's frequency.
Exceptions
- ArgumentNullException
contextis null.- ArgumentOutOfRangeException
delayDaysis negative.- ArgumentException
The pool is fully paid off at the settlement date.
- NanoQLException
The solver finds no root.