---
name: project-mm-gross-margin-gate
description: Market-maker book P&L equals sum of per-leg margin over fair; gating on gross margin works, but the right threshold depends entirely on how often the third leg needs the completion rule
metadata:
  type: project
---

Tested 2026-07-27 via `research/mm_gross_gate_history.py` on `kalshi_backfill.csv`
(641 settled books) plus the 7 live paper books.

**The identity that makes this measurable:** the three pin fairs sum to 100c by
construction, so a complete book's gross edge is EXACTLY the sum of per-leg
(our_ask - fair). Nothing else enters. Book P&L = gross - completion cost.

**Historical result (370 clean books), net is monotone in gross:**
gross <1c -> **-1.62c**, 1-2c -> +0.90c, 2-3c -> +1.91c, 3-5c -> +3.12c. So the
mechanism the 7 paper books suggested is real at n=370, not a 7-point fit.

**But the correct threshold depends on the completion regime, which is the whole
ballgame:**
- Historically ~93% of books filled all 3 legs naturally -> completion rarely
  charged -> total profit maximised at T~1c; gating at 2.5c cuts volume 84% and
  total profit 70%.
- On 2026-07-27 live, **7 of 7** books needed the completion rule (the draw
  essentially never sells naturally). Under that regime mean completion cost is
  1.64c, **44% of historical books have gross < their own completion cost**, and
  ungated mean net collapses to +0.15c/contract (~zero).

**How to apply:** do not use a global constant. Gate per book on arithmetic:
post only if `gross > 1.0c (crossing) + fee(worst bid) + buffer`. The threshold
is then derived, not tuned. Wire it only after measuring the natural-completion
rate over more days — that single number decides whether the gate should be ~1c
(volume) or ~2.5c (selectivity). See [[project-mm-paper-implementation]].

**Charging more on xlow legs (user idea) is unachievable at the leg level:**
our ask is `min(fair+margin, market_ask)`, and an xlow signal MEANS market_ask <
fair, so the cap binds and raising the margin changes nothing. Posting above the
best ask simply never fills. The book-level gate subsumes it anyway — an in-band
leg drags the book's gross down.

**DATA QUALITY WARNING on kalshi_backfill.csv:** 271 of 641 books are unusable.
192 have empty books (mean 3-leg spread 20.1c vs 4.2c; one quotes asks
0.80/0.81/0.80 against bids 0.20/0.20/0.20). A further ~96 carry IN-PLAY prices
(sum of bids up to 155c, one leg at 0.96) because the recorded kickoff is wrong,
so "last candle at or before kickoff" picked a mid-match candle. Always filter
`spread <= 6c` AND `sum(bids) < 100c` before using it. Any result using the raw
file is contaminated — the first run of this test reported a fake +20c/contract.

**Remaining optimism, not yet corrected:** the historical fill model counts a
fill whenever any trade printed at/above our ask, ignoring queue priority. We
join at the back of the queue at the same price, so true fill rates are below the
93% measured — reality sits between the two regimes above, probably nearer the
all-completions one.
