| name | breakout-strategy-engine |
| description | Pre-built breakout strategy templates โ volatility squeeze detection, range breakout, momentum breakout with confirmation filters. Use this skill whenever the user asks about "breakout strategy", "Bollinger squeeze", "range breakout", "momentum breakout", "volatility expansion", "ATR breakout", "Donchian breakout", "breakout confirmation", "false breakout filter", "squeeze momentum", "compression breakout", or any breakout-based trade setup. Works with market-regime-classifier, mt5-chart-browser, and risk-and-portfolio.
|
| kind | engine |
| category | trading/strategies |
| status | active |
| tags | ["breakout","engine","mt5","regime","risk-and-portfolio","strategies","strategy","trading"] |
| related_skills | ["market-regime-classifier","mt5-chart-browser"] |
Breakout Strategy Engine
Pre-Built Breakout Strategies with Confirmation Filters
import pandas as pd
import numpy as np
from dataclasses import dataclass
from typing import Optional
@dataclass
class BreakoutSignal:
symbol: str
direction: str
entry: float
stop_loss: float
target: float
strategy: str
confirmation: list[str]
strength: float
class BreakoutEngine:
@staticmethod
def bollinger_squeeze(df: pd.DataFrame, bb_period: int = 20, kc_period: int = 20,
kc_mult: float = 1.5) -> dict:
"""Bollinger inside Keltner Channel = squeeze. Breakout when squeeze releases."""
close = df["close"]
bb_mid = close.rolling(bb_period).mean()
bb_std = close.rolling(bb_period).std()
bb_upper = bb_mid + 2 * bb_std
bb_lower = bb_mid - 2 * bb_std
atr = ((df["high"] - df["low"]).rolling(kc_period).mean())
kc_upper = bb_mid + kc_mult * atr
kc_lower = bb_mid - kc_mult * atr
squeeze_on = (bb_lower > kc_lower) & (bb_upper < kc_upper)
squeeze_off = ~squeeze_on
squeeze_fire = squeeze_off & squeeze_on.shift(1)
momentum = close - close.rolling(bb_period).mean()
direction = np.where(momentum > 0, "long", "short")
df_out = df.copy()
df_out["squeeze_on"] = squeeze_on
df_out["squeeze_fire"] = squeeze_fire
df_out["direction"] = direction
df_out["bb_width"] = (bb_upper - bb_lower) / bb_mid * 100
current = df_out.iloc[-1]
return {
"strategy": "bollinger_squeeze",
"squeeze_active": bool(current["squeeze_on"]),
"squeeze_firing": bool(current["squeeze_fire"]),
"direction": current["direction"],
"bb_width": round(current["bb_width"], 3),
"bars_in_squeeze": int(squeeze_on.iloc[-20:].sum()),
"signal": "BREAKOUT FIRING" if current["squeeze_fire"] else
"SQUEEZE BUILDING" if current["squeeze_on"] else "NO SQUEEZE",
}
@staticmethod
def donchian_breakout(df: pd.DataFrame, period: int = 20, atr_mult: float = 1.5) -> dict:
"""Break above/below N-period high/low with ATR confirmation."""
high_n = df["high"].rolling(period).max().shift(1)
low_n = df["low"].rolling(period).min().shift(1)
atr_val = ((df["high"] - df["low"]).rolling(14).mean())
close = df["close"]
long_break = close > high_n
short_break = close < low_n
vol_confirm = df["volume"] > df["volume"].rolling(20).mean() * 1.5
current = df.iloc[-1]
return {
"strategy": "donchian_breakout",
"upper_channel": round(high_n.iloc[-1], 5),
"lower_channel": round(low_n.iloc[-1], 5),
"current_price": round(current["close"], 5),
"long_breakout": bool(long_break.iloc[-1]),
"short_breakout": bool(short_break.iloc[-1]),
"volume_confirmed": bool(vol_confirm.iloc[-1]),
"atr": round(atr_val.iloc[-1], 5),
"stop_long": round(high_n.iloc[-1] - atr_mult * atr_val.iloc[-1], 5),
"stop_short": round(low_n.iloc[-1] + atr_mult * atr_val.iloc[-1], 5),
}
@staticmethod
def momentum_breakout(df: pd.DataFrame) -> dict:
"""Multi-filter momentum breakout: ADX + volume + close above/below structure."""
close = df["close"]
atr = (df["high"] - df["low"]).rolling(14).mean()
plus_dm = df["high"].diff().clip(lower=0).rolling(14).mean()
minus_dm = (-df["low"].diff()).clip(lower=0).rolling(14).mean()
dx = abs(plus_dm - minus_dm) / (plus_dm + minus_dm + 1e-10) * 100
adx = dx.rolling(14).mean()
mom_10 = close.pct_change(10)
vol_ratio = df["volume"] / df["volume"].rolling(20).mean()
high_20 = df["high"].rolling(20).max()
low_20 = df["low"].rolling(20).min()
current = df.iloc[-1]
filters = []
if adx.iloc[-1] > 25: filters.append("ADX>25 (trending)")
if vol_ratio.iloc[-1] > 1.5: filters.append("Volume 1.5x avg")
if current["close"] > high_20.iloc[-2]: filters.append("New 20-bar high")
if current["close"] < low_20.iloc[-2]: filters.append("New 20-bar low")
if abs(mom_10.iloc[-1]) > 0.01: filters.append("Strong 10-bar momentum")
direction = "long" if mom_10.iloc[-1] > 0 else "short"
return {
"strategy": "momentum_breakout",
"direction": direction,
"adx": round(adx.iloc[-1], 1),
"momentum_10": round(mom_10.iloc[-1] * 100, 2),
"volume_ratio": round(vol_ratio.iloc[-1], 2),
"confirmations": filters,
"n_confirmations": len(filters),
"signal_quality": "A+" if len(filters) >= 4 else "A" if len(filters) >= 3 else "B" if len(filters) >= 2 else "C",
"atr_stop": round(atr.iloc[-1] * 2, 5),
}
@staticmethod
def false_breakout_probability(df: pd.DataFrame, lookback: int = 100) -> dict:
"""Historical false breakout rate for current pair to calibrate expectations."""
high_n = df["high"].rolling(20).max().shift(1)
low_n = df["low"].rolling(20).min().shift(1)
breakouts = (df["close"] > high_n) | (df["close"] < low_n)
false_count = 0
total = 0
for i in range(20, len(df) - 5):
if breakouts.iloc[i]:
total += 1
future = df.iloc[i+1:i+6]
mid = (high_n.iloc[i] + low_n.iloc[i]) / 2
if (future["close"] < high_n.iloc[i]).any() and (future["close"] > low_n.iloc[i]).any():
false_count += 1
rate = false_count / max(total, 1)
return {
"false_breakout_rate": round(rate * 100, 1),
"total_breakouts": total,
"recommendation": "Wait for retest" if rate > 0.5 else "Trade breakout with confirmation",
}
@staticmethod
def scan_all(df: pd.DataFrame, symbol: str = "") -> dict:
return {
"symbol": symbol,
"squeeze": BreakoutEngine.bollinger_squeeze(df),
"donchian": BreakoutEngine.donchian_breakout(df),
"momentum": BreakoutEngine.momentum_breakout(df),
"false_breakout_rate": BreakoutEngine.false_breakout_probability(df),
}
Automated Breakout Detection with Liquidity Sweep (CodeTrading Python)
Source: "Automated Break Out Detection in Python" by CodeTrading (Nov 2025)
Why Simple Breakouts Fail
A candle closing above a recent high is NOT enough โ price often reverts back (fake breakout). A stronger breakout pattern is preceded by a liquidity sweep.
The Liquidity-Confirmed Breakout Pattern
Bullish breakout with sweep:
- Identify pivot highs and pivot lows within a lookback window (e.g., 40 candles)
- Find the most recent pivot high (resistance level)
- Check if a pivot low formed AFTER that high AND is lower than all previous pivot lows in the window = liquidity sweep
- Current candle closes above the pivot high AND previous candle was below it = breakout confirmed
- Filter: only take bullish breakouts when last 15 candles are ALL above EMA (trend confirmation)
Bearish breakout with sweep: Mirror logic โ pivot low โ higher high sweep โ breakdown below pivot low
Python Implementation Details
Pivot Detection (no look-ahead bias):
def mark_pivots(df, window=7, high_col='high', low_col='low'):
Breakout Detection Function:
def detect_breakout(candle_idx, back_candles=40, window=5):
Trend Filter (EMA-based):
- Check if last N candles (e.g., 15) are ALL above EMA โ uptrend โ only bullish breakouts
- ALL below EMA โ downtrend โ only bearish breakouts
- Adjustable selectivity: 10, 15, 20, 25 candles
Backtest Results (EURUSD, 20 years hourly data, 2003-2023)
Optimization surface (TP/SL ratio vs ATR multiplier):
- Best zone: TP/SL ratio 4-5x, ATR multiplier 4+
- Returns: 5-52% depending on parameters (no leverage, no commission)
- Drawdown minimized at ATR mult ~1, TP/SL ~1 (but returns limited to 5-8%)
Key Parameters
back_candles = 40
pivot_window = 5-7
ema_candles = 15
atr_mult = 1-5
tp_sl_ratio = 1-5
Usage Recommendation
- Best as an alert indicator โ bot detects pattern, human manages trade
- Run simultaneously on multiple assets to multiply signal count without losing precision
- Trade management (TP/SL optimization) is asset-specific โ needs tuning per instrument
See also: smart-money-trap-detector (fake breakout detection), liquidity-order-flow-mapper, chart-pattern-scanner