From Signal to Trade: The Full Decision Pipeline
Put it all together: see how a complete algorithm moves from raw market data to a placed order, combining screening, scoring, timing, and options selection.
From Signal to Trade: The Full Decision Pipeline
The previous four lessons covered each component in isolation. Now we wire them together into a single, end-to-end pipeline — the actual engine that runs inside a production algorithm. Understanding the full flow is what separates a trader who uses indicators from one who thinks systematically.
The Four Gates
Every potential trade must pass four sequential gates. A rejection at any gate ends the evaluation — the algorithm moves on to the next candidate.
- Gate 1 — Universe Filter: Does this stock meet liquidity, quality, and technical conditions? (Lesson 1)
- Gate 2 — Score & Rank: Is this stock in the top N by composite factor score? (Lesson 2)
- Gate 3 — Entry Signal: Has the specific trigger fired today? (Lesson 3)
- Gate 4 — Position Sizing: Is there enough portfolio capacity and margin to take this trade? (Lesson 4 risk principles)
A Complete Example: Equity + Options Pipeline
def run_daily_pipeline(universe, portfolio):
candidates = []
# ── GATE 1: Screen ───────────────────────────────────────
for ticker in universe:
if not passes_liquidity_filter(ticker): continue
if not passes_fundamental_filter(ticker): continue
if not passes_technical_screen(ticker): continue
candidates.append(ticker)
# ── GATE 2: Score & Rank ─────────────────────────────────
scores = {}
for ticker in candidates:
z_mom = z_score_momentum(ticker)
z_qual = z_score_quality(ticker)
z_value = z_score_value(ticker)
scores[ticker] = 0.5*z_mom + 0.3*z_qual + 0.2*z_value
top_picks = sorted(scores, key=scores.get, reverse=True)[:10]
# ── GATE 3: Entry Signal ──────────────────────────────────
signals = []
for ticker in top_picks:
if not entry_signal_fired(ticker):
continue
# Decide: equity or options?
ivr = get_iv_rank(ticker)
if ivr > 50:
# High IV → sell premium (cash-secured put)
contract = select_strike(get_chain(ticker,'put'), 0.20)
expiry = select_expiry(ticker, target_dte=45)
signals.append({'ticker': ticker, 'type': 'sell_put',
'contract': contract, 'expiry': expiry})
else:
# Low IV → buy directional call
contract = select_strike(get_chain(ticker,'call'), 0.40)
expiry = select_expiry(ticker, target_dte=60)
signals.append({'ticker': ticker, 'type': 'buy_call',
'contract': contract, 'expiry': expiry})
# ── GATE 4: Position Sizing & Capacity Check ─────────────
orders = []
for signal in signals:
size = calculate_position_size(signal, portfolio, risk_pct=0.01)
if portfolio.has_capacity(size):
orders.append({'signal': signal, 'size': size})
return ordersRunning on a Schedule
The pipeline above does not run constantly — it runs on a defined schedule. Fundamental data changes weekly or quarterly; technical signals change daily. Most equity strategies run the full pipeline once per day after market close, generate a list of orders, and execute them at the next market open.
| Component | Run Frequency | Why |
|---|---|---|
| Liquidity & price filters | Daily | Volume and price change every session |
| Fundamental filters | Weekly or on earnings | Quarterly reports drive factor values |
| Factor scoring & ranking | Daily or weekly | Scores shift as price and estimates move |
| Entry signal check | Daily (after close) | Technical triggers are daily events |
| Options contract selection | At signal time | Chain changes continuously — pull fresh |
| Position sizing | At order generation | Depends on current portfolio state |
Do Not Over-Optimize the Pipeline
It is tempting to add more gates, more factors, and more filters until the backtest looks perfect. Every gate you add fits the past data better and generalises to the future worse. Start with 3–4 factors and 2–3 entry conditions. Complexity is the enemy of robustness.
Monitoring a Live Pipeline
Once deployed, the pipeline needs monitoring. Track three things daily: (1) how many candidates pass each gate — a sudden drop signals a market regime change; (2) whether live P&L matches backtest expectations within a reasonable range; (3) whether any individual position is approaching the stop or max-loss level defined at entry.
You Now Have the Full Picture
Screening narrows the universe. Scoring ranks the survivors. Entry timing picks the moment. Options selection picks the contract. Position sizing controls the risk. These five steps are the complete decision engine behind every algorithmic trade on this platform — and in professional quant shops worldwide.
- Every trade passes through four gates: universe filter → score → entry signal → position size
- Each gate can reject a trade — only the best setups reach execution
- Position sizing is the last step, not an afterthought
- The pipeline runs on a schedule — daily or weekly — not on impulse