5 releases
Uses new Rust 2024
| new 0.5.3 | Feb 10, 2026 |
|---|---|
| 0.5.2 | Feb 7, 2026 |
| 0.5.1 | Feb 5, 2026 |
| 0.5.0 | Feb 5, 2026 |
| 0.4.0 | Feb 4, 2026 |
#1433 in Database interfaces
545KB
14K
SLoC
BetEx Engine
A high-performance, event-sourced order matching engine for sports betting exchanges and prediction markets.
Event Sourcing Model
The engine uses a command → events → WAL → handlers architecture:
- Commands arrive via the
Enginehandler (e.g., PlaceOrder, CancelOrder) - Validation happens in
EngineRoot::handleagainst current state - Events are emitted describing state changes (e.g., OrderAccepted, TradeMatched)
- WAL persists events durably before acknowledgment
- Handlers receive events via the disruptor for downstream processing
Key Guarantees
- Durability: Events are written to the WAL before response callbacks fire
- Ordering: Events are strictly ordered by sequence number
- Determinism: Replaying the same event sequence produces identical state
- Atomicity: Multi-event commands (trades) commit or rollback together
Market Models
The engine supports two market models:
- ExchangeOdds: Traditional sports betting with BACK/LAY sides at decimal odds (e.g., 2.50 means "win $1.50 for every $1 staked")
- BinaryYes: Prediction markets with BUY/SELL sides at tick prices (0-10000 basis points)
Quick Start
use betex::prelude::*;
// Create engine with markets
let config = Config::default();
let engine = EngineBuilder::with_markets(
config,
[MarketConfig::two_runner(
MarketId(1),
RunnerId(1),
RunnerId(2),
MarketKind::InPlayCapable,
)],
"/tmp/wal",
)?.build()?;
// Submit orders
engine.submit(Command {
correlation_id: CorrelationId(1),
market_id: MarketId(1),
kind: CommandKind::PlaceOrder {
runner_id: RunnerId(1),
account_id: AccountId(1),
client_order_id: None,
side: Side::Yes,
odds: OddsX10000(20000), // 2.0
stake: Money(10000), // $1.00
persistence: Persistence::Persist,
time_in_force: TimeInForce::Gtc,
},
})?;
# Ok::<(), anyhow::Error>(())
Module Overview
book: Order book implementations (two-runner, multi-runner, binary prediction)engine: Core engine and builder with WAL recoverycross_match: Multi-leg cross-matching for 3-runner marketstypes: Core domain types (Money, OrderId, OddsX10000, etc.)config: Engine and market configurationsnapshot: Market state snapshots for external consumptionstream: Event streaming for downstream consumers
Dependencies
~13–20MB
~274K SLoC