High-performance exchange feed parser and orderflow analytics engine with Rust and Python bindings
Project description
fastReader Library Guide
fastReader is a high-performance Python extension (implemented in Rust via PyO3) for reading binary order/trade feed files and building an in-memory order book.
This README is generated from the current API in src/lib.rs and explains:
- how users should import and use the library,
- what each public function does,
- expected output shape/examples,
- and architecture with a practical workflow.
Correct Python Import
The module name is defined by this function in src/lib.rs:
#[pymodule]
fn fastReader(_py: Python<'_>, m: &Bound<'_, PyModule>) -> PyResult<()> {
So in Python, import like this:
import fastReader as fr
You can use any alias (fr, reader, etc.), but fastReader must match the module name.
Architecture (How Data Flows)
Binary feed file (.bin)
|
v
read_trd_ord_only(path)
|- mmap file
|- detect msg type (N / M / X / T)
|- parse packed structs (OrderPacket / TradePacket)
`- return Vec<Message>
|
+--> MessageCacheReader (full cache in memory)
|
`--> StreamingBinaryLoader (cursor-based sequential consumption)
|
v
OrderbookBuilder
|
|- apply_filter(...) [optional]
|- build_from_list(...) or build_from_source(...)
`- get_snapshot(token, levels)
Internal Components
MessageCacheReader- Stores parsed messages in
Arc<Vec<Message>>for shared read access.
- Stores parsed messages in
StreamingBinaryLoader- Holds parsed messages + an index pointer (
index) for sequential playback.
- Holds parsed messages + an index pointer (
OrderbookBuilder- Owns
OrderBookManagerand replays messages into order-book state.
- Owns
Message Types
N: New orderM: Modify orderX: Cancel orderT: Trade
Quick Start
import fastReader as fr
file_path = "/data/feed.bin"
# 1) Load and cache
reader = fr.MessageCacheReader()
loaded = reader.load_to_cache(file_path)
print("Loaded:", loaded)
# 2) Build order book from cached data
builder = fr.OrderbookBuilder()
applied = builder.build_from_list(reader)
print("Applied:", applied)
# 3) Snapshot top levels
snap = builder.get_snapshot(token=1660, levels=3)
print(snap)
Expected output example:
Loaded: 4231887
Applied: 4231887
{'token': 1660, 'found': True, 'mid_price': 234550, 'best_bid': (234500, 1500), 'best_ask': (234600, 800), 'spread': 100, 'bids': [(234500, 1500), (234400, 3200), (234300, 700)], 'asks': [(234600, 800), (234700, 2100), (234800, 4500)]}
API Reference (Every Public Function)
1) MessageCacheReader
MessageCacheReader()
Creates an empty cache reader.
reader = fr.MessageCacheReader()
Expected output: no direct output.
load_to_cache(file_path: str) -> int
Parses the binary file and stores all messages in cache.
count = reader.load_to_cache("/data/feed.bin")
print(count)
Expected output example:
4231887
Errors:
- Raises
RuntimeError(from Rust I/O error) if file cannot be opened/read.
get_all_messages() -> list[str]
Returns formatted string representation of every cached message.
msgs = reader.get_all_messages()
print(msgs[0])
print(msgs[1])
Expected output example:
Order Message: SeqNo 42, MsgLen 10, MsgType 'N', ExchTs 100000, LocalTs 200000, OrderId 55, Token 1001, Side 'B', Price 500, Quantity 100, Missed 0
Trade Message: SeqNo 99, MsgLen 10, MsgType 'T', ExchTs 300000, LocalTs 400000, BuyOrderId 101, SellOrderId 202, Token 1001, Price 505, Quantity 20, Missed 0
get_cache_summary() -> dict
Returns summary statistics.
summary = reader.get_cache_summary()
print(summary)
Expected output shape:
{
'file_source': '/data/feed.bin',
'total_messages': 4231887,
'total_orders': 3854321,
'total_trades': 377566,
'memory_usage_bytes': 226411296
}
Field meaning:
file_source: last loaded file path orNonetotal_messages: total cached messagestotal_orders: count of order messages (N/M/X)total_trades: count of trade messages (T)memory_usage_bytes: approximate cache memory aslen(messages) * sizeof(Message)
2) StreamingBinaryLoader
StreamingBinaryLoader()
Creates an empty stream loader.
loader = fr.StreamingBinaryLoader()
Expected output: no direct output.
open_stream(file_path: str) -> int
Loads messages and resets stream cursor to start.
total = loader.open_stream("/data/feed.bin")
print(total)
Expected output example:
4231887
Notes:
- After
open_stream, data is consumed throughOrderbookBuilder.build_from_source(loader, limit=...). - Internal cursor advances as messages are consumed.
3) OrderbookBuilder
OrderbookBuilder()
Creates a fresh order-book builder.
builder = fr.OrderbookBuilder()
Expected output: no direct output.
apply_filter(logic_criteria: list[str] | None = None) -> None
Sets optional message-type filter.
builder.apply_filter(["N", "M", "X"]) # process only order lifecycle
builder.apply_filter(["T"]) # process only trades
builder.apply_filter(None) # clear filter (default all)
How it works:
- The first character of each string is used.
- Valid practical values:
N,M,X,T.
Expected behavior:
None: all messages processed['N','M','X']: trade messages skipped['T']: only trades processed
build_from_list(reader: MessageCacheReader) -> int
Replays cached messages into order book.
applied = builder.build_from_list(reader)
print(applied)
Expected output example:
4231887
If filter is set, return value is number of messages actually applied (after filtering).
build_from_source(source, limit: int | None = None) -> int
Accepts either:
MessageCacheReaderStreamingBinaryLoader
Examples:
# Source: cache reader
n1 = builder.build_from_source(reader)
print(n1)
# Source: streaming loader, process only first 500k messages
n2 = builder.build_from_source(loader, limit=500000)
print(n2)
Expected output example:
4231887
500000
Error case:
- Raises
TypeErrorifsourceis neitherMessageCacheReadernorStreamingBinaryLoader.
get_snapshot(token: int, levels: int = 5) -> dict
Returns top-of-book snapshot for one token.
snap = builder.get_snapshot(token=1660, levels=3)
print(snap)
Expected output when token exists:
{
'token': 1660,
'found': True,
'mid_price': 234550,
'best_bid': (234500, 1500),
'best_ask': (234600, 800),
'spread': 100,
'bids': [(234500, 1500), (234400, 3200), (234300, 700)],
'asks': [(234600, 800), (234700, 2100), (234800, 4500)]
}
Expected output when token does not exist:
{
'token': 9999999,
'found': False,
'mid_price': 0,
'best_bid': None,
'best_ask': None,
'spread': None,
'bids': [],
'asks': []
}
Field explanation:
found: whether token book existsmid_price: midpoint based on best bid/askbest_bid/best_ask:(price, qty)tuplesspread:best_ask_price - best_bid_pricebids/asks: top N levels
Practical End-to-End Scenarios
A) Full Replay (All Messages)
import fastReader as fr
reader = fr.MessageCacheReader()
reader.load_to_cache("/data/feed.bin")
builder = fr.OrderbookBuilder()
builder.apply_filter(None)
builder.build_from_list(reader)
print(builder.get_snapshot(1660, 5))
B) Replay Only First N Stream Messages
import fastReader as fr
loader = fr.StreamingBinaryLoader()
loader.open_stream("/data/feed.bin")
builder = fr.OrderbookBuilder()
processed = builder.build_from_source(loader, limit=1_000_000)
print("Processed:", processed)
print(builder.get_snapshot(1660, 3))
C) Order-Only Book (Ignore Trades)
import fastReader as fr
reader = fr.MessageCacheReader()
reader.load_to_cache("/data/feed.bin")
builder = fr.OrderbookBuilder()
builder.apply_filter(["N", "M", "X"])
builder.build_from_list(reader)
print(builder.get_snapshot(1660, 5))
Performance and Usage Notes
get_all_messages()can be expensive on huge files because it builds Python strings for every message.- Use
get_cache_summary()for fast sanity checks. build_from_source(loader, limit=...)is useful for point-in-time reconstruction.OrderbookBuilderkeeps state across calls; create a new instance for a clean replay.
Troubleshooting
Import error for module name
If import rmoney_orderbook fails, that is expected after renaming module to fastReader.
Use:
import fastReader as fr
Type error in build_from_source
Pass only MessageCacheReader or StreamingBinaryLoader instances.
Empty snapshot
If found is False, confirm:
- token exists in your feed,
- replay consumed relevant messages,
- filter did not exclude needed message types.
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.24.tar.gz.
File metadata
- Download URL: orderpulse-0.2.24.tar.gz
- Upload date:
- Size: 23.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: maturin/1.13.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
09142c26f10b1014cbb0987c6a4b99b724d6860a0754e4f840392ad4f47e83bd
|
|
| MD5 |
3829f205aa35fe5f0c0cf39689eb3375
|
|
| BLAKE2b-256 |
16c6f5b287e4abf150fa6a0aa0f510e44992a9c3c5c2d049659bce66fe4aec24
|
File details
Details for the file orderpulse-0.2.24-cp312-cp312-manylinux_2_34_x86_64.whl.
File metadata
- Download URL: orderpulse-0.2.24-cp312-cp312-manylinux_2_34_x86_64.whl
- Upload date:
- Size: 246.7 kB
- Tags: CPython 3.12, manylinux: glibc 2.34+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: maturin/1.13.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3cb773277027bab5b7f7026ad9f205a809429809786e634a01a491726ed8e141
|
|
| MD5 |
4ac56bd5f8ffe091d11ab728fe2e0c64
|
|
| BLAKE2b-256 |
68aa9d792aafcd0f7e80180cae1dcf8a1fa9d909876bebe744b15b185dae9a6c
|