High-performance exchange feed parser and orderflow analytics engine with Rust and Python bindings
Project description
OrderPulse
Ultra-fast exchange feed parser and in-memory order book engine written in Rust with Python bindings using PyO3.
OrderPulse is designed for quantitative trading infrastructure where binary market feeds must be decoded with minimal latency and reused efficiently across analytics, simulation, and execution pipelines.
Why This Library Exists
In real trading systems, the biggest bottleneck is usually not strategy logic. It is:
- binary feed parsing
- repeated disk I/O
- inefficient Python loops
- rebuilding order books repeatedly
- memory duplication
This library solves that.
The architecture is intentionally designed like a production-grade market data engine:
- Rust handles parsing and memory management
- Python becomes orchestration layer only
- Binary file is read once
- Messages are shared using
Arc<Vec<Message>> - Multiple consumers can process same data without re-reading disk
- Orderbook reconstruction is incremental and event-driven
This is exactly how low-latency market data infrastructure is designed in professional trading firms.
Architecture
Binary Exchange Feed
|
v
+-----------------------+
| ReadMsgFromBinary |
|-----------------------|
| Parse binary packets |
| Filter token streams |
| Store in shared RAM |
+-----------------------+
|
Shared Arc<Vec<Message>>
|
------------------------------------------------
| |
v v
+----------------------+ +---------------------------+
| BinaryLoader | | OrderBookGenerator |
|----------------------| |---------------------------|
| Sequential streaming | | Incremental book builder |
| Cursor-based access | | Top-of-book snapshots |
| Zero reread | | Bid/ask reconstruction |
+----------------------+ +---------------------------+
Installation
Build Rust Extension
maturin develop --release
or
pip install maturin
maturin build --release
Python API
The library exposes three primary classes:
| Class | Purpose |
|---|---|
ReadMsgFromBinary |
Parse and hold binary feed in memory |
BinaryLoader |
Sequential streaming over parsed messages |
OrderBookGenerator |
Build live order book snapshots |
1. ReadMsgFromBinary
This is the entry point of the entire system.
It performs:
- binary file parsing
- decoding order packets
- decoding trade packets
- optional token filtering
- storing all parsed messages into shared memory
The important architectural decision:
File is read ONLY ONCE.
After parsing, every component works from RAM.
Constructor
ReadMsgFromBinary(path, token=None)
Parameters
| Parameter | Type | Description | |
|---|---|---|---|
path |
str |
Binary market feed file | |
token |
`int | None` | Optional instrument filter |
Example — Full Feed Load
from fastreader import ReadMsgFromBinary
reader = ReadMsgFromBinary(
path="nse_market_feed.bin"
)
What Happens Internally
Disk Binary File
↓
Rust Decoder
↓
Order + Trade Messages
↓
Stored Into Shared Arc<Vec<Message>>
No additional disk access occurs afterward.
Example — Single Instrument Feed
In production trading systems, strategies usually subscribe to a small subset of instruments.
This constructor-level filtering avoids unnecessary memory usage.
reader = ReadMsgFromBinary(
path="market_feed.bin",
token=26000
)
This means:
- only token
26000messages are retained - all unrelated packets are discarded during parsing
- memory footprint becomes significantly smaller
- downstream analytics become faster
Functions in ReadMsgFromBinary
total_messages()
Returns total parsed packets.
count = reader.total_messages()
print(count)
Production Use Case
Useful for:
- feed completeness checks
- session diagnostics
- replay validation
- packet gap analysis
total_orders()
Returns total order messages.
orders = reader.total_orders()
print(orders)
Typical Order Messages
These may include:
- add order
- modify order
- cancel order
- delete order
total_trades()
Returns total trade messages.
trades = reader.total_trades()
print(trades)
Production Usage
Useful for:
- trade intensity analysis
- execution profiling
- aggressor flow estimation
- VWAP reconstruction
summary()
Quick feed overview.
reader.summary()
Example Output
Total Messages: 12093811
Total Orders: 11800210
Total Trades: 293601
Why Traders Use This
Usually the first command after loading any exchange capture.
Acts as:
- sanity check
- parser verification
- session health indicator
reset_cursor()
Resets internal iterator.
reader.reset_cursor()
Why This Matters
In replay systems:
- one strategy may consume messages once
- another backtest may need replay again
Cursor reset avoids reloading the file.
get_all_messages(limit=None)
Returns all parsed packets.
messages = reader.get_all_messages(limit=5)
for msg in messages:
print(msg)
Example Output
Order Message: SeqNo1001, msg_len64, Msg_Type'N', ...
Trade Message: SeqNo1002, msg_len56, Msg_Type'T', ...
Engineering Insight
This function is useful for:
- debugging parsers
- validating exchange packet structure
- building analytics prototypes
- replay verification
get_order_messages(limit=None)
Returns only order packets.
orders = reader.get_order_messages(limit=10)
Typical Usage
Used when reconstructing:
- queue position
- order flow imbalance
- liquidity dynamics
- passive/active pressure
get_trade_messages(limit=None)
Returns only trade packets.
trades = reader.get_trade_messages(limit=10)
Production Use Cases
Used for:
- tape reading
- execution analytics
- trade clustering
- market impact modeling
2. BinaryLoader
BinaryLoader is a lightweight sequential reader.
It does NOT:
- reopen files
- allocate memory again
- duplicate messages
It simply streams over already parsed RAM data.
This design is critical in high-frequency simulation systems.
Constructor
BinaryLoader(reader)
Example
from fastreader import BinaryLoader
loader = BinaryLoader(reader)
Internal Design
BinaryLoader
↓
Shared Arc<Vec<Message>>
↓
Cursor-based sequential fetch
This is essentially a replay engine.
get_next_message()
Returns next sequential packet.
while True:
msg = loader.get_next_message()
if msg == "END":
break
print(msg)
Why This Is Important
Professional trading systems are event-driven.
Strategies consume:
- one packet at a time
- in strict sequence order
- without loading entire dataset repeatedly
This method replicates live-feed style consumption.
reset_cursor()
Restart sequential replay.
loader.reset_cursor()
Use Case
Useful for:
- strategy reruns
- simulation resets
- deterministic testing
- model validation
3. OrderBookGenerator
This is the order book reconstruction engine.
It processes:
- order add
- modify
- cancel
- trade execution
and incrementally maintains:
- bid levels
- ask levels
- mid price
- depth snapshots
This is the core of market microstructure infrastructure.
Constructor
from fastreader import OrderBookGenerator
ob = OrderBookGenerator()
create_orderbook(reader)
Builds top-of-book snapshots from parsed messages.
rows = ob.create_orderbook(reader)
print(rows)
Internal Processing Pipeline
Market Messages
↓
OrderBookManager
↓
Incremental Bid/Ask Update
↓
Top 5 Levels Extraction
↓
Mid Price Computation
↓
Snapshot Output
Example Snapshot
local_ts1711000100,
exch_ts1711000001,
mid_price22451.25,
bid_price_022450.95,
bid_qty_0150,
ask_price_022451.55,
ask_qty_0100
What Makes This Fast
1. Rust Memory Safety
No Python object overhead during parsing.
2. Shared Memory Architecture
Arc<Vec<Message>>
Messages are:
- stored once
- shared safely
- reused everywhere
- zero-copy shared
3. Sequential Replay Design
Cursor-based replay avoids:
- reallocation
- reindexing
- repeated parsing
4. Event-Driven Order Book
Order book updates are incremental.
The engine does NOT rebuild entire depth every tick.
This is how institutional trading engines work.
Complete Production Example
from fastreader import (
ReadMsgFromBinary,
BinaryLoader,
OrderBookGenerator
)
# =====================================================
# STEP 1 — LOAD BINARY FEED
# =====================================================
reader = ReadMsgFromBinary(
path="nse_capture.bin",
token=26000
)
reader.summary()
# =====================================================
# STEP 2 — EVENT REPLAY
# =====================================================
loader = BinaryLoader(reader)
while True:
msg = loader.get_next_message()
if msg == "END":
break
# strategy logic here
print(msg)
# =====================================================
# STEP 3 — ORDER BOOK RECONSTRUCTION
# =====================================================
ob = OrderBookGenerator()
rows = ob.create_orderbook(reader)
print(f"Generated snapshots: {rows}")
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file orderpulse-0.2.19.tar.gz.
File metadata
- Download URL: orderpulse-0.2.19.tar.gz
- Upload date:
- Size: 26.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: maturin/1.12.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
87781ba33738d49fa013dd48cac15d59461a06101995de31c23f96a106a66c47
|
|
| MD5 |
8969a268680014e22ae92f41cf2d93f4
|
|
| BLAKE2b-256 |
64b7059530a57b39c76d3032f3fdbecd7ebb184d41aa3e46d8715a120126a2bb
|
File details
Details for the file orderpulse-0.2.19-cp39-cp39-manylinux_2_34_x86_64.whl.
File metadata
- Download URL: orderpulse-0.2.19-cp39-cp39-manylinux_2_34_x86_64.whl
- Upload date:
- Size: 248.6 kB
- Tags: CPython 3.9, manylinux: glibc 2.34+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: maturin/1.12.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
509d7e404b35aecbc7a4ca69ef7940afecf20199d76a2154f070168deea5f423
|
|
| MD5 |
f90bdb693bad110a14f0259650de42c1
|
|
| BLAKE2b-256 |
b11170aedf5fa1558f880e544c4079c006a4b2d8f36813b216384ccbc7329163
|