Volatility Breakout Patterns
Keltner Channel Breakout
Tags: volatility, breakout, keltner, trend, momentum
Functions: keltner
Description: Treats a breakout above the upper Keltner Channel as a strong trend signal and enters long. Exits when price falls below the channel midline.
Code:
upper, middle, lower = keltner(high, low, close, 20, 2.0)
# Breakout Entry
long_cond = close > upper
# Exit: trend reversal below the channel midline
exit_cond = close < middle
emit(long_cond, entry(context["ticker"], "LONG", Weight(1.0), label="KC_BREAK"))
emit(exit_cond, exit_position(context["ticker"]))
Volatility Squeeze (BB vs Keltner)
Tags: volatility, squeeze, bbands, keltner, expansion
Functions: bollinger_bands, keltner
Description: Enters when Bollinger Bands expand and break above the upper band after a squeeze period (BB inside the Keltner Channel).
Code:
bb_up, bb_mid, bb_low = bollinger_bands(close, 20, 2.0)
kc_up, kc_mid, kc_low = keltner(high, low, close, 20, 1.5)
# Squeeze Condition: BB lies inside KC
squeeze_on = (bb_up < kc_up) & (bb_low > kc_low)
# Breakout Condition: Price breaks BB Upper AND Squeeze was ON recently
was_squeeze = squeeze_on.shift(1) | squeeze_on.shift(2)
breakout = (close > bb_up) & was_squeeze
long_cond = breakout
exit_cond = close < bb_mid
emit(long_cond, entry(context["ticker"], "LONG", Weight(1.0), label="VOL_SQUEEZE"))
emit(exit_cond, exit_position(context["ticker"]))
ATR Trailing Stop System
Tags: risk_management, atr, trailing_stop, chandelier_exit
Functions: atr
Description: Chandelier Exit logic using 3x ATR. Dynamically sets a stop loss based on ATR at entry, trailing the highest high.
Code:
atr_val = atr(high, low, close, 14)
multiplier = 3.0
# Calculate Trailing Stop Level (Highest High - ATR * Mult)
# Note: For full trailing logic in vectorized, we need a custom loop or adjust intent with stop_loss
# Here we use the simplified Intent Stop Loss feature which supports ATRMultiple
# Simple MA Entry
long_cond = close > sma(close, 50)
# Entry with ATR Trailing Stop attached
emit(long_cond, entry(context["ticker"], "LONG", Weight(1.0),
stop_loss=ATRMultiple(multiplier), # Dynamic ATR Stop
label="ATR_TRAIL"))
# Standard Exit signal (optional, as SL handles downside)
exit_cond = close < sma(close, 50)
emit(exit_cond, exit_position(context["ticker"]))