Strategies
DOGE Deleveraging-Flush Reversal: 7-Day Sell-Off on Rising Volume and Falling Open Interest, Long-Only 3-Day Hold (DOGEUSDT.BINANCE USD-M, Daily Bars, Single Instrument)
Outcome: Abandoned
DogeDeleveragingFlushReversalLong
Outcome Summary
The strategy took the volume-up / open-interest-down conditioning from a futures short-term-reversal paper and traded only its long side on one Binance DOGE perp, holding each trade for 3 days. Its supporting evidence was a pre-study cell picked from a small grid (+1.84% mean over 54 trades, t≈2.3), which QA noted makes selection, not fees, the main risk; the hypothesis itself asked for an XRP cross-check before any promotion. The code never passed verification: after 3 iterations, QA still found an off-by-one in the time stop that held trades for 4 bars instead of 3. The run was abandoned as a verification-loop code defect before any backtest, optimization or analyst review.
Hypothesis
Implementation
Long-only strategy on DOGEUSDT.BINANCE USD-M with daily bars. It waits for a 7-day sell-off during which weekly volume rose sharply and weekly open interest fell sharply: the flush score min(vol_z, -oi_z) must be above z_thresh, where vol_z and oi_z are z-scores of the weekly volume change and open-interest change. It then buys at the daily close, which on a 24/7 venue is the next bar's open, and sells after 3 daily bars. Each position uses 50% of equity at 1x.
Iteration 3 fix for the Layer-3 frozen supplementary snapshot failure. The old _build() step parsed metrics and open_interest once into cached arrays; it is removed. Open interest is now read on every bar with self.supp_arrays(key) and np.searchsorted on the point-in-time view, using only rows at or before the bar and within oi_tolerance_hours. Signal, entry, exit, sizing and config are unchanged. Risk control route (b): a time-stop exit with sizing capped at 50% of equity, 1x.
Verification Results
Count bars since the entry fill so the exit fires on bar N+hold_bars. Either set _bars_held = 1 the first time the position is seen, or compute the count from the position's open time: bars_held = (bar.ts_init - position.ts_opened) // NS_PER_DAY, exiting when it reaches hold_bars. Anchoring on position.ts_opened also removes the restart-state issue below.
Off-by-one in the time stop: hold_bars=3 holds 4 daily bars, not 3. The entry market order fills inside bar N's event, at its close. On bar N+1, calculate_signal sees the position for the first time, sets _in_position=True and _bars_held=0. The counter then reads 1 on N+2, 2 on N+3 and 3 on N+4, and should_exit fires on N+4. So the position runs from close(N) to close(N+4): a 4-day hold. The hypothesis specifies a 3-day hold and its pre-registered +1.84% is a 3-day mean. The measured horizon would be 33% longer than the stated one, and every hold_bars value the optimizer tries would be mislabelled by +1 bar.
Derive the hold from position.ts_opened (see the critical fix).
_bars_held and _in_position live only in process memory. After a paper restart with an open position, the counter restarts at 0 and the hold is extended. The backtest does not restart, so this does not affect measurement.
If open_interest is present, read only that key, and drop the metrics fallback when it is not needed.
The sandbox took 688 s for 2,305 daily bars and was flagged runtime_review_required. supp_arrays is O(log n) per call. _oi_at calls it for two keys, twice per bar, and walks back up to 12 rows each time. That should be cheap, so the cost may come from the size of the metrics series or the first cache build. Runtime is a resource concern, not a correctness one.
Iteration History
Verification failed (Layer 1 — static analysis): - Syntax error: invalid decimal literal (<unknown>, line 1) (line 1)
Verification failed (Layer 3 — frozen supplementary snapshot): metrics, open_interest were read once and never again while new observations arrived. parameters['supplementary_data'] is a point-in-time view: anything built from it once holds only what was known at that bar. Read the series on every bar with self.supp_arrays(key) / self.supp_as_of(key) / self.supp_window(key, n).
Outcome Summary
Count the holding period from the position's open time (position.ts_opened), not from an in-memory counter that starts at 0 on the first bar after the fill, so the hold length matches the hypothesis and survives restarts.
After 3 iterations it was abandoned in the verification loop, at Layer 4 QA review. The review flagged a critical code defect: an off-by-one in the time stop meant hold_bars=3 actually held for 4 daily bars, which does not match the pre-registered 3-day horizon. It also warned that the hold counter lived only in memory and would reset on a restart, and that the sandbox run was slow (688 s for 2,305 bars).
A long-only, 3-day-hold reversal on DOGEUSDT.BINANCE daily bars, entering after a 7-day sell-off that came with rising volume and falling open interest, on the idea that forced deleveraging rather than new directional capital drove the move and that it should partly revert.
No pipeline backtest or optimization results exist. The only figures are from the hypothesis's own pre-study: 54 DOGE longs averaging +1.84% over 3 days (t≈2.3), picked as the best cell of a 10-name x 2-hold x 3-threshold grid, with a pooled 7-day result across 10 names of +0.62% (t=1.2).
Abandon Reason
Analysis
Short Term Reversal with Futures
Backtest and paper results are hypothetical. Trading involves risk of loss.