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 and licensed sources.
Data and universe
Equities. Ten large-cap US single stocks, selected on 31 December 2022 by median daily dollar volume over October to December 2022. The source is 1-minute NBBO-eligible trade and quote data, excluding odd lots and non-NBBO venues. Instruments are keyed by a stable security identifier with adjustment factors chained across identifier changes, so splits and ticker reuse cannot corrupt returns.
Crypto. Ten Binance USDT-margined perpetual contracts, selected the same way from public kline and funding archives, each required to have 24 months of genuinely traded volume before the sample starts.
Sample. Out-of-sample testing runs from 1 January 2023 through 31 July 2026, at 15-minute and 1-hour bar frequencies, for both markets.
Feature set
Every model family sees the same 62 features, built only from OHLCV: returns and momentum at several lags, rolling realized volatility, position-in-range, distance to the rolling high and low, volume ratios and changes, and candle-shape features such as body fraction and wick sizes. No cost, spread, fee or funding column is present in the feature matrix, and that was verified programmatically before any out-of-sample result was produced.
# 6-bar realized volatility and position within the recent high/low range
df["vol_6"] = df["ret_1"].rolling(6).std()
df["pos_in_range_6"] = (
(df["close"] - df["low"].rolling(6).min())
/ (df["high"].rolling(6).max() - df["low"].rolling(6).min())
)Model search, frozen before OOS
Three model families: a regularized linear model, a gradient-boosted tree ensemble and a small feed-forward neural network. Each family gets exactly 30 candidate configurations, generated and hashed once, before any out-of-sample window is scored. Every run checks the hash before touching data, and a mismatch aborts the run rather than letting the grid drift silently between sessions.
import hashlib, json
configs = {"linear": linear_grid, "gbt": gbt_grid, "mlp": mlp_grid}
digest = hashlib.sha256(json.dumps(configs, sort_keys=True).encode()).hexdigest()
assert digest == "6c6d89b6cfd435ce875876820443405f5d383956a5673ea38f5d2d410b490e47"Walk-forward mechanics
Six training lengths (1, 2, 3, 6, 12 and 24 calendar months) crossed with three out-of-sample schedules (fixed one month, fixed three months, and two-thirds of the training length) gives 216 result cells. Walking that forward across the full sample produced 5,868 rolling model-windows and 176,040 total configuration attempts.
Selection inside each window is chronological, never shuffled, and the winning configuration is refit on the complete in-sample window before it ever touches the out-of-sample block. Each window's configuration scores, metadata, predictions and full trade ledger are persisted before a completion sentinel is written, so the run is resumable and can be re-checked window by window.
for window in rolling_windows(train_months, schedule):
fit_rows, val_rows = chronological_split(window.is_slice, frac=0.8)
scored = [fit_and_validate(cfg, fit_rows, val_rows) for cfg in configs[model_family]]
winner = max(scored, key=lambda s: s.validation_ic)
final_model = fit(winner.config, window.is_slice) # refit on the full IS window
preds = final_model.predict(window.oos_slice) # scored exactly once, out of samplePortfolio rule and cost model
The forecast target is the next bar's open-to-close return. The trading rule buys the top two cross-sectional predictions and shorts the bottom two, at 25% absolute weight each, entering at the next bar's open and exiting at that bar's close.
book = pd.concat([
ranked.head(2).assign(side=+1),
ranked.tail(2).assign(side=-1),
]).assign(weight=lambda d: 0.25 * d["side"])
gross = book["weight"] * book["fwd_return"]
net = (
gross
- book["weight"].abs() * book["spread"]
- book["weight"].abs() * fee_bps # 5 bps taker (crypto), 0.5 bps (equities)
- book["weight"].abs() * slippage_bps # 2 bps (crypto only)
+ book["weight"] * book["funding_signed"] # crypto only, on the true settlement bar
)Crypto pays the measured monthly spread, a 5 bps taker fee and 2 bps of slippage per fill, plus actual signed funding at its true eight-hour settlement event: positive funding debits longs and credits shorts, negative funding reverses that. Equities pay the measured per-bar spread and 0.5 bps per fill, with no funding leg. Gross, spread, fees, slippage, funding and net are kept as separate ledger columns for every position, and the aggregate reconciles to those components exactly. The largest observed identity error across the full run was 0.0 bps.
Statistical inference
Comparisons use a week-clustered bootstrap on pooled out-of-sample series, not per-window Sharpe averaging and not row-wise resampling, because returns are serially and cross-sectionally correlated. The Benjamini-Hochberg procedure controls the false discovery rate across every tested cell, including the losing ones.
boot_diffs = week_clustered_bootstrap(shorter_length_pnl, baseline_24m_pnl, n_boot=10_000) p_values = [two_sided_p(observed_diff, boot_diffs) for observed_diff in cell_diffs] significant = benjamini_hochberg(p_values, alpha=0.05)
Credibility and leak checks
Before any out-of-sample number was inspected: future-truncation testing reproduced every feature with a maximum error of 0.0; the forecast target matched the next bar's realized open-to-close return to within 0.0000018 bps; all funding events in the gate sample matched their raw exchange timestamps; a positive control with the target planted directly into the feature set raised pooled IC from 0.0172 to 0.9999; and three circular-rotation negative controls, which destroy any genuine time alignment, returned ICs of 0.0165, 0.0418 and −0.0461, consistent with noise.
A generic lookahead guard initially flagged the majority of representative bundles, because it assumes a score correlated with the return at timestamp t was traded during that same return. This engine's convention is different: the return at t is an input observed at that bar's close, and the position enters at the following bar's open. A row-level timeline check joining decisions, entries, exits and targets back to the source panel, across 3,563,992 prediction rows, found zero timing errors, zero entry or exit price mismatches, and a maximum target reconstruction error of 0.0000008 bps — confirming the guard's assumption, not the pipeline, was wrong.
Environment
Python 3.10.12 polars 1.40.1 numpy 2.2.6 scipy 1.15.3 scikit-learn 1.7.2 lightgbm 4.6.0 torch 2.11.0+cu130 matplotlib 3.10.9 pyarrow 24.0.0 markdown 3.10.2
All model, bootstrap and configuration-generation seeds are fixed. A window is only reused from a prior run when its completion sentinel and configuration hash agree with the current run's files; otherwise it is recomputed.
The charts in the note are drawn from the published result tables, which are the same tables the numbers in the text come from.
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 and licensed data sources. The production scripts — data pull, panel construction, the experiment runner, the analysis and the figure build — are not attached. Email daniel@daru.finance and I'll send them over.

