bat-markets
Headless Rust exchange engine for Binance USD-M, Bybit USDT, and MEXC USDT-M linear futures.
bat-markets gives applications a typed root client for:
- REST market reads
- REST private/account reads
- shared websocket watchers
- order and account commands
- deterministic state projection and reconciliation
- low-level adapter access when a venue-specific escape hatch is needed
Install
[]
= "0.3.4"
Single-venue build:
[]
= { = "0.3.4", = false, = ["binance"] }
Feature flags:
| Feature | Purpose |
|---|---|
binance |
Binance USD-M linear futures adapter |
bybit |
Bybit USDT linear futures adapter |
mexc |
MEXC USDT-M linear futures adapter |
private-trading |
Authenticated private reads and commands |
metrics |
Reserved for metrics integrations |
serde |
Reserved for serde-facing API expansion |
At least one venue feature must be enabled. The default build enables all
venues; use default-features = false with features = ["binance"] or
features = ["bybit"] or features = ["mexc"] for a single-venue build.
Quick Start
Offline/static client:
use ;
Live public data:
use ;
async
Runtime Rules
| Area | Rule |
|---|---|
build() |
Offline constructor. No network I/O. Useful for fixtures, metadata, and local ingestion. |
build_live().await |
Live constructor. Builds transport, resolves auth, syncs time, refreshes metadata. |
| Public reads | Do not require credentials. |
| Private reads, private watches, commands | Use explicit config or BINANCE_API_KEY, BINANCE_API_SECRET, BYBIT_API_KEY, BYBIT_API_SECRET, MEXC_API_KEY, MEXC_API_SECRET. |
| Watch handles | Use recv().await for the next typed event. Use shutdown().await or drop the handle to release the shared lease. |
| Command handles | Immediate ack() is available. receipt().await, next_lifecycle().await, and resolved().await observe command outcome. |
| Uncertain writes | Timeouts/disconnects can return UnknownExecution; reconciliation resolves what local evidence can prove. |
API Reference
Builder And Identity
| Method | Input | Output | Purpose |
|---|---|---|---|
BatMarkets::builder |
none | BatMarketsBuilder |
Start client configuration. |
BatMarketsBuilder::venue |
Venue |
BatMarketsBuilder |
Select exchange venue. |
BatMarketsBuilder::product |
Product |
BatMarketsBuilder |
Select product family. Defaults to LinearUsdt. |
BatMarketsBuilder::config |
BatMarketsConfig |
BatMarketsBuilder |
Replace full runtime config. |
BatMarketsBuilder::build |
none | Result<BatMarkets> |
Build offline/static client. |
BatMarketsBuilder::build_live |
none | Result<BatMarkets> |
Build live client with REST/bootstrap. |
venue |
none | Venue |
Selected venue. |
product |
none | Product |
Selected product family. |
Metadata, Status, Capabilities
| Method | Input | Output | Purpose |
|---|---|---|---|
markets |
none | Vec<InstrumentSpec> |
Cached market metadata. No network I/O. |
instrument_specs |
none | Vec<InstrumentSpec> |
Same metadata projection as markets. |
load_markets |
none | Result<Vec<InstrumentSpec>> |
Refresh venue metadata through REST. |
capabilities |
none | CapabilitySet |
Venue/product support matrix. |
lane_set |
none | LaneSet |
Public/private/command lane support. |
status |
none | HealthReport |
Cheap synchronous runtime health snapshot. |
watch_status |
none | StatusWatch |
Health change watcher. |
Public REST Reads
| Method | Input | Output | Payload |
|---|---|---|---|
fetch_ticker |
&InstrumentId |
Result<Ticker> |
Latest ticker snapshot. |
fetch_tickers |
Vec<InstrumentId> |
Result<Vec<Ticker>> |
Batch ticker snapshots. |
fetch_order_book |
&InstrumentId, Option<usize> |
Result<OrderBookSnapshot> |
Focused depth snapshot. |
fetch_ohlcv |
&FetchOhlcvRequest |
Result<Vec<Kline>> |
Historical candles; supports bounded window paging. |
fetch_trades |
&InstrumentId, Option<usize> |
Result<Vec<TradeTick>> |
Recent public trades. |
fetch_mark_price |
&InstrumentId |
Result<MarkPrice> |
Latest mark-price snapshot. |
fetch_funding_rate |
&InstrumentId |
Result<FundingRate> |
Latest funding-rate snapshot. |
fetch_open_interest |
&InstrumentId |
Result<OpenInterest> |
Latest open-interest snapshot. |
fetch_liquidations |
&InstrumentId, Option<usize> |
Result<Vec<Liquidation>> |
Recent cached liquidation events. |
Private REST Reads
| Method | Input | Output | Payload |
|---|---|---|---|
fetch_balance |
none | Result<AccountSnapshot> |
Balances plus optional account summary. |
fetch_positions |
none | Result<Vec<Position>> |
Current positions. |
fetch_open_orders |
Option<&ListOpenOrdersRequest> |
Result<Vec<Order>> |
Open orders scoped by request. |
fetch_order |
&GetOrderRequest |
Result<Order> |
Single order snapshot. |
fetch_my_trades |
Option<&ListExecutionsRequest> |
Result<Vec<Execution>> |
Private execution history. |
Public Websocket Watches
All public watchers use the shared public websocket hub.
| Method | Input | Output | Event from recv().await |
|---|---|---|---|
watch_ticker |
InstrumentId |
Result<TickerWatch> |
Ticker |
watch_tickers |
Vec<InstrumentId> |
Result<TickerWatch> |
Ticker |
watch_trades |
InstrumentId |
Result<TradesWatch> |
TradeTick |
watch_trades_for_symbols |
Vec<InstrumentId> |
Result<TradesWatch> |
TradeTick |
watch_order_book |
InstrumentId, Option<usize> |
Result<OrderBookWatch> |
OrderBookDelta |
watch_ohlcv |
InstrumentId, interval string |
Result<OhlcvWatch> |
Kline |
watch_ohlcv_for_symbols |
Vec<InstrumentId>, interval string |
Result<OhlcvWatch> |
Kline |
watch_mark_price |
InstrumentId |
Result<MarkPriceWatch> |
MarkPrice |
watch_funding_rate |
InstrumentId |
Result<FundingRateWatch> |
FundingRate |
watch_open_interest |
InstrumentId |
Result<OpenInterestWatch> |
OpenInterest |
watch_liquidations |
InstrumentId |
Result<LiquidationWatch> |
Liquidation |
Private Websocket Watches
All private watchers use the shared authenticated private websocket hub.
| Method | Input | Output | Event from recv().await |
|---|---|---|---|
watch_balance |
none | Result<BalancesWatch> |
Balance |
watch_orders |
none | Result<OrdersWatch> |
Order |
watch_my_trades |
none | Result<ExecutionsWatch> |
Execution |
watch_positions |
none | Result<PositionsWatch> |
Position |
Watch Handles
| Method | Output | Applies to | Purpose |
|---|---|---|---|
recv().await |
Result<T> |
all typed watch handles | Wait for the next matching event. |
shutdown().await |
Result<()> |
root watch handles | Explicitly release the local subscription lease. |
current() |
HealthReport |
StatusWatch |
Read the current health snapshot without waiting. |
abort() |
() |
stream-compatible public handles | Stop waiting on the handle; shared hubs own the socket. |
wait().await |
Result<()> |
stream-compatible public handles | Complete the handle lifecycle. Prefer shutdown() in new code. |
Commands
Default command methods choose the best supported live transport and may use REST fallback where the venue requires it.
| Method | Input | Output | Effect |
|---|---|---|---|
create_order |
&CreateOrderRequest |
Result<PendingCommandHandle> |
Submit one order. |
create_orders |
&CreateOrdersRequest |
Result<Vec<PendingCommandHandle>> |
Submit batch orders. |
edit_order |
&EditOrderRequest |
Result<PendingCommandHandle> |
Modify one order. |
edit_orders |
&EditOrdersRequest |
Result<Vec<PendingCommandHandle>> |
Modify batch orders. |
cancel_order |
&CancelOrderRequest |
Result<PendingCommandHandle> |
Cancel one order. |
cancel_orders |
&CancelOrdersRequest |
Result<Vec<PendingCommandHandle>> |
Cancel batch orders. |
cancel_all_orders |
&CancelAllOrdersRequest |
Result<PendingCommandHandle> |
Cancel all orders in request scope. |
close_position |
&ClosePositionRequest |
Result<PendingCommandHandle> |
Close a position using an actionable order. |
validate_order |
&ValidateOrderRequest |
Result<PendingCommandHandle> |
Validate without intentionally opening a position. |
set_leverage |
&SetLeverageRequest |
Result<PendingCommandHandle> |
Set instrument leverage. |
set_margin_mode |
&SetMarginModeRequest |
Result<PendingCommandHandle> |
Set margin mode. |
set_position_mode |
&SetPositionModeRequest |
Result<PendingCommandHandle> |
Set one-way or hedge mode. |
Websocket-only command methods never fall back to REST. Unsupported paths return
ErrorKind::Unsupported.
| Method | Input | Output |
|---|---|---|
create_order_ws |
&CreateOrderRequest |
Result<PendingCommandHandle> |
create_orders_ws |
&CreateOrdersRequest |
Result<Vec<PendingCommandHandle>> |
edit_order_ws |
&EditOrderRequest |
Result<PendingCommandHandle> |
edit_orders_ws |
&EditOrdersRequest |
Result<Vec<PendingCommandHandle>> |
cancel_order_ws |
&CancelOrderRequest |
Result<PendingCommandHandle> |
cancel_orders_ws |
&CancelOrdersRequest |
Result<Vec<PendingCommandHandle>> |
cancel_all_orders_ws |
&CancelAllOrdersRequest |
Result<PendingCommandHandle> |
Command Handle
| Method | Output | Purpose |
|---|---|---|
ack |
&CommandAck |
Immediate acknowledgement and initial receipt. |
receipt().await |
Result<CommandReceipt> |
Initial receipt first, then matching receipt events. |
next_lifecycle().await |
Result<CommandLifecycleEvent> |
Ack, recovery scheduling, recovery completion, and receipt lifecycle. |
resolved().await |
Result<CommandReceipt> |
Best known final receipt after local recovery evidence. |
Advanced
advanced() is for custom transports, fixture replay, diagnostics, and
venue-specific access. Normal application code should prefer root methods.
| Method | Input | Output | Purpose |
|---|---|---|---|
advanced |
none | AdvancedClient |
Enter low-level API. |
ingest_public_json |
&str |
Result<Vec<PublicLaneEvent>> |
Decode and apply public native JSON. |
ingest_private_json |
&str |
Result<Vec<PrivateLaneEvent>> |
Decode and apply private native JSON. |
subscribe_public_events |
none | broadcast::Receiver<PublicLaneEvent> |
Raw public event stream. |
subscribe_private_events |
none | broadcast::Receiver<PrivateLaneEvent> |
Raw private event stream. |
subscribe_command_events |
none | broadcast::Receiver<CommandLaneEvent> |
Raw command event stream. |
subscribe_health_notifications |
none | broadcast::Receiver<HealthNotification> |
Structural health changes. |
require_instrument |
&InstrumentId |
Result<InstrumentSpec> |
Resolve known instrument metadata. |
cached_ticker |
&InstrumentId |
Option<Ticker> |
Cached ticker. |
cached_recent_trades |
&InstrumentId |
Option<Vec<TradeTick>> |
Cached recent public trades. |
cached_book_top |
&InstrumentId |
Option<BookTop> |
Cached top of book. |
cached_funding_rate |
&InstrumentId |
Option<FundingRate> |
Cached funding rate. |
cached_mark_price |
&InstrumentId |
Option<MarkPrice> |
Cached mark price. |
cached_open_interest |
&InstrumentId |
Option<OpenInterest> |
Cached open interest. |
cached_liquidations |
&InstrumentId |
Option<Vec<Liquidation>> |
Cached liquidation events. |
cached_balances |
none | Vec<Balance> |
Cached balances. |
cached_account_summary |
none | Option<AccountSummary> |
Cached account summary. |
cached_positions |
none | Vec<Position> |
Cached positions. |
cached_orders |
none | Vec<Order> |
Cached orders. |
cached_open_orders |
none | Vec<Order> |
Cached open orders. |
cached_executions |
none | Vec<Execution> |
Cached private executions. |
classify_command_json |
CommandOperation, Option<&str>, Option<RequestId> |
Result<CommandReceipt> |
Decode raw command response and apply state hint. |
reconcile().await |
none | Result<ReconcileReport> |
Manual REST-backed private-state repair. |
diagnostics |
none | RuntimeDiagnosticsSnapshot |
Runtime latency and state-lock diagnostics. |
native |
none | NativeClient |
Venue-specific adapter access. |
native().binance() |
Binance client | Result<&BinanceLinearFuturesAdapter> |
Binance adapter access. |
native().bybit() |
Bybit client | Result<&BybitLinearFuturesAdapter> |
Bybit adapter access. |
native().mexc() |
MEXC client | Result<&MexcLinearFuturesAdapter> |
MEXC adapter access. |
Runtime Architecture
Application
-> BatMarkets root methods
-> live runtime: REST, WS runners, command transport, reconcile
-> shared hubs: one public stream plan, one private stream lease set
-> SharedState: EngineState, event buses, health, diagnostics
-> bat-markets-core domain contracts
-> venue adapter: Binance, Bybit, or MEXC native decoding/classification
Core rules:
bat-markets-coreowns domain types, state, errors, capabilities, and adapter traits.bat-markets-binance,bat-markets-bybit, andbat-markets-mexcown native payload decoding and venue behavior.bat-marketsowns the public facade and live transport runtime.bat-markets-testingis unpublished and owns fixtures, smoke tests, and benches.
Quality Gate
The gate verifies release consistency, formatting, clippy, tests, docs, single-venue clippy, audit, packaging, and benchmark compilation.
Focused commands:
Publishing is automated from the protected GitHub Actions environment
crates-io. Store crates.io tokens only as GitHub Actions secrets or local
environment variables. Never commit tokens.