/**
 * # series/state — the canonical market state per signal instrument (RUNTIME §2)
 *
 * One causal coordinate per signal instrument: `spot`, `hod`/`lod` (+ their timestamps),
 * the **opening range**, `vwap`, `prior_close`, and the session **phase**. It is updated
 * **only** from bus events via {@link CanonicalState.applyEvent} — the single ingress —
 * and every derived series (the window metrics, the provider) reads back through it;
 * nothing is recomputed per consumer (RUNTIME §2). State at event *N* is a pure function
 * of events `≤ N` (no look-ahead, RUNTIME §0/§7).
 *
 * ## VWAP — time-weighted (documented choice)
 * The v1 bus `SpotPayload` is `{ instrument, px }` — it carries **no volume**. VWAP is
 * therefore **time-weighted**: each price is weighted by the time it prevailed, so
 * `vwap = Σ pxᵢ·dtᵢ / Σ dtᵢ` where `dtᵢ` is the interval price *i* was the standing quote
 * (the left-price of each interval). This is the honest reduction the data supports; the
 * accumulator is generic over the weight, so a future volume-bearing SPOT specializes to
 * true volume-weighting with no change to callers. Before the second tick there is no
 * elapsed interval, so vwap reads the first spot (a degenerate single-sample average).
 *
 * ## prior_close — injected, not on the v1 META
 * `prior_close` is a *cross-session* fact and the v1 `MetaPayload`
 * (`session_date/instruments/mode/bus_schema`) does not carry it. It is injected via
 * {@link CanonicalStateConfig.priorClose} at construction. Absent that, `prior_close`
 * reads UNKNOWN and any statement referencing it de-arms cleanly (fail-closed, RUNTIME §8).
 *
 * ## Opening range — first N minutes
 * The opening range is the high/low of spot over the first `openingRangeMinutes` (default
 * 5) of the session, anchored at the **first SPOT tick's ts** (the session's first observed
 * price). It reads UNKNOWN until that first tick; once the window elapses it is frozen.
 *
 * ## Inclusive vs exclusive levels — the pane/trigger split (RUNTIME §2)
 * `hod`/`lod` (and `or_high`/`or_low` while the range is still forming) come in **two
 * flavours**. The plain getters (`hod`, `lod`, `orHigh`, `orLow`) are **inclusive** of the
 * current sample — the true running extreme a pane/frame should display. The **`*Trigger`**
 * getters (`hodTrigger`, …) are **exclusive** of the current sample: the value as it stood
 * **before** this event's spot was folded in. Trigger evaluation reads the exclusive flavour
 * so `spot crosses above hod` can actually fire — a fresh high IS a cross above the prior
 * high (the trader idiom). With the inclusive value the current spot is already baked into
 * `hod`, so `spot > hod` is never true and the cross can never fire. The exclusive value is
 * captured at the top of {@link CanonicalState.onSpot}, before the extreme is updated; a
 * non-SPOT event leaves it untouched (there is no new sample to be exclusive of).
 */
import type { BusEvent, SessionPhase } from "../bus/index.ts";
import { type Unknown } from "./types.ts";
import { WindowEngine, type WindowConfig } from "./windows.ts";
/** A `(value, ts)` reading — a level with the injected timestamp it was set at. */
export interface Stamped {
    readonly value: number;
    readonly ts: number;
}
export interface CanonicalStateConfig {
    /** The signal instrument this state tracks. Only SPOT ticks for this symbol drive it. */
    readonly instrument: string;
    /** Prior session's close (cross-session; not on the v1 META). UNKNOWN if omitted. */
    readonly priorClose?: number;
    /** Opening-range span in minutes (default 5). */
    readonly openingRangeMinutes?: number;
    /** Window-engine configuration (baseline capacity, warmup floor, sample cap). */
    readonly windows?: WindowConfig;
}
export declare class CanonicalState {
    readonly instrument: string;
    readonly windows: WindowEngine;
    private readonly orMs;
    private readonly priorCloseVal;
    private spotVal;
    private spotTs;
    private hodVal;
    private lodVal;
    private hodExclVal;
    private lodExclVal;
    private orHiExclVal;
    private orLoExclVal;
    private orAnchorTs;
    private orHi;
    private orLo;
    private vwapNum;
    private vwapDen;
    private lastPx;
    private lastPxTs;
    private phaseVal;
    constructor(cfg: CanonicalStateConfig);
    /** The single ingress. Applies a bus event to the canonical state — SPOT (this
     * instrument) drives price/level/vwap/windows; HEARTBEAT carries the session phase; all
     * other streams are ignored here (they are handled by other modules). Idempotent-safe on
     * unrelated events. */
    applyEvent(ev: BusEvent): void;
    private onSpot;
    get spot(): number | Unknown;
    get spotStamp(): Stamped | Unknown;
    get hod(): number | Unknown;
    get hodStamp(): Stamped | Unknown;
    get lod(): number | Unknown;
    get lodStamp(): Stamped | Unknown;
    /** `hod` as it stood before this event's spot — so a fresh high is a cross above it. */
    get hodTrigger(): number | Unknown;
    /** `lod` as it stood before this event's spot — so a fresh low is a cross below it. */
    get lodTrigger(): number | Unknown;
    /** `or_high` exclusive of the current sample while the range forms; the frozen level after. */
    get orHighTrigger(): number | Unknown;
    /** `or_low` exclusive of the current sample while the range forms; the frozen level after. */
    get orLowTrigger(): number | Unknown;
    get priorClose(): number | Unknown;
    get orHigh(): number | Unknown;
    get orLow(): number | Unknown;
    get phase(): SessionPhase | Unknown;
    /** Time-weighted VWAP (see file header). UNKNOWN before the first spot; the first spot's
     * price until an interval accrues; the weighted average thereafter. */
    get vwap(): number | Unknown;
    reset(): void;
}
//# sourceMappingURL=state.d.ts.map