Sensors
Sensors turn broker and public-source observations into typed measurements with
an as_of time, source health, freshness, and a semantic fingerprint. They do
not decide trading policy, authorize an order, or prove that an alert reached a
device.
The daemon is the measurement authority. It owns source access, scheduling, last-good state, and evaluation. CLI, MCP, app, and web surfaces read the same typed results without refetching sources or recreating the verdict.
Dependencies and boundaries
PNG fallback · SVG source generator · Tabler Icons license
Gamma feeds Regime; Regime and market events feed Stress and Rulebook. Alerts may consume the resulting typed state, but a sensor result is not evidence that delivery is active or that a notification arrived.
A dependent sensor receives the upstream result with its health and does not recompute it. Stress uses the exact Regime publication; Rulebook uses the daemon's classified Regime stage rather than rebuilding one from market rows.
Read the state before the number
PNG fallback · SVG source generator · Tabler Icons license
Freshness is part of the measurement. The daemon refreshes before a result's hard expiry where the source permits it. A successful refresh atomically replaces the last-good publication. A failed refresh leaves the older result visible with explicit health; it never changes an old value's timestamp or turns absence into zero.
| State | Meaning | Safe interpretation |
|---|---|---|
current |
The source refresh is complete and no newer observation is due. | Use the value subject to its quality and scope. |
not_due |
The source's publication or trading window is closed, so no newer observation should exist yet. | Keep valid last-good context visible, but do not promote it to fresh confirmation. |
partial |
Some expected fields, symbols, or child sources arrived and others did not. | Use only the explicitly complete part; absence elsewhere is unknown. |
pending |
A refresh for the current publication period is in flight, evidenced by a typed marker, inside a bounded window anchored to the period start. | Keep the previous period's value visible as context; it never becomes fresh confirmation, and the state expires into overdue at the window's deadline. |
stale |
A known value is older than its allowed evidence window or a due refresh failed. | Display as old context; dependent decisions normally degrade or block. |
unavailable |
No usable value exists for the requested scope. | Do not infer a neutral, inactive, or passing result. |
degraded |
The result exists, but source or model quality limits how it may be used. | Read the blocker and use only the permitted context. |
computing |
A background calculation is running and no completed replacement can yet be served. | Wait or poll; progress is not a measurement. |
overdue |
The native cadence says a newer observation should already exist. | Treat required evidence as a data-quality failure, not a warning signal. |
not_due and overdue are opposites: an expected schedule gap against a missed
obligation. pending sits between them — the observation is genuinely due and is
being produced — and it is bounded, so a computation that never finishes still
reaches overdue. partial describes coverage and stale describes time. One
source can be both incomplete and old at different layers of a result.
A failed refresh is stale, never not_due: the distinction is whether a newer
observation could exist, not whether one arrived.
Gamma
What it answers
Gamma models a conditional hedging response under an explicit OI sign assumption. Positive GEX at observed spot suggests damping, negative GEX suggests amplification, in either direction. Several crossings can exist, so above/below a level is insufficient to infer sign. It is market-structure context, not observed dealer inventory or a directional forecast.
SPX/SPXW is the canonical S&P 500 signal; SPY is corroborating ETF context. The
two use different scales, so the default spy+spx result keeps separate
per-index price levels and intentionally has no combined top-level spot or
zero-gamma price. It also reports whether the two books agree. A healthy SPX
result stays usable when SPY is throttled or unavailable; SPY-only remains a
labeled proxy when SPX is absent. Concepts has the
methodology behind that reading, the sign convention, and the agreement
classifier's values.
Inputs and outputs
The daemon qualifies IBKR SPX/SPXW and SPY option contracts, collects option prices or derives IV, captures open interest, and anchors the sweep to observed spot. Missing open interest is unknown, never zero. Priced legs can support the IV/skew fit but do not contribute open-interest-weighted exposure without observed OI.
Each per-index result reports:
- zero-gamma status, zero-gamma price when a crossing exists, and spot's percentage gap from it;
- the signed profile, swept range and
profile_metricswith exact spot GEX, gross GEX, net-to-gross percentage and all detected crossings; - separate 0DTE, 1–7 DTE, and term profiles and crossings;
gamma_total_abs, the sign-agnostic gross gamma magnitude, andtop_strikes, the largest individual-contract absolute concentrations;- same-expiry 25-delta put-minus-call IV where both sides are bracketed, and a daemon-authored interpretation with quality and provenance;
- priced and contributing leg counts, OI/IV/skew coverage, warnings, and
quality.rankability.
Only rankable may contribute a Regime band or confirm stress. context_only
is displayable but does not vote. blocked and unavailable are not usable
signals. Missing 0DTE is disclosed in horizon coverage and warnings; it alone
does not block a healthy SPX surface with 1–7 DTE and term coverage, because
once the expiring SPXW series closes the 0DTE bucket can be absent while the
broader surface stays usable.
Some Gamma quality bars, skew-fit quality among them, remain heuristic pending calibration from retained diagnostics. The result exposes the gate and its reason instead of presenting those bars as proven thresholds.
The Brief and app Monitor preserve this explanation, including horizon availability and the distinction between option pricing and unknown bullish/ bearish positioning. Old-method current state is invalidated by the v4 method token. Retained historical observations survive; a cold off-hours model waits for eligible market data rather than fabricating an updated read.
Timing and last-good behavior
After the gateway is ready, the daemon prewarms canonical combined Gamma and
checks refresh eligibility every minute. A request with no serveable result
returns computing with progress and an ETA for the multi-minute background
compute; concurrent callers for one scope share that work.
During regular US options hours, normally 09:30–16:15 ET on the US options calendar, a successful result becomes due for refresh after 15 minutes. The daemon serves last-good while the replacement computes, promotes only a successful replacement, and backs off repeated failures. Outside those hours, automatic refresh is suppressed on purpose.
The 15-minute interval triggers a refresh; it does not set the quality ceiling. Standalone rankability on the direct surface needs a current-session result no more than 60 minutes old during RTH, or a closed-session cache no more than 24 hours old.
Regime treats that closed-session result differently. The latest
completed-options-session value is typed not_due context before the next open
and cannot confirm. At the open it becomes pending while the session's first
compute is actually in flight, for a bounded 30 minutes measured from the open,
and overdue after that or as soon as no compute is running. Neither state can
confirm. No last-good result, a missed completed session, or a due refresh gap
is a data-quality condition.
Safe check
canary status --json
canary brief --json
Read the Gamma subsystem and brief source-health rows first, including quality, as-of, session, coverage, and warning codes. The standalone Gamma command was retired in v3; forced recompute is an internal diagnostic, not the normal freshness mechanism.
Regime
What it answers
Regime asks whether several independent market channels agree that stress is developing. Its eight rows draw on live IBKR market data, official public series, Gamma, and S&P 500 breadth, and group into six clusters. Concepts explains what each row measures. Cluster independence is what gates confirmation.
| Cluster | Rows |
|---|---|
| Volatility | VIX/VIX3M term structure; VVIX |
| Credit | HYG/SPY divergence; HY/IG option-adjusted spreads |
| Funding | Commercial-paper/T-bill spread |
| FX | USD/JPY weekly move |
| Gamma | SPX-canonical dealer gamma with SPY context |
| Breadth | S&P 500 breadth |
Each row carries measurements, band, reason, source and scalar provenance,
native-cadence freshness, streak, and red-band eligibility. The combined result
reports raw and confirmed cluster counts, source health, posture, a semantic
fingerprint, and one of quiet, early_warning, confirmed_stress, panic,
stabilization, opportunity, or data_quality.
Red does not automatically mean confirmed. Only a fresh observation may
confirm, and the check is an allowlist: a state whose authority has not been
decided cannot inherit confirmation. Depth, persistence, freshness, and cluster
independence decide whether a red row may confirm stress. A provisional red
stays visible and may support early_warning only when the required evidence
set is otherwise usable. One cluster whose evidence has gone defective or stale
degrades readiness and is named rather than discarding the other five; two of
them, an unattributable defect, or a defect in the very evidence the current
stage rests on produce data_quality, blocked readiness, and the label
Market state undefined — data incomplete.
Thresholds and severity governors labeled heuristic and pending_backtest are
reviewed starting assumptions awaiting point-in-time calibration, not proven
market laws. The result exposes governors so a lower severity beside red rows is
explainable rather than silently rewritten.
Timing and authority
Regime publishes one immutable, daemon-owned last-good result to daemon.db,
with a five-minute operational authority window. A scheduler checks every five
seconds and starts a refresh about one minute before expiry, leaving the full
45-second acquisition budget plus a cushion. A Gamma publication can also wake
Regime. App polling and alert consumers do not own this schedule.
A row's per-scalar *_quality.as_of is when the observation arrived, not when
the snapshot was assembled, so a subscription the gateway still labels live but
which has stopped delivering ticks reads as a growing age. Two limits bind that
reading. A frozen quote's arrival instant is essentially read time, because the
gateway re-sends the last known value on request; and the instant advances on
any tick, size and volume included, so a name delivering only size ticks looks
alive while its price is frozen. An absent instant, or one ahead of the daemon
clock, is served as no as_of at all rather than as a fresh observation. No
rule keys off that age today — it is measurement, and the market-data-type flag
still reports the subscription's mode rather than whether data is flowing.
Two slower inputs keep their own publication clocks. Outside VIX3M
dissemination — before it opens as well as after it closes — the VIX term
observation stays visible and reads not_due whichever subscription mode the
broker reports for either Cboe index leg; while VVIX is current the volatility
source is healthy and not_due, not a stale-source warning.
Off-window the served VIX3M is Cboe's own published daily close whenever one
covers the last completed session, so the value carries a real observation date
rather than an inferred one. That matters because in frozen mode the broker
re-sends its last known value on request: arrival time cannot tell a current
value from a session-old one, and an index has no trade timestamp to date it
with. Comparing the two independent readings is what makes a stuck or lapsed
broker subscription visible, and not_due — which exempts a row from every age
bound short of the cluster's served maximum — is available only while that
comparison vouches for the leg. A contradicted or uncorroborated leg reads
overdue instead. Cboe publishes after the session, so for the evening between
the close and publication the broker leg stands in, bounded to one session; a
frozen leg is stamped with the end of the window that produced it, and a poll
missed while the thin index is not publishing carries the previous print rather
than blanking the row.
A poll missed while VIX3M is publishing is a different thing: the window is
open, so it is a failed refresh, and the carried print reads stale rather than
not_due. It bands and stays visible but can never confirm, and it is carried
only while live VIX has moved less than 1% since that print was observed, and
for at most 15 minutes. Past either bound the row is unavailable, because a
stale denominator overstates backwardation — the false-positive direction.
S&P 500 breadth starts after the official equity close plus a 35-minute
settlement delay. A full broker-paced pass can take about 74 minutes, so the
prior last-good is healthy pending context only while a refresh or retry
remains inside the explicit 90-minute publication window, and stale at that
deadline without a current-session result.
The FX carry proxy follows its venue instead of a publication clock. IDEALPRO
trades one continuous weekly session, so USD/JPY needs a live tick only while
that session is open; the weekend and the daily 17:00-17:15 ET changeover are
not_due context on the last tick, not a dead feed.
Breadth counts only constituent windows whose last bar matches the requested trading session. Successful windows are checkpointed every ten names, so a restart resumes near its last completed work instead of repeating the fan-out. The result exposes refresh start, processed and total names, publication deadline, and a redacted failure reason. Those fields describe progress; they never make an incomplete snapshot current.
Only a complete replacement becomes current. During a refresh, consumers see the
prior publication with refreshing authority health; a failed refresh keeps
last-good and marks authority stale with the typed failure and retry state. A
cold start with no valid publication is unavailable. Dependent sensors receive
this authority health and must not present a stale publication as current.
Safe check
canary status --json
canary regime --json
canary stress --json
canary rules --json
Since v3.4, canary regime --explain and MCP canary_regime restore the
indicator drill-down. JSON retains measurements, thresholds, eligibility and
source health; gamma profile arrays require --profiles or MCP
include_profiles=true. History and forced refresh remain retired.
Check Regime authority health, as_of, lifecycle readiness, each cluster's
source_health, row freshness and eligibility, then governors. A green row
does not prove the whole result is usable when another required cluster is
overdue.
Stress
What it answers
Stress asks whether the current broad-market state is relevant to the portfolio actually held. It combines four daemon-owned inputs: account, positions, the exact published Regime result, and market events for held names. It does not fetch a second market view, and it never treats the portfolio's own losses as confirmation of a broad market event.
The output separates market_confirmation, portfolio_fit, and input_health,
then derives an action such as stand_down, watch, defend, rebalance,
deploy, or confirm_inputs. It also reports planner readiness, bounded
held-name stress, source health, drivers, warnings, and a semantic fingerprint.
Timing and fail-closed prerequisites
The daemon evaluates Stress every minute, even when the app is closed. Evaluation is stateless; retained decision events are history, not an alternate current authority. Account and positions observations older than 10 minutes are stale during pre-market and RTH, 90 minutes outside those phases. Regime must carry usable last-good authority, and market-event source health must stay explicit.
The account timestamp still requires a completed, account-scoped broker
snapshot. Per-currency ledger rows are accepted only through the broker's
closed, typed ledger field set; aggregate ordinary and foreign-account rows fail
closed. Daily P&L is required during the US equity regular session. Silence
outside the session is not_due, leaves otherwise current account evidence
healthy, and keeps the P&L-specific observation explicitly unavailable.
Account and positions JSON also carry an authority block. It names the one
account and paper/live mode, the source, whether the result is available, and
whether it is current, stale, or of unknown age. Account summary fields each
have an availability flag, so 0 means zero only when that field was actually
received. An unresolved or conflicting account scope stays unavailable; a list
of managed accounts is never treated as one combined account.
Missing, stale, partial, or failed required inputs produce degraded/failed input
health and normally confirm_inputs with blocked readiness. Reg SHO and halt
health are required for a held book. Borrow inventory and fee health become
required only for a book holding a short stock, so an all-long book does not
fail for absent short-borrow evidence. Market-only stress cannot become a
portfolio defense instruction without usable portfolio fit, and portfolio loss or
margin pressure cannot manufacture market confirmation. Independently current
evidence may stay visible, but the input gap remains the headline condition.
Safe check
canary regime --json
canary stress --json
canary rules --json
Read Stress input health and source warnings before its summary, then compare
source timestamps, embedded market lifecycle, and held stress. Since v3.4,
canary stress and MCP canary_stress expose the complete assessment again;
canary brief retains the summary. canary stress --details shows market rows
and source health alongside the risk evidence.
Rulebook
What it answers
Rulebook evaluates 14 advisory discipline checks over the current book: which pass, which need attention, and which cannot be evaluated. Inputs are account and positions evidence, per-name earnings evidence, the classified Regime stage, and current SPY tape where a rule needs it. The pure evaluator returns all 14 rows in stable order plus a hardest-first ranking, breach counts, offenders, observed values, thresholds, and evidence. The detailed Trading Rulebook is the semantic authority; compiled v2 is an advisory model, not proof that every threshold has operator approval.
Row outcomes are pass, info, watch, act, unknown, or not_evaluated.
Missing or partial input cannot create a false pass. Provider disagreement or an
unresolved earnings source remains unknown. A carried or stale Regime stage is
evaluated against both the carried and calm threshold sets, keeping the worse
result so old market state cannot relax a rule.
Outside the US equity regular session, an absent Daily P&L frame is not_due
rather than an account failure. Rules with complete account and position inputs
still evaluate; the green-day/P&L rule alone remains not_evaluated. During the
regular session, missing or malformed Daily P&L continues to degrade account
health and fail closed.
Fetched earnings evidence is fresh for 24 hours, retained for bounded recovery up to 45 days, and retried after 15 minutes when a provider attempt fails. Last-good evidence stays labeled; it never replaces a current successful provider outcome or resolves disagreement.
Timing and preview reuse
The daemon owns a complete evaluation every minute, independently of the app. CLI, app, and preview readers reuse a result bound to scope, connector, and broker generation for up to 75 seconds. After that, a reader gets a bounded canonical evaluation or an explicit unavailable advisory; it never silently borrows a result from another account or connection generation.
Order previews may include Rulebook causes from this cache, but those warnings remain advisory and do not change broker submit eligibility. A missing preview warning is not evidence that the underlying input was healthy.
Safe check
canary rules --all --json
Check top-level status and every input_health row before counting passes.
Inspect unknown and not_evaluated reasons, policy identity, and the ranked
rows. Do not treat an old preview's annotations as a new Rulebook evaluation.
Market events
What they answer
Market events flag borrow, threshold-list, LULD, and halt context on a held or requested stock/ETF, to annotate risk review and protection proposals. The flags are reduce-only context and safety gates; they do not create opening-trade recommendations.
| Source | Authority and output | Cadence and failure meaning |
|---|---|---|
| Nasdaq Reg SHO | Latest available Nasdaq threshold-security file; emits reg_sho_threshold for covered symbols |
Cached fetch for 12 hours; source age may extend to 96 hours. Fetch failure serves labeled stale last-good when present. Absence covers Nasdaq's feed only, not every listing exchange. |
| Nasdaq halts | Nasdaq trade-halt feed; emits active/recent LULD or regulatory/news halt flags | One-minute freshness and one-minute retry. A failed refresh may serve labeled stale records; no current feed means halt absence is not conclusive. |
| IBKR borrow inventory | Generic tick 236 shortable-share observation; emits tight/scarce inventory | Two-minute source window. Missing ticks are unknown; recently absent symbols are re-probed after 30 minutes rather than held false for the day. |
| IBKR FTP borrow fee | Global short-stock availability file; emits extreme annualized fee only from current, policy-eligible evidence | Refreshes during the US equity regular session; 15-minute fresh window, 90-minute maximum age, 15-minute failure retry. Off-hours is typed not_due and may serve the latest completed-session last-good. |
TWS FEE_RATE |
Exact-contract historical context for currently held short stocks when due FTP evidence is unusable | Portfolio-only diagnostic fallback. Its numeric scale is uncommissioned, nullable, and policy-ineligible; it never creates or clears the global extreme-fee flag. |
The result carries per-source status, refresh_state, next_attempt, a
redacted typed last_failure, warnings, and a semantic fingerprint. Empty
flags is conclusive only when source health establishes current, complete
coverage. Unknown and null never mean inactive or zero. Borrow-inventory
aggregate health can read ok after at least one requested symbol reports, so
check the coverage note: other symbols may still lack a tick.
Safe check
canary status --json
canary brief --json
canary rules --symbol GME --json
Read market-event source_health before flags surfaced by the brief or rules.
For borrow fee, inspect
borrow_fee_coverage for global versus portfolio-only scope, entitlement, scale
status, and policy_eligible.
Operator checklist
Use read-only checks in this order:
- Run
canary status --jsonand confirm the gateway, data farms, background tasks, sensor subsystems, and top-level data-quality warnings. - Open the brief, rules, proposal, or app JSON surface that owns the sensor.
Check status, authority or source health, scope,
as_of, freshness, and warnings before interpreting measurements. - Follow the named dependency. Investigate Gamma before treating Regime's gamma row as a problem, and Regime before treating the stress read as a portfolio verdict.
- Re-read after the typed retry or publication window. Do not create a fetch
storm around a source that reports
not_dueor a futurenext_attempt. - Treat an alert surface as a downstream view. Sensor health does not prove push activation, delivery, receipt, or acknowledgement.
These checks are diagnostic only. None places, modifies, cancels, or authorizes an order.
Related pages
- Architecture: process, source, RPC, and runtime ownership.
- Trading Policy: who chooses limits and what remains advisory.
- Trading Rulebook: canonical rule, input-health, preview, alert, and authority semantics.
- Storage: last-good documents, observations, evidence, and recovery boundaries.
- Concepts: how to interpret calendars, Gamma, Regime, Stress, market events, and breadth.
- Risk Regime Dashboard Contract: row methodology, model detail, and evidence required to replace pending heuristics with calibrated policy.