22 — Pass-Throughs, Prepayment, and WAL¶
Free learning pack¶
resources/fixed_income.mdreference/fixed_income/pass_throughs.md,prepayment_models.md
Do not search for more material until these are insufficient.
PREDICT¶
A mortgage pool has a 30-year scheduled amortization. If every borrower prepays faster than scheduled (CPR > 0), does the pool's actual weighted average life (WAL) end up longer or shorter than 30 years?
Formula¶
Scheduled (no prepayment) amortization: standard level-payment formula.
SMM = 1 - (1-CPR)^(1/12)
TotalPrincipal_t = ScheduledPrincipal_t + (BeginningBalance_t - ScheduledPrincipal_t) * SMM
WAL = sum(t_i * Principal_i) / sum(Principal_i)
import numpy as np
balance = 1_000_000.0
annual_rate = 0.06
months = 360
# MANUAL FIRST:
# build the scheduled amortization: beginning balance, scheduled
# principal, interest, ending balance for each of the 360 months.
# (payment = balance * r / (1 - (1+r)^-months), r = annual_rate/12)
beginning = None
scheduled_principal = None
print(beginning[:3] if beginning is not None else None)
PREDICT (PSA)¶
At 100% PSA, when does the pool reach its fastest prepayment speed — immediately, or after a ramp-up period?
psa_multiplier = 1.5 # 150% PSA
# MANUAL FIRST:
# for each month 1..360, compute the PSA CPR (ramps 0% to 6%*multiplier
# over the first 30 months, then flat), convert to SMM, then overlay it
# on `beginning`/`scheduled_principal` to get total principal per month.
# Finally compute the WAL of the resulting principal cash flows and
# compare it to the WAL of the no-prepayment schedule.
wal_with_prepay = None
wal_scheduled = None
print(wal_with_prepay, wal_scheduled)
Experiment¶
Re-run at 300% PSA. How much shorter does WAL get, and does it keep shrinking proportionally, or is there a floor?
Reference¶
reference/fixed_income/pass_throughs.md
reference/fixed_income/prepayment_models.md
Promote¶
Use src/pm/fixed_income/mbs.py (mortgage_amortization_schedule,
single_monthly_mortality, psa_cpr, apply_prepayment,
weighted_average_life) only after your own implementation.
Test¶
pytest tests/test_mbs.py
ORAL CHECK¶
Explain to a PM why a 30-year MBS pool's actual average life is almost never close to 30 years, and what assumption drives the gap.
Try /tutor fixed-income prepayment for an adaptive walkthrough.