954 lines
33 KiB
HTML
954 lines
33 KiB
HTML
<!doctype html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="utf-8" />
|
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
<title>The Anatomy of an Options Print and Smart Money</title>
|
|
<style>
|
|
:root {
|
|
color-scheme: dark;
|
|
--bg-core: oklch(0.14 0.015 240);
|
|
--bg-shell: oklch(0.17 0.018 240);
|
|
--bg-pane: oklch(0.2 0.02 240);
|
|
--bg-pane-2: oklch(0.23 0.02 240);
|
|
--bg-soft: oklch(0.28 0.022 240 / 0.48);
|
|
--line: oklch(0.48 0.03 240 / 0.34);
|
|
--line-strong: oklch(0.67 0.06 75 / 0.48);
|
|
--text: oklch(0.93 0.01 240);
|
|
--text-dim: oklch(0.74 0.02 240);
|
|
--text-faint: oklch(0.62 0.016 240);
|
|
--amber: oklch(0.79 0.16 76);
|
|
--amber-soft: oklch(0.33 0.07 76 / 0.32);
|
|
--green: oklch(0.74 0.15 154);
|
|
--green-soft: oklch(0.31 0.06 154 / 0.3);
|
|
--blue: oklch(0.72 0.12 244);
|
|
--blue-soft: oklch(0.31 0.05 244 / 0.28);
|
|
--red: oklch(0.69 0.17 28);
|
|
--red-soft: oklch(0.31 0.06 28 / 0.32);
|
|
--shadow: 0 30px 80px rgba(0, 0, 0, 0.38);
|
|
--radius-xl: 20px;
|
|
--radius-lg: 16px;
|
|
--radius-md: 12px;
|
|
--radius-sm: 10px;
|
|
--mono: "IBM Plex Mono", "SFMono-Regular", Consolas, "Liberation Mono", Menlo, monospace;
|
|
--sans: "IBM Plex Sans", "Avenir Next", "Segoe UI", sans-serif;
|
|
--display: "Quantico", "IBM Plex Sans", sans-serif;
|
|
}
|
|
|
|
* {
|
|
box-sizing: border-box;
|
|
}
|
|
|
|
html {
|
|
scroll-behavior: smooth;
|
|
}
|
|
|
|
body {
|
|
margin: 0;
|
|
font-family: var(--sans);
|
|
color: var(--text);
|
|
background:
|
|
radial-gradient(circle at 0% 0%, rgba(245, 166, 35, 0.09), transparent 24%),
|
|
radial-gradient(circle at 100% 0%, rgba(77, 163, 255, 0.12), transparent 26%),
|
|
linear-gradient(180deg, var(--bg-shell) 0%, var(--bg-core) 100%);
|
|
}
|
|
|
|
a {
|
|
color: var(--amber);
|
|
}
|
|
|
|
code,
|
|
pre,
|
|
.eyebrow,
|
|
.chip,
|
|
.mini-label,
|
|
th,
|
|
.lane-label {
|
|
font-family: var(--mono);
|
|
}
|
|
|
|
main {
|
|
width: min(1440px, calc(100vw - 32px));
|
|
margin: 0 auto;
|
|
padding: 28px 0 64px;
|
|
}
|
|
|
|
.hero {
|
|
display: grid;
|
|
gap: 22px;
|
|
padding: 28px;
|
|
border: 1px solid var(--line);
|
|
border-radius: 28px;
|
|
background:
|
|
linear-gradient(180deg, rgba(255, 255, 255, 0.035) 0%, rgba(255, 255, 255, 0.015) 100%),
|
|
linear-gradient(135deg, rgba(17, 24, 32, 0.96) 0%, rgba(8, 11, 16, 0.98) 100%);
|
|
box-shadow: var(--shadow);
|
|
}
|
|
|
|
.hero-top {
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
gap: 12px;
|
|
}
|
|
|
|
.eyebrow {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: 10px;
|
|
padding: 8px 12px;
|
|
border-radius: 999px;
|
|
border: 1px solid var(--line);
|
|
background: rgba(255, 255, 255, 0.03);
|
|
color: var(--text-dim);
|
|
font-size: 0.72rem;
|
|
letter-spacing: 0.14em;
|
|
text-transform: uppercase;
|
|
}
|
|
|
|
h1,
|
|
h2,
|
|
h3 {
|
|
margin: 0;
|
|
line-height: 1.08;
|
|
}
|
|
|
|
h1 {
|
|
font-family: var(--display);
|
|
font-size: clamp(2.35rem, 5vw, 4.8rem);
|
|
letter-spacing: 0.04em;
|
|
text-transform: uppercase;
|
|
}
|
|
|
|
h2 {
|
|
font-family: var(--display);
|
|
font-size: 1.5rem;
|
|
letter-spacing: 0.04em;
|
|
text-transform: uppercase;
|
|
}
|
|
|
|
h3 {
|
|
font-size: 1.04rem;
|
|
font-weight: 650;
|
|
}
|
|
|
|
.hero-copy {
|
|
display: grid;
|
|
grid-template-columns: minmax(0, 1.7fr) minmax(280px, 0.85fr);
|
|
gap: 26px;
|
|
align-items: start;
|
|
}
|
|
|
|
.lede {
|
|
margin: 0;
|
|
max-width: 68ch;
|
|
color: var(--text-dim);
|
|
font-size: 1rem;
|
|
line-height: 1.62;
|
|
}
|
|
|
|
.hero-note {
|
|
padding: 18px;
|
|
border-radius: var(--radius-lg);
|
|
border: 1px solid var(--line);
|
|
background: rgba(255, 255, 255, 0.03);
|
|
}
|
|
|
|
.hero-note p {
|
|
margin: 0;
|
|
color: var(--text-dim);
|
|
line-height: 1.55;
|
|
}
|
|
|
|
.hero-note p + p {
|
|
margin-top: 12px;
|
|
}
|
|
|
|
.toolbar {
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
gap: 10px;
|
|
}
|
|
|
|
.chip {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
padding: 7px 12px;
|
|
border-radius: 999px;
|
|
border: 1px solid var(--line);
|
|
text-decoration: none;
|
|
color: var(--text);
|
|
background: rgba(255, 255, 255, 0.03);
|
|
font-size: 0.75rem;
|
|
letter-spacing: 0.08em;
|
|
text-transform: uppercase;
|
|
}
|
|
|
|
.chip:hover {
|
|
border-color: var(--line-strong);
|
|
}
|
|
|
|
.chip .dot {
|
|
width: 8px;
|
|
height: 8px;
|
|
border-radius: 999px;
|
|
flex: 0 0 auto;
|
|
}
|
|
|
|
.chip.raw .dot {
|
|
background: var(--blue);
|
|
}
|
|
|
|
.chip.derived .dot {
|
|
background: var(--amber);
|
|
}
|
|
|
|
.chip.store .dot {
|
|
background: var(--green);
|
|
}
|
|
|
|
.chip.live .dot {
|
|
background: var(--red);
|
|
}
|
|
|
|
.stack {
|
|
display: grid;
|
|
gap: 22px;
|
|
margin-top: 22px;
|
|
}
|
|
|
|
.section {
|
|
border: 1px solid var(--line);
|
|
border-radius: 24px;
|
|
padding: 24px;
|
|
background:
|
|
linear-gradient(180deg, rgba(255, 255, 255, 0.035) 0%, rgba(255, 255, 255, 0.016) 100%),
|
|
var(--bg-pane);
|
|
box-shadow: var(--shadow);
|
|
}
|
|
|
|
.section-head {
|
|
display: grid;
|
|
gap: 8px;
|
|
margin-bottom: 18px;
|
|
}
|
|
|
|
.section-head p,
|
|
.copy p,
|
|
.copy li,
|
|
.table-wrap td,
|
|
.table-wrap th {
|
|
color: var(--text-dim);
|
|
line-height: 1.58;
|
|
}
|
|
|
|
.section-head p,
|
|
.copy p {
|
|
margin: 0;
|
|
max-width: 74ch;
|
|
}
|
|
|
|
.summary-grid {
|
|
display: grid;
|
|
grid-template-columns: repeat(3, minmax(0, 1fr));
|
|
gap: 16px;
|
|
}
|
|
|
|
.summary-card {
|
|
padding: 18px;
|
|
border-radius: var(--radius-lg);
|
|
border: 1px solid var(--line);
|
|
background: linear-gradient(180deg, rgba(255, 255, 255, 0.025) 0%, rgba(255, 255, 255, 0.01) 100%);
|
|
}
|
|
|
|
.summary-card p {
|
|
margin: 10px 0 0;
|
|
}
|
|
|
|
.mini-label {
|
|
display: inline-block;
|
|
margin-bottom: 8px;
|
|
color: var(--text-faint);
|
|
font-size: 0.72rem;
|
|
letter-spacing: 0.12em;
|
|
text-transform: uppercase;
|
|
}
|
|
|
|
.flow-scroll {
|
|
overflow-x: auto;
|
|
padding-bottom: 6px;
|
|
}
|
|
|
|
.flow-board {
|
|
min-width: 1320px;
|
|
display: grid;
|
|
gap: 18px;
|
|
}
|
|
|
|
.lanes {
|
|
display: grid;
|
|
grid-template-columns: 160px repeat(6, minmax(180px, 1fr));
|
|
gap: 14px;
|
|
align-items: stretch;
|
|
}
|
|
|
|
.lane-label {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
padding: 16px;
|
|
border-radius: var(--radius-lg);
|
|
border: 1px solid var(--line);
|
|
background: rgba(255, 255, 255, 0.025);
|
|
color: var(--text-faint);
|
|
font-size: 0.74rem;
|
|
letter-spacing: 0.12em;
|
|
text-transform: uppercase;
|
|
text-align: center;
|
|
}
|
|
|
|
.node {
|
|
position: relative;
|
|
min-height: 138px;
|
|
padding: 16px;
|
|
border-radius: 18px;
|
|
border: 1px solid var(--line);
|
|
background: var(--bg-pane-2);
|
|
display: grid;
|
|
gap: 10px;
|
|
}
|
|
|
|
.node strong {
|
|
font-size: 1.02rem;
|
|
line-height: 1.25;
|
|
}
|
|
|
|
.node p {
|
|
margin: 0;
|
|
color: var(--text-dim);
|
|
font-size: 0.92rem;
|
|
line-height: 1.48;
|
|
}
|
|
|
|
.node ul {
|
|
margin: 0;
|
|
padding-left: 18px;
|
|
color: var(--text-dim);
|
|
}
|
|
|
|
.node li + li {
|
|
margin-top: 6px;
|
|
}
|
|
|
|
.node.raw {
|
|
box-shadow: inset 0 0 0 1px rgba(77, 163, 255, 0.18);
|
|
}
|
|
|
|
.node.derived {
|
|
box-shadow: inset 0 0 0 1px rgba(245, 166, 35, 0.24);
|
|
}
|
|
|
|
.node.store {
|
|
box-shadow: inset 0 0 0 1px rgba(37, 193, 122, 0.24);
|
|
}
|
|
|
|
.node.live {
|
|
box-shadow: inset 0 0 0 1px rgba(255, 107, 95, 0.24);
|
|
}
|
|
|
|
.node-arrow::after {
|
|
content: "";
|
|
position: absolute;
|
|
top: 50%;
|
|
right: -12px;
|
|
width: 24px;
|
|
height: 2px;
|
|
background: linear-gradient(90deg, var(--line-strong) 0%, var(--amber) 100%);
|
|
}
|
|
|
|
.node-arrow::before {
|
|
content: "";
|
|
position: absolute;
|
|
top: calc(50% - 5px);
|
|
right: -12px;
|
|
border-top: 6px solid transparent;
|
|
border-bottom: 6px solid transparent;
|
|
border-left: 8px solid var(--amber);
|
|
}
|
|
|
|
.branch-grid {
|
|
display: grid;
|
|
grid-template-columns: 160px repeat(6, minmax(180px, 1fr));
|
|
gap: 14px;
|
|
align-items: stretch;
|
|
}
|
|
|
|
.branch-empty {
|
|
border-radius: var(--radius-lg);
|
|
border: 1px dashed transparent;
|
|
min-height: 112px;
|
|
}
|
|
|
|
.branch-box {
|
|
min-height: 112px;
|
|
}
|
|
|
|
.branch-box p {
|
|
margin: 0;
|
|
}
|
|
|
|
.copy {
|
|
display: grid;
|
|
gap: 16px;
|
|
}
|
|
|
|
.copy ul {
|
|
margin: 0;
|
|
padding-left: 18px;
|
|
}
|
|
|
|
.copy li + li {
|
|
margin-top: 8px;
|
|
}
|
|
|
|
.detail-grid {
|
|
display: grid;
|
|
grid-template-columns: minmax(0, 1.2fr) minmax(320px, 0.8fr);
|
|
gap: 18px;
|
|
}
|
|
|
|
.callout {
|
|
padding: 18px;
|
|
border-radius: var(--radius-lg);
|
|
border: 1px solid var(--line);
|
|
background: rgba(255, 255, 255, 0.025);
|
|
}
|
|
|
|
.callout p {
|
|
margin: 0;
|
|
}
|
|
|
|
.callout p + p {
|
|
margin-top: 10px;
|
|
}
|
|
|
|
.table-wrap {
|
|
overflow-x: auto;
|
|
border: 1px solid var(--line);
|
|
border-radius: var(--radius-lg);
|
|
}
|
|
|
|
table {
|
|
width: 100%;
|
|
border-collapse: collapse;
|
|
min-width: 720px;
|
|
}
|
|
|
|
th,
|
|
td {
|
|
padding: 12px 14px;
|
|
border-bottom: 1px solid var(--line);
|
|
text-align: left;
|
|
vertical-align: top;
|
|
}
|
|
|
|
th {
|
|
color: var(--text);
|
|
background: rgba(255, 255, 255, 0.035);
|
|
font-size: 0.76rem;
|
|
letter-spacing: 0.1em;
|
|
text-transform: uppercase;
|
|
}
|
|
|
|
tr:last-child td {
|
|
border-bottom: 0;
|
|
}
|
|
|
|
pre {
|
|
margin: 0;
|
|
padding: 18px;
|
|
border-radius: var(--radius-lg);
|
|
background: oklch(0.13 0.012 240);
|
|
border: 1px solid var(--line);
|
|
color: var(--text);
|
|
overflow-x: auto;
|
|
line-height: 1.5;
|
|
font-size: 0.88rem;
|
|
}
|
|
|
|
.footer-note {
|
|
color: var(--text-faint);
|
|
font-size: 0.88rem;
|
|
}
|
|
|
|
@media (max-width: 1080px) {
|
|
.hero-copy,
|
|
.detail-grid,
|
|
.summary-grid {
|
|
grid-template-columns: 1fr;
|
|
}
|
|
}
|
|
|
|
@media (max-width: 720px) {
|
|
main {
|
|
width: min(100vw, calc(100vw - 20px));
|
|
padding-top: 12px;
|
|
}
|
|
|
|
.hero,
|
|
.section {
|
|
padding: 18px;
|
|
border-radius: 18px;
|
|
}
|
|
|
|
h1 {
|
|
font-size: clamp(1.9rem, 8vw, 2.8rem);
|
|
}
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<main>
|
|
<section class="hero">
|
|
<div class="hero-top">
|
|
<span class="eyebrow">Islandflow Reference · Options Flow Pipeline</span>
|
|
<nav class="toolbar" aria-label="Page navigation">
|
|
<a class="chip raw" href="#flow-chart"><span class="dot"></span>Flow Chart</a>
|
|
<a class="chip derived" href="#executive"><span class="dot"></span>Executive</a>
|
|
<a class="chip store" href="#technical"><span class="dot"></span>Technical</a>
|
|
<a class="chip live" href="#operator"><span class="dot"></span>Operator Detail</a>
|
|
</nav>
|
|
</div>
|
|
|
|
<div class="hero-copy">
|
|
<div>
|
|
<h1>The Anatomy of an Options Print and Smart Money</h1>
|
|
<p class="lede">
|
|
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.
|
|
</p>
|
|
</div>
|
|
<aside class="hero-note">
|
|
<p>
|
|
The key distinction is structural: the options tape is print-level, flow is packet-level, and smart
|
|
money is model output on those packets.
|
|
</p>
|
|
<p>
|
|
Synthetic mode changes the source of prints and NBBO context, not the downstream architecture.
|
|
</p>
|
|
</aside>
|
|
</div>
|
|
</section>
|
|
|
|
<div class="stack">
|
|
<section class="section">
|
|
<div class="section-head">
|
|
<h2>Legend</h2>
|
|
<p>Color coding is semantic, not decorative, so you can scan the diagram without relearning the vocabulary.</p>
|
|
</div>
|
|
<div class="toolbar" aria-label="Legend">
|
|
<span class="chip raw"><span class="dot"></span>Raw market or synthetic input</span>
|
|
<span class="chip derived"><span class="dot"></span>Derived compute stage</span>
|
|
<span class="chip store"><span class="dot"></span>Stored or persisted state</span>
|
|
<span class="chip live"><span class="dot"></span>API, websocket, or user-facing surface</span>
|
|
</div>
|
|
</section>
|
|
|
|
<section class="section" id="flow-chart">
|
|
<div class="section-head">
|
|
<h2>Main Flow Chart</h2>
|
|
<p>
|
|
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.
|
|
</p>
|
|
</div>
|
|
|
|
<div class="flow-scroll">
|
|
<div class="flow-board">
|
|
<div class="lanes">
|
|
<div class="lane-label">Input</div>
|
|
<article class="node raw node-arrow">
|
|
<span class="mini-label">Stage 1</span>
|
|
<strong>Option print candidate arrives</strong>
|
|
<p>
|
|
The source can be a native market adapter or the synthetic adapter. Synthetic mode can also emit a
|
|
matching NBBO update.
|
|
</p>
|
|
</article>
|
|
<article class="node raw node-arrow">
|
|
<span class="mini-label">Stage 2</span>
|
|
<strong>ingest-options enriches the print</strong>
|
|
<p>
|
|
The service joins recent option NBBO and underlying equity quote context, derives metadata, and
|
|
computes <code>signal_pass</code>.
|
|
</p>
|
|
</article>
|
|
<article class="node store node-arrow">
|
|
<span class="mini-label">Stage 3</span>
|
|
<strong>Raw print is written and published</strong>
|
|
<ul>
|
|
<li>ClickHouse: <code>option_prints</code></li>
|
|
<li>NATS: <code>options.prints</code></li>
|
|
</ul>
|
|
</article>
|
|
<article class="node derived node-arrow">
|
|
<span class="mini-label">Stage 4</span>
|
|
<strong>Signal gate decides if compute should care</strong>
|
|
<p>
|
|
Only <code>signal_pass=true</code> prints are published to <code>options.prints.signal</code> and
|
|
consumed by compute.
|
|
</p>
|
|
</article>
|
|
<article class="node derived node-arrow">
|
|
<span class="mini-label">Stage 5</span>
|
|
<strong>compute builds or updates a parent cluster</strong>
|
|
<p>
|
|
Nearby signal prints for the same contract are grouped inside the cluster window while NBBO and
|
|
equity-quote caches supply context.
|
|
</p>
|
|
</article>
|
|
<article class="node live">
|
|
<span class="mini-label">Stage 6</span>
|
|
<strong>API and UI consume the resulting streams</strong>
|
|
<p>
|
|
The API hydrates hot snapshots, history endpoints read ClickHouse, and the terminal surfaces tape,
|
|
flow, smart-money, classifier, and alert views.
|
|
</p>
|
|
</article>
|
|
</div>
|
|
|
|
<div class="branch-grid">
|
|
<div class="lane-label">Tape-only branch</div>
|
|
<div class="branch-empty"></div>
|
|
<div class="branch-empty"></div>
|
|
<article class="node store branch-box">
|
|
<span class="mini-label">Branch A</span>
|
|
<strong>Raw print remains visible</strong>
|
|
<p>
|
|
Even if the print does not pass the signal gate, it still exists in ClickHouse and can appear in
|
|
raw tape or history views.
|
|
</p>
|
|
</article>
|
|
<article class="node derived branch-box">
|
|
<span class="mini-label">Branch A outcome</span>
|
|
<strong>No compute packet path</strong>
|
|
<p>
|
|
No <code>FlowPacket</code>, no smart-money evaluation, no classifier hits, and no alert emission.
|
|
</p>
|
|
</article>
|
|
<div class="branch-empty"></div>
|
|
<div class="branch-empty"></div>
|
|
</div>
|
|
|
|
<div class="branch-grid">
|
|
<div class="lane-label">Smart-money branch</div>
|
|
<div class="branch-empty"></div>
|
|
<div class="branch-empty"></div>
|
|
<div class="branch-empty"></div>
|
|
<article class="node derived branch-box">
|
|
<span class="mini-label">Branch B</span>
|
|
<strong>Signal print enters compute</strong>
|
|
<p>
|
|
compute subscribes to <code>options.prints.signal</code>, not raw <code>options.prints</code>.
|
|
</p>
|
|
</article>
|
|
<article class="node derived branch-box">
|
|
<span class="mini-label">Branch B outcome</span>
|
|
<strong>FlowPacket is emitted</strong>
|
|
<ul>
|
|
<li>ClickHouse: <code>flow_packets</code></li>
|
|
<li>NATS: <code>flow.packets</code></li>
|
|
</ul>
|
|
</article>
|
|
<article class="node live branch-box">
|
|
<span class="mini-label">Branch B continuation</span>
|
|
<strong>Smart-money, classifier hits, alerts</strong>
|
|
<p>
|
|
The packet is scored into a <code>SmartMoneyEvent</code>, which may abstain, produce classifier
|
|
hits, and finally emit an alert.
|
|
</p>
|
|
</article>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<section class="section" id="executive">
|
|
<div class="section-head">
|
|
<h2>Executive Read</h2>
|
|
<p>
|
|
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.
|
|
</p>
|
|
</div>
|
|
<div class="summary-grid">
|
|
<article class="summary-card">
|
|
<span class="mini-label">1. Tape</span>
|
|
<h3>Every print is stored</h3>
|
|
<p>
|
|
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.
|
|
</p>
|
|
</article>
|
|
<article class="summary-card">
|
|
<span class="mini-label">2. Compute</span>
|
|
<h3>Only signal prints reach the parent-event engine</h3>
|
|
<p>
|
|
A print must pass the signal gate before compute clusters it with neighboring prints and builds a
|
|
packet that represents a possible parent order.
|
|
</p>
|
|
</article>
|
|
<article class="summary-card">
|
|
<span class="mini-label">3. Smart money</span>
|
|
<h3>Smart money is a scored interpretation</h3>
|
|
<p>
|
|
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.
|
|
</p>
|
|
</article>
|
|
</div>
|
|
</section>
|
|
|
|
<section class="section" id="technical">
|
|
<div class="section-head">
|
|
<h2>Mixed Technical Walkthrough</h2>
|
|
<p>
|
|
This layer is for teammates who know the product and want the exact branching logic without reading
|
|
through service code first.
|
|
</p>
|
|
</div>
|
|
<div class="detail-grid">
|
|
<div class="copy">
|
|
<p>
|
|
<strong>Step 1:</strong> a candidate print enters <code>ingest-options</code>. In synthetic mode this
|
|
print was manufactured by the synthetic adapter, which may also emit a synthetic NBBO update for the
|
|
same contract.
|
|
</p>
|
|
<p>
|
|
<strong>Step 2:</strong> 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
|
|
<code>signal_pass</code> decision.
|
|
</p>
|
|
<p>
|
|
<strong>Step 3:</strong> the enriched print is persisted to ClickHouse and published to
|
|
<code>options.prints</code>. If <code>signal_pass=true</code>, the same print is also published to
|
|
<code>options.prints.signal</code>.
|
|
</p>
|
|
<p>
|
|
<strong>Step 4:</strong> 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.
|
|
</p>
|
|
<p>
|
|
<strong>Step 5:</strong> compute aggregates nearby signal prints for the same option contract into a
|
|
cluster, then flushes that cluster into a <code>FlowPacket</code> with features such as total premium,
|
|
print count, aggressor ratios, NBBO coverage, stale-quote counts, IV context, and structure clues.
|
|
</p>
|
|
<p>
|
|
<strong>Step 6:</strong> the packet is transformed into a <code>SmartMoneyEvent</code>. 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.
|
|
</p>
|
|
</div>
|
|
<aside class="callout">
|
|
<span class="mini-label">Important distinction</span>
|
|
<p>
|
|
A <code>FlowPacket</code> is already a derived parent-event candidate. It is not just another name for
|
|
the options tape.
|
|
</p>
|
|
<p>
|
|
A <code>SmartMoneyEvent</code> is model output on that packet, not a raw tape fact. The system treats
|
|
it as evidence-backed interpretation with explicit abstention and suppression paths.
|
|
</p>
|
|
</aside>
|
|
</div>
|
|
</section>
|
|
|
|
<section class="section" id="operator">
|
|
<div class="section-head">
|
|
<h2>Operator and Code-Level Detail</h2>
|
|
<p>
|
|
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.
|
|
</p>
|
|
</div>
|
|
<div class="copy">
|
|
<p>
|
|
The first fork is the signal gate in <code>ingest-options</code>. The enriched print is always stored and
|
|
published raw. The only thing <code>signal_pass</code> controls is whether compute receives that print on
|
|
<code>options.prints.signal</code>.
|
|
</p>
|
|
<p>
|
|
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.
|
|
</p>
|
|
<p>
|
|
The cluster becomes a <code>FlowPacket</code> 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.
|
|
</p>
|
|
<p>
|
|
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.
|
|
</p>
|
|
<p>
|
|
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 <code>/history/*</code>.
|
|
</p>
|
|
</div>
|
|
|
|
<div class="table-wrap">
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Subject or table</th>
|
|
<th>Produced by</th>
|
|
<th>Carries</th>
|
|
<th>Why it exists</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td><code>options.prints</code></td>
|
|
<td><code>ingest-options</code></td>
|
|
<td>All enriched option prints</td>
|
|
<td>Preserves the full tape, even when a print is not interesting enough for compute.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>options.prints.signal</code></td>
|
|
<td><code>ingest-options</code></td>
|
|
<td>Signal-passing option prints</td>
|
|
<td>Acts as the compute admission gate so packet building starts from a filtered tape.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>flow.packets</code></td>
|
|
<td><code>compute</code></td>
|
|
<td>Parent-event candidates</td>
|
|
<td>Turns several child prints into one summarized event with market-structure features.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>flow.smart_money</code></td>
|
|
<td><code>compute</code></td>
|
|
<td>Smart-money evaluations</td>
|
|
<td>Publishes the scored interpretation of a packet, including abstained outcomes.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>flow.classifier_hits</code></td>
|
|
<td><code>compute</code></td>
|
|
<td>Top classifier consequences</td>
|
|
<td>Exposes the strongest profile-level labels that downstream UX and alerting can decorate.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>flow.alerts</code></td>
|
|
<td><code>compute</code></td>
|
|
<td>Alert events with evidence refs</td>
|
|
<td>Packages the final severity and supporting evidence into a user-facing alert stream.</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</section>
|
|
|
|
<section class="section">
|
|
<div class="section-head">
|
|
<h2>Normal Path Versus Smart-Money Path</h2>
|
|
<p>
|
|
These two sequences are easy to confuse, especially because both begin with the same enriched tape
|
|
record.
|
|
</p>
|
|
</div>
|
|
<div class="detail-grid">
|
|
<div class="callout">
|
|
<span class="mini-label">Normal market path</span>
|
|
<p>
|
|
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.
|
|
</p>
|
|
</div>
|
|
<div class="callout">
|
|
<span class="mini-label">Smart-money path</span>
|
|
<p>
|
|
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.
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<section class="section">
|
|
<div class="section-head">
|
|
<h2>Annotated Event Sequence</h2>
|
|
<p>
|
|
The example below is the shortest operator-friendly way to think about the branch that leads to a
|
|
smart-money result.
|
|
</p>
|
|
</div>
|
|
<pre><code>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</code></pre>
|
|
</section>
|
|
|
|
<section class="section">
|
|
<div class="section-head">
|
|
<h2>What Synthetic Mode Changes</h2>
|
|
<p>
|
|
Synthetic mode can make the upstream generator artificial, but the downstream branch logic stays
|
|
identical.
|
|
</p>
|
|
</div>
|
|
<div class="copy">
|
|
<p>
|
|
The synthetic adapter constructs an <code>OptionPrint</code> with fields such as
|
|
<code>execution_iv_source="synthetic_pressure_model"</code>, 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.
|
|
</p>
|
|
<p>
|
|
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.
|
|
</p>
|
|
</div>
|
|
</section>
|
|
|
|
<section class="section">
|
|
<div class="section-head">
|
|
<h2>Code Anchors</h2>
|
|
<p>
|
|
If you want to confirm this page against the code, these are the most useful entry points.
|
|
</p>
|
|
</div>
|
|
<div class="copy">
|
|
<ul>
|
|
<li><code>services/ingest-options/src/enrichment.ts</code>: enriches the print and decides <code>signal_pass</code>.</li>
|
|
<li><code>services/ingest-options/src/index.ts</code>: writes prints and publishes raw versus signal subjects.</li>
|
|
<li><code>services/compute/src/index.ts</code>: subscribes to signal prints, maintains clusters, emits packets, smart money, hits, and alerts.</li>
|
|
<li><code>services/compute/src/parent-events.ts</code>: builds <code>SmartMoneyEvent</code>, suppression rules, primary profile, abstention, and classifier derivation.</li>
|
|
<li><code>packages/bus/src/subjects.ts</code>: canonical subject names for the pipeline.</li>
|
|
</ul>
|
|
</div>
|
|
<p class="footer-note">
|
|
This document is intended as a living product reference, not a turn artifact. If the packet features,
|
|
thresholds, or stream names change, update this page alongside the relevant pipeline code.
|
|
</p>
|
|
</section>
|
|
</div>
|
|
</main>
|
|
</body>
|
|
</html>
|