docs(experiments): three rules, 24 assets, zero free parameters — the viable intersection is empty - #252
Merged
Merged
Conversation
… viable intersection is empty Measures every signal rule the codebase ships at its shipped constructor defaults, across the whole 24-asset hourly corpus, at three fee levels. 270 backtests, 0 errors. No combination clears the trade floor with an edge surviving even the maker rate, and the three rules fail for three unrelated reasons — cost, signal, and sample size — which pooling destroys. Supersedes two earlier conclusions: - #248 recorded rsi_meanrev as having "no gross edge at all" from BTC alone. Across 24 assets it has the BEST gross distribution of the three (median 1.1631 vs turtle 0.9892, pullback 0.9292); BTC is near the bottom of it. Its failure is sample size — 0 of 24 reach n>=100. - #248 framed the sweep winner as a selection artifact. Arm B refutes it: 0.6335 in-sample reproduces as 0.6346 on 18 disjoint assets. Not overfit — stably unprofitable, which is worse. pullback_continuation is measured here for the first time since it was written. Two ledger rows (Arm A a_priori, Arm B fitted), both diagnostic_only, chain verifies clean at 82. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This was referenced Aug 12, 2026
eaitbrahim
added a commit
that referenced
this pull request
Aug 12, 2026
… last live lead closes (#255) #252 left one open question: does rsi_meanrev's gross edge survive being made to fire more often? It does not. The rule reaches the promotion floor trivially — 21 of 24 assets at oversold=40 — and has no edge when it gets there. gross PF at oversold=20 (median n=38) : median 1.1631 gross>1 14/24 gross PF at every cell with n>=100 : median 0.8938 gross>1 11/76 net > 1.0 at n>=100, at ANY fee : 0 of 76, including maker The edge evaporates exactly when the rule becomes measurable. The 1.1631 that made this look like the best of the three rules IS what n=38 looks like. Pre-registration lives in the script docstring this time, which is the correction to the defect #252 recorded against itself. The declared statistic — a linear slope — is reported as declared (-0.0386/100 trades, 15/24 negative) AND flagged as underpowered: the phenomenon is a threshold effect at the floor, and two barely-trading assets supply most of its variance. Investigating a 34x non-monotonic trade count on UNI-USD found a simulator defect: backtest() never expires a pending setup, so a strategy whose entry is never revisited freezes silently for the rest of the series. Filed as #254, deliberately not fixed here. #252's headline results were checked against it and are clean. Closes #253. Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
eaitbrahim
added a commit
that referenced
this pull request
Aug 13, 2026
…ine, and record why the defects were invisible (#261) Both experiments re-run under #256 (pending setups no longer freeze the detector) and #258 (entries fill at the next bar's open, as production's market orders do). Same designs, same combinations, same fee grid and slippage pin -- only the engine differs. EVERY CONCLUSION SURVIVES EXCEPT ONE. ZEC-turtle no longer clears the maker line (1.034 -> 0.968), so #252 section 6's three-probe narrative describes a survivor the faithful engine never produces. The replacement is simpler and worse for the library: the viable quadrant is empty at every reachable fee -- 0 of 90 in #252, 0 of 82 in #255 -- with nothing needing three gates to die. #255 strengthens: the level shift across the trade floor widens from 1.1631 -> 0.8938 to 1.1251 -> 0.8396, gross-positive cells at the floor nearly halve (11/76 -> 6/82), and the 34x UNI-USD monotonicity anomaly that exposed both defects is structurally gone (3 assets -> 0). The two defects pushed in OPPOSITE directions -- #256 suppressed opportunity, #258 flattered execution -- so correcting both moved everything one way rather than adding noise: trade counts rose in 87 of 90, gross profit factors fell in 69 of 90. Arm B's transfer is restated on a single engine: 0.5770 in-sample vs 0.5427 out-of-sample, a gap of 0.034. #252's 0.6335 vs 0.6346 compared figures from one engine and was partly luck. The conclusion is unchanged -- the sweep winner is not overfit, it is stably unprofitable. Records the operational takeaway as section 5: NEITHER DEFECT WAS FOUND BY LOOKING FOR DEFECTS, and neither was findable by the means we had. 2,712 tests passed throughout. A frozen backtest and a highly selective strategy produce identical-looking output, so no summary ledger distinguishes them. The fix is invariants the engine reports about itself -- a dead-tail warning, intent-vs-fill divergence logging (#260), and cost anchored to output (#247, shipped, and the model for the rest) -- not more unit tests, which only assert behaviour someone already imagined. Annotates rather than rewrites, per the convention #247 set: the original numbers were real outputs of the code as it stood. Both documents keep their figures and carry a banner pointing here. Two ledger rows; chain verifies clean at 85. Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #251.
Measures every signal rule the codebase ships at its shipped constructor defaults, across the
whole 24-asset hourly corpus, at three fee levels. 270 backtests, 0 errors. Documentation only
— no code, no config, no rule status, no version bump.
Verdict
There is no asset-rule combination that clears the promotion trade floor with an edge surviving
even the cheapest fee we can reach — and the three rules fail for three unrelated reasons.
n≥100turtle_breakoutpullback_continuationrsi_meanrevThe single survivor, ZEC-
turtle, is then eliminated by a temporal decomposition: threeconsecutive losing years (2022–24) with 92.7% of lifetime PnL compressed into 2025–26.
Two earlier conclusions this supersedes
1.
rsi_meanrevdoes not lack gross edge. #248 recorded that it "has no gross edge at all" onthe strength of BTC at 0.775. Across all 24 assets it has the best gross distribution of the
three rules — median gross PF 1.1631, against
turtle's 0.9892 andpullback's 0.9292 overthe same universe. BTC sits near the bottom of its distribution. The rule does not lose; it is
not observable — 0 of 24 assets reach
n≥100, median n=38. #248's figures came from widenedparameters (oversold 25–35), not defaults, so both documents are right about what they measured;
the error was generalising from one asset.
2. The 864-trial sweep winner is not overfit. #248 framed it as selection. Arm B evaluates that
config on the 18 assets it was never scored on: in-sample mean net PF 0.6335 → out-of-sample
0.6346, gross 1.5317. A clean three-decimal replication across disjoint assets. That is a
harder result than overfitting — overfitting has a methodology fix; a stable measurement of 0.63
does not.
pullback_continuation, measured for the first timeIn
RULE_REGISTRYsince it was written, never backtested. Median gross 0.929, and a feecollapse qualitatively unlike
turtle's — PAXG-USDT 1.097 → 0.001 at maker. The cause is inthe win rates: 52–75% wins at PF≈1.0 is
measured_1to1taking small wins against small losses, soa 1.2% round trip does not reduce the edge, it erases it. High win rate is the symptom of maximal
fee fragility here, not a strength.
Why the temporal probe is reported and never gated
Three reasons in §6, the third decisive: ZEC under
pullback_continuationis the onlycombination in the study with no losing complete year (1.06/1.17/1.16/1.13) — at gross PF
0.875. Perfectly stationary at losing slightly, reliably. A stationarity gate would wave it
through while rejecting ZEC-
turtle, which at least made money gross. The probe is alsounderpowered (passes zero-edge strategies ~50% of the time at four buckets) and fragile to bucket
boundaries (excluding partial 2021/2026 flips the verdict for 4 of 21 assets, including FET).
The principled instrument already exists and is now live: #247 wired
g4_pbo_gateintocan_promote, wherepbo=Noneblocks. It is deployed and nothing feeds it. Building a weakerannual-bucket heuristic beside an unfed rigorous one is the wrong order of work.
Honesty notes recorded in the document rather than omitted
every other harness here. The script now says so at the top instead of presenting the
reconstruction as though it had always been there.
is exactly why they are diagnostics.
tail(buffers until EOF,then dies with the shell) and by
pkill -fnot reapingmultiprocessingchildren. Both producedconfident status reports that were false. §7.
independence was checked, not assumed: BTC-USD reproduces to six decimal places across the
boundary.
What this leaves open
One lead, and it is cheap: does
rsi_meanrev's gross edge survive being made to fire moreoften? #248's 108-cell diagnostic widened the thresholds and found no net-viable cell, but never
asked whether widening preserved the gross edge or simply bought trades by accepting worse
setups. Different findings, different consequences, and the data separating them was never
computed.
A limit-order queue simulator has no target: its measured prize was one asset with ~8bp of headroom
below maker, and §6 removes that asset.
Ledger
Two rows — Arm A (
a_priori) and Arm B (fitted, since the params were selected even though thisevaluation selects nothing further). Both
diagnostic_only, bothseries_missing: trueso theCSCV matrix refuses them.
verify_chainclean at 82 rows.🤖 Generated with Claude Code