Interest Rate Swap Valuation and Applications › Practical Applications
Quantitative FinanceAll chapters Interest Rate Swap Valuation and Applications › Practical ApplicationsOne section · Sections in this chapter13 / 17 ↓
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 following examples show how swaps can change borrowing-rate exposure, construct synthetic fixed coupons and adjust a balance sheet's duration gap under stated matching and risk assumptions.
Hedging Interest Rate Exposure
If you have floating-rate debt, you face uncertainty about future interest payments. When rates rise, borrowing costs increase, potentially squeezing profit margins or even threatening solvency. A pay-fixed, receive-floating swap allows you to convert your exposure to fixed-rate debt synthetically. You continue to make floating payments on your original loan but enter a swap to receive floating and pay fixed. The floating index received on the swap offsets the matching index paid on the loan, leaving the fixed swap payment plus the loan's original spread and any fees. This requires matching notionals, index conventions, payment dates and accrual fractions.
import numpy as np
import pandas as pd
# Corporate hedging example
corporate_loan = {
"principal": 100_000_000,
"spread": 0.015, # SOFR + 150 bps
"reference_rate": "SOFR",
}
hedge_swap = {
"notional": 100_000_000,
"fixed_rate": 0.048, # Pay 4.80% fixed
"receive": "SOFR",
}
def analyze_corporate_hedge(loan, swap, sofr_scenarios):
"""
Compare annualized borrowing rates in hypothetical SOFR scenarios.
Assumes equal loan/swap notionals, matching SOFR observation, reset,
accrual and payment conventions, and an unchanged loan spread.
This is a rate illustration, not a discounted valuation or forecast.
"""
results = []
for sofr in sofr_scenarios:
# Without hedge
unhedged_cost = sofr + loan["spread"]
# With hedge
# Loan: Pay SOFR + spread
# Swap: Pay fixed, receive SOFR
# Net: Pay fixed + spread
hedged_cost = swap["fixed_rate"] + loan["spread"]
results.append(
{
"sofr": sofr,
"unhedged": unhedged_cost,
"hedged": hedged_cost,
"savings": unhedged_cost - hedged_cost,
}
)
return pd.DataFrame(results)
sofr_scenarios = np.arange(0.02, 0.10, 0.01)
hedge_analysis = analyze_corporate_hedge(corporate_loan, hedge_swap, sofr_scenarios)Corporate Interest Rate Hedge Analysis ================================================================= Loan Terms: $100M at SOFR + 1.50% Swap Terms: Pay 4.80% fixed, receive SOFR SOFR Unhedged Cost Hedged Cost Saving/(cost), pp ----------------------------------------------------------------- 2.00% 3.50% 6.30% -2.80 pp 3.00% 4.50% 6.30% -1.80 pp 4.00% 5.50% 6.30% -0.80 pp 5.00% 6.50% 6.30% +0.20 pp 6.00% 7.50% 6.30% +1.20 pp 7.00% 8.50% 6.30% +2.20 pp 8.00% 9.50% 6.30% +3.20 pp 9.00% 10.50% 6.30% +4.20 pp
The table shows that the hedge locks in a fixed borrowing cost of 6.30% (4.80% swap rate + 1.50% spread). When SOFR exceeds 4.80%, the hedge provides savings; when SOFR is below 4.80%, the unhedged position would have been cheaper, but the hedge provides certainty. A borrower who values predictable payments may accept a higher cost in low-rate scenarios in exchange for budgeting certainty.

Creating Synthetic Assets
Swaps enable the creation of synthetic instruments that may not be available directly in the market. If you own a floating-rate note but desire fixed-rate exposure, you can use a swap to transform the economic characteristics of the asset. Rather than selling the floating-rate note and purchasing a fixed-rate bond, which might involve transaction costs and tax consequences, you can overlay a swap to achieve the desired exposure.
def create_synthetic_fixed_bond(floating_asset, swap):
"""
Describe fixed-coupon exposure from a performing matched-notional package.
The asset and swap must match SOFR, accrual, reset and payment conventions.
This does not price the package or remove issuer/counterparty credit risk.
"""
# Floating asset: Receive SOFR + spread
# Swap: Pay SOFR, receive fixed
# Net: Receive fixed + spread (synthetic fixed bond)
synthetic_coupon_rate = swap["receive_fixed_rate"] + floating_asset["spread"]
return {
"type": "Synthetic Fixed Bond",
"coupon_rate": synthetic_coupon_rate,
"components": {
"Floating Asset": f"SOFR + {floating_asset['spread']:.2%}",
"Swap Receive": f"{swap['receive_fixed_rate']:.2%}",
"Swap Pay": "SOFR",
},
}
# Example: Convert floating-rate note to synthetic fixed
frn = {
"spread": 0.0080, # SOFR + 80 bps
"principal": 25_000_000,
}
conversion_swap = {"pay": "SOFR", "receive_fixed_rate": 0.045}
synthetic = create_synthetic_fixed_bond(frn, conversion_swap)Synthetic Fixed-Rate Bond Construction ======================================================= Starting Position: Floating Rate Note Coupon: SOFR + 0.80% Principal: $25,000,000 Swap Overlay: Pay: SOFR Receive: 4.50% fixed Result: Synthetic Fixed-Rate Bond Fixed coupon rate: 5.30% (4.50% + 0.80% spread)
With equal notionals, matching SOFR observation, accrual, reset and payment dates, and both contracts performing, the combined coupon rate is 5.30%: the swap's fixed rate plus the note's spread. This establishes coupon income, not a yield-to-maturity, which also requires the package price and dated redemption cash flows. The issuer exposure remains, and the swap adds counterparty exposure; contractual basis risk can arise if the two contracts' floating-rate terms diverge.
Asset-Liability Management
Banks and insurance companies use swaps to manage mismatches between asset and liability duration. For a common parallel-rate shock, let and be asset and liability values and and their durations for that same shock. The first-order equity change is . Equity falls for a small rate rise when , equivalently when the asset-normalized gap is positive (). Raw duration ordering alone does not state this condition. The following example has long-duration mortgages funded by short-duration deposits.
def calculate_duration_gap(assets, liabilities):
"""
Calculate duration gap for an institution.
"""
# Weighted average duration of assets
total_assets = sum(a["value"] for a in assets)
asset_duration = sum(a["value"] * a["duration"] for a in assets) / total_assets
# Weighted average duration of liabilities
total_liabilities = sum(l["value"] for l in liabilities)
liability_duration = (
sum(l["value"] * l["duration"] for l in liabilities) / total_liabilities
)
# Duration gap (simplified)
duration_gap = asset_duration - liability_duration * (
total_liabilities / total_assets
)
return {
"asset_duration": asset_duration,
"liability_duration": liability_duration,
"duration_gap": duration_gap,
"total_assets": total_assets,
"total_liabilities": total_liabilities,
}
# Bank balance sheet
bank_assets = [
{"type": "Mortgages", "value": 800_000_000, "duration": 7.5},
{"type": "Commercial Loans", "value": 400_000_000, "duration": 3.0},
{"type": "Securities", "value": 200_000_000, "duration": 5.0},
]
bank_liabilities = [
{"type": "Deposits", "value": 1_000_000_000, "duration": 0.5},
{"type": "CDs", "value": 250_000_000, "duration": 2.0},
{"type": "Subordinated Debt", "value": 50_000_000, "duration": 6.0},
]
gap_analysis = calculate_duration_gap(bank_assets, bank_liabilities)Bank Duration Gap Analysis ======================================================= Asset Duration: 5.86 years Liability Duration: 1.00 years Duration Gap: 4.93 years Total Assets: $1.40 billion Total Liabilities: $1.30 billion Equity: $0.10 billion


To reduce the duration gap, choose a receive-floating, pay-fixed swap with negative signed dollar duration under the same parallel-rate shock as the balance sheet. For that selected exposure, the pay-fixed position gains value when rates rise and offsets some of the losses on long-duration assets. The calculation below assumes the stated positive magnitude of this negative sensitivity; the pay-fixed label alone does not establish its size or sign for every fixing and cash-flow state.
def hedge_duration_gap(gap_analysis, target_gap, payer_sensitivity_magnitude):
"""Positive payer notional for a reduction in an asset-normalized gap.
d=payer_sensitivity_magnitude>0 means dV_payer/dy=N*d, so signed
notional-normalized duration is -d. Balance-sheet and swap sensitivities
must use the same first-order parallel shock. This is not net-value
duration, which is undefined for a zero-MTM swap.
"""
current_gap = gap_analysis["duration_gap"]
total_assets = gap_analysis["total_assets"]
d = payer_sensitivity_magnitude
if (
not np.all(np.isfinite([current_gap, total_assets, target_gap, d]))
or total_assets <= 0
or d <= 0
or target_gap > current_gap
):
raise ValueError(
"Use positive assets/magnitude and a target no larger than the gap."
)
return (current_gap - target_gap) * total_assets / d
target_duration_gap = 1.0 # Target 1-year gap
payer_sensitivity_magnitude = 4.0 # Assumed |D_N|, years; signed payer D_N=-4
hedge_notional = hedge_duration_gap(
gap_analysis, target_duration_gap, payer_sensitivity_magnitude
)Duration Gap Hedging Strategy ======================================================= Current Duration Gap: 4.93 years Target Duration Gap: 1.00 years Gap Reduction Needed: 3.93 years Hedging Swap (Pay Fixed, Receive Float): Payer |D_N| magnitude: 4.0 years Required Notional: $1,375 million
A pay-fixed notional of $1.375 billion reduces the calculated duration gap from 4.93 years to the target of 1.00 year under the assumed 4-year sensitivity magnitude. The swap contributes negative dollar duration, reducing the balance sheet's first-order parallel-rate exposure. The nonzero target leaves residual rate risk; it is not complete immunization.