Skip to content
All strategies

Strategies

King Keltner (Raschke) Channel Breakout, Slope-Confirmed, Long-Short, Exit on Midline Recross, restated on a 4H clock (ETHUSDT.BYBIT 4H, pure OHLCV, author's 20/50 defaults)

Outcome: Abandoned

EthBybitKingKeltnerBreakout4H

Outcome Summary

EthBybitKingKeltnerBreakout4H restated the FMZ King Keltner breakout (a slope-confirmed EMA midline with ATR bands, long and short, exiting on a midline recross) on ETHUSDT.BYBIT 4H. The 4H clock was chosen after a pre-study showed the 1H version could not cover fees. The code never passed Layer 3 sandbox verification: the smoke test repeatedly ran past the 300s limit on a ~20,000-bar window. After 3 iterations, including a rewrite of the ATR as an O(1) rolling sum, the run was abandoned before backtest review, optimization, analysis or risk review, so the edge was never measured inside the factory.

Hypothesis

Source: 发明者量化-小小梦, 'Keltner Channel upgrade: King Keltner strategy', FMZ digest (https://www.fmz.com/digest-topic/4104), sections '升级版的金肯特纳' and '金肯特纳策略My语言'. Credit to the author. The mechanism is restated from first principles, not ported faithfully (L167). Channel: typical price TP=(H+L+C)/3. Midline = EMA(TP, 20), which is Raschke's EMA version from the article's text; the article's My-language code uses an SMA. Band width = SMA(TrueRange, 50), used with a 1.0x multiplier as in the article. Upper = mid +……Show moreShow less

Source: 发明者量化-小小梦, 'Keltner Channel upgrade: King Keltner strategy', FMZ digest (https://www.fmz.com/digest-topic/4104), sections '升级版的金肯特纳' and '金肯特纳策略My语言'. Credit to the author. The mechanism is restated from first principles, not ported faithfully (L167). Channel: typical price TP=(H+L+C)/3. Midline = EMA(TP, 20), which is Raschke's EMA version from the article's text; the article's My-language code uses an SMA. Band width = SMA(TrueRange, 50), used with a 1.0x multiplier as in the article. Upper = mid + ATR50, lower = mid - ATR50. Direction rules: long when the midline is rising and the close is above the upper band; short when the midline is falling and the close is below the lower band. A long exits on a close below the midline and a short on a close above it. No other gate, filter or supplementary feed (L130). ONE ADAPTATION: the clock moves from the article's 1H to 4H, because my point-in-time pre-study on BYBIT 1H (7 alts/majors, 2021-2026, 0.11% RT) showed the 1H version is fee-dead on every name. Net per trade was -0.14% to 0.00%, with PF 0.82-1.00 on 2,000-2,600 trades. The midline-recross exit cuts trades at about 1 ATR, and on 1H that is too small against the round trip. Instrument selection is disclosed (L122): I screened SOL/XRP/LINK/DOGE/AVAX/ETH/BNB on BYBIT at 4H/12H/1D. I chose ETHUSDT 4H because it is the only cell with (a) >=500 lifetime trades, (b) symmetric long and short capture (net +0.38% long / +0.39% short, so it is not disguised long beta) and (c) positive net in 4 of 6 calendar years with no single-year dominance. Several 1D/12H cells had higher PF (SOL 1D PF 2.6) but only 70-170 trades, and those were concentrated in one year and long-side-driven, so they fail L128/L170. Venue: BYBIT linear perp (0.8% corpus share against a >=5% target). Pure-price trigger, so the L160 supplementary-feed restriction does not bite. Bybit ETH has ~5.5 years of 4H history (2021-03 onward, ~12,100 bars). BTC is avoided (over-concentrated), as is Hyperliquid (L168: short history). The factory's other ETH candidates (OKX SuperTrend, volume-confirmed momentum) use different triggers and exits. This one is a volatility-band breakout with the exit tied to a moving midline, flat ~33% of the time.

Iteration 3 fixes the Layer-3 sandbox_timeout. The only per-bar loop under the strategy's control was the 50-bar true-range sum used to rebuild the ATR on every bar. It is now a rolling scalar sum: add the newest TR and subtract the TR leaving the window, with a one-time O(atr_len) re-seed on the first bar or after a gap. That makes per-bar cost O(1). The EMA midline was already incremental, so there are no history rescans and no supplementary feeds. Entry, exit, signal and sizing logic are byte-for-byte unchanged, so Layers 1 and 2 stay green. The code was already about 50 float ops per bar on ~12k bars, so if the timeout recurs the likely cause is harness or engine load rather than strategy compute.

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 ETHUSDT.BYBIT-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

King Keltner (Raschke) channel breakout on ETHUSDT.BYBIT 4H. Midline = EMA(typical price, 20); band = +/-1.0 x SMA(TrueRange, 50). Long when the midline is rising and the close is above the upper band; short when the midline is falling and the close is below the lower band. Exit on a close back across the midline. The signal is the close's distance from the midline in ATR units. Sizing is 0.9 x equity notional at 1x.

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 ETHUSDT.BYBIT-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).

Outcome Summary

Any per-bar cost that grows with history makes the sandbox time out before the signal is ever tested, so every indicator should be written as O(1) incremental state from the first iteration, and any base-class history handling (such as the self._bars buffer) should be checked as a possible remaining bottleneck.

After 3 iterations the strategy was abandoned in a verification loop. Layer 3 (sandbox backtest) failed with sandbox_timeout: the smoke test ran past the 300s wall-clock limit on a ~20,000-bar window (2400 days of ETHUSDT.BYBIT 4H). This happened even though iteration 3 had replaced the per-bar ATR loop with an O(1) rolling sum.

A King Keltner (Raschke) channel breakout on ETHUSDT.BYBIT 4H, pure OHLCV: long when the EMA(typical price, 20) midline is rising and the close is above mid + 1.0x SMA(TrueRange, 50), short on the mirror condition, and exit when the close recrosses the midline; the clock moved from 1H to 4H because the researcher's own pre-study found the 1H version fee-dead.

No factory performance numbers exist, because the backtest report is empty and no optimization ran. The only figures come from the hypothesis's own pre-study, which reported net +0.38% per trade on longs and +0.39% on shorts for ETHUSDT 4H, and -0.14% to 0.00% net per trade (PF 0.82-1.00) for the 1H version.

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