Skip to content
zhou.
Forum

NUtil Release Note

zhouzhouzhouzhouNUtil27 Aug 2026

2026-08-23

feed_sim.py learned to publish aggregated depth, so nqbook's L2 path has a feed to run against.

  • --l2 publishes nlib::level records. The script keeps a five-level ladder per side around a mid price that random-walks one tick per interval, and sends one record per rung whose quantity changed, plus a quantity of 0 for every price the ladder left behind. Records carry the level's total resting quantity rather than a delta, which is what makes them idempotent — a repeat changes nothing.
  • LEVEL_FORMAT mirrors the 48-byte nlib::level, behind tag 2, with the same packed-size assert guarding ORDER_FORMAT. Both layouts are still hand-written and unchecked against the header; md/kraken generates its own from common.h.
  • The two publishing loops are functions, run_l3 and run_l2, which main picks between. The argument parsing, the socket, and the shutdown path are shared.
  • nlib bumped to 4fc74f1 for nlib::level, the order_tag / trade_tag / level_tag framing constants, and the feed_event and record variants. md/kraken publishes the same frames as before; the regenerated bindings only gain the new record.

2026-08-22

The wire stopped being a transcription, and the feed grew a second channel.

  • nlib is a submodule, and the records are generated from it. md/kraken/build.rs runs bindgen over third_party/nlib/include/nlib/common.h, so the crate publishes the C++ structs themselves — bindgen's size, alignment, and offset assertions hold them to the header, and the absence of a Default impl forces every record to name every field. The hand-written Order struct and byte-offset encode in wire.rs are gone: a field added to common.h is now a compile error here, not frames nqbook silently drops for the wrong size. wire.rs keeps what is genuinely this crate's — framing, fixed-point parsing, timestamps, and the FNV-1a hashes — and reads PRICE_DECIMALS / QTY_DECIMALS off nlib's own scales.
  • Kraken's trade channel is published alongside level3, as nlib::trade behind tag 1. The tape is public, so it needs no token and names no counterparty: buy_order_id and sell_order_id stay zero and side is the aggressor's. The book stays driven entirely by level3; trades are tape data nqbook's writer stores alongside it. Snapshots are declined, since a reconnect would replay trades already published.
  • A channel is a module. feed.rs keeps only what every connection does — connect, subscribe, detect stalls, back off, publish — and takes a Channel describing the rest; level3.rs and trade.rs are the two. Both draw sequence numbers from one counter and feed one PUB socket, so nqbook still reads a single ordered stream. The report line and totals gained a trade rate and count.
  • cancel_qty and new_qty follow nlib. A delete carries the quantity leaving the book in cancel_qty, a modify the new remainder in new_qty, so nqbook no longer reads qty against the action. feed_sim.py's ORDER_FORMAT mirrors the resulting 88-byte nlib::order.

Comments

Sign in to join the discussion.

No comments yet. Be the first.