Strategies
Connors RSI(2) Pullback in the Index-ETF Domain It Was Designed For: Long-Only SPY/QQQ/IWM/DIA When Close > SMA200 and RSI(2) < 5, Exit on Close > SMA5 or 10-Session Clock, Published Parameters Frozen as a Post-2009 Out-of-Sample Test (USEQ 1-DAY)
Outcome: Abandoned
ConnorsRsi2IndexEtfPullbackUseq
Outcome Summary
This run was meant to test Connors' RSI(2) pullback rule on the four broad US index ETFs it was designed for, with post-2009 data as a pre-registered out-of-sample check. The strategy never got past Layer-3 sandbox verification: all three iterations hit the 300s smoke-test limit. In iteration 2 the developer made per-bar indicator work O(1). In iteration 3 profiling pointed to the NautilusTrader catalog file scan, which strategy code cannot shorten. The run was abandoned with no backtest, optimization or analyst verdict, so the hypothesis itself is still untested.
Hypothesis
Implements Connors' published rule with the article's parameters frozen (SMA200, RSI(2) <= 5, exit on close > SMA5), plus the hypothesis's 10-session clock, on the four broad index ETFs. Each ETF is its own sleeve; an extra leg acts only on a bar stamped at the primary session close. use_trend_filter=false gives the pre-registered secondary variant without SMA200. Iteration 3: v2 was profiled in the actual sandbox runner. Run time is dominated by NautilusTrader's catalog.bars() fsspec glob over about 126k bar directories on an overloaded host (load ~34). Per-bar strategy work is O(1) per leg, and the strategy ran to completion (1406 bars, 28 SPY entries). The trading logic is unchanged; only documentation changed. The timeout is infrastructure (catalog scan / host load) and should be retried or fixed on the platform side, not in strategy code.
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 SPY.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
Connors RSI(2) pullback, long-only, on four independent USEQ daily sleeves (SPY primary; QQQ/IWM/DIA extras). Entry: close > SMA200 and Wilder RSI(2) <= 5. Exit: close > SMA5 or after 10 sessions. Each sleeve is 25% of equity (max gross 1.0x, inside the 2x Reg-T cap). Whole-share sizing.
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 SPY.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).
Outcome Summary
When a sandbox timeout comes from the catalog/data-loading layer and not from per-bar strategy cost, changing the strategy code will not fix it; it needs an infrastructure fix or a manual escalation, or the verification loop keeps abandoning a valid hypothesis before any backtest runs.
The strategy was abandoned in a verification loop after 3 iterations. Each attempt failed Layer 3 (sandbox backtest) because the smoke test ran past the 300s wall-clock limit on a ~20000-bar SPY.USEQ 1-DAY window. The developer's own profiling blamed ParquetDataCatalog bar-file globbing (~126k bar dirs on a heavily loaded host), not per-bar strategy work.
Test Connors' published RSI(2) pullback rule, with its parameters frozen, as a long-only independent sleeve on each of SPY, QQQ, IWM and DIA (USEQ, 1-day bars): buy when close > SMA200 and Wilder RSI(2) <= 5, and exit when close > SMA5 or after 10 sessions. The rule relies on short-horizon negative autocorrelation in index returns, and data from 2009 onward serves as a pre-registered out-of-sample test.
No performance numbers exist. The backtest report is empty and optimization, backtest review and analyst review never ran. The only figures come from a note in the iteration-3 code: the sandbox smoke test ran 1406 bars and made 28 SPY entries before it hit the time limit.
Backtest and paper results are hypothetical. Trading involves risk of loss.