Class ShardedTradingEngine
java.lang.Object
com.quantfinlib.trading.ShardedTradingEngine
- All Implemented Interfaces:
AutoCloseable
Horizontal scaling as shipped machinery, not a recipe: N independent
bus → risk gate → order gateway stacks (one consumer core and one
venue core per shard) behind a single symbol-routing facade. The scaling
model is shared-nothing: shards never touch each other's state, so
aggregate capacity is per-shard throughput × shard count — measured at
~2.3M ticks/s per shard on the 300-symbol probe.
Symbol routing rules:
registerSymbol(String, int...)assigns a symbol to one or MORE shards — multi-shard registration is the cross co-location tool: a synthetic cross must live where both its legs tick, and duplicating a leg's feed into a second shard costs one extra ring publish (~40 ns), which is the whole point of shared-nothing;publish(int, double, double, long)fans a tick to every shard hosting the symbol — primitive arrays only, zero allocation, single producer thread (or one producer per disjoint symbol set);- strategies/quoters attach per shard via
bus(int)exactly as they would to a standalone bus — the shard is invisible to them.
What sharding deliberately does NOT solve: firm-wide risk. Each
shard's HftRiskGate sees only its own symbols; put a
GlobalRiskAggregator over gates() for cross-shard
exposure caps.
-
Constructor Summary
ConstructorsConstructorDescriptionShardedTradingEngine(int shardCount, int busRingCapacity, int orderRingCapacity, int maxSymbolsPerShard, boolean busySpin, IntFunction<HftRiskGate> gateFactory) -
Method Summary
Modifier and TypeMethodDescriptionbus(int shard) Shard components, for wiring listeners/quoters and observability.voidclose()longOrders delivered to venue listeners across all shards.gate(int shard) gates()All gates — the input to aGlobalRiskAggregator.gateway(int shard) intlocalId(int handle, int shard) The symbol's dense id within one of its shards (for subscriptions).longTicks processed across all shards.booleanpublish(int handle, double price, double size, long timestampNanos) The producer hot path: fans one tick to every shard hosting the symbol.intregisterSymbol(String symbol, int... shards) Registers a symbol on the given shard(s); returns the global handle used withpublish(int, double, double, long).intvoidstart()Starts every shard (subscribe strategies viabus(int)first).
-
Constructor Details
-
ShardedTradingEngine
public ShardedTradingEngine(int shardCount, int busRingCapacity, int orderRingCapacity, int maxSymbolsPerShard, boolean busySpin, IntFunction<HftRiskGate> gateFactory) - Parameters:
shardCount- independent stacks (2 threads each: consumer + venue)busRingCapacity- tick ring per shard (power of two)orderRingCapacity- order ring per shard (power of two)maxSymbolsPerShard- dense-id capacity per shardbusySpin- spin-wait consumers (latency) vs park (cores)gateFactory- builds each shard's risk gate (limits per shard)
-
-
Method Details
-
registerSymbol
Registers a symbol on the given shard(s); returns the global handle used withpublish(int, double, double, long). Setup path — call beforestart(). -
localId
public int localId(int handle, int shard) The symbol's dense id within one of its shards (for subscriptions). -
start
public void start()Starts every shard (subscribe strategies viabus(int)first). -
publish
public boolean publish(int handle, double price, double size, long timestampNanos) The producer hot path: fans one tick to every shard hosting the symbol. Zero allocation. Returns false when ANY hosting shard's ring was full (that shard missed the tick; counted on its bus). -
shardCount
public int shardCount() -
bus
Shard components, for wiring listeners/quoters and observability. -
gate
-
gateway
-
gates
All gates — the input to aGlobalRiskAggregator. -
processedCount
public long processedCount()Ticks processed across all shards. -
deliveredCount
public long deliveredCount()Orders delivered to venue listeners across all shards. -
close
public void close()- Specified by:
closein interfaceAutoCloseable
-