add an anatomy page for options flow
This commit is contained in:
parent
5a68a3e38e
commit
db7370052f
4 changed files with 1711 additions and 52 deletions
954
docs/anatomy.html
Normal file
954
docs/anatomy.html
Normal file
|
|
@ -0,0 +1,954 @@
|
|||
<!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>
|
||||
Loading…
Add table
Add a link
Reference in a new issue