Bond Fundamentals and Pricing › Fixed Rate vs. Floating Rate Bonds
Quantitative FinanceAll chapters Bond Fundamentals and Pricing › Fixed Rate vs. Floating Rate BondsOne section · Sections in this chapter6 / 14 ↓
Reading tools Definitions & inline links
Choose your expertise level to adjust how many terms are explained. Beginners see more tooltips, experts see fewer to maintain reading flow. Hover over underlined terms for instant definitions.
Article links
Make inline references clickable
The bonds we've discussed so far have fixed coupon rates set at issuance. Floating rate bonds (or floating rate notes, FRNs) have coupon rates that reset periodically based on a reference rate plus a spread. This fundamental structural difference creates very different risk profiles and pricing dynamics.
Floating Rate Mechanics
As an illustrative advance-reset contract, suppose a quarterly floater uses a specified three-month reference rate plus 100 basis points. A 4.5% reference fixing would produce a 5.5% annualized coupon. Do not equate that term fixing with overnight SOFR: SOFR-linked notes may instead compound daily overnight rates in arrears, so the period's final coupon is not known at its start.
The coupon for each period is calculated as:
where:
- : the interest rate for the upcoming coupon period
- : the contractually specified fixing or period benchmark; its observation timing depends on the advance-reset or in-arrears convention
- : the contractual coupon margin, distinct from the current market-required discount margin
The contract determines the observation dates, lookback, and whether the rate is fixed in advance or compounded in arrears. Its quoted margin may be fixed at issuance, but the market-required margin can change with credit and liquidity conditions. Resets reduce some benchmark-rate exposure relative to an otherwise comparable fixed-rate bond; they do not remove credit, spread, basis, reset-lag, or liquidity risk.
Pricing Floating Rate Bonds
Future coupons depend on the contract's reference-rate observations. For a one-period valuation, assume the note's ex-coupon value will be immediately after its next coupon/reset. This is a pricing assumption, not a consequence of unchanged issuer credit quality alone.
Let be the current annualized fixed coupon, the full current coupon-period accrual fraction, the remaining time to payment under the same simple-accrual basis, and the current reference discount rate plus required discount margin. Between coupon dates the next full coupon is , not merely interest on the remaining time.
Here is face value, is the coupon fixed for the current period, is that full coupon's accrual fraction, is remaining time, is the chosen reference discount rate, and is the market-required discount margin. On a coupon date just after payment, for the new period, and this model is at par only if . Between dates, dirty price also includes accrued interest.
As the next payment approaches, while the full coupon remains due: dirty value tends to before payment and drops by that coupon after payment. Under the matching simple accrual convention, clean price is dirty price minus . A coupon reset does not erase an already accrued coupon.
def price_frn_between_resets(
face_value,
current_coupon_rate,
current_reference_rate,
time_to_reset,
*,
coupon_accrual_fraction,
spread=0,
):
"""Return dirty value under an explicit next-reset ex-coupon-par model.
coupon_accrual_fraction is the FULL current coupon period, while
time_to_reset is its remaining fraction on the same simple basis.
Credit/basis/curve effects beyond the stated flat discount margin are
not modeled. The coupon and principal are assumed to be paid in full.
"""
face = _finite_number(face_value, "face_value")
coupon_rate = _finite_number(current_coupon_rate, "current_coupon_rate")
reference = _finite_number(current_reference_rate, "current_reference_rate")
remaining = _finite_number(time_to_reset, "time_to_reset")
alpha = _finite_number(coupon_accrual_fraction, "coupon_accrual_fraction")
margin = _finite_number(spread, "spread")
if face <= 0 or alpha <= 0 or not 0 <= remaining <= alpha:
raise ValueError(
"Require positive face and full accrual fraction, with 0 <= remaining <= full fraction"
)
payment = face * (1 + coupon_rate * alpha)
denominator = 1 + (reference + margin) * remaining
if payment <= 0 or denominator <= 0:
raise ValueError(
"Require positive promised next payment and discount denominator"
)
value = payment / denominator
if not np.isfinite(value) or value <= 0:
raise ValueError("Price is outside the supported floating-point range")
return float(value)
# Example at the start of a quarter: fixed coupon 5.5%, reference 5%,
# full and remaining accrual fractions both 0.25, required margin 1%.
frn_price = price_frn_between_resets(
face_value=1000,
current_coupon_rate=0.055,
current_reference_rate=0.05,
time_to_reset=0.25,
coupon_accrual_fraction=0.25,
spread=0.01, # 100 bps required discount margin
)
# Halfway through the same coupon period, the full $13.75 coupon remains due.
mid_period_dirty = price_frn_between_resets(
1000, 0.055, 0.05, 0.125, coupon_accrual_fraction=0.25, spread=0.01
)
mid_period_accrued = 0.055 * 1000 * (0.25 - 0.125)
mid_period_clean = mid_period_dirty - mid_period_accruedFloating Rate Note Price: $998.77 Price deviation from par: $-1.23 Mid-period dirty price: $1006.20 Mid-period accrued: $6.88 Mid-period clean price: $999.33
The function returns about $998.77, or $1.23 below par. The fixed 5.5% coupon is below the 6% discount rate formed from the 5% reference rate and 1% required margin. This conditional example illustrates a small price deviation; it does not establish that FRN prices are stable under changes in credit spreads or other risks.