A Signal Is Not a Decision
Suneet Malhotra
Sep 03, 2026
A trading system can produce a valid signal and still make the correct decision by doing nothing.
That sounds obvious until the data model is inspected. Many systems record the signal, record the orders that were sent, and record the fills that arrived. The space between those records is where the strategy actually exercises judgment.
The signal is an observation about market conditions. The decision is a state transition made under constraints. Treating them as the same object makes every refusal look like a missing trade and every trade look like an inevitable consequence of the indicator.
The indicator does not know the portfolio
An indicator can say that its conditions are true. A moving-average relationship can hold. Volatility can be inside the strategy's accepted range. A regime classifier can label the session. None of those facts knows the current position, the remaining risk budget, the time until the session ends, or whether an earlier order is still unresolved.
The portfolio does.
The decision layer has to combine the new signal with state that the signal generator should not own. Is the instrument already held? Is the proposed exposure larger than the risk limit? Is the market open for this instrument? Has the same intent already been submitted? Did a previous order time out without a confirmed terminal state?
Those questions can turn the same signal into an entry, a resize, a no-op, a queued action, or a refusal. The signal did not change. The decision context did.
A missing trade is not necessarily a failure
Suppose a strategy emits ten signals and sends six orders. A report that counts only the six orders cannot distinguish the reasons for the other four. They may have been blocked by a position limit, deduplicated because the intent was already active, rejected because the market window was closed, or lost between the signal process and the order adapter.
The total is the same. The system meaning is not.
This is the same measurement problem that appears in a backtest with unrealistic fills. If the dataset contains only completed trades, it cannot explain whether the strategy had no opportunity, declined the opportunity, or failed to persist the opportunity. More analysis of the completed rows will not recover the missing branch.
The refusal needs a first-class record. I want an intent identifier, signal timestamp, decision timestamp, relevant position and risk state, selected action, refusal code when applicable, and the policy version that governed the outcome. A string such as "skipped" is not enough. It preserves the absence of an order while discarding the reason.
Decision state should be explicit
The useful state machine is small:
- Signal observed.
- Intent constructed.
- Decision evaluated.
- Action authorized or refused.
- Order submitted, if authorized.
- Broker state reconciled.
- Intent closed with a terminal reason.
The point is not to create ceremony around every indicator. It is to prevent a downstream status from rewriting the history of an upstream decision.
An order that was never authorized should not be labeled unfilled. An order that was authorized but never submitted should not be labeled rejected by the venue. An order submitted before a network timeout should not be treated as absent until reconciliation proves it absent.
These distinctions matter during review. A high refusal rate may indicate a useful risk boundary, a stale calendar, an overly restrictive position limit, or a broken adapter. Without the reason code, all four collapse into the same empty space in the trade log.
The signal table is not the audit trail
I used to think a signal table was enough because it gave the system a durable memory of what the strategy saw. It is only a memory of one layer. The table can answer, "What conditions were true?" It cannot answer, "What did the system decide, and why?"
That second question requires snapshots of the inputs that can change between detection and action. Position quantity, buying power, open intents, session state, risk limits, and adapter health are not commentary. They are decision inputs.
There is also a useful separation between reason and outcome. A decision can be correct even when its desired market outcome never occurs. A refusal because the risk budget was exhausted is still a valid decision. A submission that later fails at the venue is a different event. Mixing these makes the system look more active than it was and makes the risk controls impossible to evaluate.
What I would test
I would replay the same signal against several controlled states: flat portfolio, existing position, exhausted risk budget, closed session, duplicate active intent, and uncertain prior order status. The expected result is not one trade. The expected result is a set of explicit decisions.
The test should assert that every branch writes a terminal reason, that duplicate intents do not create duplicate side effects, and that an uncertain transport result triggers reconciliation before another submission. It should also assert that changing a policy version changes the recorded reason, not just the final order count.
The practical rule is simple: do not evaluate a strategy from signals and fills alone. The strategy lives in the decisions between them.
A signal tells me what the market offered the system. A decision record tells me what the system was permitted to do with that information. If the second record is missing, the trade history is not merely incomplete. It is unable to explain the strategy it claims to measure.
Share this post
You Might Also Like
The Quote Is Not the Fill
A backtest can use the right price and still model the wrong trade. The missing variable is often not slippage. It is the time between seeing a quote and joining the book.
Quantitative TradingA Retry Is Not a Trading Decision
A rejected order is a decision. Retrying it without preserving the reason can turn a risk control into a duplicate trade.
Agentic AIThe Plan Is Not the Permission
An AI agent can produce a correct plan and still be unsafe to run. The plan describes an action; it does not authorize the write boundary that makes the action real.
AI & AutomationReplay the Decision, Not the Answer
Agent tests that compare only final answers miss the failure that matters: the same input can produce a different tool choice, path, or refusal before the answer changes.
Latest Blog Posts
The Plan Is Not the Permission
An AI agent can produce a correct plan and still be unsafe to run. The plan describes an action; it does not authorize the write boundary that makes the action real.
The Quote Is Not the Fill
A backtest can use the right price and still model the wrong trade. The missing variable is often not slippage. It is the time between seeing a quote and joining the book.
Replay the Decision, Not the Answer
Agent tests that compare only final answers miss the failure that matters: the same input can produce a different tool choice, path, or refusal before the answer changes.
Related Tools & Demos
The QA Field Manual to Language Models
A free 24-chapter book. Start at βwhat is AI, really?β and finish with a small language model you built yourself β one that reads a failing Playwright test and proposes a fix you can run. Read it in your browser, or download the PDF or the Mac app.
View Source Code βMulti-Model LLM Harness
One interface to call any AI model β capability routing, fallback chains, budgets, circuit breakers, and a quality feedback loop. A practical architecture pattern write-up.
Automated Trading System
Multi-engine trading platform with real-time risk management, regime-based strategy selection, and automated order execution.
View Source Code β
Stay in the Loop
Get weekly insights on AI-driven QA, engineering leadership, and automation strategies.
No spam, ever. Unsubscribe anytime.