/**
 * # engine/pricing — price resolution + order intents (RUNTIME §4)
 *
 * The **pure** layer between a parsed price line (a {@link PriceExpr} + its
 * {@link OrderPolicy}, both from `src/lang`) and a concrete resting price with its audit
 * annotation and reprice intent. It is the one place that knows what `fair`, `mid`,
 * `lean(a,b,x)`, `join`, `improve`, `cap`, `floor`, `esc`, and `peg` mean when an order
 * rests (ARCHITECTURE §4: "exactly one place knows"). The lifecycle engine (next phase)
 * calls this to turn a plan clause's price into an order it can place / cancel-replace.
 *
 * No I/O, no clock, no RNG (RUNTIME §0): every timestamp (`now`, `placedAt`) is injected, the
 * only fair value comes from the pure {@link executionFair}, and the reprice rate limiter is an
 * injected {@link RepriceTokenBucket} the caller owns. Same inputs ⇒ same result.
 *
 * ## The contract it enforces (RUNTIME §4)
 * - **`fair` = ExecutionFair with receipts.** When fair is unbuildable (`fairInput` null, or
 *   {@link executionFair} returns null) the resolution falls back to an **annotated** book
 *   value — `fair=fallback(mid)` for a BUY, `fair=fallback(max(mid,intrinsic))` for a SELL —
 *   and the annotation rides on the result. **A silent mid is forbidden**: the fallback is
 *   never invisible.
 * - **`basis` with no held position is UNRESOLVABLE** (the engine de-arms the statement,
 *   RUNTIME §8) — never a guessed cost.
 * - **BOOK anchors** (`bid ask mid last join improve`) read the leg quote; a dark side they
 *   need makes the whole line unresolvable (fail-closed, never a fabricated level).
 * - **BUY caps compose to the TIGHTEST** (min upper bound); a pegged BUY carries an implicit
 *   default `fair` cap (heritage) so a chase never bids above fair.
 * - **SELL floors compose to the HIGHEST** (max lower bound) and **always include intrinsic**;
 *   every resolved SELL price is `>= intrinsic`, ceil-snapped, always.
 * - **Tick snapping:** BUY floor-snaps, SELL ceil-snaps — and a SELL never lands below
 *   intrinsic after the snap.
 * - **`esc` stages are ABSOLUTE-FROM-PLACEMENT:** the stage clock starts at `placedAt`, not at
 *   the last reprice; the active stage's target replaces the base price, and crossing a stage
 *   boundary is a reprice.
 * - **`peg` re-resolves on data change** but only emits a reprice intent on **>= 1-tick drift**
 *   (hysteresis) and only if the injected token bucket grants a token; sub-tick drift or a
 *   denied token holds the order at its prior price.
 */
import type { Right } from "../bus/index.ts";
import type { OrderPolicy, PriceExpr } from "../lang/index.ts";
import type { ExecutionFairInput } from "../fair/index.ts";
/** A parsed price line: which price ({@link PriceExpr}) and how it rests ({@link OrderPolicy}
 * — peg/fix, esc ladder, cap/floor lists). Extracted by the caller from any ticket clause
 * (`DO` / `ALSO` / `RELOAD` / `TP` / `EXIT`), all of which carry a `price` + optional
 * `policy`. */
export interface PriceLine {
    readonly price: PriceExpr;
    readonly policy?: OrderPolicy;
}
/** The injected global reprice rate limiter. A pegged reprice consumes a token; when the
 * bucket is empty the order holds at its prior price (RUNTIME §4). The caller owns refill and
 * scope — pricing only asks. */
export interface RepriceTokenBucket {
    /** Take one token, returning whether one was available. Called at most once per pegged
     * reprice, only after the >=1-tick hysteresis gate passes. */
    tryTake(): boolean;
}
/** The prior resolution of the same order, supplied on re-resolution so peg hysteresis and
 * esc-boundary detection have something to diff against. Absent on the first placement. */
export interface PriorResolution {
    readonly px: number;
    readonly escStage: number;
}
/** The quote a price resolution reads — the structural subset of a bus `OptionQuote` (which
 * satisfies it as-is), and exactly the shape a spot instrument's own NBBO provides (ADR-0017:
 * no strike/right on a spot quote). A dark side is `null`. */
export interface LegQuote {
    readonly bid: number | null;
    readonly ask: number | null;
    /** Last trade price, when one has printed. */
    readonly last?: number;
}
/** Everything a single price resolution needs. All time is injected (RUNTIME §0). */
export interface PriceCtx {
    /** The order side — decides fallback shape, join/improve direction, snap direction, and the
     * intrinsic floor. */
    readonly side: "buy" | "sell";
    /** The leg being priced (locates the quote on the book; carried for annotation/audit).
     * `strike`/`right` are absent for a spot instrument (ADR-0017 — a spot leg has neither). */
    readonly leg: {
        readonly instrument: string;
        readonly strike?: number;
        readonly right?: Right;
    };
    /** The current quote for this leg (`bid`/`ask`/`last`). A dark side is `null`. */
    readonly quote: LegQuote;
    /** Which price doctrine applies (ADR-0017). Absent or `"option"` ⇒ the options doctrine
     * (Black-76 `@fair` with annotated fallback, `@intrinsic`/`@basis` anchors, intrinsic SELL
     * floor) — byte-identical to before this field existed. `"spot"` ⇒ the spot doctrine:
     * `@fair` = the instrument's own two-sided quote mid with a receipt (`exec-fair-quote-v1`,
     * fail-closed to UNRESOLVABLE when one-sided/dark/crossed — never a silent mid, never
     * Black-76), and `@intrinsic`/`@basis` are refused (option anchors; a spot leg has no strike
     * to take an intrinsic of). */
    readonly instrumentKind?: "option" | "spot";
    /** The inputs to {@link executionFair} for this leg, or `null` when no fair can even be
     * attempted — either way `@fair` resolves through the annotated fallback when unbuildable. */
    readonly fairInput: ExecutionFairInput | null;
    /** The held position's cost basis, or `null` when nothing is held — a `basis` anchor is then
     * unresolvable (the statement de-arms, RUNTIME §8). */
    readonly basis: number | null;
    /** Per-contract intrinsic of this leg at the current spot (injected — the engine computes it
     * from canonical state). The `intrinsic` anchor and the mandatory SELL floor read it. */
    readonly intrinsic: number;
    /** The canonical underlying spot — the SAME value the `spot` SERIES reads (`CanonicalState.spot`),
     * NOT the quote mid (that would be a two-truths divergence). The `spot` PRICE anchor (ADR-0030 /
     * kestrel-ipc) reads it, and ONLY for an equity/spot instrument. `null` (UNKNOWN — a gapped/dead
     * feed) ⇒ the `spot` anchor is unresolvable and the statement de-arms fail-closed (ven.4); a
     * silent fallback to mid/last is forbidden. Absent for an option leg — the anchor is refused
     * there before this field is ever read. */
    readonly spot?: number | null;
    /** The instrument tick size (dollars). BUY floor-snaps to it, SELL ceil-snaps; `improve`
     * steps one of these; peg hysteresis is measured in it. */
    readonly tickSize: number;
    /** The current event timestamp (epoch ms, the bus clock in sim — RUNTIME §0). */
    readonly now: number;
    /** The order's placement timestamp (epoch ms). `esc` stages are ABSOLUTE-FROM-PLACEMENT, so
     * elapsed = `now - placedAt`. Defaults to `now` (fresh placement ⇒ stage 0). */
    readonly placedAt?: number;
    /** The prior resolution, for peg hysteresis + esc-boundary reprice. Absent on first
     * placement. */
    readonly prior?: PriorResolution;
    /** The injected reprice token bucket (peg only). Absent ⇒ no rate limit. */
    readonly tokenBucket?: RepriceTokenBucket;
}
/** A resolved order intent, or an unresolvable line. The resolved shape always carries a
 * `sourceAnnotation` — the audit trail RUNTIME §4 requires (a fallback is never silent). When
 * `repriceOf` is present the caller should cancel/replace the prior resting order at that
 * price; when absent the order holds (first placement, sub-tick hysteresis, or a denied
 * token). */
export type PriceResolution = {
    readonly px: number;
    readonly sourceAnnotation: string;
    readonly capped: boolean;
    readonly floored: boolean;
    /** 0 = the base price line; N>0 = the Nth `esc` stage (1-based) is active. */
    readonly escStage: number;
    /** The prior resting price this intent cancel-replaces, when it is a reprice. */
    readonly repriceOf?: number;
} | {
    readonly unresolvable: string;
};
/** Is this resolution an unresolvable line? */
export declare function isUnresolvable(r: PriceResolution): r is {
    readonly unresolvable: string;
};
/**
 * The horizon inside which a book is FRESH enough for the fair-vs-book bound to have authority
 * (kestrel-ku99). Deliberately bound to the SAME declared staleness horizon the settle-mark gate
 * uses (kestrel-xwf) rather than forking a second tunable: both answer one question — "is this
 * quote still a live fact?" — and its rationale carries over verbatim (comfortably coarser than
 * the tape's event cadence, orders of magnitude finer than the hours-frozen-feed failure it
 * exists to catch). One declared staleness horizon, not two that silently drift apart.
 */
export declare const BOOK_FRESH_WITHIN_MS = 300000;
/**
 * Resolve a price line to a concrete resting price + order intent (RUNTIME §4). Pure and
 * total: any unbuildable anchor / missing basis / dark side needed returns
 * `{ unresolvable }` (the engine de-arms, RUNTIME §8) rather than throwing or guessing.
 *
 * Pipeline: pick the active `esc` stage (absolute-from-placement) → resolve its expression
 * (anchors, offsets, lean, min/max) → apply BUY caps (tightest) → apply floors (highest; SELL
 * always intrinsic) → snap to tick (BUY down, SELL up, SELL never below intrinsic) → decide the
 * reprice intent (esc boundary always reprices; peg reprices on >=1-tick drift under the token
 * bucket; fix and sub-tick hold).
 */
export declare function resolvePrice(line: PriceLine, ctx: PriceCtx): PriceResolution;
//# sourceMappingURL=pricing.d.ts.map