Skip to main content

Crate of_core

Crate of_core 

Source
Expand description

§of_core

of_core defines the canonical data model and analytics primitives used across the Orderflow stack. It is provider-agnostic and intentionally lightweight so every binding (C, Python, Java) can rely on the same normalized semantics.

§What This Crate Contains

§New In 0.3.0

0.3.0 keeps the core data model API stable. The release hardens the runtime, persistence, dashboard, and binding layers around these types rather than changing of_core contracts.

§New In 0.2.0

Relative to the 0.1.x line, of_core now includes:

These are additive data-model extensions. They do not change the older AnalyticsSnapshot contract.

§Public API Inventory

Public types:

Public DataQualityFlags methods:

Public AnalyticsAccumulator methods:

§Design Principles

  • Deterministic arithmetic: prices and sizes are integer values, avoiding float drift in replay/backtests.
  • Stable schema: types are designed for cross-language transport and long-lived storage.
  • Minimal dependencies: this crate stays small so it can be embedded broadly.

§Type Semantics Reference

§Market identity and direction

  • SymbolId is the canonical identity key used everywhere in the project. venue should be the normalized venue name and symbol should remain stable for the life of a stream.
  • Side uses Bid and Ask for both book updates and trade aggressor direction.
  • BookAction uses Upsert for insert-or-replace semantics and Delete for level removal.

§Book event types

  • BookUpdate represents a single level mutation. level is the depth index from top of book. price and size are integer-normalized values. sequence, ts_exchange_ns, and ts_recv_ns preserve replay ordering and latency analysis.
  • BookLevel is the materialized view of one price level after runtime consolidation.
  • BookSnapshot is the full reconstructed book for one symbol at one point in time. bids and asks are level-ordered arrays. last_sequence is the sequence of the last applied update. ts_exchange_ns and ts_recv_ns are copied from that last applied update.

§Trade event types

  • TradePrint represents one normalized trade. price and size are integer-normalized. aggressor_side is the trade direction used by the analytics engine. sequence may be zero when a source does not provide a venue sequence.

§Analytics and signal output types

  • AnalyticsSnapshot is the base session analytics payload. It includes directional volume, delta, cumulative delta, POC, value area, and the active quality flags.
  • DerivedAnalyticsSnapshot adds additive session totals that were intentionally kept out of the original analytics payload so older consumers would not break.
  • SessionCandleSnapshot is a session-wide candle view derived from ingested trades.
  • IntervalCandleSnapshot is a rolling-window candle view computed on demand from recent trades for a caller-supplied window_ns.
  • SignalState is the stable directional state machine used across the runtime and bindings.
  • SignalSnapshot packages state, confidence, reason text, and quality flags for downstream consumers.

§AnalyticsAccumulator Contract

AnalyticsAccumulator is session-oriented.

Important behavior:

  • No book data is required for AnalyticsAccumulator; it is trade-driven.
  • All price and size arithmetic uses integer math at ingest time and converts only where a derived floating result is needed, such as vwap.
  • point_of_control is volume-based, not quote-based.
  • Value area fields are derived from traded-volume distribution, not full order-book depth.

§Quick Start

use of_core::{AnalyticsAccumulator, Side, SymbolId, TradePrint};

let symbol = SymbolId {
    venue: "CME".to_string(),
    symbol: "ESM6".to_string(),
};

let mut acc = AnalyticsAccumulator::default();
acc.on_trade(&TradePrint {
    symbol,
    price: 505_000,
    size: 10,
    aggressor_side: Side::Ask,
    sequence: 1,
    ts_exchange_ns: 1,
    ts_recv_ns: 2,
});

let snap = acc.snapshot();
assert_eq!(snap.buy_volume, 10);
assert_eq!(snap.delta, 10);

§Quality Flags

DataQualityFlags is a bitset used to express data-health issues such as stale feed, sequence gaps, and out-of-order events. Signals and runtime gating can use these flags to block unsafe decisions.

use of_core::DataQualityFlags;

let q = DataQualityFlags::STALE_FEED | DataQualityFlags::SEQUENCE_GAP;
assert!(q.intersects(DataQualityFlags::STALE_FEED));
assert_eq!(q.bits() & DataQualityFlags::SEQUENCE_GAP.bits(), DataQualityFlags::SEQUENCE_GAP.bits());

§Analytics Model Notes

  • delta tracks current session directional imbalance.
  • cumulative_delta retains directional accumulation over time.
  • point_of_control is computed as highest-volume price level.
  • value_area_low / value_area_high approximate the high-volume range around POC.
  • DerivedAnalyticsSnapshot adds session totals such as total_volume, trade_count, vwap, average_trade_size, and imbalance_bps without changing the original analytics payload.
  • SessionCandleSnapshot adds a candle-style session view with open, high, low, close, trade_count, and first/last exchange timestamps.
  • IntervalCandleSnapshot adds a parameterized rolling-window candle view with window_ns, open, high, low, close, trade_count, total_volume, vwap, and first/last exchange timestamps.

For full orchestration and adapter integration, see of_runtime.

§Book Snapshot Model

BookSnapshot materializes the latest known order book for one symbol:

  • bids: bid-side levels ordered by level
  • asks: ask-side levels ordered by level
  • last_sequence: sequence number of the most recent applied book event
  • ts_exchange_ns / ts_recv_ns: timestamps from the most recent applied book event

This snapshot model is used by the runtime and exposed through the FFI and bindings.

§Choosing the Right Snapshot Type

§Real-World Use Cases

§1. Offline research and replay analytics

Use AnalyticsAccumulator directly when you already have normalized trade data and want deterministic session analytics without the full runtime.

Typical use cases:

  • replaying one session from a CSV/JSONL converter
  • validating a strategy hypothesis before wiring live adapters
  • generating session summaries for dashboards or reports

§2. Shared schema between components

Use of_core as the common contract when writing:

  • custom adapters that emit normalized BookUpdate and TradePrint
  • custom signal modules that consume AnalyticsSnapshot
  • persistence or replay tools that must stay aligned with runtime semantics

§3. Strategy prototyping before runtime integration

For early-stage ideas, it is often faster to work only with TradePrint, AnalyticsAccumulator, and the output snapshot types before integrating with of_runtime.

§Detailed Example: Build Session Analytics From Trades

use of_core::{AnalyticsAccumulator, Side, SymbolId, TradePrint};

fn main() {
    let symbol = SymbolId {
        venue: "CME".to_string(),
        symbol: "ESM6".to_string(),
    };

    let trades = vec![
        TradePrint {
            symbol: symbol.clone(),
            price: 505_000,
            size: 8,
            aggressor_side: Side::Ask,
            sequence: 1,
            ts_exchange_ns: 1_000,
            ts_recv_ns: 1_100,
        },
        TradePrint {
            symbol: symbol.clone(),
            price: 505_025,
            size: 4,
            aggressor_side: Side::Ask,
            sequence: 2,
            ts_exchange_ns: 2_000,
            ts_recv_ns: 2_100,
        },
        TradePrint {
            symbol,
            price: 505_000,
            size: 6,
            aggressor_side: Side::Bid,
            sequence: 3,
            ts_exchange_ns: 3_000,
            ts_recv_ns: 3_100,
        },
    ];

    let mut acc = AnalyticsAccumulator::default();
    for trade in &trades {
        acc.on_trade(trade);
    }

    let analytics = acc.snapshot();
    let derived = acc.derived_snapshot();
    let session_candle = acc.session_candle_snapshot();
    let interval_candle = acc.interval_candle_snapshot(5_000);

    println!(
        "delta={} poc={} total_volume={} vwap={:.2}",
        analytics.delta,
        analytics.point_of_control,
        derived.total_volume,
        derived.vwap
    );
    println!(
        "session ohlc=({}, {}, {}, {}) trades={}",
        session_candle.open,
        session_candle.high,
        session_candle.low,
        session_candle.close,
        session_candle.trade_count
    );
    println!(
        "interval close={} interval_vwap={:.2}",
        interval_candle.close,
        interval_candle.vwap
    );
}

§Strategy-Prototyping Pattern

A common progression is:

  1. use TradePrint and AnalyticsAccumulator to compute deterministic features
  2. test threshold logic over AnalyticsSnapshot and DerivedAnalyticsSnapshot
  3. once stable, move the logic into an of_signals::SignalModule
  4. finally run it inside of_runtime for live or replay orchestration

Structs§

AnalyticsAccumulator
In-memory accumulator that updates analytics state from normalized trades.
AnalyticsSnapshot
Aggregated analytics for a symbol/session.
BookLevel
One normalized price level in a materialized book snapshot.
BookSnapshot
Materialized order-book snapshot for a symbol.
BookUpdate
Level-2 order book update.
DataQualityFlags
Bitset wrapper for feed-quality flags.
DerivedAnalyticsSnapshot
Additive derived analytics computed from the current session accumulator state.
IntervalCandleSnapshot
Rolling interval candle-style summary derived from recent session trades.
SessionCandleSnapshot
Session candle-style summary derived from the current analytics session.
SignalSnapshot
Snapshot of a signal module evaluation.
SymbolId
Canonical market symbol identifier used across venues.
TradePrint
Last-trade print/tick.

Enums§

BookAction
Book mutation kind.
Side
Trade or book side.
SignalState
Output state emitted by signal modules.