Risk and sensitivities
Locate the exposure before choosing a hedge. The risk analysis shows schedule and capital lines, coverage, exposure by age and moneyness, credit-loss measures and sensitivities to the modelled path. It also compares rational walk-away boundaries under different Buyer beliefs.
Implementation: exposure.rs, boundary.rs and forwardflow_api.rs::ff_risk; reference tests: tests/exposure.rs. Open Risk analysis to run a scenario.
The worked snapshots below were recorded in early September 2026; they are not refreshed 0.6.1 results or current GBM workspace defaults. Their numbers use the base terms: a $60,000 coin, 1.475×, 60 monthly payments of $1,475 (Purchase Price $88,500), the first payment to BTC Now, 5% servicing on every dollar delivered to the Holder, the Holder at par, the stop sale 18 days after the missed payment, 25 bp sale cost. Where a number needs a whole book, it comes from the cockpit’s base configuration: 24 monthly cohorts of 10 Agreements, a 60,000 → 60,000 bridge at 43% volatility, a 40% lifetime stop prior, 2.5% monthly early-completion propensity, dispersed strikes, seed 42. Every figure was printed by POST /api/forwardflow/risk on that configuration, asserted by a test, or is one line of arithmetic from one that was.
What the desk draws
The plan (§1) writes the paper as four legs: a fixed-dollar amortizing annuity; a short put on the coin struck at the remaining schedule, exercised only when the Buyer stops; a long call struck at the Purchase Price, exercised only when the Buyer stops with the coin worth more than the Purchase Price; and the Buyer’s early completion option. Five exhibits put numbers and signs on legs two and three, and the last section maps the legs back onto them.
The two lines
Both lines are sale proceeds as a fraction of the coin’s entry price, indexed by \(t\), the number of payments made. Both fall every month. exposure.rs::two_lines builds them once from cohort-1 terms; they are scale-invariant in the strike, so one table serves a book of dispersed strikes.
The schedule line
Above the schedule line a stop sale delivers the whole remaining schedule and the Holder loses only the future yield on that Agreement. It is the remaining nominal schedule over the strike:
\[ \ell^{S}t = \frac{R_t}{\text{strike}}, \qquad R_t = \sum{k=t+1}^{n} p_k , \]
with \(R_t\) from contract.rs::ContractTerms::schedule summed from \(t+1\). At the base terms \(R_t = 88{,}500 - 1{,}475,t\): 1.475 before any payment, 1.450 after payment 1, zero at payment 60. It is also the strike of the embedded put: the waterfall pays the Holder \(\min(V, R_t)\) first (the stop waterfall), so the Holder’s shortfall on a stop is \(\max(0, R_t - V)\), a put on the proceeds struck at \(R_t\).
The capital line, from the waterfall
The capital line is the sale proceeds that return the Holder’s own money, counting what it has already been paid. Let \(U_t\) be the unrecovered capital after \(t\) payments,
\[ U_t = \max!\Big(0,\ \text{purchase} - \sum_{k=N+1}^{t} p_k,(1-f)\Big), \]
where \(N\) is the number of first payments routed to BTC Now and \(f\) the servicing fee. At the base terms \(U_0 = U_1 = 60{,}000\) (payment 1 never reaches the Holder) and \(U_t = 60{,}000 - 1{,}401.25,(t-1)\) after that, reaching zero at \(t = 44\): by then the Holder has received \(43 \times 1{,}401.25 = $60{,}253.75\) net.
The proceeds that recover \(U_t\) are read off the waterfall, not off a discount. With \(A_t = P - R_t\) the Buyer’s paid-in total and \(V\) the sale proceeds, the waterfall delivers the Holder \(V\) while \(V \le R_t\) (the refund is zero), exactly \(R_t\) while \(R_t < V \le P\) (everything above the schedule refunds the Buyer, up to \(A_t\)), and \(V - A_t\) above \(P\) (the refund is capped, the surplus is the Holder’s). The Holder nets \((1-f)\) of what is delivered. So exposure.rs::capital_proceeds_needed solves \(\text{delivered}(V),(1-f) = U_t\) piecewise:
\[ V^{\text{cap}}_t = \begin{cases} \dfrac{U_t}{1-f} & \text{if } \dfrac{U_t}{1-f} \le R_t \\ A_t + \dfrac{U_t}{1-f} & \text{otherwise,} \end{cases} \qquad \ell^{C}_t = \frac{V^{\text{cap}}_t}{\text{strike}} . \]
The second branch exists because between \(R_t\) and \(P\) the Holder cannot be delivered more than \(R_t\); if \(R_t(1-f)\) is short of \(U_t\), capital is recoverable only from the surplus above the Purchase Price, and the row is flagged capital_above_purchase_price. At par the first branch holds at every \(t\): \(U_1/(1-f) = 63{,}157.89 < R_1 = 87{,}025\), and the ratio only improves. capital_line_is_piecewise_when_it_would_cross_the_schedule_line builds a Holder at 160% of the coin’s cost, where \(96{,}000/0.95 > R_1\), and checks the line jumps to \(1{,}475 + 96{,}000/0.95\) dollars with the flag set.
The table at the base terms
two_lines at the base terms, which the test two_lines_match_the_plan_table pins against the plan’s own arithmetic, \(\ell^S_t = (88{,}500 - 1{,}475,t)/60{,}000\) and \(\ell^C_t = \max(0,\ 60{,}000 - 1{,}401.25,(t-1))/0.95/60{,}000\):
| Payments made \(t\) | Schedule line | Capital line | \(R_t\) | \(U_t\) |
|---|---|---|---|---|
| 0 | 1.475 | 1.053 | $88,500 | $60,000 |
| 1 | 1.450 | 1.053 | $87,025 | $60,000 |
| 6 | 1.328 | 0.930 | $79,650 | $52,993.75 |
| 12 | 1.180 | 0.782 | $70,800 | $44,586.25 |
| 19 | 1.008 | 0.610 | $60,475 | $34,777.50 |
| 24 | 0.885 | 0.487 | $53,100 | $27,771.25 |
| 36 | 0.590 | 0.192 | $35,400 | $10,956.25 |
| 44 | 0.393 | 0.000 | $23,600 | $0 |
| 60 | 0.000 | 0.000 | $0 | $0 |
The plan prints the same rows as 1.45/1.05, 1.33/0.93, 1.18/0.78, 1.00/0.63, 0.89/0.49, 0.59/0.19, 0.39/0.00. Six of the seven agree to the plan’s rounding; at month 19 the plan’s own formula gives 0.610, so 0.63 is a slip in the plan’s table, not a different definition. The schedule line crosses 1.0 between payments 19 and 20 (\(t = 19.32\)); the cockpit reports the first row at or below 1.0, month 20. The 25 bp sale cost is not in the lines; it enters through the proceeds when the lines meet a path.
Two things a desk reads first. The capital line starts above the entry price: a stop at any coin price below 105.3% of entry in the first month loses the Holder money, because payment 1 went to BTC Now and every delivered dollar carries the 5%. And it reaches zero at month 44: after that no stop, at any price, can lose the Holder capital on that Agreement.
Why the loss story lives in the first two years
Between the two lines a stop leaves a shortfall against the schedule but still returns the Holder’s capital. Below the capital line it does not. At month 24 the capital line sits at 0.487 of entry, inside a normal Bitcoin drawdown; at month 36 it is 0.192, which is not. So the window in which a par Holder can lose capital is the first two years of each vintage, and it narrows every month. Coverage on the base path says the same in Agreement-months: the count below the capital line peaks at 127 in month 22 and is zero from month 30, while the count below the schedule line is still 62 at month 30 and first reaches zero at month 40. The plan adds that every breach of the loss line in the memo’s historical replays came before month 18; that sentence is the plan’s, and this chapter’s evidence is the engine’s.
Coverage on the simulated path
Coverage applies the two lines to the run’s path, month by month. exposure.rs::exposure first reconstructs each Agreement’s monthly state from the ledger (exposure.rs::tracks): origination month, exit month, and the months in which a payment posted (OriginationFee or PaymentDelivery), so AgreementTrack::payments_made_by(m) is exact even when a walk consumed a payment date unpaid.
Per month
For each calendar month \(m\) the proceeds a stop sale at that month’s mark would record are priced as the engine prices them, exposure.rs::stop_proceeds:
\[ V_m = S_m, e^{-\text{haircut}},(1 - \text{sale cost}) , \]
the same function as engine.rs::stop_sale without the 18-day interpolation: coverage asks what a sale at this month’s mark would do, not when the actual sale happened. Then over every Agreement active at \(m\), with \(t\) its payments made by \(m\):
CoveragePoint field | Definition |
|---|---|
active | Agreements active at \(m\) |
below_schedule | Those with \(V_m < R_t\): a stop would leave a shortfall |
below_capital | Those with \(V_m < V^{\text{cap}}_t\): a stop would lose the Holder’s capital |
notional_usd | \(\sum R_t\), the embedded put ladder’s notional |
capital_at_risk_usd | \(\sum U_t\), the dollars that can actually be lost |
intrinsic_shortfall_usd | \(\sum_{\text{below schedule}} (R_t - V_m)\), the book’s intrinsic loss if every one of them stopped now |
A check at month 0: the mark is $60,000, so \(V_0 = 59{,}850\). Ten Agreements of cohort 0 are active with no payment made, so all ten sit below the schedule line (\(R_0 = 1.475 \times \text{strike}\)). Eight sit below the capital line: with dispersed strikes the capital line is \(\text{strike}/0.95\), which $59,850 clears only for a strike below $56,857.50, and two of the ten drew below that. The endpoint prints 10 / 10 / 8.
The base bridge dips to $28,581 at month 11. At month 12 the book has 123 active Agreements, 123 below the schedule line and 117 below the capital line, capital at risk $4.54m, intrinsic shortfall $3.18m. The largest intrinsic shortfall is $3.73m at month 21 (mark $28,792, 188 of 188 active below the schedule line). Peak capital at risk is $5.94m at month 23, the last origination month: 203 active, 200 below the schedule line, 63 below the capital line.
One lifecycle, one timing rule
Every consumer reads the same state of an Agreement at a month — coverage, capital at risk and the ladder here, the hedge desk’s on-book test (hedge.rs::on_book_at) and the monthly mark (series.rs) — from engine.rs::state_at: Performing (on the book and paying; a draw at age \(t\) marks the exit at \(t+1\) but the paper performs until the missed date), StoppedAwaitingSale { missed, sale_month } (the missed date has passed and the coin is still held for the sale: price exposure), SoldAwaitingCash { landed_month } (the month the sale’s cash lands: a settlement receivable, no price exposure), and Closed. The timing is engine.rs::stop_sale_timing, the stop’s own: \(\text{pos} = D + \text{lag}/30.4375\); the sale executes inside \(\lfloor \text{pos} \rfloor\) and is booked at \(\lceil \text{pos} \rceil\), the first payment date at or after the sale point — whose mark is the later of the two the sale reads, so cash is never booked before the last mark that priced it (model audit 2026-09-07, R02) — where stop_sale posts the delivery, the fee and the refund. The coin is price-exposed at every mark strictly before the landed month (engine.rs::price_exposed_at); tracks sets exit_month to price_exposure_end, the payoff date for a completion or an early completion and the landed month for a stop. At the program’s 18 days that is the month after the missed date, so the base numbers did not move; at 90 days the coin stays on the panel three months (model audit 2026-09-06, M04: before, tracks and the hedge desk both hard-coded month + 1, and at a 90-day lag coverage read zero active, zero notional and zero capital at risk in the two months the mark still read $46,109 and $36,205 while the Greeks — the engine’s own re-run — read a $287 per 1% delta; tests/model_audit_2026_09_06_m04.rs runs the probe and the six lags 0, 10, 18, 45, 60 and 90).
Per cohort
CohortCoverage sums the per-Agreement counters by origination month: months_below_schedule and months_below_capital are the mean active months an Agreement of that cohort spent below each line; share_below_schedule and share_below_capital divide by the cohort’s active Agreement-months. On the base path cohort 0 spent a mean 27.0 months below the schedule line and 17.6 below the capital line (62% and 41% of its active months); cohort 23, originated at the trough’s exit, spent 10.5 and 1.3 (33% and 4%). The page’s headline is the book-wide share of Agreement-months below the capital line.
The exposure ladder
The ladder cuts the book at one calendar month (ladder_month; left unset, the month of peak capital at risk) and bins every active Agreement by the embedded put’s moneyness and tenor. Moneyness is what a stop sale at that month’s mark would realize against the put’s strike, the remaining schedule:
\[ \text{moneyness} = \frac{V_m}{R_t} , \qquad \text{tenor} = n - t \text{ months remaining.} \]
The buckets are exposure.rs::MONEYNESS_BUCKETS and exposure.rs::TENOR_BUCKETS: six of moneyness (\(<0.50\), \(0.50\)–\(0.70\), \(0.70\)–\(0.85\), \(0.85\)–\(1.00\), \(1.00\)–\(1.20\), \(\ge 1.20\), lower bound inclusive) by five of tenor (\(\le 6\), 7–12, 13–24, 25–36, \(> 36\) months). Each of the 30 cells carries the Agreement count, the notional \(\sum R_t\) and the capital at risk \(\sum U_t\). Notional is the size of the puts the Holder is short; capital at risk is what a par Holder can actually lose in that cell, and it is the figure the page colours. ladder_and_coverage_tie_to_each_other holds the totals equal to the coverage row of the same month and the cells’ sums equal to the totals.
A worked cell. At month 23 on the base path the mark is $33,375.25, so \(V = 33{,}291.81\). A cohort-0 Agreement at a $60,000 strike that paid every date has \(t = 23\): \(R_{23} = 54{,}575\), moneyness 0.610, tenor 37, unrecovered capital \(60{,}000 - 22 \times 1{,}401.25 = $29{,}172.50\). It lands in the \(0.50\)–\(0.70\) × \(> 36\) cell. A cohort-23 Agreement originated that month at a strike near the mark has moneyness \(0.9975/1.475 = 0.676\), the same cell. That is why 84 of the 203 active Agreements sit there (notional $4.58m, capital at risk $2.85m), 74 in \(0.70\)–\(0.85\), 41 in \(0.85\)–\(1.00\), 3 in \(1.00\)–\(1.20\) and 1 below 0.50, and why every cell at month 23 is in the \(> 36\) column: the oldest Agreement has 37 payments left. The tenor axis spreads out later. At month 48 (mark $62,345) the same book has 125 active Agreements, all at \(\ge 1.20\), split 6 / 59 / 60 across 7–12, 13–24 and 25–36 months, capital at risk $814k against a notional of $2.78m.
This is the shape a desk maps onto listed strikes: a put ladder from about 1.05 of spot down to zero, with the capital at risk in the 0.50–0.85 rows. The plan notes that corner of the surface carries the heaviest put skew and the thinnest listed liquidity, which is the first thing a desk will say about a flat 43% bridge; the ladder makes the mapping possible, it does not price it.
PD, LGD and EAD per vintage
The credit triple is read off outputs.rs::agreement_table, per origination month and once for the whole book (origination_month: null, last row). A stop is any row whose outcome is not completed, settled or open; the tags non_performance, non_performance_rational, conviction_walk and rational_boundary all count.
| Quantity | Definition in exposure.rs::exposure |
|---|---|
| PD | stops ÷ Agreements in the vintage |
| EAD | mean \(R_t\) at the stop (the remaining schedule at the missed date) |
| LGD | \(\sum \text{shortfall} ,/, \sum R_t\) over the vintage’s stops, with shortfall \(= \max(0, R_t - V)\) from engine.rs::stop_sale |
| EL | \(\sum \text{shortfall}\) in dollars |
| EL rate | EL ÷ capital deployed (the sum of purchase prices) |
| Capital loss | \(\sum \max(0, -\text{capital P&L})\) over stops, where capital_pnl = net delivered to the Holder − purchase price |
| Refunds, surplus | \(\sum\) buyer_refund_usd, \(\sum\) stop_surplus_usd over the vintage’s stops |
The identity a credit desk expects holds by construction:
\[ \text{EL} = \text{PD} \times \text{LGD} \times \text{EAD} \times n , \]
since \(\text{PD} \cdot n\) is the stop count, \(\text{EAD} \cdot \text{stops} = \sum R_t\), and LGD divides the shortfall by that sum. On the base configuration the book row reads 240 Agreements, 101 stops, 84 completed, 55 completed early; PD 0.421, EAD $43,563, LGD 0.225, EL $990,282 (10.3% of $9.62m deployed), and \(0.4208 \times 0.2251 \times 43{,}562.82 \times 240 = 990{,}282\). The book’s EL equals the simulate response’s total_shortfall_usd at the same seed.
Two columns separate the put’s intrinsic loss from the par Holder’s loss. EL is measured against the schedule, the put’s strike; capital loss against the Holder’s outlay net of what it had already been paid. On the base book they are $990k and $231k: most of the shortfall lands on Agreements that had already returned most of the Holder’s capital, the dollar version of the gap between the two lines. Refunds ($604k) and surplus ($149k) are the waterfall’s other two branches.
The vintages tell the timing story. Cohort 1, its first two years spent in the bridge’s dip, has 4 stops of 10, EAD $75,325, LGD 0.531, EL $159,921, a capital loss of $57,708 and no refunds. Cohort 23, originated at the trough’s exit, has 7 stops of 10 but LGD 0.043, EL $9,506, no capital loss, $108,878 of refunds and $46,735 of surplus: its Buyers stopped with the coin above the schedule, so the waterfall paid the Holder in full, refunded them, and handed the Holder the surplus. On the base configuration the drawdown multipliers (input #23) are off, so those in-the-money Buyers stopped at the full baseline hazard, price-blind; whether Buyers with a winning coin stop at anything like that rate is the behavior the Model Card names as the least-evidenced in the model, where it runs at the ×0.5 in-the-money multiplier.
The Greeks by bump-and-revalue
The Greeks are sensitivities of the Holder’s net cash gain, collections minus capital deployed (exposure.rs::net_gain, from outputs.rs::analyze), to a bump in the future path. Nothing is differentiated analytically; exposure.rs::greeks re-runs the engine with the bump applied and takes finite differences, averaged over a seed ensemble.
The as-of month and the two books
The book is valued as it stands at the ladder month, as_of. The bump starts the month after, from = as_of + 1, through paths.rs::PathBump (apply_bump leaves earlier months untouched). Two books are revalued. The existing book is the configuration with origination_stop_month cut to from, so no cohort originates after the as-of month and every strike is set on unbumped prices. The commitment is the full pacing, in which later cohorts strike at the bumped prices and their schedules grow with the price. On the base configuration the as-of month defaults to 23, the last origination month, so the two coincide; as of month 0 they differ, and greeks_vanish_on_a_riskless_book checks that a book with no stops has a zero existing-book delta and a positive commitment delta.
Seven runs per seed, for seeds \(s, s+1, \dots, s+k-1\) (greek_seeds, default 16): base, price up, price down, commitment up, commitment down, vol up, vol down. base_net_gain_usd and base_irr are ensemble means of the first, which is why the Greeks’ base IRR on the base configuration (15.86%) is not the seed-42 run’s 14.21%.
Delta and gamma
With \(b\) the price bump (default 0.05) and \(G_s(\cdot)\) the net gain under seed \(s\), every future price multiplied by \(1 \pm b\):
\[ \Delta = \frac{1}{k}\sum_s \frac{G_s(1+b) - G_s(1-b)}{2 \cdot 100,b}, \qquad \Gamma = \frac{1}{k}\sum_s \frac{G_s(1+b) - 2,G_s(1) + G_s(1-b)}{(100,b)^2} , \]
in dollars per 1% and per (1%)². Delta in coins divides by 1% of the as-of mark:
\[ \Delta_{\text{coins}} = \frac{\Delta}{0.01 \times S_{\text{as of}}} , \]
the number of coins whose 1% move matches the book’s, which is what a market-neutral desk shorts in perpetuals or futures to flatten it. The commitment delta repeats the central difference with the full pacing. The same differences on the effective IRR give delta_irr_pp_per_pct in percentage points.
Vega
Vega is one method on every path mode, and the response names it (vega_method: “path-amplitude scaling of the log-return deviations after as_of on the base path (every path mode), seed ensemble”). The base path is kept through the as-of month, bit for bit, and the deviations of the log returns after it are scaled around their mean so that the realized volatility of the base path (exposure.rs::realized_vol, log returns, annualized by \(\sqrt{12}\)) moves by \(\pm v\) (default 0.05, five points) — a PathBump { from_month: as_of + 1, vol_factor }, never a regeneration; vega is the difference over the span actually applied, in vol points, and the scaling is a no-op on a flat path. That holds on the bridge, GBM, jump diffusion, regime switching, the bootstrap and the replay alike: until the follow-up audit of 6 September 2026 (finding 2) the bridge branch moved the bridge’s own vol_annual and re-simulated from inception, which re-drew months 0–23 and every strike struck on them, so an existing book of fixed dollar schedules — which has no sensitivity to future volatility — reported a vega of +$6,977.44 per vol point on the audit’s fixed book (24 × 10, 60-month terms, 84-month horizon, 43% bridge, dispersion on, no stops, no early completion, month 12, 32 seeds); finding_2_the_vol_bump_leaves_the_existing_books_history_alone_on_every_path_mode (tests/audit_2026_09_06.rs) now reads 0.000000 on every mode, finding_2_the_bumped_path_shares_every_month_up_to_as_of_bit_for_bit holds the months through as-of identical, and the notes say only the months after as-of differ. So this is the continuation’s vega — the only vega an existing book has — never a whole-life re-draw; on the base configuration it is +$8,631 per vol point where the old bridge method printed ≈ +$30k. bump_overlay_scales_prices_and_vol checks the mechanics: month 0 untouched, every later price scaled, a zero vol factor giving constant log returns, hold_strikes pinning every strike to the unbumped level.
Theta
Theta is not a bump. It is the markup accrual on a path with no price risk: the engine is run on a flat bridge (end price = start price, zero volatility, no shock, no bump) and the net gain is divided by the weighted average life in months:
\[ \Theta = \frac{G_{\text{flat}}}{\text{WAL}_{\text{flat}}} . \]
On the base configuration the flat run collects $18,971,951.25 on $14,400,000 deployed (no dispersion on a flat path, so 240 × $60,000) with a WAL of 35.95 months: \(4{,}571{,}951.25 / 35.954 = $127{,}160\) per month. That is what the paper earns for being held, positive by construction; the flat path’s own stops (proceeds $59,850 against an early schedule) are already inside it.
Why per-Agreement streams make this a sensitivity
A finite difference is only a sensitivity if the two runs differ by the bump alone. Since v1.6 every Agreement draws its stop and early-completion decisions from its own ChaCha20 stream, seeded from (config seed, Agreement id) through splitmix64 (engine.rs::agreement_rng). A bumped price changes which side of a threshold a draw falls on; it never changes the draw, and it never shifts the random numbers of every later Agreement, which a single shared stream would do the moment one exit moved. greeks_are_sensitivities_not_draw_noise bumps a 240-Agreement book (12 cohorts of 20, on the base bridge) by one basis point from month 24 and requires at most two of 240 exits to flip, then checks that the delta at 2% and at 5% agree in sign and within a factor of two. The seed ensemble averages the remaining threshold noise. The endpoint refuses a configuration that already carries a bump, because the Greeks own it.
The signs, and the base-config numbers
From the endpoint on the base configuration, as of month 23 (mark $33,375.25), 16 seeds, bumps 5% and 5 points — re-read on 6 September 2026 under the as-of-preserving bumps (the two audits’ finding 2: the existing book’s horizon pinned to the base run’s, the vol bump a continuation bump on every mode), so the delta, gamma and vega rows differ from the 3 September figures (+24,885 / −175.6 / +29,718) the earlier method printed:
| Greek | Value | Unit |
|---|---|---|
| Delta, existing book | +23,259 | dollars per +1% in every future price |
| Delta, commitment | +23,259 | dollars per +1% (coincides: no cohort after month 23) |
| Delta in coins | 69.7 | coins at the as-of mark |
| Gamma | −28.9 | dollars per (1%)² |
| Vega | +8,631 | dollars per +1 vol point (the continuation after month 23, every mode) |
| Theta | +127,160 | dollars per month of WAL, flat path |
| Delta of IRR | +0.083 | pp per +1% |
| Vega of IRR | +0.036 | pp per vol point |
| Realized vol of the base path | 39.4% | annualized |
These are the signs in this dated example. Higher prices can reduce shortfalls below the schedule line and increase surplus proceeds above the Purchase Price. In the intermediate waterfall regime, a stop delivers the remaining schedule. Buyer behavior and the path determine the aggregate sensitivities. Theta is the flat-path gain-per-WAL proxy described above; vega is recomputed over the continuation after the selected as-of month. Neither the example’s signs nor its magnitudes apply to every scenario.
Vega’s sign is the one the plan got wrong, and the plan’s Phase 1 status says so. Under the v1.2 stop sale, sized to the schedule with the residual coin returned, the Holder was short a put and nothing else, so more volatility could only mean more stops in the money and the sign was negative. Under the ruled waterfall (Marc, 2026-09-03; spec v1.5) the Holder also keeps the surplus above the Purchase Price on an in-the-money stop, a long call, and a wider path feeds that call as much as it feeds the put. So vega is negative where the book’s stops are underwater and positive where the surplus dominates. On the base bridge, with both endpoints pinned at $60,000, the wider paths wander above the strike as often as below and the ensemble vega is positive. On a falling bridge to $30,000 with drawdown multipliers, greeks_have_the_signs_of_a_short_put_on_a_stopping_book gets the negative vega and the positive delta. A desk reading the number should read vega_method and the path shape beside it.
The walk-away frontier family
The fifth exhibit is not read off the run. It is the computed boundary below which a rational Buyer is better off walking, drawn on the same axes as the two lines for several values of the one parameter that is a belief. boundary.rs::rational_frontier was lifted from the parked Behavior Engine and re-derived for the September stop; the same function is the fifth behavior mode, input #25 (who stops paying).
The lattice
Optimal stopping by backward induction on a full-width log-price grid with Cox-Ross-Rubinstein steps, four price steps per month (SUB = 4), decisions at payment dates only, under the Buyer’s believed annual drift \(\mu\), the lattice volatility \(\sigma\) and the Buyer’s own discount rate \(r_c\) (boundary.rs::BoundaryParams, defaults 0.414, 0.25, 0.15, and a walk cost of 2.5% of the coin’s cost: $1,500 at the base terms, about one payment):
\[ \Delta = \tfrac{1}{48}\ \text{yr}, \quad u = e^{\sigma\sqrt{\Delta}}, \quad d = 1/u, \quad q = \frac{e^{\mu\Delta} - d}{u - d}, \quad \text{disc} = e^{-r_c \Delta} . \]
At the defaults \(\sigma\sqrt{\Delta} = 0.0598\). The grid spans \(4n + 12\) nodes on each side of the entry price (PAD = 12), beyond what a tree rooted at a single node could reach: such a tree sees only \(e^{-4\sigma\sqrt{\Delta},t}\) at date \(t\), and at month 1 could not see a coin at half of entry. The Phase 1 review found that defect (a Buyer whose coin halved at payment 1 kept paying until payment 4); rational_boundary_walks_the_book_in_a_crash_and_spares_it_in_a_rally now pins the walk at payment 1 with a custom path at 45% of entry.
The three choices
At the payment date of payment \(t\), with \(A = \sum_{k<t} p_k\) the payments made before this date, \(R = P - A\) the remaining schedule with payment \(t\) included, spot \(S\) and \(V = S(1 - \text{sale cost})\):
\[ \text{pay} = -p_t + \text{disc}^{4},\mathbb{E}[\text{value at the next date}] \quad (\text{at } t = n:\ -p_n + S), \]
where the expectation runs over the four price steps to the next payment date and \(\text{disc}\) is applied at each step, so one month discounts at \(e^{-r_c/12}\). The other two choices are
\[ \text{settle} = S - R \ \text{ if } S > R, \text{ else } -\infty, \qquad \text{walk} = \min(A, \max(0, V + A - P)) - c_{\text{walk}} . \]
The walk payoff is the September refund (R-1033) in the Buyer’s frame, less the cost of walking. The lattice sells at the decision date’s spot with the sale cost only, not the engine’s 18-day lag and haircut: the frontier is a boundary, and the engine’s stop prices the sale. Where the refund is positive (\(V > R\)), settling beats walking by \(S - V + c_{\text{walk}} > 0\), so walking is optimal only where the refund is zero, and the walk region is a single lower region per payment date. The frontier is the crossing between the highest grid node where walking wins and the next node up, interpolated in log-spot on the value gap; None means no node walks at that date. walk_region_sits_where_the_refund_is_zero holds the whole frontier at or below the schedule line to within one grid step. Each row is reported as walk_below_spot, walk_below_of_entry (spot ÷ strike, the two lines’ frame) and walk_below_moneyness (spot ÷ the amortized obligation from contract.rs::ContractTerms::remaining_obligation_at).
Row \(m = t - 1\) is the decision before payment \(t\), so the frontier row for payment \(t\) sits beside line row \(t - 1\). In engine.rs::run (step 1) a Buyer whose spot is below frontier[t − 1] × strike does not pay; the walk is the missed payment, executed in step 2a as stop_sale with the missed date \(m\) itself and the exit tag rational_boundary.
The frontier on the two lines
The endpoint’s default family is \(\mu \in {0, 0.10, 0.25, 0.50}\) at the default lattice parameters; the frontier is scale-invariant in the strike (frontier_is_scale_invariant_in_the_strike). As a fraction of entry:
| Payment | \(\mu = 0\) | \(\mu = 10%\) | \(\mu = 25%\) | \(\mu = 50%\) | Schedule line (row \(t-1\)) | Capital line (row \(t-1\)) |
|---|---|---|---|---|---|---|
| 1 | 1.162 | 1.011 | 0.521 | 0.152 | 1.475 | 1.053 |
| 2 | 1.149 | 1.000 | 0.521 | 0.155 | 1.450 | 1.053 |
| 6 | 1.084 | 0.952 | 0.519 | 0.168 | 1.352 | 0.954 |
| 12 | 0.984 | 0.872 | 0.505 | 0.187 | 1.205 | 0.807 |
| 24 | 0.773 | 0.706 | 0.467 | 0.221 | 0.910 | 0.512 |
| 36 | 0.543 | 0.508 | 0.385 | 0.233 | 0.615 | 0.217 |
| 48 | 0.287 | 0.276 | 0.240 | 0.187 | 0.320 | 0.000 |
| 59 | 0.024 | 0.024 | 0.024 | 0.023 | 0.049 | 0.000 |
| 60 | none | none | none | none | 0.025 | 0.000 |
Every curve lies below the schedule line, as the lattice requires. Where it lies relative to the capital line is the desk’s question. The zero-drift Buyer walks at 1.16 of entry at payment 1, above the capital line: his stop costs the Holder yield, not capital, though it is a shortfall against the schedule. His frontier stays above par through payment 11 and crosses below 1.0 at payment 12 (pessimist_robot_walks_at_par checks moneyness \(\ge 1\) at payments 2, 4, 7 and 10). The 25% Buyer walks only near half of entry through the first year, below the capital line through payment 26 (0.457 against 0.463) and above it from payment 27; his stops are the ones that lose the Holder capital, and they happen only in a halving. The 50% Buyer walks almost nowhere. Higher \(\sigma\), a higher walk cost and a stronger belief all deepen the frontier (higher_sigma_deepens_the_frontier, walk_cost_and_belief_deepen_the_frontier).
What each curve means to a desk
The frontier is the only behavior number in the engine that does not depend on BTC Now’s priors, which is why the plan lifted it. Each curve is the walk-away price of a Buyer with one belief about the coin, and the family brackets the book. The zero-drift Buyer is the pessimist robot who should never have signed: a coin he does not believe will appreciate is never worth financing at 1.475×, so he walks at or above par from the first months and a book of such Buyers is a book of stops in any flat market. That is the lattice’s finding of 2026-08-06, unchanged by the new stop. A believing Buyer walks only far inside the money of the put, where the stop already costs the Holder capital; his curve says where the capital line is actually tested. The distance between a curve and the capital line at a given month is the price fall that has to happen before that Buyer’s stop becomes the Holder’s loss. Run with input #25, the engine turns any one curve into a book’s exits.
The four legs on these numbers
The annuity is the schedule line’s numerator and theta’s numerator: \(R_t\) falling by one payment a month, and the flat-path net gain per month of WAL, +$127,160 on the base book.
The short put at the schedule is the schedule line as its strike, the ladder’s notional as its size, EL as its realized intrinsic value, and the positive delta and negative gamma as its price sensitivities. Its exercise is behavioral, which is why the frontier family sits beside the line: the curves say at what price a rational Buyer exercises it.
The long call at the Purchase Price is the surplus column of the credit table ($149k on the base book, all of it in vintages originated from month 10 on) and the positive half of vega. It exists only since the ruled waterfall, and it is why the base-config vega is positive rather than the negative the plan expected.
The Buyer’s completion option is the completed_early count (55 of 240); it is not a risk exhibit, since it only ever accelerates the annuity.
The capital line is not a leg. It is where the put’s intrinsic loss stops being paid out of the Holder’s yield and starts being paid out of its capital; the capital-at-risk figures on coverage and the ladder are the size of that, month by month.
Reproducing this chapter
POST /api/forwardflow/risk with the cockpit’s BASE_CONFIG and no options returns every number above except the month-48 ladder (ladder_month: 48) and the flat-path check (POST /api/forwardflow/simulate with the bridge’s volatility at zero). cargo test --release --workspace runs the nine tests of tests/exposure.rs and the seven unit tests in boundary.rs. The wire format is in The API; the reproduction rules are in Verification and reproduction.