A signal firing does not mean an order has been placed. The entry strategy decides two things after a signal:
- Filters run in order and can block or delay the signal (require a confirmation bar, gate by ADX, sit out around CPI, cool down after the prior trade, …).
- The executor decides how the order is placed once the signal survives every filter — a single aggressive limit, a passive rest at the signal price, an ATR-scaled pullback, a scale-in ladder, TWAP, or a modifier that wraps another executor.
Both pieces are optional. A strategy with no filters and no configured executor fires every signal through the default Aggressive Limit executor — the byte-for-byte pre-plugin behavior.
Filters#
Filters are pure transforms over the signal data. Each one either passes the signal through, blocks it, or shifts it forward by a bar. They run in the order you list them — a filter later in the chain never sees a signal an earlier filter dropped.
| Category | Filter | When to use |
|---|---|---|
| Confirmation | Wait for Close Confirmation | Require the confirmation bar's close to agree with the signal direction — filters false triggers at one bar of lag. |
| Confirmation | Two-Bar Reversal | Only fire after one adverse bar + one reclaim. Catches trends with a pullback; drops trends that extend immediately. |
| Confirmation | Volume Confirmation | Require the signal bar's volume to exceed a multiple of the rolling mean. Thin-volume signals are more often fakeouts. |
| Momentum | Momentum Alignment | Require an indicator column (RSI, MACD histogram, custom) to agree with the signal direction. |
| Momentum | ADX Gate | Only fire when ADX is above (or below) a threshold — the classic trend-strength gate. |
| Volatility | ATR Band Gate | Only fire when ATR/price sits inside a min/max band. Skips dead markets and blow-off spikes. |
| Volatility | Squeeze Release | Only fire within N bars of a volatility-squeeze release. |
| Schedule | Session Gate | Restrict entries to a UTC time-of-day window on selected weekdays. |
| Schedule | Macro Event Blackout | Suppress entries around scheduled macro events (CPI, FOMC, NFP, ...). |
| Timing | Next Bar Open Entry | Shift every signal forward by one bar — the "don't cheat" backtest convention. |
| Timing | Cooldown | Suppress entries for N bars after the prior signal fires — reduces overtrading in choppy regimes. |
Every filter that references an indicator (ATR band, ADX, squeeze, macro event, momentum) needs that indicator attached to the strategy so the referenced column exists on the DataFrame. A missing column is treated as "no signal to filter" and the filter becomes a no-op — the strategy keeps trading, just without the intended gate. That's usually a symptom, not the goal.
Executor#
The executor decides how the entry order is placed once the signal survives every filter.
| Category | Executor | Behaviour |
|---|---|---|
| Flat | Aggressive Limit (default) | Walks a LIMIT from 0.5% slippage up to 2% until it fills. Near-immediate fill in liquid markets. |
| Flat | Passive Limit | Rests at the signal-bar price for N bars — no chase, no spread paid. |
| Flat | ATR Pullback Limit | Rests atr_multiplier × ATR below (long) or above (short) the signal. Requires an ATR indicator. |
| Flat | Prior Bar Extreme Limit | Rests at the signal bar's own low (long) or high (short). Wick-back retest entry. |
| Flat | Structural Level Limit | Rests at a named indicator level — pivot, support/resistance, Donchian band, POC. |
| Flat | Value Area Reversion | Rests at VolumeProfile POC/VAL/VAH. Requires a VolumeProfile indicator. |
| Multi-fill | Price Ladder | Scale in with several LIMIT orders at progressively deeper offsets from the signal. |
| Multi-fill | TWAP | Time-weighted equal slices, one per bar-interval. Reduces market impact on larger orders. |
| Modifier | Two-Phase Probe | Aggressive probe slice + follower handles the rest. Hedges "we missed the entry" against "we chased the top". |
| Modifier | Adverse Move Abort | Wraps another executor with a "don't chase" cutoff: cancels every pending order if price moves against fill by abort_pct. |
Modifier executors wrap another executor — you pick the inner behavior (passive / pullback / ladder / etc.) and the modifier layers its own rule on top. Modifiers cannot wrap other modifiers; nesting is capped at one level so the mental model stays "wrapper + inner".
The Aggressive Limit default is right for most signals in liquid markets — a small spread is a cheap price for a near-immediate fill. Reach for a passive or pullback variant when you're trading a signal that reliably retraces (a volatility squeeze, a value-area reversion, a trend pullback) — you'll pay less per fill when you fill, at the cost of missing a fraction of signals.
Fail-open by design#
If an executor or filter references an indicator that isn't attached to
the strategy, the runtime falls back to a safe default (a passive limit
at the signal price for the executor; a no-op for the filter) rather
than crashing the trade. The Build rail surfaces missing dependencies
in the picker with a [needs …] chip so you catch them before saving
the config.