Skip to content

feat(rules): the promotion gate prices fills per product, and the restatement that fires it (#335) - #686

Open
eaitbrahim wants to merge 1 commit into
mainfrom
exp-335-per-product-slippage
Open

feat(rules): the promotion gate prices fills per product, and the restatement that fires it (#335)#686
eaitbrahim wants to merge 1 commit into
mainfrom
exp-335-per-product-slippage

Conversation

@eaitbrahim

Copy link
Copy Markdown
Contributor

Closes #335. It waits for "a thin-asset candidate to reach the gate" — measuring the universe answers a sharper question than the trigger asked.

Every document in this repo prices fills at a floor nobody reaches

slippage_for_quote_volume reaches its 5bp floor only at the model's $500M/day anchor. Over the 24-asset universe's own cached candles:

assets at the floor 0 of 24
cheapest BTC-USD, 5.5bp — 1.1×
dearest TON-USD, 183.8bp — 36.8× (the cap)
median 10×

#335 names "the STX/CRO-class 1.15–1.30× floor entries" as the live example of a thin-asset candidate. The live example is the entire universe.

What it costs

240 trials — five rules at shipped defaults × 24 assets × both regimes, run in one driver so the A/B is internally consistent rather than compared across documents.

rule flat per-product delta
turtle_breakout 0.336 0.267 −0.063
rsi_meanrev 0.261 0.175 −0.082
pullback_continuation 0.042 0.012 −0.021
cusum_event 0.343 0.243 −0.080
triple_barrier 0.338 0.237 −0.092

Median across 120 cells: 0.309 → 0.219. Every one of the 120 deltas is ≤ 0.

The comparison that matters

That 0.090 median overstatement sits next to the other number measured this week: the triple barrier's better exit bought +0.033 of gross profit factor.

The error in the cost model was 2.7× larger than the best genuine improvement any rule change produced. Every strategy comparison in this repository has been made through a lens that mis-priced execution by more than the differences being compared.

The corpus's only positive cell dies

turtle_breakout on WLD-USD: 1.061 → 0.626, at 24.2× the rate it was priced at, already below the trade floor at n=58. Zero of 120 clear PF 1.0 per-product.

Why the deferral was safe, and why it isn't now

#259 deferred on the reasoning that the correction is conservative-only — real cost is higher, a corrected profit factor can only fall, and per-product pricing can never manufacture an edge. Confirmed: all 120 deltas are ≤ 0.

What it doesn't survive is the magnitude. A correction assumed to be a rounding adjustment is worth 0.090 of median PF and kills the only positive cell in the corpus. A gate pricing promotion decisions at the best rate the model can produce is not being conservative.

The change

rules backtest / rules promote now price per product, from the product's cached ONE_DAY bars by the same one definition simulate.slippage_assumptions uses — deliberately not the rule's own trading granularity, because median_daily_quote_volume is a per-bar median despite its name, and an hourly figure handed to a daily-anchored model reports every asset as maximally thin. (triple_barrier.per_product_round_trip can't read daily bars — a pure rule has only what it's handed — and scales explicitly instead. Both say so where they do it.)

No daily bars falls back to the flat floor and is flagged as a fallback, never presented as a measured verdict. ResolvedBacktest carries both, so a front-end can print the assumption beside the number it produced.

Verification

7 mutants, 7 killed — two were the call sites. Removing slippage_pct= from _backtest_rule or from backtest_resolved left every helper test green, because the helper being right proves nothing about anything using it.

Full suite 5247 passed / 3 skipped; ruff and mypy clean. Ledger verifies at 93 rows.

Deliberately not done

The older documents keep their flat-priced figures. Their verdicts don't move — the correction only pushes them further from 1.0 — and re-running them isn't free. A pointer note is worth more than the compute.

The null is unchanged and firmer: 0 of 138, now at honest cost.

…tatement that fires it (#335)

#335 waits for a thin-asset candidate to reach the gate. Measuring the universe
answers a sharper question than the trigger asked.

EVERY EXPERIMENT DOCUMENT IN THIS REPOSITORY PRICES FILLS AT THE FLOOR, AND NOT
ONE ASSET REACHES THE FLOOR. `slippage_for_quote_volume` gets there only at its
$500M/day anchor; over the 24-asset universe's own cached candles the range is
1.1x the floor (BTC, 5.5bp) to 36.8x (TON, the 183.8bp cap), median near 10x, ten
assets above 10x and four above 20x. #335 names the "STX/CRO-class 1.15-1.30x
floor entries" as the live example of a thin-asset candidate. The live example is
the entire universe.

WHAT IT COSTS: 240 trials, five rules at shipped defaults x 24 assets x both
regimes, run in ONE driver so the A/B is internally consistent rather than
compared across documents. Median profit factor over 120 cells falls 0.309 ->
0.219. Every one of the 120 deltas is negative or zero.

THE COMPARISON THAT MATTERS. That 0.090 median overstatement sits next to the
other number measured this week: the triple barrier's better exit bought +0.033
of gross profit factor. THE ERROR IN THE COST MODEL WAS 2.7x LARGER THAN THE BEST
GENUINE IMPROVEMENT ANY RULE CHANGE PRODUCED -- every strategy comparison in this
repository has been made through a lens that mis-priced execution by more than
the differences being compared.

THE CORPUS'S ONLY POSITIVE CELL DIES. turtle_breakout on WLD-USD, 1.061 -> 0.626
at 24.2x the rate it was priced at, already below the trade floor at n=58. Zero
of 120 clear PF 1.0 per-product.

WHY THE DEFERRAL WAS SAFE AND IS NOT. #259 deferred on the reasoning that the
correction is conservative-only -- real cost is higher, a corrected profit factor
can only fall, and per-product pricing can never manufacture an edge. Confirmed:
all 120 deltas are <= 0. What it does not survive is the magnitude. A correction
assumed to be a rounding adjustment is worth 0.090 of median PF and kills the
only positive cell in the corpus, and a gate pricing PROMOTION decisions at the
best rate the model can produce is not being conservative.

`rules backtest` / `rules promote` now price per product, computed from the
product's cached ONE_DAY bars by the same one definition
`simulate.slippage_assumptions` uses -- deliberately NOT the rule's own trading
granularity, because `median_daily_quote_volume` is a PER-BAR median despite its
name and an hourly figure handed to a daily-anchored model reports every asset as
maximally thin. `triple_barrier.per_product_round_trip` cannot read daily bars (a
pure rule has only what it is handed) and scales explicitly; both say so where
they do it. No daily bars falls back to the flat floor and is FLAGGED as a
fallback, never presented as a measured verdict, and `ResolvedBacktest` carries
both so a front-end can print the assumption beside the number it produced.

7 mutants, 7 killed. Two were the CALL SITES: removing `slippage_pct=` from
`_backtest_rule` or from `backtest_resolved` left every helper test green,
because the helper being right proves nothing about anything using it.

Deliberately NOT restated: the older documents keep their flat-priced figures.
Their verdicts do not move -- the correction only pushes them further from 1.0 --
and re-running them is not free. The null is unchanged and firmer: 0 of 138, now
at honest cost. Ledger verifies at 93 rows.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NzuKAe2RVrPt9acVAWjRyL
@eaitbrahim eaitbrahim self-assigned this Sep 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Opt the promotion gate into per-product slippage — prerequisite-gated on a thin-asset candidate or a load-bearing restatement

1 participant