Islandflow Reference ยท Options Flow Pipeline

The Anatomy of an Options Print and Smart Money

This page explains how a single options print moves through Islandflow under normal market conditions, how the signal gate decides whether compute should care, how a parent flow packet is assembled, and how smart-money, classifier-hit, and alert events emerge from that packet. It is designed as one artifact with three reading depths: executive, mixed technical, and operator-level.

Legend

Color coding is semantic, not decorative, so you can scan the diagram without relearning the vocabulary.

Raw market or synthetic input Derived compute stage Stored or persisted state API, websocket, or user-facing surface

Main Flow Chart

The first row shows the common path every print touches. The second row shows the branch between prints that remain tape-only and prints that become packet candidates for smart-money evaluation.

Input
Stage 1 Option print candidate arrives

The source can be a native market adapter or the synthetic adapter. Synthetic mode can also emit a matching NBBO update.

Stage 2 ingest-options enriches the print

The service joins recent option NBBO and underlying equity quote context, derives metadata, and computes signal_pass.

Stage 3 Raw print is written and published
  • ClickHouse: option_prints
  • NATS: options.prints
Stage 4 Signal gate decides if compute should care

Only signal_pass=true prints are published to options.prints.signal and consumed by compute.

Stage 5 compute builds or updates a parent cluster

Nearby signal prints for the same contract are grouped inside the cluster window while NBBO and equity-quote caches supply context.

Stage 6 API and UI consume the resulting streams

The API hydrates hot snapshots, history endpoints read ClickHouse, and the terminal surfaces tape, flow, smart-money, classifier, and alert views.

Tape-only branch
Branch A Raw print remains visible

Even if the print does not pass the signal gate, it still exists in ClickHouse and can appear in raw tape or history views.

Branch A outcome No compute packet path

No FlowPacket, no smart-money evaluation, no classifier hits, and no alert emission.

Smart-money branch
Branch B Signal print enters compute

compute subscribes to options.prints.signal, not raw options.prints.

Branch B outcome FlowPacket is emitted
  • ClickHouse: flow_packets
  • NATS: flow.packets
Branch B continuation Smart-money, classifier hits, alerts

The packet is scored into a SmartMoneyEvent, which may abstain, produce classifier hits, and finally emit an alert.

Executive Read

The shortest truthful version of the system: not every options print is considered meaningful, and smart money is not detected directly from a single print.

1. Tape

Every print is stored

All enriched prints are written to ClickHouse and published to the raw options subject. This preserves evidence even when the print is uninteresting for higher-order inference.

2. Compute

Only signal prints reach the parent-event engine

A print must pass the signal gate before compute clusters it with neighboring prints and builds a packet that represents a possible parent order.

3. Smart money

Smart money is a scored interpretation

The model evaluates the packet using quote quality, aggressor mix, size, structure, DTE, IV, and event context. It can still abstain if the evidence is weak or suppressed.

Mixed Technical Walkthrough

This layer is for teammates who know the product and want the exact branching logic without reading through service code first.

Step 1: a candidate print enters ingest-options. In synthetic mode this print was manufactured by the synthetic adapter, which may also emit a synthetic NBBO update for the same contract.

Step 2: the print is enriched with the most recent option NBBO and underlying equity quote at or before the print timestamp. The service derives metadata, execution-side context, and the signal_pass decision.

Step 3: the enriched print is persisted to ClickHouse and published to options.prints. If signal_pass=true, the same print is also published to options.prints.signal.

Step 4: compute subscribes to the signal subject plus NBBO and equity-quote subjects. It does not build packet candidates from every raw print. It only clusters signal prints.

Step 5: compute aggregates nearby signal prints for the same option contract into a cluster, then flushes that cluster into a FlowPacket with features such as total premium, print count, aggressor ratios, NBBO coverage, stale-quote counts, IV context, and structure clues.

Step 6: the packet is transformed into a SmartMoneyEvent. If suppression rules trip or the top profile probability is too weak, the event abstains. Otherwise, it can emit classifier hits and finally an alert with evidence references back to the packet and member prints.

Operator and Code-Level Detail

This section is for someone tracing the live pipeline, debugging a regression, or trying to understand exactly why a given print surfaced on tape but did or did not become a smart-money event.

The first fork is the signal gate in ingest-options. The enriched print is always stored and published raw. The only thing signal_pass controls is whether compute receives that print on options.prints.signal.

The compute service maintains separate caches for option NBBO and underlying equity quotes. When signal prints arrive, it flushes aged clusters, extends the active cluster for that contract if the print lands within the configured window, or emits the old cluster and starts a new one.

The cluster becomes a FlowPacket only after compute summarizes parent-level features. That packet then passes through smart-money scoring. The scoring layer derives a profile set such as institutional directional, retail whale, event driven, vol seller, arbitrage, or hedge reactive.

A packet can still fail to produce actionable downstream artifacts. Suppression rules down-rank special print context, stale or missing quote context, and cross-like execution patterns. The top profile must also clear the probability threshold. If it does not, the smart-money event is emitted in abstained form and classifier hits stop there.

If the packet does clear those checks, compute writes and publishes the smart-money event, derives up to a few classifier hits from the top profile set, scores a final alert, and publishes all three derived streams. The API subscribes to those subjects and fans them out into live websocket channels while ClickHouse remains the history source behind /history/*.

Subject or table Produced by Carries Why it exists
options.prints ingest-options All enriched option prints Preserves the full tape, even when a print is not interesting enough for compute.
options.prints.signal ingest-options Signal-passing option prints Acts as the compute admission gate so packet building starts from a filtered tape.
flow.packets compute Parent-event candidates Turns several child prints into one summarized event with market-structure features.
flow.smart_money compute Smart-money evaluations Publishes the scored interpretation of a packet, including abstained outcomes.
flow.classifier_hits compute Top classifier consequences Exposes the strongest profile-level labels that downstream UX and alerting can decorate.
flow.alerts compute Alert events with evidence refs Packages the final severity and supporting evidence into a user-facing alert stream.

Normal Path Versus Smart-Money Path

These two sequences are easy to confuse, especially because both begin with the same enriched tape record.

Normal market path

Print arrives, gets enriched, gets stored, appears on the raw tape, and stops there unless it passes the signal gate. This is the dominant path for ordinary or low-signal activity.

Smart-money path

Print arrives, passes the signal gate, joins a cluster, becomes a packet, receives a smart-money score, then may emit classifier hits and an alert if the packet is not suppressed or abstained.

Annotated Event Sequence

The example below is the shortest operator-friendly way to think about the branch that leads to a smart-money result.

1. Synthetic or market adapter emits OptionPrint candidate
2. ingest-options enriches it with latest NBBO and underlying quote context
3. Enriched print is written to ClickHouse option_prints
4. Enriched print is published to options.prints
5. If signal_pass=true, the same print is also published to options.prints.signal
6. compute consumes options.prints.signal and updates the active contract cluster
7. Cluster flush builds a FlowPacket with parent-level features
8. FlowPacket is written to ClickHouse flow_packets and published to flow.packets
9. compute scores the packet into a SmartMoneyEvent
10. If suppressed or low-confidence, the SmartMoneyEvent abstains and stops there
11. Otherwise classifier hits are emitted
12. Alert scoring emits a final alert with evidence refs to smart-money event, flow packet, and member prints
13. API subscribes to these streams and exposes them through live websocket channels and ClickHouse-backed history

What Synthetic Mode Changes

Synthetic mode can make the upstream generator artificial, but the downstream branch logic stays identical.

The synthetic adapter constructs an OptionPrint with fields such as execution_iv_source="synthetic_pressure_model", and it may emit a synthetic NBBO for the same contract. From that point forward, the pipeline is the same one used for normal ingest.

That means synthetic smart-money is not a special smart-money subsystem. It is the standard signal-to-packet-to-smart-money pipeline running on synthetic upstream events.

Code Anchors

If you want to confirm this page against the code, these are the most useful entry points.

  • services/ingest-options/src/enrichment.ts: enriches the print and decides signal_pass.
  • services/ingest-options/src/index.ts: writes prints and publishes raw versus signal subjects.
  • services/compute/src/index.ts: subscribes to signal prints, maintains clusters, emits packets, smart money, hits, and alerts.
  • services/compute/src/parent-events.ts: builds SmartMoneyEvent, suppression rules, primary profile, abstention, and classifier derivation.
  • packages/bus/src/subjects.ts: canonical subject names for the pipeline.