Skip to main content

FloatingRateNote

Struct FloatingRateNote 

pub struct FloatingRateNote {
Show 18 fields pub index: String, pub currency: Currency, pub collateral: CollateralSpec, pub quoted_margin: f64, pub gearing: f64, pub face: f64, pub issue: NaiveDate, pub maturity: NaiveDate, pub day_count: DayCountFraction, pub coupons: Leg, pub issuer: Option<CreditCurveId>, pub security_spread: Option<String>, pub outstanding: Vec<f64>, pub tenor_years: f64, pub cap: Option<f64>, pub floor: Option<f64>, pub cap_strip: Option<InterestRateCapFloor>, pub floor_strip: Option<InterestRateCapFloor>,
}
Expand description

A floating-rate note: coupons projecting an index, plus the face at maturity.

Swap-shaped — the coupons project off a projection curve and discount on a separate one — so it prices at par plus its margin’s annuity, and a parallel shift moves its cashflows and its discounting together. Each coupon carries its own fixing date, the accrual start taken back the index’s lag on the index calendar: a period already reset reads the fixing store, and a withheld reset fails loud naming the index and date.

Fields§

§index: String

The index the coupons reset against, by registry code.

§currency: Currency

The note’s currency.

§collateral: CollateralSpec

The discounting key.

§quoted_margin: f64

The quoted margin over the index, as a decimal.

§gearing: f64

Gearing on the index.

§face: f64

The face amount, paid at maturity.

§issue: NaiveDate

The issue date.

§maturity: NaiveDate

The maturity date.

§day_count: DayCountFraction

The accrual day count (the index’s).

§coupons: Leg

The compiled coupons, receive-oriented on face.

§issuer: Option<CreditCurveId>

The issuer, when the note is valued risky.

§security_spread: Option<String>

A security-spread key composed onto the discounting.

§outstanding: Vec<f64>

The fraction of the original face outstanding in each coupon period, one entry per period — all ones for a bullet. The compiled leg carries the profile: each coupon accrues on its period’s fraction, the drop between two periods is a redemption coupon at the boundary, and the last fraction is the redemption at maturity. Per-100 readings stay per 100 of the original face, as the fixed-rate bond’s do.

§tenor_years: f64

The index tenor in years — the axis a cap vol surface is read on.

§cap: Option<f64>

The rate the coupons are capped at, on the coupon’s own rate (gearing · fixing + margin), when the note is capped.

§floor: Option<f64>

The rate the coupons are floored at, likewise, when floored.

§cap_strip: Option<InterestRateCapFloor>

The caplet strip a cap is worth: the note’s own term-index coupons on the bare fixing, at the effective strike (cap − margin) / gearing and gearing times the face alive — rebuilt whenever the coupons are.

§floor_strip: Option<InterestRateCapFloor>

The floorlet strip a floor is worth, likewise.

Implementations§

§

impl FloatingRateNote

pub fn with_cap(self, cap: f64) -> Self

Caps every coupon’s rate at cap. The option is priced on the index’s own fixing — max(g·F + s − K, 0) = g · max(F − (K − s)/g, 0) — so the strip is struck at the effective strike and scaled by the gearing, which is how a geared coupon is capped.

pub fn with_floor(self, floor: f64) -> Self

Floors every coupon’s rate at floor, as with_cap caps it.

fn rebuild_strips(&mut self)

The strips a cap and a floor are worth, from the coupons as they now stand. A non-positive gearing has no caplet form and leaves no strip, which the pricer refuses by name.

pub fn new( index: &IborIndex, issue: NaiveDate, maturity: NaiveDate, quoted_margin: f64, face: f64, ) -> Self

A note on index from issue to maturity at quoted_margin on face, collateralised in its own currency. The schedule generates backward from maturity by the index tenor (short initial stub) on the index’s fixing calendar under its convention; coupons fix at the accrual start less the index’s lag and project as every term coupon does — a regular period over the index’s own window, a stub over its accrual — so the note’s leg is its asset swap’s floating leg.

§Panics

If the index’s currency code is not a currency, or maturity is not after issue.

pub fn on_terms( index: &IborIndex, issue: NaiveDate, maturity: NaiveDate, quoted_margin: f64, face: f64, day_count: DayCountFraction, calendar: &dyn Calendar, convention: BusinessDayConvention, ) -> Self

As new, the note accruing on its own terms rather than the index’s: the coupon grid generated on calendar under convention, each coupon counted under day_count, on a schedule of the trade’s own. Fixing dates and the index window stay the index’s.

§Panics

As new.

pub fn with_amortisation( self, outstanding: Vec<f64>, ) -> Result<Self, CurveError>

This note with a notional profile: outstanding[k] is the fraction of the original face alive in coupon period k. The leg is recompiled: each coupon on its fraction of the face, a redemption of the drop at every boundary where the fraction falls, and the last fraction redeemed at maturity — so legs() still hands out everything the note pays.

§Errors

CurveError::Malformed under the same rules as FixedRateBond::with_amortisation.

pub fn is_amortising(&self) -> bool

Whether any principal is repaid before maturity.

pub fn outstanding_fraction(&self, date: NaiveDate) -> f64

The fraction of the original face alive on date: the first period’s before issue, zero at or after maturity, the containing period’s otherwise.

pub fn current_face(&self, date: NaiveDate) -> f64

The face alive on date: the original face times outstanding_fraction.

pub fn with_projection(self, projection: IborProjection) -> Self

The window every coupon forwards over: IndexTenor the index’s own from each period’s value date (the reading new builds), AccrualPeriod the coupon’s own accrual between its boundaries’ value dates, on the index’s day count, fixing on the same date: the par coupon, as a swap template’s float leg elects it. Stated by window rather than left to the coupon so a note on its own day count still reads its index on the index’s.

pub fn with_gearing(self, gearing: f64) -> Self

Sets the gearing on every coupon.

pub fn issued_by(self, issuer: CreditCurveId) -> Self

Tags the note to issuer’s credit.

pub fn spread_by(self, key: impl Into<String>) -> Self

Composes the security spread under key onto the discounting.

pub fn schedule(&self) -> Vec<NaiveDate>

The coupon-period boundaries, issue to maturity.

§

impl FloatingRateNote

pub fn projected_flows_per_100<R: Scalar>( &self, view: &PricingView<'_, R>, ) -> Result<Vec<(NaiveDate, R)>, PricingError>

The projected flows per 100 face strictly after the view’s reference date: each of the leg’s coupons on its own date, the redemption of face at maturity among them.

§Errors

A missing historical fixing, or a curve query.

pub fn accrued_per_100<R: Scalar>( &self, view: &PricingView<'_, R>, ) -> Result<f64, PricingError>

The accrued on the running coupon, per 100 face.

The rate is the running period’s, which has already reset whenever the note is seasoned — so this reads a published fixing, not a projection, exactly as the coupon itself does.

§Errors

A missing historical fixing, or a curve query.

pub fn discount_margin_with<R: Scalar>( &self, view: &PricingView<'_, R>, quoted_clean: f64, ) -> Result<f64, PricingError>

The discount margin: the flat continuously-compounded spread on the discount curve that reprices the note’s quoted clean price.

The number an FRN actually trades on. Solved passively — a margin is a quoted quantity read off a price, so the iterations record nothing.

The projected amounts and base discount factors are snapshotted once before the loop. They cannot depend on the margin: it sits on the discounting, not the projection. That is what makes each iteration one exp per flow with no curve queries at all — and it is an assumption this speed rests on, so a future variant that spread the projection must not inherit the snapshot.

§Errors

PricingError::UnbracketedSolve when no margin in [−10%, 30%] reproduces the quote; PricingError::SolverUnconverged on the cap; the fixing and curve errors otherwise.

pub fn simple_margin(&self, quoted_clean: f64, settlement: NaiveDate) -> f64

The simple margin: ((100 − clean)/years)/100 + quoted margin, the years measured from settlement to maturity on the index day count.

A closed-form shortcut to the discount margin — the pull-to-par spread over the note’s remaining life, added to what it already pays. No curve, no projection, no solve; a matured note returns its quoted margin.

pub fn spread_duration_with<R: Scalar>( &self, view: &PricingView<'_, R>, ) -> Result<f64, PricingError>

Spread duration: the note’s sensitivity to a flat continuous overlay on its discounting — its dominant risk, and of order the time to maturity, against a rate duration that resets to near zero each period.

Taken by pv_weighted_time — the same call that produces Macaulay duration in yield space. Not an analogous formula: the same one. Passing a zero yield on a continuous basis makes the discount factor exactly one, so the body reduces to Σ pvᵢ·exp(−s·τᵢ) and its seeded derivative is the t-weighted moment.

§Errors

A missing historical fixing, or a curve query.

Trait Implementations§

§

impl Clone for FloatingRateNote

§

fn clone(&self) -> FloatingRateNote

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
§

impl Debug for FloatingRateNote

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
§

impl PartialEq for FloatingRateNote

§

fn eq(&self, other: &FloatingRateNote) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
§

impl<R: Scalar> Priceable<R> for FloatingRateNote

§

fn npv(&self, view: &PricingView<'_, R>) -> Result<R, PricingError>

The coupon leg on discount and projection — the redemption of face is a coupon of that leg, not a term added beside it — survival-weighted with recovery of face when the note is tagged. A capped or floored note is the leg less the cap’s strip plus the floor’s: a capped coupon pays min(r, K) = r − max(r − K, 0); the shapes that cannot carry one were refused by the declaration.

§

fn par_rate(&self, _view: &PricingView<'_, R>) -> Result<R, PricingError>

The par rate — the fixed rate at which the product is worth nothing. Read more
§

fn par_spread(&self, _view: &PricingView<'_, R>) -> Result<R, PricingError>

The par (breakeven) floating-leg spread. Zero for a product with no floating leg. Read more
§

impl PricingRiskFactors for FloatingRateNote

§

fn risk_factors(&self) -> Result<RiskFactors<'_>, PricingError>

A capped or floored note also reads the currency’s cap vol surface. A tagged note with a cap or floor is refused here, before any market is asked — the option would need survival weighting the strip does not carry — as is a cap on a note geared at or below zero, which has no caplet form.

§

impl Product for FloatingRateNote

§

fn currency(&self) -> Currency

The currency the product pays in. An FX product values in its quote currency; a book converts.
§

fn contract_dates(&self) -> Vec<(&'static str, NaiveDate)>

The contract dates the product resolved to, as (name, date) pairs — exactly the dates its stated constructor takes, so a product built through a derived form can be read back and rebuilt through the stated one. Empty for a product with no stated form. No default: every product states which it is — see AnyInstrument::contract_dates.
§

fn legs(&self) -> Option<Vec<&Leg>>

The legs the product itself holds, in a declared order, or None for a product that holds none — see AnyInstrument::legs. No default: every product states which it is.
§

fn final_payment_date(&self) -> Option<NaiveDate>

The date of the product’s final payment, where a calibration rung can be built on it; None for a product no ladder is built from.
§

fn restruck_at_rate(&self, _rate: f64) -> Option<AnyInstrument>

This product re-struck at the par rate rate — the scalar a par calibration rung on it is quoted in — or None for a product that carries no such scalar. What a quote scenario moves a rung to.
§

fn restruck_at_spread(&self, _spread: f64) -> Option<AnyInstrument>

This product re-struck at the basis spread spread on its spread leg, or None for a product that quotes none.
§

impl StructuralPartialEq for FloatingRateNote

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.