Signal Engine Rules
Last updated: April 23, 2026
SignalFloor records signal outcomes using a deterministic lifecycle engine. Every pending activation, stop-loss hit, take-profit hit, and expiry follows the same rules for every provider — there is no manual override, no discretionary re-labeling, and no retroactive edits after a candle closes. This page documents the rules providers need to understand before publishing signals to followers.
The engine evaluates one OHLC candle at a time from the market-data feed. It does not reconstruct tick-by-tick path inside a bar. When a wide candle could have hit both protective and profit levels, we apply an explicit conflict policy rather than guessing which level printed first.
Same-candle stop-loss vs take-profit conflicts
When a single OHLC candle touches both the stop-loss and a take-profit level, the engine closes the signal as a stop-loss. This conservative rule avoids overstating win rate on volatile candles where the path inside the bar is unknown.
The engine stores this outcome as SL_priority_same_candle. Followers see the signal closed at the stop-loss price; win rate and profit-factor stats reflect the loss, not a take-profit win.
Long (buy) example
Entry at 100, stop-loss at 90, take-profit at 120. A single candle prints a high of 125 and a low of 85 — both levels are touched. The engine closes the signal at the stop-loss (90) with conflict flag set. Without this rule, a provider could show an inflated win rate whenever a volatile candle spans both sides of the trade.
Short (sell) example
Entry at 100, stop-loss at 110, take-profit at 80. A candle prints a high of 115 and a low of 75. Both stop-loss and take-profit are inside the range, so the engine again records a stop-loss at 110 under SL_priority_same_candle.
Why conservative? Intra-candle sequencing is unknowable from OHLC alone. Choosing stop-loss priority understates performance rather than overstating it, keeps leaderboard math honest, and aligns with how risk-conscious followers expect protective levels to behave when liquidity sweeps both sides of a range.
Unguarded signals (no stop-loss)
Providers may publish signals without a stop-loss. These are labeled Unguarded on every card and detail view. The engine will not auto-close them at a protective level — only take-profit hits, manual provider close, or expiry apply. Followers must acknowledge the disclosure before viewing unguarded signal details.
Take-profit levels
Signals may define up to three take-profit targets (TP1, TP2, TP3). On each candle the engine checks from the farthest target inward (TP3, then TP2, then TP1). The first level whose price is touched by the candle high (longs) or low (shorts) closes the signal at that target. Partial scaling is not modeled — the engine records one terminal outcome per signal.
Pending activation & order types
Limit, stop, and stop-limit orders activate when the candle range crosses the entry (and stop price, when applicable). Market orders activate on the first valid candle after publish subject to entry guards: if price has already moved more than 15% away from entry within five minutes of the signal anchor, the engine marks the entry invalid rather than filling at an unrelated price. See provider tier formula for how closed outcomes feed tier assignment.
Stale & expired pending signals
Pending signals that never activate are marked stale after four bar periods of their declared timeframe, then auto-expired after six bar periods. Stale signals remain visible with a warning badge; expired signals close with result expired and do not count as wins or losses in provider stats.
Changes to these rules
Lifecycle logic lives in the shared signal engine module mirrored between the marketing app and Supabase edge functions. Any change to conflict resolution or activation thresholds requires a versioned deploy and will be announced on the blog before it affects live signals. The conflict mode identifier above is the contract providers can grep in their signal audit logs.