Strategies
QuantRocket GDX–GLD daily Johansen/Bollinger pairs strategy: faithful USEQ translation
Outcome: Abandoned
GdxGldJohansenBollingerPairs
Outcome Summary
GdxGldJohansenBollingerPairs set out to port QuantRocket's GDX/GLD Johansen/Bollinger pairs strategy to the USEQ venue as faithfully as possible, re-implementing statsmodels' coint_johansen in numpy because statsmodels is not available in the sandbox. Across 3 iterations, the Layer 3 sandbox smoke test kept going over its 300-second limit on the ~20,000-bar GDX daily window. The run was abandoned in that verification loop. No backtest, optimization or analyst verdict was ever produced, so it is still unknown whether the strategy has an edge.
Hypothesis
Translate QuantRocket's executable GDX_GLD_Pair subclass, preserving its daily rolling Johansen weights, one-standard-deviation bands, independent persistent long/short signal states, daily target-weight recalculation and next-session-open execution. Use GDX.USEQ as primary and GLD.USEQ as the secondary trading leg, both with 1-DAY-LAST-EXTERNAL bars. Original defaults are LOOKBACK_WINDOW=20, BBAND_STD=1, DB_FIELDS=['Close','Open']; the subclass selects GDX and GLD from usstock-1d. Original USStockCommission charges $0.005/share; replace that commission with platform USEQ zero commissions and modeled spread/impact, explicitly reporting the difference. Do not claim source profitability or add filters, stop-losses, cointegration significance tests or parameter optimization.
The explicit request for a faithful source translation determines the instruments and mechanism. This pair adds long/short, two-instrument equity exposure to a corpus dominated by long-only Binance strategies. It does not fill the Hyperliquid or cross-venue quotas. Corpus concentration was empty, so instrument-specific research shares cannot be assessed. Unlike the prior dual-class-share proposal, this source trades miners versus bullion and recalculates Johansen share weights daily; its economics nevertheless remain unverified.
verification_loop: sandbox_timeout: Verification failed (Layer 3 — sandbox backtest): smoke test exceeded the 300s wall-clock limit on a ~20000-bar window (2400 days of GDX.USEQ-1-DAY-LAST-EXTERNAL). This almost always means per-bar work that scales with history — e.g. rescanning the full funding/supplementary series, or rebuilding a list and calling min()/sorted() inside calculate_signal()/on_bar() on every bar. Precompute sorted timestamp arrays ONCE in __init__ and use bisect, or cache lookups keyed by timestamp, so per-bar cost is O(log n) not O(n).
Implementation
Faithful Stratmill translation of QuantRocket's GDX_GLD_Pair (PairsStrategy, Apache-2.0). Each session it fits a Johansen hedge vector (det_order=0, k_ar_diff=1) on the prior 20 closes of [GLD, GDX]. Today's spread gets 20-session 1-sigma Bollinger bands (ddof=1). Independent persistent long and short spread states enter beyond a band and exit at the mean. Target weights are signal x hedge x close, normalised to 1x gross. Both legs are rebalanced to the target in whole shares one session later.
Verification Results
sandbox_timeout: Verification failed (Layer 3 — sandbox backtest): smoke test exceeded the 300s wall-clock limit on a ~20000-bar window (2400 days of GDX.USEQ-1-DAY-LAST-EXTERNAL). This almost always means per-bar work that scales with history — e.g. rescanning the full funding/supplementary series, or rebuilding a list and calling min()/sorted() inside calculate_signal()/on_bar() on every bar. Precompute sorted timestamp arrays ONCE in __init__ and use bisect, or cache lookups keyed by timestamp, so per-bar cost is O(log n) not O(n).
Iteration History
Verification failed (Layer 1.5 — hypothesis/config consistency) [class=hypothesis_mismatch]: - optimization_plan fixes leverage at 1.0
Outcome Summary
A rolling Johansen calculation that rebuilds matrices and inverts or decomposes them on every bar, in pure numpy, has to be kept cheap per bar (for example by caching per timestamp and avoiding repeated buffer rescans) or it won't fit within the sandbox time limit.
The run was abandoned in a verification loop after 3 iterations. The Layer 3 sandbox backtest went over its 300s limit on a ~20,000-bar window (2400 days of GDX.USEQ daily bars), so backtest review, optimization, analyst review and risk review never ran.
This was a direct port of QuantRocket's GDX/GLD pairs strategy to daily USEQ bars. Each day it computed a hedge ratio from a Johansen test on the last 20 closes, traded the spread between one-standard-deviation Bollinger bands, and rebalanced to target weights one session later, with zero commissions plus modelled spread and impact.
There are no performance numbers: no backtest report, no optimization report and no trade count were produced, because the strategy never got past verification.
Analysis
PairsStrategy
Backtest and paper results are hypothetical. Trading involves risk of loss.