| Name | Typ. value | Description |
|---|---|---|
| Entry | 1 pro Run | The trigger. Exactly one entry condition is active. Trend entries (Donchian, EMA cross) vs. mean-reversion entries (BB Extreme, RSI-MR) serve opposite regimes. |
| Filter | 0..n | Veto only. Each filter can block the trade, none triggers it. More filters = fewer bad trades, but also a smaller sample and greater overfitting risk. |
| Position Sizing | risk% / Stop-Distanz | How much capital is risked per trade. Capped by MAX_POSITION_USD. According to the ML findings, volatility-based sizing is the most robust edge. |
| Exit | 0..n | Stops (ATR trailing, swing, fixed), targets (swing high, ATR multiple), and time/signal exits. They balance profit-taking against risk. |
Pros
- Combinatorial: every entry × every filter set × every exit set — the mega-sweep searches exactly this space
- Reusable: a new filter is immediately combinable with every entry, without any strategy code
- Regime-aware: entry type and filters can be tuned specifically to trend or range phases
- A single source of truth (registry.py) — UI, runner, mega-sweep, and experiment tracking read the same defaults/ranges
Cons
- The combination space is huge → overfitting risk; every additional filter shrinks the sample
- A wrong pairing (mean-reversion entry + trend filter) is self-destructive and not prevented automatically
- Many building blocks died in walk-forward validation (sweep:False) — availability ≠ edge
Botty has no 'strategies' — only building blocks
The most important point first: in Botty there is no fixed strategy object like 'the Donchian strategy'. There are only conditions that the runner freely assembles per run. 'Donchian' is therefore not a strategy but an entry condition that you combine with any filters, a sizing, and any exits (strategies/conditions/registry.py is the single source of truth).
Every strategy = exactly one entry + any number of filters + position sizing + any number of exits, chained via resolve_signal().
(Tip: the linked building blocks below lead to the respective indicator/concept entry in the knowledge base.)
The four pillars on a single trade

| Pillar | Role | Mnemonic |
|---|---|---|
| ① Entry | The trigger. Exactly one per run. | "When do I enter?" |
| ② Filter | Conditions that all must agree on. They only veto — none triggers a trade. | "When do I not enter?" |
| ③ Position Sizing | How large the position becomes, usually risk% ÷ stop distance. | "How much do I risk?" |
| ④ Exit | Stops, trailing, targets, time/signal exits. | "When do I exit — with profit or a capped loss?" |
In the image: the filters form a gate before entry (yellow). Only once all pass does the entry trigger fire (light blue). The stop distance is the risk unit from which the position size is derived (purple). The trailing stop (teal) follows the price upward and locks in the profit until it is hit on the pullback.
Pillar ①: Entry conditions (exactly one per run)
This list comes live from the condition registry (strategies/conditions/registry.py) — new entries appear here automatically. Which entry fits which market regime is shown in the regime table further down.
| Baustein | Bezeichnung | Beschreibung | Parameter |
|---|---|---|---|
adx_dmi_regime |
ADX/DMI Regime Trend-Onset | Frischer Trendbeginn: ADX/DMI-Regime kippt mit Hysterese auf Trend. | adx_period (default 14, 2–40), regime_range_enter (default 20.0, 10–30), regime_trend_enter (default 25.0, 18–40) |
bb_extreme |
Bollinger Band Extreme (Mean Reversion) | Mean reversion: entry at the Bollinger band extreme, target back to the band midline. | bb_std (default 2.0, 1.5–3.0), bb_period (default 20, 10–50) |
burj_khalifa |
Burj-Khalifa Reversal (Pifagor) | Reversal at LMACD+RSI+EMA200 confluence (Pifagor rebuild). | bk_vol_mult (default 1.2, 0.5–3.0), bk_rsi_threshold (default 35.0, 20–55) |
donchian_breakout |
Donchian Channel Breakout | Breakout above the N-period high/low (Turtle-style trend following). | dc_period (default 20, 10–100) |
elliott_wave_w3 |
Elliott Wave 3 Entry ⛔ sweep:False | Entry into the presumed Elliott wave 3 after a wave 1/2 structure. | fib_max (default 0.786, 0.3–1.0), fib_min (default 0.382, 0.1–0.7), min_w1_pct (default 0.02, 0.005–0.15), max_w2_bars (default 50, 5–300), zz_threshold (default 0.03, 0.01–0.15) |
ema_crossover |
EMA Crossover | Schnelle EMA kreuzt langsame — klassischer Trendfolge-Einstieg. | ema_fast (default 9, 2–50), ema_slow (default 21, 5–200) |
fibdiv |
FibDiv Fibonacci Retracement (Pifagor) | Fibonacci retracement zone + divergence confirmation (Pifagor rebuild). | fibdiv_max_bars (default 30, 5–100), fibdiv_threshold (default 0.03, 0.01–0.1), fibdiv_stop_level (default 0.8, 0.7–0.95), fibdiv_entry_level (default 0.618, 0.5–0.75), fibdiv_min_impulse (default 0.02, 0.005–0.1) |
funding_rate_extreme |
Funding Rate Extreme (Contrarian) | Contrarian: extremes Perp-Funding wird gefadet. | funding_long_threshold (default -1e-05, -0.001–-1e-06), funding_short_threshold (default 5e-05, 1e-05–0.0005) |
holy_grail_pullback |
Holy Grail EMA20 Pullback | Raschke Holy Grail: Pullback an die EMA20 im starken ADX-Trend. | lookback (default 5, 2–20), adx_threshold (default 30.0, 10–60) |
macd_crossover |
MACD Zero-Line Crossover ⛔ sweep:False | MACD crosses the zero line — trend-momentum entry. | ema_fast (default 9, 2–50), ema_slow (default 21, 5–200) |
micro_pullback |
Micro Pullback (Ross Cameron) | Impuls (Squeeze) -> flacher Pullback -> Einstieg auf der ersten Candle mit neuem Hoch. Momentum-Continuation, long. | min_impulse_pct (default 0.004, 0.001–0.02), impulse_lookback (default 10, 5–30), pullback_min_pct (default 0.001, 0.0–0.01) |
outside_inside_day |
Outside-Inside Breakout (Raschke) | Raschke 3-bar pattern: inside day after outside day, breakout entry. | — |
regime_switch |
Regime-Switch (SFP im Trend / BB-Extreme im Range) | Regime-adaptiv: SFP-Entries im Trend, BB-Extreme in der Range (ADX/DMI als Schalter). | bb_std (default 2.0, 1.5–3.0), bb_period (default 20, 10–50), adx_period (default 14, 2–40), sfp_lookback (default 20, 5–100), regime_range_enter (default 20.0, 10–30), regime_trend_enter (default 25.0, 18–40) |
rsi_mean_reversion |
RSI Mean Reversion (Sideways) | RSI extreme in sideways phases: buy oversold, short overbought. | rsi_oversold (default 30.0, 10–45), rsi_overbought (default 70.0, 55–90), rsi_min_bars_in_extreme (default 1, 1–5) |
sfp |
Swing Failure Pattern (Hsaka) | Swing failure pattern (Hsaka): a failed breakout above the swing high/low is faded. | sfp_lookback (default 20, 5–100) |
zscore_dislocation |
Z-Score Dislocation (Mean Reversion) | Fades a statistically abnormal price spike (>N σ) — mean reversion on a dislocation. | zscore_period (default 20, 10–100), zscore_threshold (default 2.0, 1.5–4.0) |
zscore_momentum |
Z-Score Momentum (Continuation) | Goes WITH a statistically abnormal spike (>N σ) — continuation instead of mean reversion. | zscore_period (default 20, 10–100), zscore_threshold (default 2.0, 1.5–4.0) |
Pillar ②: Filters (any number — veto only)
| Baustein | Bezeichnung | Beschreibung | Parameter |
|---|---|---|---|
adx_filter |
ADX Trend Strength | Minimum ADX — trade only when a trend is present. | min_adx (default 0.0, 0–60), adx_period (default 14, 2–40) |
adx_rising_filter |
ADX Rising (Raschke) | ADX slope must be positive — the trend is gaining strength (Raschke). | adx_period (default 14, 2–40), min_adx_slope (default 0.0, 0–5) |
atr_pct_filter |
ATR% Volatility Filter | ATR as % of price must be within the allowed volatility band. | min_atr_pct (default 0.0, 0–5) |
big_guy_filter |
Big Guy Whale Volume (Pifagor) | Requires a whale volume spike in the trade direction (Pifagor Big Guy). | big_guy_vol_mult (default 2.5, 1.5–5.0) |
bocpd_filter |
BOCPD Fresh-Change-Point Filter | Bayesian Online Changepoint Detection — trade only shortly after a fresh structural break. | bocpd_max_p_short (default 0.3, 0.1–0.95) |
choppiness_filter |
Choppiness Index (Trend vs Range) | Choppiness Index — vetot Entries in zerhacktem Markt. | chop_period (default 14, 5–60), max_choppiness (default 100.0, 30–100), min_choppiness (default 0.0, 0–70) |
cooldown |
Post-Trade Cooldown | Locks out re-entries for N candles after a stop-out. | cooldown_candles (default 0, 0–20) |
cvd_align_filter |
CVD/OFI Direction-Alignment Filter | Cumulative Volume Delta / order flow must confirm the trade direction. | ofi_min_for_long (default 0.0, 0.0–0.5) |
cvd_divergence_filter |
CVD Divergence Filter | Vetoes entries on divergence between CVD and price. | divergence_threshold (default 0.0, -0.3–0.3) |
efficiency_filter |
Efficiency Ratio (Trend Quality) | Kaufman efficiency ratio as a trend-quality gate (ensemble partner to the ADX). | er_period (default 20, 5–60), min_efficiency (default 0.0, 0.0–0.8) |
ema200_filter |
EMA 200 Trend Filter | Allows trades only in the direction of the EMA200. | ema200_filter (default False) |
ew_w3_filter |
Elliott Wave W3 Structure Filter | Elliott-Welle-3-Struktur als Kontext-Veto. | ew_fib_max (default 0.786, 0.3–1.0), ew_fib_min (default 0.5, 0.1–0.7), ew_min_w1_pct (default 0.02, 0.005–0.15), ew_max_w2_bars (default 25, 5–200), ew_zz_threshold (default 0.05, 0.01–0.15) |
funding_rate_filter |
Funding Rate Contrarian Filter | Vetoes entries on unfavorable perp funding (contrarian band). | max_funding_for_long (default 0.001, 0.0001–0.01), min_funding_for_short (default -0.001, -0.01–-0.0001) |
hurst_regime_filter |
Hurst Regime Filter (Trending Only) | Hurst-Exponent muss ein Trending-Regime anzeigen (Persistenz). | hurst_lag (default 10, 2–30), hurst_min (default 0.55, 0.45–0.7), hurst_window (default 100, 50–300) |
lmacd_pink_filter |
LMACD Pink/Orange Signal (Pifagor) | LMACD-Signalfarbe (Pink/Orange) als Momentum-Gate (Pifagor). | lmacd_lookback (default 1, 1–5) |
mfi_pifagor_filter |
MFI Pifagor Filter | Money Flow Index per Pifagor rules. | mfi_long_threshold (default -9.0, -50–0), mfi_short_threshold (default 9.0, 0–50) |
money_waterfall_filter |
Money Waterfall Capital Flow (Pifagor) | Capital-flow filter: long only in the contrarian buy zone of the waterfall (Pifagor). | mw_long_max (default 0.0, -0.5–0.5), mw_short_min (default 0.0, -0.5–0.5) |
obv_organic_filter |
OBV Organic Movement Filter (Pifagor Histogram) | Blocks entries when OBV momentum diverges from price (Pifagor). | — |
range_filter |
Range Market Filter (max ADX) | Maximum ADX — trade only in sideways phases (counterpart to the ADX filter). | max_adx (default 25.0, 15–50), adx_period (default 14, 2–40) |
regime_ensemble_filter |
Regime-Ensemble (ADX+ER+CHOP Mehrheitsvotum) | Majority vote from ADX, efficiency ratio and choppiness on trend vs. range. | ens_er (default 0.3, 0.1–0.6), ens_adx (default 22.0, 15–35), ens_chop (default 55.0, 35–65), ens_range_votes (default 0, 0–3), ens_trend_votes (default 0, 0–3) |
rsi_filter |
RSI Momentum Filter | Vetoes entries when the RSI is outside the allowed band. | rsi_long_max (default None, 0–100), rsi_short_min (default None, 0–100) |
session_filter |
Trading Session (UTC hours) | Trades only within defined UTC hour windows. | session_hour_end (default 24, 1–24), session_hour_start (default 0, 0–23) |
volume_filter |
Volume vs Rolling Average | Volume must be above the rolling average. | volume_lookback (default 20, 5–100), min_volume_ratio (default 1.0, 0.1–5) |
vrp_filter |
VRP Min-Percentile Filter (DVOL/RV) | Volatility risk premium (DVOL vs. realized vol) must be above the minimum percentile. | vrp_min_percentile (default 0.2, 0.0–0.8) |
Rule of thumb: the filter must fit the entry. A trend filter (adx_filter) belongs with a trend entry; a range_filter (max ADX) belongs with mean-reversion entries like bb_extreme. Example from the code: the bocpd_filter helps bb_extreme (+17%) but hurts Donchian (−15%).
Pillar ③: Position Sizing
| Baustein | Bezeichnung | Beschreibung | Parameter |
|---|---|---|---|
equity_throttle |
Equity-Curve Throttle (Turtle) | Drawdown brake per Turtle rule: reduce trade size by cut% per dd_step of drawdown from the equity high; normalizes with the recovery — pushes risk of ruin toward zero. | throttle_cut (default 0.2, 0.1–0.5), throttle_dd_step (default 0.1, 0.05–0.25) |
risk_sizing |
Risk-Based Sizing | Position size = account × risk% ÷ stop distance — constant equity loss per stop-out. | risk_pct (default 1.0, 0.1–5.0) |
| Baustein | Bezeichnung | Beschreibung | Parameter |
|---|---|---|---|
pyramid_entry |
Turtle Pyramiding (price-based adds) | Scales up winning positions: one more unit per +step×ATR above the last fill, until max_units is reached; the stop trails with every add. Anti-martingale — never into the losing direction. | pyramid_step_atr (default 0.5, 0.25–2.0), pyramid_max_units (default 3, 2–5), pyramid_stop_mult (default 1.0, 0.5–4.0), pyramid_regime_gate (default 0, 0–1) |
staggered_entry |
Staggered Entry ⛔ sweep:False | ⚰️ Buried (2026-06-11): pure timing smoothing with no return evidence — the EV-relevant variant is pyramid_entry. Entry in N equal tranches across consecutive candles (Pifagor: 5). | entry_parts (default 3, 2–5) |
Plus the global caps from execution/config.py — live values:
| Parameter | Live value |
|---|---|
POSITION_SIZE_PCT |
1.0 |
| Position cap | 100% der Equity (MAX_POSITION_PCT = 1.0, MAX_POSITION_USD = 12.0) |
LEVERAGE |
3x |
| Vol-target sizing | advisory mode (off) |
| Equity throttle (Turtle brake) | active: −30% size per −10% drawdown from the equity high |
According to Botty's ML findings, volatility-based sizing is the most robust edge of all — the vol regime is predictable, the direction is not.
Pillar ④: Exits (any number)
| Baustein | Bezeichnung | Beschreibung | Parameter |
|---|---|---|---|
atr_profit_target |
ATR Profit Target | Profit target as an ATR multiple — makes the R:R explicit. | atr_target_mult (default 2.0, 0.5–5.0) |
atr_trailing_stop |
ATR Trailing Stop | Initial-Stop + nachgezogener Stop, beide als ATR-Multiple. | atr_stop_mult (default 1.5, 0.1–10), atr_trail_mult (default 2.0, 0.1–10) |
bailout_exit |
Bailout Exit (Williams) | Williams' Bailout: Ausstieg am ersten profitablen Open. | bailout_min_bars (default 1, 1–20) |
ema_cross_exit |
EMA Crossover Exit (signal-based) | Exit on the opposite crossover of the EMAs. | exit_ema_fast (default 9, 2–50), exit_ema_slow (default 21, 5–200) |
fixed_stop |
Fixed % Stop | Fixed stop as % of the entry price. | fixed_stop_pct (default 1.0, 0.1–10) |
macd_cross_exit |
MACD Zero-Line Exit (signal-based) | Exit when the MACD crosses back over the zero line. | — |
partial_tp |
Partial TP (3-stage) | Three-stage partial exits at % targets, the remainder rides on the trailing stop. | tp1_pct (default 1.8, 0.5–20.0), tp2_pct (default 2.7, 0.5–20.0), tp3_pct (default 6.1, 0.5–30.0), tp1_size (default 0.33, 0.1–0.9), tp2_size (default 0.33, 0.1–0.9), tp3_size (default 0.34, 0.1–1.0) |
profit_target |
Swing High/Low Target | Profit target at the opposite swing high/low. | target_lookback (default 20, 5–50) |
swing_stop |
Swing Stop (Touching Candle) | Stop am letzten Swing-Tief/-Hoch (Touching Candle). | — |
time_stop |
Time Stop | Exit after N candles, regardless of price. | time_stop_bars (default 3, 1–20) |
Which entry for which regime?
This is the key that holds the mental model together: trend entries and mean-reversion entries serve opposite regimes. A Donchian breakout wants a trend; BB Extreme wants a range. Confuse the two and you trade against yourself.
| Entry | Trend ↑ | Trend ↓ | Range | Reversal | Maturity | Note / open question |
|---|---|---|---|---|---|---|
donchian_breakout |
✅ | ✅ | ❌ | ❌ | 🟢 | live (DONCHIAN_20, wallet 1); stop-robustness sweep winner |
ema_crossover |
✅ | ✅ | ❌ | ❌ | 🟡 | in the sweep pool; whipsaw-prone, not a live winner |
adx_dmi_regime |
✅ | ✅ | ❌ | ➖ | ⚪ | new — no completed sweep yet |
holy_grail_pullback |
✅ | ✅ | ❌ | ➖ | 🟡 | tested, no live use (yet) |
macd_crossover |
➖ | ➖ | ❌ | ❌ | 🔴 | sweep:False — negative in 10/11 WF windows |
elliott_wave_w3 |
➖ | ➖ | ❌ | ➖ | 🔴 | sweep:False — worst performer |
fibdiv |
✅ | ✅ | ➖ | ➖ | ⚪ | Pifagor replica, not conclusively validated |
sfp |
➖ | ➖ | ✅ | ✅ | 🟡 | in the pool, verdict open |
bb_extreme |
❌ | ❌ | ✅ | ✅ | 🟢 | live (BB_EXTREME_1/2); 7/9 OOS windows, the most thoroughly tested |
rsi_mean_reversion |
❌ | ❌ | ✅ | ➖ | 🟡 | own sweep run, verdict open |
burj_khalifa |
❌ | ❌ | ➖ | ✅ | ⚪ | Pifagor replica, open |
funding_rate_extreme |
❌ | ❌ | ➖ | ✅ | ⚪ | open |
Regime suitability: ✅ fits well · ➖ neutral / conditional · ❌ unsuitable
Maturity: 🟢 validated (live-ready) · 🟡 under review · ⚪ untested · 🔴 discarded. What the levels mean and which metrics (mega-sweep score, walk-forward, PBO, Monte Carlo …) decide them is explained under Live readiness: when is a backtest live-ready?. The maturity column is a living field and is continuously extended.
The pattern is clear: trend entries (top) and mean-reversion/reversal entries (bottom) serve opposite regimes — the green cells form a diagonal, and the opposite corner is red in each case. Botty detects the regimes themselves via the ADX/DMI filter (see /regime); what other methods exist for this is described in the research entry Detecting & predicting market regimes.
To look up yourself
- Building blocks + defaults/ranges:
strategies/conditions/registry.py - Chaining:
strategies/conditions/resolver.py(resolve_signal) - Combinatorial search:
backtesting/megasweep.py - Regime classifier:
indicators/regime.py→ UI/regime