oddsx · read-only research status
Generated 2026-09-14T10:00:49Z · HEAD 9612e75

Maker-economics dossier — is (toxic-flow-filtered) market-making OOS-profitable net?

Verdict: NO (net, out-of-sample, tail-robust). The maker's earned spread is REAL but tiny (+1.3% gross per fill, OOS — the exact mirror of the taker's −1.3%), and it lives entirely in the cheap-token fat right tail. By the project's own tail-robust standard (equal-notional, capped [−1,1]) the naive maker is −13.5% per fill OOS, and a TRAIN-derived toxic-flow filter halves the bleed (−13.5% → −7.8%) but does not reach profitability. The adverse-selection *mechanism* the filter targets is clean and confirmed — the maker bleeds monotonically more as flow gets more one-sided — but mitigating it is not enough to make passive making +EV in this dataset.

Ticket: T-0016. Script: research/05_maker.py. Date: 2026-07-24. Reproduce: uv run --extra backtest python research/05_maker.py · uv run pytest -q → green.

> Honest > profitable. The whole SCORECARD showed every intrinsic signal is > real but smaller than the ~3–4% *taker* cost, pointing at the *maker* side as > the natural next question (post limit orders, pay ~0 fee, capture the bias as > spread). We tested it directly. The answer: the maker *does* earn the spread > (the fee asymmetry is real and large), but it is ~1.3% gross, tail-dependent, > eaten by adverse selection, and it does not survive as a robust per-bet > positive. This is a clean negative on the naive maker and a clean negative > on the toxic-flow fix — with the adverse-selection mechanism nonetheless > confirmed as the reason a live maker must skew/pull quotes.

---

THE MODELING CAVEAT (read first)

This is an upper bound on maker economics, not a live P&L. We assume we win every passive fill at the observed price. That ignores:

  1. Queue position / fill probability — a real resting quote is not guaranteed to be hit; you get filled *selectively*, and disproportionately by the informed side (that is adverse selection).
  2. Book impact — our own quote would change the book and the counterparty's behavior; the historical fill would not have occurred unchanged.

So every maker number here is the most optimistic case. That the *most optimistic* case is still net-negative on the tail-robust measure is the finding.

---

Method

`` maker_realized_return = -( taker_realized_return ) [EXACT] ``

and the cache's taker realized_return already contains everything — negate it. The maker's fill price sits on the favorable side of mid (the taker crossed the spread to reach it), so the "earned spread" is already embedded in this gross number; no extra credit is added (conservative).

---

Q1 — naive maker: does the earned spread beat adverse selection?

Answer: only in gross/uncapped terms (+1.3%), and it is a cheap-token tail artifact. NO on the tail-robust measure (−13.5%).

  price band |   N_train  mkr_net_tr  uncap_tr |    N_test  mkr_net_te  uncap_te    med_te  win_te
[0.0,0.1) | 1,154,807     -0.6480   +0.1631 |   582,121     -0.6194   +0.2542   -1.0000  0.190
[0.1,0.2) | 1,191,358     -0.4947   -0.0274 |   608,468     -0.4843   -0.0058   -1.0000  0.258
[0.2,0.3) | 1,592,229     -0.3776   -0.0147 |   831,154     -0.4075   -0.0762   -1.0000  0.296
[0.3,0.4) | 2,314,103     -0.2143   +0.0143 | 1,135,850     -0.1922   +0.0497   -1.0000  0.404
[0.4,0.5) | 2,891,054     -0.0914   -0.0125 | 1,539,053     -0.0673   +0.0129   -1.0000  0.466
[0.5,0.6) | 3,043,568     +0.0103   +0.0103 | 1,639,200     -0.0118   -0.0118   +0.6949  0.526
[0.6,0.7) | 2,266,973     -0.0109   -0.0109 | 1,116,850     -0.0263   -0.0263   +0.4706  0.591
[0.7,0.8) | 1,646,652     +0.0066   +0.0066 |   855,851     +0.0265   +0.0265   +0.2987  0.698
[0.8,0.9) | 1,267,482     +0.0029   +0.0029 |   613,952     +0.0032   +0.0032   +0.1628  0.736
[0.9,1.0) | 2,328,024     +0.0007   +0.0007 | 1,033,026     -0.0014   -0.0014   +0.0010  0.683
     OVERALL | 19,696,250   -0.1359   +0.0077 | 9,955,525   -0.1347   +0.0132   -0.0010  0.499

Q1 verdict: naive making is NOT robustly profitable OOS. The maker earns the spread (+1.3% gross), but adverse selection plus the cheap-token tail leave it at −13.5% on the tail-robust measure, flat in the clean mid-price region, and median ~0.

---

Q2 — the polymm fix: does a toxic-flow filter cure adverse selection?

Answer: it confirms and halves the adverse-selection bleed, but does NOT reach profitability. FALSIFIED as a profitability fix.

Adverse-selection scan (maker NET by |one-sidedness|, TRAIN only) — the maker is the counterparty of the flow, so informed one-sided flow should hurt it. It does, cleanly and monotonically:

   |osid| band           N   maker_net  win_rate
     [0.0,0.1)   5,249,591     -0.0725    0.506
     [0.1,0.2)   4,031,132     -0.1028    0.498
     [0.2,0.3)   3,207,602     -0.1288    0.497
     [0.3,0.4)   2,263,085     -0.1616    0.498
     [0.4,0.5)   1,559,235     -0.1952    0.500
     [0.5,0.6)   1,097,293     -0.2238    0.500
     [0.6,0.7)     674,702     -0.2433    0.503
     [0.7,0.8)     417,752     -0.2629    0.512
     [0.8,0.9)     244,581     -0.2719    0.518
     [0.9,1.0)     681,792     -0.2115    0.552
 no prior flow     244,305     -0.2678    0.438

This monotone gradient (−0.07 at balanced flow → −0.27 at one-sided flow) is the strongest, cleanest result in the study: it is the adverse-selection signature made explicit. A maker who quotes into one-sided flow is being picked off, in direct proportion to how one-sided the flow is.

But every bucket is already net-negative (capped), so the TRAIN-derived threshold falls to the least-toxic cut — τ = 0.10 (skip |osid| ≥ 0.10; keep the near-balanced and no-prior-flow fills):

              strategy  split          N   mean_net   uncapped    median    sharpe top1%|PnL|
           naive maker  train 19,696,250    -0.1359    +0.0077   +0.0010   -0.1641     0.013
           naive maker   test  9,955,525    -0.1347    +0.0132   -0.0010   -0.1610     0.013
   filtered (tau=0.10)  train  5,493,896    -0.0812    +0.0086   +0.0010   -0.0923     0.012
   filtered (tau=0.10)   test  2,870,437    -0.0778    +0.0091   -0.0010   -0.0873     0.012

vbt.pro (gate L1.2) — filtered-maker hourly equal-weight TEST book: total_return −100.0%, sharpe(1h-ann) −89.4, max_drawdown −100.0% over 379 bars — consistent with the negative capped per-fill net.

---

Control — the fee-asymmetry sanity (is the fee the driver?)

Confirmed. The maker and taker hold the exact opposite positions (maker_gross = −taker_gross), so the only thing separating who profits is the cost, all of which the taker pays:

                      role  split          N   mean_net   uncapped    sharpe
             MAKER (fee 0)  train 19,696,250    -0.1359    +0.0077   -0.1641
             MAKER (fee 0)   test  9,955,525    -0.1347    +0.0132   -0.1610
       TAKER (fee .05/.02)  train 19,696,250    -0.2975    -0.0077   -0.1430
       TAKER (fee .05/.02)   test  9,955,525    -0.1973    -0.0132   -0.1073
 MAKER *paying taker cost*   test  9,955,525    -0.3940    +0.0132   -0.2455

---

Tail honesty

---

Verdict

Naive market-making is NOT profitable net OOS by the project's tail-robust standard (−13.5%/fill capped, median ~0, flat in the clean mid-price region); its only positive is a +1.3% gross earned-spread that is a cheap-token fat-tail artifact. The toxic-flow filter does NOT fix it — it confirms and *halves* the adverse-selection bleed (−13.5% → −7.8% OOS, a clean monotone mechanism) but never clears 0, and slightly reduces the uncapped edge. The fee asymmetry is real and large (wedge +0.26/fill; maker beats taker by the whole cost) — just not large enough to overcome adverse selection under honest, tail-robust sizing.

Every intrinsic signal being real-but-sub-taker-cost pointed at the maker side; the maker side turns out to earn the spread but bleed it back to adverse selection and the cheap-token tail. Under the *upper-bound* fill assumption. A real maker, filled *selectively* by the informed side, would do worse than this ceiling.

---

Caveats

  1. Upper-bound fills (the big one). Every number assumes we win every passive fill at that price — no queue, no fill-probability, no book impact. Real selective fills skew toward the informed side, so live making is worse than this ceiling. This is a *ceiling test*, and the ceiling is already net-negative (capped).
  2. The [−1,1] cap mis-measures cheap-token maker positions. A $1-notional buy of a 0.05 token can legitimately pay +$19; capping to +$1 understates it. The capped verdict (−13.5%) is therefore partly a cap artifact of cheap-token holdings — but the uncapped +1.3% is itself a fat-tail artifact of the same positions, and by the project's stated methodology (equal-notional, capped, to prevent tail-fabricated means) the capped read governs the verdict. Both are reported.
  3. Taker-control fee schedule. The control uses the repo/SCORECARD sports taker rate 0.05 (+ spread 0.02) for continuity with the edge dossiers. Under Fee Structure V2 (eff. 2026-03-30) the sports taker rate is actually 0.03; a lower taker fee would *shrink* the fee-asymmetry wedge, i.e. the maker's cost advantage is somewhat smaller than the control's 0.05 implies. It does not change the maker's own (fee-0) economics, which drive the verdict.
  4. Maker rebate ignored. V2 pays makers a ~20–25% daily rebate of the counterparty's taker fee; we set it to 0 (conservative). Including it would add a small positive to the maker but cannot bridge a −7.8%…−13.5% gap.
  5. Fill-clustering / weighting. The all-fills view weights high-volume markets by fill count (as in the edge dossiers). Event-level weighting is the stricter unit (deferred); the monotone adverse-selection gradient is unlikely to reverse under it.

Reproduce

uv run --extra backtest python research/05_maker.py
# tunables:  ODDS_FLOW_WINDOW=30min   ODDS_MAKER_FEE=0.0
# first run computes + caches the 30-min one_sidedness (runs/data/maker_flow_osid.parquet);
# subsequent runs reload it.

uv run pytest -q → green (includes tests/test_maker.py, the maker-identity proof).