33 — TBA, the Dollar Roll, Specified Pools, and CMO/REMIC Structuring¶
Learning objectives¶
Compute a TBA dollar roll's implied financing rate and read it against a GC repo rate to judge roll specialness; understand why specified pools trade at a pay-up over TBA; understand how CMO/REMIC tranching redistributes (not eliminates) prepayment risk across a capital structure. This extends Day 9 (securitized/mortgages) with the practitioner/market-structure layer underneath the prepayment and duration math already covered.
Free learning pack¶
reference/fixed_income/tba_and_dollar_roll.mdreference/fixed_income/specified_pools.mdreference/fixed_income/cmo_remic_structuring.md- Dollar roll — Wikipedia https://en.wikipedia.org/wiki/Dollar_roll
Do not search for more material until these are insufficient.
PREDICT (the roll)¶
A dealer offers to roll your TBA position: sell now at 101.00, buy back next month at 100.625 (a 0.375 drop) on a 5% coupon pool. GC repo for agency MBS is trading at 5.30%. Without calculating: is giving up a month of 5% coupon income worth a 0.375-point drop, roughly? Is this roll likely to come out cheaper or more expensive than GC repo?
Formula¶
implied_financing_rate = (coupon_income - drop_income) / near_amount / horizon_years
where coupon_income and drop_income are dollar amounts over the roll
period (not annualized), near_amount = near_price/100 * face, and
horizon_years is the roll period in years (1/12 for a standard
monthly roll).
from pm.fixed_income.mbs import dollar_roll_implied_financing_rate
face = 1_000_000.0
coupon_rate = 0.05
near_price, far_price = 101.00, 100.625
horizon_years = 1 / 12
# MANUAL FIRST:
coupon_income = None # face * coupon_rate / 12
drop_income = None # (near_price - far_price) / 100 * face
near_amount = None # near_price / 100 * face
implied_financing_rate = None # use dollar_roll_implied_financing_rate
print("coupon_income:", coupon_income)
print("drop_income:", drop_income)
print("near_amount:", near_amount)
print("implied_financing_rate (%):", None if implied_financing_rate is None else implied_financing_rate * 100)
# CHECK (uncomment after your attempt):
# import numpy as np
# assert np.isclose(coupon_income, 4166.6667, atol=1e-2)
# assert np.isclose(drop_income, 3750.0)
# assert np.isclose(near_amount, 1_010_000.0)
# assert np.isclose(implied_financing_rate, 0.004950495, atol=1e-6)
Was your PREDICT right?¶
At ~0.50% implied financing, this roll is far cheaper than the 5.30% GC repo rate quoted above - deeply "special." That tells you this coupon/program is in unusually high demand to be short for delivery, not just that financing happens to be cheap this month.
Now flip it: a drop that's too rich¶
Same pool and coupon, but the drop is 0.90 points instead of 0.375 (a richer drop than the coupon income given up justifies).
rich_drop = 0.90
rich_drop_income = rich_drop / 100 * face
# MANUAL FIRST:
rich_implied_financing_rate = None # same formula, using rich_drop_income
print("rich_implied_financing_rate (%):", None if rich_implied_financing_rate is None else rich_implied_financing_rate * 100)
# CHECK (uncomment after your attempt):
# assert rich_implied_financing_rate < 0.0, (
# "a drop this much larger than the coupon given up should make the "
# "implied financing rate negative - the roll pays you more than the "
# "coupon you gave up"
# )
PREDICT (specified pools)¶
A low-balance specified pool (loans under $85k original balance) of the same 5% coupon trades at a pay-up over TBA. Is that pool's prepayment speed likely to be faster or slower than the generic TBA population, and does that make it more or less attractive to a premium-priced buyer who wants prepayments to happen slowly?
PREDICT (CMO/REMIC)¶
A REMIC deal splits one $500M pool into a PAC tranche (targeting a 90-300 PSA band) and a support tranche. Prepayments come in at 500 PSA (much faster than the PAC band). Whose average life moves more as a result - the PAC tranche's or the support tranche's? Has the pool's total prepayment risk gone up, down, or stayed the same because of the tranching?
Reference¶
reference/fixed_income/tba_and_dollar_roll.md
reference/fixed_income/specified_pools.md
reference/fixed_income/cmo_remic_structuring.md
Promote¶
Use src/pm/fixed_income/mbs.py's
dollar_roll_implied_financing_rate only after your own implementation.
Test¶
pytest tests/test_mbs.py
ORAL CHECK¶
Explain to a PM why a dollar roll's implied financing rate can go negative, and what that tells you about collateral scarcity versus a plain funding-cost number. Then explain why a PAC tranche's cash-flow certainty doesn't mean the underlying pool's prepayment risk has gone away - just where it's been moved to.
Try /tutor dollar roll or /tutor specified pools for an adaptive
walkthrough.