Every number in the note, and where it came from
Enough method to check the arithmetic by hand, or to rebuild an equivalent study from the same public sources, including the rules that govern a contract that stops trading and the hashes the run is frozen under.
Venue, universe and dates
Binance USDT-margined perpetual futures. The selection date is 31 December 2022 and nothing after it informs the ranking. A contract is eligible if it is quoted and margined in USDT, has at least 24 months of genuine traded-volume history by the selection date, measured as a first day with positive traded volume on or before 31 December 2020, traded at all during October to December 2022 and is not a duplicate claim on the same underlying exposure. The enumeration runs over all 986 contracts ever listed on the venue and leaves 78 eligible, ranked by median daily notional traded during October to December 2022. No eligible contract is a thousand-unit denomination or a second quote denomination of another, so the duplicate rule removes nothing and the ranking is the raw notional ranking.
The frozen universe is ranks 1 to 30. Tranches and ladder rungs are two deterministic partitions of that one ranking, fixed before anything was run.
| Tranche | Markets | Median daily notional |
|---|---|---|
| T1, ranks 1-6 | BTC, ETH, DOGE, XRP, BNB, SOL | $6,978M to $433M |
| T2, ranks 7-14 | MATIC, LTC, ETC, LINK, ADA, NEAR, DOT, EOS | $347M to $128M |
| T3, ranks 15-22 | AVAX, SUSHI, CRV, AXS, ATOM, FIL, FTM, BCH | $127M to $72M |
| T4, ranks 23-30 | TRX, UNI, WAVES, ALGO, AAVE, BAND, RSR, XMR | $58M to $34M |
Ranks 1 to 6 reproduce the six markets of the inherited study exactly. The rank axis spans a factor of 205 in traded notional.
Ladder rungs are the nested top-N universes for N in {6, 10, 15, 20, 25, 30}, giving 36, 60, 90, 120, 150 and 180 sleeves, each rung deploying the same fixed capital at an equal weight per sleeve. Out of sample runs 1 January 2023 through 30 June 2026, fourteen complete non-overlapping quarters. Data was pulled to 30 June 2026 exclusive, so the registered partial-window sensitivity for July 2026 is not applicable.
Data
Hourly UTC klines from each contract's launch, one-minute klines from 1 November 2021 for intrabar path reconstruction, historical funding events at their true timestamps with the published settlement interval, and hourly mark-price opens for funding cash flows. One-minute bars are consumed and discarded; what persists per hour is the derived path information the engine needs, which is the timestamp of the bar's high and low, their order, the minute count and the repair flags.
Panels are built on a common UTC hourly grid per market with no forward filling. Positive traded volume is the test of both a contract's history and its end. That matters: the local delisted-contract panel pads dead contracts with zero-volume bars well past settlement, 11,510 padded rows for one contract and 16,527 for another, both running to 2026-04-30 despite settling in January 2025 and June 2024. Reading file extent rather than traded volume would have kept two dead contracts trading at stale prices for more than a year of the out-of-sample period.
For the six incumbent markets the earlier study's frozen panel is reused byte for byte, so the nesting check can be exact. Local panels are cross-checks on the fresh pull rather than sources, and any bar-level disagreement was resolved against the exchange before freeze.
Contract death and forced settlement
Four of the twenty-four added contracts stopped trading inside the out-of-sample period. Binance force-settled all four at 09:00 UTC, and the last hour of positive traded volume matches the announced settlement in every case. Each announcement is stored with its URL, retrieval timestamp and SHA-256 in a death manifest that the data gate reads.
| Rank | Contract | Announced settlement, UTC | Last hour with positive volume |
|---|---|---|---|
| 7 | MATICUSDT | 2024-09-04 09:00 | 2024-09-04 08:00 |
| 14 | EOSUSDT | 2025-05-21 09:00 | 2025-05-21 08:00 |
| 21 | FTMUSDT | 2025-01-06 09:00 | 2025-01-06 09:00 |
| 25 | WAVESUSDT | 2024-06-11 09:00 | 2024-06-11 08:00 |
The primary rule is no stitching. A sleeve ends when its contract stops trading, any open position closes at the last observed open, and from the next bar the sleeve holds cash for the rest of the study. Surviving sleeves are never renormalized to absorb the freed capital. That is the literal description of what the exchange did rather than merely the conservative choice: positions were closed and settled, and no successor position was created.
Registered alongside it is a stitching sensitivity, which keys a successor on the token named in the exchange's own swap announcement, identified before any price comparison, because ticker resemblance picks the wrong contract here. Two Sonic-like tickers trade concurrently on this venue and only one of them is the token FTM was swapped into. A successor is accepted only when its first observed open and the predecessor's last traded close agree within 5% after the announced ratio.
| Predecessor | Successor | Gap with no contract | Ratio-adjusted change | 5% tolerance |
|---|---|---|---|---|
| MATICUSDT | POLUSDT | 9 days 4 hours | +6.03% | fail, not stitched |
| EOSUSDT | AUSDT | 7 days 0 hours | +0.23% | pass |
| FTMUSDT | SUSDT | 10 days 1 hour | +3.87% | pass |
With both stitched markets substituted the primary contrast moves from -1.046 to -1.124, with a 95% interval of -3.081 to +0.856. The ruling does not depend on how the migrations are treated.
The tolerance was written to catch a wrong conversion ratio and cannot separate that from a real market move over a gap this long. It was left unchanged anyway, because the failing case was already visible when the weakness was noticed and retargeting a test with knowledge of which contract it excludes is the exact pattern pre-registration exists to prevent. The consequence is recorded instead.
Strategies and configuration grids
Six structural families with their signal-event semantics inherited unchanged: EMA trend, Donchian breakout, time-series momentum, RSI reversal, Bollinger-band fade and volatility-compression breakout. Each carries a canonical 64-row numeric configuration list, generated once by a discrete Latin-hypercube generator with seed 20260809, reused in every market and every window and locked by hash. No market ever receives a wider search than another.
One position per sleeve. Same-direction signals are ignored, an opposite signal reverses at the next observed open and charges two fills, stop and target are fixed by Wilder ATR(14) known at entry, and a maximum hold exits at the open after H complete held bars. Same-timestamp event ordering is funding, gap barriers, reversal, maximum hold, new entry, then intrabar barriers. Intrabar execution reconstructs the hour as open, first recorded extreme, second recorded extreme, close, from one-minute bars; a gap through a stop fills at the first available open and a gap through a target fills no better than the target; where the extreme order is unresolved the stop executes first.
Walk-forward and selection
for window in quarterly_windows(oos_start="2023-01-01", oos_end="2026-07-01"):
param_block = window.is_slice[:9] # nine months, scored
axis_block = window.is_slice[9:] # three months, retained unused
attempts = [score(cfg, param_block) for cfg in family_grid] # all 64, persisted
eligible = [a for a in attempts
if a.closed_trades >= 24 and a.distinct_weeks >= 6]
if not eligible:
cash_sleeve(window) # recorded, never dropped
continue
winner = max(eligible, key=lambda a: (a.net_return, -a.turnover, -a.canonical_index))
apply(winner, window.oos_slice) # OOS starts flatTwelve months in sample split into a nine-month parameter block and a three-month axis-selection block, three months out of sample, advancing three months, fourteen complete windows. The axis-selection block has no selection role here because this study has no picker; it is retained unused so window boundaries, purge behaviour and scored blocks stay bit-identical to the inherited study and the nesting check can be exact.
Eligibility requires at least 24 closed trades across at least six distinct calendar weeks in the parameter block, decided in sample so no out-of-sample information selects which sleeves are live. A sleeve-window with no eligible configuration contributes cash and is recorded, which matters because thin contracts fail that bar more often and aborting on it would have turned the study into a survivorship filter on activity. Across the run, 54 of the 2,520 selection decisions found no eligible configuration. Ties break on lower turnover, then lower canonical index.
Costs and funding
The primary model charges 5 basis points of taker fee and 2 of slippage on every fill, on every market from rank 1 to rank 30, applied to absolute filled notional with adverse fill construction and separate slippage booking. Keeping it flat is what makes the six-market rung bit-identical to the inherited study and keeps the rank contrast a measurement of signal quality rather than of a cost model this study invented.
That is optimistic at the thin end, so a mandatory adverse sensitivity charges slippage by tranche and leaves the fee unchanged. It re-selects every configuration under the scaled cost, because a higher per-fill charge changes which parameters win the parameter block and holding selection fixed would overstate the effect.
| Tranche | Slippage per fill, primary | Slippage per fill, adverse |
|---|---|---|
| T1 | 2 bp | 2 bp |
| T2 | 2 bp | 4 bp |
| T3 | 2 bp | 6 bp |
| T4 | 2 bp | 8 bp |
The ladder is declared rather than calibrated, and is labelled that way everywhere.
The specification registered two branches for that ladder: one calibrated from an Abdi-Ranaldo spread estimator on in-sample bars, or, if validation failed, the declared ladder above as an uncalibrated stress test. The calibrated branch failed on two independent grounds, both established before any out-of-sample value was read. The estimator's mean term is negative for all thirty contracts on in-sample hourly bars, so it clips to zero and returns a flat ladder that would falsely assert that execution cost does not rise with rank; aggregating to daily bars does not rescue it, and where the term turns positive it implies 62 and 106 basis points against real perpetual spreads well under one. Separately, the only validation source in inventory begins 2023-04-01, inside the out-of-sample period, so routing the ladder on it would have let out-of-sample information choose a cost parameter. The registered fallback was taken rather than substituting an estimator chosen after seeing the first one fail.
Funding uses observed events at their true timestamps, with positive funding debiting longs and crediting shorts, assessed on the position held immediately before the settlement timestamp, and it is never a feature. Settlement intervals are read per contract from the exchange's published funding history rather than assumed at eight hours, because several altcoin contracts moved to four-hour funding inside this sample. A missing expected funding observation is a data failure rather than a zero.
net_pnl = gross_pnl - fee - slippage - funding_cost assert abs(net_pnl - ledger.net_pnl).max() < 1e-9 # measured: exactly 0.0
Inference
Paired week-clustered bootstrap on daily series, 10,000 replicates, seed 20260810, percentile intervals. Within each fixed out-of-sample window the bootstrap resamples Monday-to-Sunday UTC calendar-week clusters. A quarter boundary splits a calendar week, so its days on either side form separate fragments. Every market, family, tranche and rung inside a sampled fragment travels together, which preserves cross-sectional dependence without changing a window's cluster count.
frag = df.groupby(["window", pd.Grouper(key="ts", freq="W-MON")])
blocks = [g for _, g in frag] # whole week-fragments move together
def stat(sample): # the primary estimand
return (sample.loc[sample.group == "added", "net_bp"].mean()
- sample.loc[sample.group == "incumbent", "net_bp"].mean())
draws = [stat(pd.concat(rng.choice(blocks, len(blocks)))) for _ in range(10_000)]
lo, hi = np.percentile(draws, [2.5, 97.5])The estimand is per-sleeve net expectancy of the 144 added sleeves minus the 36 incumbent sleeves, in basis points of sleeve capital per live sleeve-day. A live sleeve-day is a day on which the contract was trading, so days after a contract dies leave the denominator entirely.
Each secondary p-value is twice the smaller bootstrap tail probability with the finite-replicate correction (count + 1) / (B + 1), capped at one, before the four enter Benjamini-Hochberg at 5%. The single primary contrast is not corrected, and no other comparison in the study may become a replacement headline.
Power was measured before freeze from the inherited study's out-of-sample panel: the week-clustered standard error of the incumbent group mean is 1.00 basis points per day, 0.98 times the independent-day calculation because sleeve returns carry almost no serial dependence, and the projected standard error of the difference is 1.21, giving a 95% half-width of about 2.4. The swing that would carry the 180-sleeve book to a Sharpe of zero is more than twice that half-width, so the design resolves an effect at less than half the size that would matter, and it cannot resolve differences below roughly 2 basis points per day.
Sharpe discipline
Sharpe is an estimand here rather than a diagnostic, so its abuse modes are closed explicitly. Sharpe never selects a configuration, a market, a tranche or a rung. Every Sharpe is computed on the pooled non-overlapping daily book across the fourteen windows; per-window Sharpes are never averaged and the window count is never multiplied into a strategy count. Every Sharpe is reported next to the cumulative net return of the same book, and no rung with a negative cumulative return may be called improved on the strength of its Sharpe alone. First-order autocorrelation of the daily books runs from -0.026 to +0.006, so the noise floor of roughly 0.52 needs no material inflation.
The breadth model check
mult = np.sqrt(n_cells / (1 + (n_cells - 1) * rho_measured)) sr_hat = per_sleeve_sharpe.mean() * mult # both measured inside the replicate gap = sr_realized - sr_hat # carries its own bootstrap interval
rho_measured is the realized average pairwise correlation of that rung's daily sleeve net returns. The registered reading, fixed in advance: an interval containing zero at every rung means breadth delivered exactly the multiplier the measured correlation structure implies and nothing beyond it, while an interval excluding zero at any rung means the model is incomplete and the direction of the miss is reported.
The estimator was validated before it touched real data, on a synthetic corpus with known per-sleeve Sharpe and known constant pairwise correlation, for rho in {0, 0.05, 0.2, 0.5} and sleeve counts in {36, 180}, 24 cases within tolerance.
One declared bias, found during checking and accepted rather than corrected: correlation is computed on daily sleeve series that are exactly zero on roughly three-quarters of sleeve-days, because a sleeve is flat most of the time. Those zeros mechanically depress correlation, which raises the multiplier and makes the predicted Sharpe more negative. All six gap point estimates are positive, so the bias runs in the same direction as the conclusion that realized tracks predicted. Changing the estimator after seeing the result was not available.
The registered counterfactual holds every added sleeve at the incumbent per-sleeve mean and volatility while keeping the realized 180-sleeve correlation structure, which splits the Sharpe difference into a breadth component and an expectancy component with a residual that must be zero to numerical tolerance. Measured: -1.1876 and +0.1221 against a residual of exactly 0.0000.
Leak, integrity and credibility checks
| Check | Result |
|---|---|
| Nesting, engine outputs on the 36 incumbent sleeves | frame-identical |
| Nesting, selected configurations | 504 rows identical, 0 mismatches |
| Nesting, daily portfolio series | max absolute difference 3.47e-18 against a 1e-12 tolerance |
| Python reference against the Rust engine | 120 cases, 41,309 trades, exact on timing, direction and exit reason, 1.94e-16 on prices |
| No-lookahead under future truncation | 427,080 earlier trades bit-identical |
| Random-walk null, zero-drift GBM, 30 seeds | no family's interval above zero |
| Window boundaries | zero trades cross a boundary across all 10,080 sleeve-block combinations |
| Data integrity, 30 markets | zero padding, zero missing intrabar hours, zero primary-period proxies |
| Death dates against exchange announcements | 4 of 4 within the settlement hour |
| Coverage, in-sample blocks only | 97.86% fill, no caveats |
| Ledger identity on the full selected ledger | residual exactly 0.0 |
Four gates each carry a planted defect proving they can fail; each exits nonzero and names the defect. Thirty tests pass and backtest-guard reports zero automated failures.
The evaluator. strategy-evaluator, pinned at the same commit the inherited study used, ran its integrity, procedure and inputs stages. Costs reconcile to 5.55e-17 across 183,842 rows, the lookahead check finds the same-bar correlation weaker than the next-bar one, and its reported-versus-recomputed check confirms the published figures against values it derives itself. Its overall verdict places the strategy set within the empirical null, an observed maximum Sharpe of -0.595 against an expected null maximum of 1.116, which for a book where every arm loses is agreement rather than contradiction. Its no_purge flag is the inherited one: the parameter block ends at the instant the out-of-sample block begins and the engine purges at trade level rather than by calendar gap, which was verified directly and re-verified independently.
The recheck from source. The implementation was rechecked from source, without reference to the write-up. That pass returned one blocker, six major and six minor findings. Working from the persisted parquet it reproduced the primary estimand, its decomposition, all four tranches, all six rungs and all four secondary tests bit-for-bit, recomputed every selection decision with zero mismatches, verified every sleeve-block boundary combination, and confirmed both that no trade occurs after a contract dies and that the 108 cash sleeves contribute exactly zero live sleeve-days.
The blocker was that the mandatory rank-scaled sensitivity had never actually been run, while a draft described it as though it had. Running it changed the registered ruling under that cost model, which is why the note reports both readings side by side. Two further findings are recorded rather than fixed: the engine discards rather than force-closes a position open when a contract stops trading, six trades against 91,277, and an unregistered gross contrast had been promoted to a headline in a draft and is withdrawn.
Scale. 180 sleeves over 56 blocks each, 645,120 candidate configuration-block scores, and 2,520 selection decisions per cost policy. Across the cost policies the selected ledger holds 527,013 rows, of which 91,277 are rolling out-of-sample trades, produced in 358 seconds of engine wall time at four workers for 15 GB. Analysis was parallelised across 16 workers and verified bit-identical to the serial path.
What the addendum does, and how
No engine was re-run. Every fill's cost is reconstructed from the study's persisted per-trade ledger, and that decomposition rebuilds the stored fee and slippage columns to 4.3e-19 and exactly zero, so the re-pricing is a transform of artifacts rather than a new simulation.
| Fill | Order type | Fee | Slippage |
|---|---|---|---|
| Entry at the next open | market, taker | 5 bp | 2 bp |
| Stop exit, including a gap through the stop | market, taker | 5 bp | 2 bp |
| Reversal, both legs | market, taker | 5 bp | 2 bp |
| Maximum-hold exit at the open | market, taker | 5 bp | 2 bp |
| Target exit | resting limit, maker | 2 bp | 0 bp |
Binance USD-M VIP0 published rates. No fee tier and no rebate are assumed, so the reported saving is a floor.
Re-selection is required rather than optional, because the parameter block is scored on net return and net return depends on the cost model. Each model therefore runs the full registered selection, 64 attempts per family per market per window, and the note reports both the re-priced-with-fixed-selections figure and the re-selected one so the difference between them is visible.
Gross profit and funding are bit-identical after re-pricing, the ledger identity holds at exactly zero, and of 156,661 materially changed rows not one is a non-target exit. The control that matters: selection under the inherited all-taker model reproduces this study's 2,520 selections exactly, zero mismatches. Without that, any difference could be the cost model or could be a bug, with no way to tell which.
Fills are granted on touch, so a resting limit order that is merely touched counts as filled. That is the optimistic branch on fill probability, which only strengthens the conclusion. Entries stay taker throughout, because resting those would change which trades happen rather than only what they cost.
The addendum also registers, in advance, the force-close charge the parent study had to leave uncorrected. A position open when a contract stops trading should pay a full taker exit fill, and exactly 6 selected out-of-sample sleeve-windows carry one. The engine flags the discard without emitting the trade's price, so the charge cannot be applied retroactively; its upper bound is 0.0023 percentage points per sleeve.
Frozen hashes
Specification, universe and every configuration list were hash-locked before any out-of-sample block was read, and the freeze record was re-verified between the run and the analysis. The runner refuses to read an out-of-sample bar or write an out-of-sample artifact until every registered hash agrees.
| Artifact | SHA-256 |
|---|---|
| Universe manifest | 60ce3d29574a5c7a0d9befecc5cb1ea9f00a82528cf7eb80b0a7ec85ae450149 |
| Data manifest, 30 markets | e3129b4b1d711adec2cd905a4ce246b2b3ad7938c9614f31af6aca5d44daff03 |
| Study blocks manifest | 325d3873324433b73979ace8c7450a1df901b46d6d6b6852553aab7dd0c26fbb |
| Freeze record | 38741abd0e08a1cdab605cd62bad15ce733b66799761fb421ec132c665014e3c |
| Engine run manifest | eb954b0d820c0f1e5e1745824c82d484cc006ac68ab6ac40729fb81cecdb3eac |
| Results | ef56d329aacd262d00d5b23679963514fb12055ff26a5b0f573e72d156f8e06d |
Requesting the full pipeline
This page is enough to check every number in the note by hand, or to rebuild an equivalent study from the same public data sources. The production scripts, meaning the data pull, panel construction, the Rust engine, the experiment runner and the analysis, are not published here. Email daniel@daru.finance and I will send them over.

