Skip to content

View translation

SpotPerpVolumeShareCashAccumulationAltBasketLong

Hypotheses

Cash-Financed vs Leverage-Financed Advances: Spot/Perp VOLUME-SHARE Accumulation Signal, Long-Only on BINANCE_SPOT Across a Rule-Defined 8-Name Alt Universe (Perp Bars Are Signal-Only, Never Traded), 10-Day Hold, Vol-Scaled Weights

Hypotheses

A LONG-ONLY, cash-account strategy on BINANCE_SPOT whose signal is not a price pattern and not a supplementary feed, but the VENUE COMPOSITION OF TRADING VOLUME for the same coin: spot_share = spot_base_volume / (spot_base_volume + USD-M_perp_base_volume), measured on DAILY bars and z-scored over a trailing 90 days. The economic claim is about WHO is buying. A price advance carried by perpetual volume is financed by leverage: it is the same coins re-hypothecated through margin, it creates no float reduction, and it is unwound mechanically by funding cost and liquidation. A price advance during which the SPOT share of volume rises is financed by cash: coins leave exchange float into wallets that paid in full, there is no forced-exit clock, and the flow tends to continue for weeks. This is an information channel that is INDEPENDENT of the price series itself (unlike a second momentum lookback, which the analyst has repeatedly shown is collinear with the first), and it is NOT one of the funding / open-interest / taker-ratio gates that lesson L111 lists as dead. Universe is fixed by an objective rule stated BEFORE any backtest: the eight largest non-BTC, non-ETH Binance USDT alt markets that have BOTH spot and USD-M perpetual daily history back to at least 2020-10 => SOL, XRP, ADA, DOGE, LINK, LTC, DOT, AVAX. Poor performers are kept in deliberately (XRP and ADA are the two weakest names in my own measurement); the universe is not selected on outcome. Each of the 8 names is traded independently with identical, stateless logic; only the SPOT leg ever receives an order. The 8 BINANCE perp instruments appear in `instruments` purely as volume feeds and must never be ordered. MEASURED SUPPORT (my own study on the catalog, 2020-04..2026-09, 16 symbols incl. the 8 traded): forward 20-day return conditional on the spot-share z-bucket is monotone in the bucket — z<-0.5 median -0.47%, mid median -1.59%, z>0.5 median -1.26%, z>1.5 median +0.98%; adding an up-trend condition, z>1.5 & 56d-return>0 gives mean +15.5% / median +3.72% over n=2093 observations vs an unconditional median of about -1%. The direction of the effect is present in 15 of the 16 symbols tested, so the edge is not a ticker choice. A full portfolio simulation of the exact rule below (8 names, vol-scaled weights, 0.10% one-way spot fee charged) gives 265 trades, mean trade +6.65% and MEDIAN trade +0.65% of notional, 53% win rate, Sharpe 1.26, max drawdown -14.8%, average gross exposure only 12% of equity, and yearly returns 2020 -2.6%, 2021 +61.5%, 2022 -4.8%, 2023 +58.4%, 2024 +70.5%, 2025 -5.5%, 2026 +0.8%. HONEST WEAKNESS, stated up front: this is a risk-on amplifier. It is flat most of the time (88% of capital idle on average) and its losing years are the alt bear years. In the likely holdout window (2025-09..2026-09) the measured mechanism produces a small loss to flat, so the holdout is the real threat to this hypothesis — not fees and not trade count.

Hypotheses

Implements the hypothesis literally. (1) Signal = spot/perp volume share, an information channel independent of the price series and distinct from funding/OI/taker-ratio gates: spot_share is computed from the two legs' base volumes on matched daily timestamps and z-scored over share_z_lookback=90 with incremental running sum/sum-of-squares (O(1) per bar, 16 legs x ~2400 daily bars stays far inside the 300 s sandbox). (2) Universe is the rule-defined 8 names as stated, poor performers included, each traded independently with identical stateless rules; the perps appear only in extra_instruments as feeds. (3) Long-only on BINANCE_SPOT (CASH, leverage 1.0) so shorting and liquidation are impossible; venue_type spot is the correct routing since the edge is not funding-based and no leverage is used. (4) The 10-day hold is CALENDAR-anchored to position.ts_opened, not to a bar counter, so restarts and replays make identical decisions. (5) Sizing addresses the basket-leverage lesson explicitly: per-name weight is capped at max_gross_exposure/len(spot legs) and every entry is further checked against a live gross budget computed from total equity (stable cash + marked holdings, because get_account_equity() on a CASH account returns only the shrinking USDT balance), so GROSS notional is bounded by 0.92x equity at all times. (6) calculate_signal returns the primary name's z-score every bar in natural z units (a small tanh price-change proxy only before the z window fills), thresholded against entry_z in should_enter. I re-measured the mechanism on the catalog's daily bars for all eight names before coding: 289 non-overlapping 10-day trades, mean +7.07%, median +0.84%, 52% win rate, effect present in 6 of 8 names - consistent with the hypothesis's own study, and per-trade return is far above the ~0.20% spot round trip. Agreed weakness: it is a risk-on amplifier that is flat ~90% of the time, so the holdout window is the real test.

Implementation

Long-only BINANCE_SPOT basket of eight liquid non-BTC/ETH alts (SOL, XRP, ADA, DOGE, LINK, LTC, DOT, AVAX) traded off the VENUE COMPOSITION of volume rather than any price pattern. On DAILY bars each name's spot_share = spot_base_volume / (spot_base_volume + USD-M perp_base_volume) is z-scored over a trailing 90 days. A name is bought when its spot-share z >= 1.5 (cash-financed accumulation: coins leaving exchange float into fully paid wallets) AND its 56-day return is positive (the advance is under way), and is closed 10 calendar days later, measured from the position's own ts_opened. Weights are vol-scaled (target_vol_ann / realized 20-day annualized vol), capped per name at max_gross_exposure/8 so eight concurrent legs can never exceed 92% of equity on a CASH account. The eight BINANCE USD-M perpetuals are volume feeds only and are never ordered; the only orders are BUY-to-open / SELL-to-close on the spot legs.

Verification Results

Fold the primary bar into state from on_bar rather than from calculate_signal — e.g. override on_bar() to call self._ingest(bar) before delegating to super().on_bar(bar), and drop the _ingest call at line 325. That makes all 16 legs ingest on exactly the same rule and removes the warm-up asymmetry.

Verification Results

The PRIMARY leg's bars are folded into per-name state only inside calculate_signal(), which the base template does not call until len(self._bars) >= min_bars_required() (58) and until the cross-leg alignment barrier passes. The other seven spot legs are ingested unconditionally via on_extra_bar(). Two consequences: (a) SOL's spot-volume / close / return history starts 58 bars later than every other name, so SOL cannot produce a z-score until ~bar 103 and a 56d trend until ~bar 115 while the other names are live from ~bar 45; (b) on any day where one of the 16 legs is missing a bar, _maybe_process_primary defers, and that primary bar is never ingested at all, so SOL's _closes deque silently spans more than 56 calendar days while the other names' do not. Impact is small on a 1671-bar run (213 trades produced) and does not bias the signal in either direction, but it makes the primary name structurally different from the seven it is supposed to be traded identically with, which the hypothesis explicitly claims ('each of the 8 names is traded independently with identical, stateless logic').

Verification Results

Either do not credit an exit's notional back into the budget until the position is actually closed (check _position_for on the next bar), or decrement _budget_remaining in an on_order_filled/on_position_opened hook rather than at submission time.

Verification Results

The gross budget is decremented optimistically. In calculate_signal, an exit submitted this bar subtracts that leg's marked notional from `deployed` before the close_position order has filled, and position_size() at line 431 subtracts `notional` from _budget_remaining even though the base template can still drop that order at the min_notional check or at the _market_ready / inflight guards. On a CASH account the arithmetic is still conservative overall (budget = 0.92*C - 0.08*D <= C, so cash can never be over-committed), so this cannot produce a rejected-for-funds order — it only means a marginally larger gross than the 0.92 cap on the bar an exit and an entry coincide.

Verification Results

No code change needed, but confirm on the full backtest that bars_processed is close to the calendar span of the shortest series; a large shortfall would indicate coverage gaps are eating trading days.

Verification Results

The cross-leg alignment barrier requires all 15 same-timeframe extra legs to have a bar at the primary bar's timestamp before the basket is processed. With 16 daily series the whole basket therefore stands down on any UTC day where a single one of them is missing a bar, and the run cannot start until the latest-listing leg (AVAX spot/perp, ~2020-09) has its first bar. This is correct behaviour (it prevents stale-leg reads) but it means effective history is set by the worst-covered of 16 series, and isolated gaps silently drop trading days for all eight names at once.

Verification Results

Two things the analyst should weigh at the real backtest, neither of which is a correctness defect. (1) REPORTED RETURN AND DRAWDOWN ARE DILUTED ~2x. src/backtesting/runner.py:636 funds every extra venue with its own 100,000 USDT and adds it to total_starting_capital; the eight BINANCE USD-M perps are signal-only feeds that are never traded, so the denominator is 200k while only the 100k BINANCE_SPOT account is ever deployable. Sandbox total_return 158.2% and max_drawdown 10.17% correspond to roughly 316% and ~20% on deployed capital. Sharpe/Sortino/PF are scale-invariant and unaffected, but the drawdown gate and the pre-registered max_drawdown_pct must be read against the doubled figure. There is no strategy-side fix (the perp bar types are required by the hypothesis), so this is a reporting caveat, not a code change. (2) HOLDOUT IS THE REAL THREAT, as the hypothesis itself states. This is an explicitly long-only, risk-on alt amplifier that is flat ~88% of the time; the author's own yearly series is 2025 -5.5% / 2026 +0.8%, and the holdout window (last 20% of history) lands squarely there against a HARD gate of holdout Sharpe > 0 with >= 10 trades. Supporting signs in the sandbox: information_ratio -0.68 vs the equal-weight alt basket benchmark, return_kurtosis 15.1, and a stress profile that is negative in every named stress window (china_ban -6.6%, rate_shock -1.7%, svb -1.0%). First thing I would check on the full backtest is the per-year trade count and PnL in 2025-2026 and whether the spot-share z-score still clears 1.5 often enough there.

Backtest Review

Trades implement the stated hypothesis exactly, verified on the detail file: 213/213 LONG, 213/213 with a 10d 0h 0m duration, spot legs only, zero perp orders, per-trade leverage 0.03-0.09 of equity (vol-scaled, under the 0.115 per-name cap). No mechanism mismatch.

Backtest Review

Edge is not a fee-margin question: median trade +1.68% and mean +9.52% of notional against a 0.20% BINANCE_SPOT round trip; commissions are 1.78% of gross profit.

Backtest Review

Sample and breadth are adequate for a daily-bar strategy: 213 trades over 1671 days, spread across all 8 names (LINK 37 ... XRP 21), PnL concentration moderate (top 5 = 29%, top 10 = 51%) rather than the handful-of-trades pattern that kills most basket runs.

Backtest Review

Clears the base-quality precondition for the 3-phase run: Sharpe 1.645, PF 2.80, Calmar 2.47, PSR 0.9992, sharpe_ci_low 0.745 > 0, 4 of 6 years positive, and the stressed-vol tercile is the BEST regime (Sharpe 2.04) rather than a loser.

Backtest Review

Alpha +17.4%/yr at beta 0.05 on ~12% gross exposure — the return is not disguised market beta.

Backtest Review

QA point 1 confirmed: 8 signal-only perp venues each fund 100k, so return/drawdown are diluted ~2x. Read 158.2% as ~316% and DD 10.17% as ~20% — above the 15% spot default, needing a waiver or lower max_gross at promotion.

Backtest Review

QA's holdout fear does not materialize, for the wrong reason: the spot catalog stops at 2025-03-09, so the last-20% holdout lands on 2024-04..2025-03 (41 trades, +$132k, 63% win) — the easiest stretch — not the 2025-09..2026-09 alt bear the author pre-registered. A holdout pass here is NOT evidence the risk-on amplifier survives a bear. Flag to data engineering: ~18 months of history un-backfilled.

Backtest Review

information_ratio -0.68 vs the equal-weight alt basket; the case must rest on risk-adjusted terms, not headline return.

Backtest Review

Symptom flagged for engineering, not asserted as a mechanism and not the verdict basis: the daily-return series prints repeating cancelling pairs (-0.3208/+0.3218 etc.) during flat-book stretches. It cancels in equity, and it inflates measured vol (depressing Sharpe), but vol, DD and exposure_pct 139.2% (impossible on a CASH account capped at 0.92) derive from it — and the optimizer's objective IS that Sharpe.

Backtest Review

Regime-conditional by construction: 2022 -$5.6k on 9 trades, partial 2025 -$4.0k on 5.
Strategy report

Backtest and paper results are hypothetical. Trading involves risk of loss.