Skip to content
All strategies

Strategies

BTC OKX 4H Donchian-Midline Regression-Slope Acceleration: Enter on ATR-Normalised Slope Breaking +/-1 ATR, Exit on 3-Bar Slope Deceleration or Chandelier Stop, Explicit Flat State (BTCUSDT.OKX 4H, pure OHLCV, long-short, single leg)

Outcome: Abandoned

BtcOkxDonchianMidlineSlopeAccelLS

Outcome Summary

BtcOkxDonchianMidlineSlopeAccelLS reworked a high-turnover FMZ slope-flip strategy into a thresholded trend strategy on OKX BTC 4H bars. It entered on ATR-normalised midline-slope acceleration, exited on deceleration or a chandelier stop, and stayed flat in between. The hypothesis stressed O(1) per-bar indicators because of recent sandbox timeouts, but after 3 iterations the code still failed Layer 3 verification: the smoke test exceeded the 300s limit on a ~20,000-bar window. Backtest review, optimization, analyst review and risk review were never reached, so there is no performance data.

Hypothesis

Rebuilt from first principles out of homily's FMZ digest 'Quantitative Speed-Rate Trading Strategy' (https://www.fmz.com/digest-topic/4987, sections 'Indicator design' and 'Trading strategy design'); this is not a faithful port. The source takes the midpoint of the 35-bar highest high and lowest low (Donchian midline), smooths it with a 5-bar SMA, and computes the 35-bar OLS regression slope 'ss' of that series (its 'speed'). It then flips long/short EVERY time ss rises or falls versus the previous bar. That……Show moreShow less

Rebuilt from first principles out of homily's FMZ digest 'Quantitative Speed-Rate Trading Strategy' (https://www.fmz.com/digest-topic/4987, sections 'Indicator design' and 'Trading strategy design'); this is not a faithful port. The source takes the midpoint of the 35-bar highest high and lowest low (Donchian midline), smooths it with a 5-bar SMA, and computes the 35-bar OLS regression slope 'ss' of that series (its 'speed'). It then flips long/short EVERY time ss rises or falls versus the previous bar. That version is always-in and flips on every tick of slope-of-slope: 1,261 trades a year on 1H, a flip on nearly every other bar. The per-flip move is far below our ~0.20% double-notional flip cost, and lessons L150, L167 and L166 all say that design dies. Its claimed Sharpe was 0.117 even with 2019 fees. What we keep is the economic idea: the SLOPE of the smoothed channel midline is a low-noise measure of trend velocity. Velocity accelerating PAST a meaningful threshold marks trend onset, and velocity DECELERATING marks exhaustion, where the source exits. Changes to the source: (1) Use 4H bars on BTCUSDT.OKX, the OKX USDT perpetual swap and the modern USDT-margined twin of the source's OKX BTC quarterly. This keeps the source's venue and underlying, with catalog history from 2019-12 (~6.7 years, ~14,600 bars). (2) Normalise the slope: S = ss * 35 / ATR(35), i.e. how many ATRs the fitted midline travels across the regression window, so one threshold applies across 2020-2026 price levels. (3) Replace the slope-tick flip with a threshold ENTRY (|S| crossing 1.0) and a deceleration EXIT (S moving toward zero for 3 consecutive bars, the source's 'momentum weakening' rule made persistent). This adds an explicit FLAT state, expected ~50-60% of the time. (4) Add a 3-ATR chandelier stop. Why BTC, given its over-concentration in the corpus: OKX is 0.3% of experiments; the source mechanism was specified and published on OKX BTC; OKX alt swaps in our catalog only start 2026-09-24 (SOL/XRP/DOGE/LTC 4H), so only BTC/ETH/BCH have multi-year OKX history; ETH OKX already has a trend-flip strategy in the pipeline (EthOkxSuperTrendFlipChandelier); and BCH is thinner, which L136 warns against. No regime gate and no supplementary feed (L130, L160). Implementation note, given the sandbox timeouts in recent results: every indicator must be O(1) per bar. Use monotonic deques for HHV/LLV, a running sum for the SMA and ATR, and the closed-form rolling OLS slope with fixed x = 0..34: slope = (sum(x*y) - 17*sum(y)) / 3570. Recomputing it over a 35-element deque each bar is O(35) and fine. Never rescan the full history.

Iteration 3. The Layer-1 syntax error at line 1 came from a malformed code payload in iteration 2: its outbox file is gone and whatever reached the verifier was not the Python class. This resubmits the full class source. It also addresses the iteration-1 Layer-3 timeout. HHV/LLV now use O(1)-amortised monotonic deques instead of max()/min() over the window each bar, and the SMA uses a running sum. The OLS slope stays a closed form over a fixed 35-element deque, so per-bar cost does not depend on the length of the backtest (~14.6k 4H bars). Signal, entry, exit and sizing logic are unchanged. The code clamps parameters, and the matching ranges are declared in _param_bounds.

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 BTCUSDT.OKX-4-HOUR-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

BTCUSDT.OKX 4H long-short. Donchian(35) midline -> SMA(5) -> 35-bar OLS slope, normalised by ATR(35) into S = ATRs travelled across the window (continuous signal). Enter long/short when S crosses +/-1.0 from flat; exit on 3 consecutive bars of S moving toward zero (deceleration) or a 3-ATR chandelier stop from the post-entry extreme. Flat state between legs. Risk-based sizing: 1.5% equity risk / max(3*ATR/price, 1%), capped at 1x equity * leverage.

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 BTCUSDT.OKX-4-HOUR-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 — static analysis): - Syntax error: leading zeros in decimal integer literals are not permitted; use an 0o prefix for octal integers (<unknown>, line 1) (line 1)

Outcome Summary

A design meant to be O(1) per bar can still time out in the sandbox. Before submitting, profile the per-bar indicator update over a 20k-bar window (for example the O(slope_len) OLS loop and the deque maintenance), because repeated sandbox timeouts end a strategy before it produces any backtest evidence.

After 3 iterations it was abandoned in a verification loop. Layer 3 (the sandbox backtest) failed with a sandbox timeout: the smoke test ran past the 300s wall-clock limit on a ~20,000-bar (2,400-day) BTCUSDT.OKX 4H window.

A long-short trend strategy on BTCUSDT.OKX 4H bars. It entered when the ATR-normalised OLS slope of a smoothed 35-bar Donchian midline crossed +/-1 ATR, and exited after 3 bars of slope deceleration or a 3-ATR chandelier stop, staying flat in between. It was rebuilt from the FMZ 'speed-rate' strategy, which flipped position on nearly every bar.

There are no performance numbers. The backtest report is empty and optimization never ran, so there is no return, Sharpe or trade count.

Analysis

定量分型速率交易策略

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