of_ffi_c
of_ffi_c exposes a stable C ABI for embedding the Orderflow runtime in non-Rust environments.
It is the native interface used by Python (ctypes), Java (JNA), and any C-compatible host runtime.
ABI Surface
- Engine lifecycle:
of_engine_create,of_engine_start,of_engine_stop,of_engine_destroy - Subscription:
of_subscribe,of_unsubscribe,of_unsubscribe_symbol,of_reset_symbol_session - External ingest and supervision:
of_ingest_trade,of_ingest_book,of_configure_external_feed,of_external_set_reconnecting,of_external_health_tick - Polling and snapshots:
of_engine_poll_once,of_get_book_snapshot,of_get_analytics_snapshot,of_get_derived_analytics_snapshot,of_get_session_candle_snapshot,of_get_interval_candle_snapshot,of_get_signal_snapshot - Metrics and memory management:
of_get_metrics_json,of_string_free
New In 0.2.0
Relative to the 0.1.x line, the C ABI now exposes:
of_get_book_snapshot(...)of_get_derived_analytics_snapshot(...)of_get_session_candle_snapshot(...)of_get_interval_candle_snapshot(...)BOOK_SNAPSHOTcallback stream supportDERIVED_ANALYTICScallback stream support
These are additive ABI extensions; existing lifecycle and polling calls remain valid.
Public ABI Inventory
Public C structs/types:
of_engine_config_tof_symbol_tof_trade_tof_book_tof_external_feed_policy_tof_error_tof_engineof_subscriptionof_event_tof_event_cb
Exported C functions:
of_api_versionof_build_infoof_engine_createof_engine_startof_engine_stopof_engine_destroyof_subscribeof_unsubscribeof_unsubscribe_symbolof_reset_symbol_sessionof_ingest_tradeof_ingest_bookof_configure_external_feedof_external_set_reconnectingof_external_health_tickof_get_book_snapshotof_get_analytics_snapshotof_get_derived_analytics_snapshotof_get_session_candle_snapshotof_get_interval_candle_snapshotof_get_signal_snapshotof_get_metrics_jsonof_string_freeof_engine_poll_once
of_get_book_snapshot returns a materialized JSON snapshot with:
venuesymbolbidsaskslast_sequencets_exchange_nsts_recv_ns
of_get_derived_analytics_snapshot returns additive session metrics with:
total_volumetrade_countvwapaverage_trade_sizeimbalance_bps
of_get_session_candle_snapshot returns candle-style session state with:
openhighlowclosetrade_countfirst_ts_exchange_nslast_ts_exchange_ns
of_get_interval_candle_snapshot returns rolling-window candle state for a caller-supplied window_ns with:
window_nsopenhighlowclosetrade_counttotal_volumevwapfirst_ts_exchange_nslast_ts_exchange_ns
Subscription stream ids:
1:BOOKraw book updates2:TRADESraw trade prints3:ANALYTICSsnapshot callbacks4:SIGNALSsnapshot callbacks5:HEALTHtransition callbacks6:BOOK_SNAPSHOTmaterialized book snapshot callbacks after book changes7:DERIVED_ANALYTICSsession-derived analytics callbacks after trade changes
C Struct Reference
of_engine_config_t:
instance_id: optional runtime instance id overrideconfig_path: optional.tomlor.jsonruntime config pathlog_level: reserved for host integrationsenable_persistence: non-zero enables persistenceaudit_max_bytes: audit rotation sizeaudit_max_files: audit retention countaudit_redact_tokens_csv: comma-separated audit redaction tokensdata_retention_max_bytes: persistence byte capdata_retention_max_age_secs: persistence age cap in seconds
of_symbol_t:
venue: venue/exchange namesymbol: normalized symbol stringdepth_levels: requested book depth for subscribe calls
of_trade_t:
symbol: embedded [of_symbol_t]price,size: integer-normalized trade valuesaggressor_side: one ofOF_SIDE_BIDorOF_SIDE_ASKsequence: venue sequence or0when unavailablets_exchange_ns,ts_recv_ns: exchange and local timestamps
of_book_t:
symbol: embedded [of_symbol_t]side: one ofOF_SIDE_BIDorOF_SIDE_ASKlevel: top-of-book-relative depth indexprice,size: integer-normalized book valuesaction: one ofOF_BOOK_ACTION_UPSERTorOF_BOOK_ACTION_DELETEsequence: venue sequence or0when unavailablets_exchange_ns,ts_recv_ns: exchange and local timestamps
of_external_feed_policy_t:
stale_after_ms: max allowed ingest silence before stale statusenforce_sequence: non-zero enables sequence-gap/out-of-order checks
of_event_t callback envelope:
kind: stream kind idpayload/payload_len: UTF-8 JSON payload bytesschema_id: payload schema id, currently1quality_flags:OF_DQ_*bits associated with the event- timestamps are copied from the underlying event when available
Function Family Reference
Lifecycle:
of_engine_createof_engine_startof_engine_stopof_engine_destroy
Subscription:
of_subscribeof_unsubscribeof_unsubscribe_symbolof_reset_symbol_session
External ingest and supervision:
of_ingest_tradeof_ingest_bookof_configure_external_feedof_external_set_reconnectingof_external_health_tick
Polling and snapshots:
of_engine_poll_onceof_get_book_snapshotof_get_analytics_snapshotof_get_derived_analytics_snapshotof_get_session_candle_snapshotof_get_interval_candle_snapshotof_get_signal_snapshot
Metadata and ownership helpers:
of_api_versionof_build_infoof_get_metrics_jsonof_string_free
Safety Contract
Callers must:
- pass valid non-null pointers for required pointer arguments
- pass UTF-8
char*values where strings are expected - preserve pointer validity for the full duration of each call
- free owned strings returned by the API using
of_string_free
Additional ownership rules:
- snapshot getters that write into caller buffers do not allocate for the caller
- functions returning owned
char*requireof_string_free - callback payload pointers are only valid for the duration of the callback
- opaque
of_engine_t*andof_subscription_t*handles must be destroyed/unsubscribed only through exported API calls
Minimal C Example
int
Error Semantics
Most functions return int32_t values mapped from [of_error_t]:
OF_OKfor successOF_ERR_INVALID_ARGfor invalid pointers/inputsOF_ERR_STATEfor lifecycle misuse or invalid runtime stateOF_ERR_IO,OF_ERR_DATA_QUALITY, and other domain-specific failures
Snapshot and Callback Payload Contracts
of_get_book_snapshot(...)andBOOK_SNAPSHOTcallbacks share the same JSON schemaof_get_derived_analytics_snapshot(...)andDERIVED_ANALYTICScallbacks share the same JSON schemaof_get_session_candle_snapshot(...)andof_get_interval_candle_snapshot(...)are additive snapshot families and do not alter the older analytics/signal contractsinout_lenis both input capacity and output required size; if the buffer is too small, retry with the returned byte count- payload field names are treated as stable once published; new fields are added additively
Integration Notes
- Treat engine and subscription handles as opaque; do not cast or inspect internals.
- Keep ABI structs initialized (zero-init is recommended before setting fields).
- Prefer explicit timestamps and sequence numbers for external ingest to maximize quality checks.
- Snapshot functions write the required byte length back through
inout_len; if the caller buffer is too small, retry with the returned size. BOOK_SNAPSHOTcallbacks emit the same JSON shape asof_get_book_snapshot(...), but only when book state changes for the subscribed symbol.DERIVED_ANALYTICScallbacks emit the same JSON shape asof_get_derived_analytics_snapshot(...), but only when trade-driven analytics change for the subscribed symbol.
Real-World Use Cases
1. Embed the runtime in a C or C++ trading host
Use the lifecycle, subscription, and polling APIs directly from a native host process that already owns process supervision and deployment.
2. Drive Python or Java bindings from the same native ABI
The Python and Java packages both rely on this ABI, so host-side operators can reason about one native contract instead of three unrelated APIs.
3. Build a custom host-side event pump
Use callbacks for snapshot/event delivery and poll-driven control for host-side scheduling.
Detailed Example: Poll And Read Snapshots
int
- Prefer explicit timestamps and sequence numbers for external ingest to maximize quality checks.
- Snapshot functions write the required byte length back through
inout_len; if the caller buffer is too small, retry with the returned size. BOOK_SNAPSHOTcallbacks emit the same JSON shape asof_get_book_snapshot(...), but only when book state changes for the subscribed symbol.DERIVED_ANALYTICScallbacks emit the same JSON shape asof_get_derived_analytics_snapshot(...), but only when trade-driven analytics change for the subscribed symbol.