Back to the blog

Engineering blog / March 15, 2026

Decision Engine Architecture: From Market Tick to Ranked Recommendation

A technical overview of a ranked decision pipeline, how raw market data becomes a ranked list of recommendations, how three parallel strategies evaluate each symbol, how a scoring function turns signal inputs into a single comparable number, and how a truth-first learning loop keeps those scores grounded in real outcomes over time.

This is a .NET 10 equity and options analysis engine. It has no execution code, it does not place trades. Every recommendation it produces is traced to specific market data, computed by a deterministic scoring function, and validated against historical outcomes before influencing future rankings.

This article describes how data enters the system, how decisions emerge from that data, and what structural constraints prevent those decisions from degrading silently over time.

Pipeline overview

The decision cycle runs on a one-second cadence. On each bar boundary, the system completes the following sequence for every configured symbol:

  1. Align and persist the current 1-second bar from accumulated ticks
  2. Compute a feature snapshot incrementally from that bar
  3. Classify the current market regime
  4. Evaluate all configured strategies against the snapshot
  5. Score each candidate via the EdgeScore function
  6. Aggregate candidates by ticker into a consolidated view
  7. Publish ranked results to the UI

A separate background scheduler computes outcomes for completed acceptances and feeds them into the learning loop. The live pipeline is latency-sensitive; the learning pipeline is not. They share a database but run independently.

Data ingestion and bar alignment

The system connects to a market data provider via REST and streaming APIs and receives a stream of price and size ticks. Each tick carries a timestamp from a configurable source, exchange trade time, quote time, or local receipt time, and that provenance is preserved through the bar layer so downstream components know which clock was authoritative.

Ticks are accumulated into one-second OHLCV bars using epoch-based boundary arithmetic, so bar alignment is identical across any rerun given the same ticks. Strategy evaluation runs only during regular trading hours (09:30–16:00 US Eastern). Extended-hours bars are ingested and stored if configured, but they are excluded from strategy evaluation by a structural check, not a runtime flag.

For options, a background process prefetches chain snapshots at a regular cadence during market hours. Each chain includes per-contract bid, ask, implied volatility, volume, and open interest.

Feature computation

After each bar closes, the system updates a feature snapshot for the symbol. All indicators are computed incrementally, each requires only the current bar plus a small running state, not a buffer of raw bars. The set of indicators maintained per symbol includes: short and long exponential moving averages (and their spread as a momentum signal), MACD and signal line, RSI, ATR, intraday VWAP, a volume moving average, and an intrabar price range in basis points. All session-scoped indicators reset at the US Eastern day boundary.

Regime classification

Before a symbol is evaluated by any strategy, the system classifies its current market regime. The output is a continuous match score per regime type, not a hard category, a symbol can have nonzero scores for multiple regimes at once. Five regimes are defined:

  • Trend: strong directional momentum with low choppiness
  • MeanRevert: RSI at an extreme with low realized volatility, conditions that favor a short-lived move and reversal
  • HighVol: elevated realized volatility
  • LowVol: subdued realized volatility
  • EventRisk: concurrent volatility spike and RSI extreme, acts as a suppressor on other strategies

The regime score feeds into the EdgeScore formula and determines which calibration model applies to the candidate.

Strategy evaluation

Three strategies run in parallel on every bar. Each targets a different time horizon and market condition.

Scalp strategy (~5 minutes). Designed for the MeanRevert regime. Triggers when a volume burst, an RSI extreme, and a VWAP divergence all align at the same time. It has the tightest liquidity requirement of the three strategies, consistent with its short hold time and low tolerance for slippage.

Swing strategy (hours to days). Triggers on an EMA crossover, with RSI used as a confirming filter to avoid entering a trend just as it exhausts. Uses a trailing stop rather than a fixed target.

Options strategy. Evaluates single-leg and spread structures against the current options chain. Greeks are computed per leg via a deterministic pricer. Eligibility filtering (spread width, volume, open interest) runs before any pricing, so only viable contracts reach the scoring stage.

Any strategy that triggers produces a candidate with a direction, entry reference price, stop/target levels, and an explain record capturing the feature values that drove the trigger. Candidates that don't clear the liquidity gate are dropped before scoring.

The EdgeScore function

Every candidate that passes the liquidity gate is scored by the EdgeScorer. The result is a single value in (−1, 1): positive means expected positive edge, negative means the candidate is assessed as below the cost of the position.

The scoring function combines three components: an estimated win probability, an expected value estimate (expected return minus spread cost), and a tail risk penalty (a volatility-scaled downside estimate). These are combined into a composite score and normalized with a softsign function, chosen over tanh because softsign preserves ordinal separation at the top of the rank order rather than collapsing highly-scored candidates toward a ceiling.

Confidence is computed separately from the win probability. It measures the quality of the input signals, how clearly the regime is defined and how liquid the symbol is, not whether the trade is long or short. A high-confidence candidate is one where the inputs are clean; a low-confidence candidate may still have a directional signal, but the data backing it is noisy.

Ranking and aggregation

Candidates are ranked by EdgeScore, with Confidence as the tiebreaker. This sort key is used everywhere, live recommendations, walk-forward evaluation, and calibration, and is version-locked, since changing it would invalidate historical comparisons.

The top candidates are then aggregated per ticker: when multiple strategies fire on the same symbol, their signals are consolidated into a single belief state. A hysteresis state machine governs the direction field, requiring a signal to accumulate confirming evidence across multiple evaluation cycles before being committed, and requiring a sustained contrary signal to clear it. This prevents the displayed direction from oscillating on marginal signals.

Truth-first learning

The learning loop updates the system's operating state using historical outcomes. Its central constraint is that outcomes are classified by provenance before they're allowed to influence rankings. An outcome has full learning weight only if it came from a real market exit, not a simulation, and has both a confirmed entry and exit price. Simulated stock outcomes carry zero weight. Options simulated outcomes are partially admitted up to a proportional cap, to avoid cold-starting the options channel when real exits are sparse.

Truth coverage, the fraction of learning inputs that are real-market-confirmed, is a tracked metric displayed in the UI. When it's zero on a fresh deployment, a cold-start banner is shown. The system still surfaces recommendations, but operators are explicitly told the learning loop has no truth data yet.

Live outcomes (real acceptances) and paper outcomes (simulated positions) are weighted separately. The paper channel is capped relative to the live channel, so a deployment with lots of paper history but no real acceptances does not end up with its rankings driven by simulated data. Under-sampled strategy/regime pairs are flagged and excluded from calibration promotion until sufficient real outcomes accumulate.

The default learning scope covers accepted candidates only, explicitly selection-biased, since the distribution of accepted signals differs from all signals. This bias is acknowledged through a provenance flag rather than silently corrected. A broader scope is available, but it blocks promotion to active calibration until counterfactual labels on rejected candidates are provided.

Signal calibration

The EdgeScore function produces stable ordinal rankings, but the raw win probability it computes is not a calibrated probability, it's a function of signal inputs that approximates likelihood without being fit to real outcomes. Signal calibration maps these raw scores to empirically-grounded estimates using the backtest record.

Calibration is computed per strategy-horizon-regime segment. Win probability, expected return, and tail risk are each calibrated independently using monotone regression against historical outcomes, with shrinkage toward broader segments when a specific segment has sparse data.

Calibration runs in shadow mode by default: calibrated values are computed and stored alongside every candidate, but ranking still uses the raw score. Promotion to active mode, where calibrated scores drive ranking, is gated on measurable improvements across several quality metrics (score accuracy, return uplift in top-ranked candidates, tail risk stability). If input distributions shift significantly over a trailing window, calibration automatically reverts from active to shadow.

Walk-forward evaluation

Walk-forward evaluation checks whether the ranking pipeline performs consistently over time and gates deployment of updated baselines. It runs rolling train/evaluate windows over a historical date range, each window trains on earlier data and evaluates on the forward period it didn't see.

The evaluation is fully deterministic: it takes explicit date arguments and derives a run key from a hash of the spec, so the same spec always produces the same result and submitting it twice returns the cached result rather than rerunning. Gating metrics (precision, mean return, and win rate among the top-ranked candidates) are checked against defined tolerances; a regression beyond tolerance marks the run as failed. Promotion of a new baseline requires a separate explicit command referencing a version-controlled gate definition, a run cannot promote itself.

Outcome calculation

When a recommendation is accepted, the system records an entry reference price captured at acceptance time. A background scheduler later computes the backtest outcome using persisted bar history for the exit timestamp. Exit price for equities comes from the bar close; for options it prefers a live quote, falls back to the most recent chain snapshot, and falls back to simulation if neither is available. The exit source is tagged so downstream filtering can distinguish real-market exits from simulated ones.

Return calculations account for transaction costs explicitly, spread and per-contract fees are modeled on both entry and exit legs. If bar history is available across the hold period, the worst intermediate price (realized drawdown) is also recorded and used in tail risk calibration.

Recommendation-only guarantee

The engine has no execution code. The codebase contains no broker API clients for order submission, no subscriptions to execution feeds, and no code paths that construct or transmit order objects. Market data connections are scoped to read-only endpoints at the credential level.

This is not a configuration setting. It is an absence of implementation. Removing the recommendation-only constraint would require writing new code that does not exist in the repository.

Every decision the system makes is persisted with full context: the feature snapshot at decision time, the strategy that triggered, the score components, and the timestamp. The explain record attached to each candidate allows any historical recommendation to be reconstructed and audited without rerunning the pipeline.

This decision engine was built on the same engineering practices behind all our products. If you're evaluating a ranking-and-learning pipeline for your domain and want to talk about the architecture, reach out →

Decision Engine Signal Pipeline Feature Computation Walk-Forward Evaluation Isotonic Regression Truth-First Learning On-Prem AI Decision Pipelines

More from the blog