Class ShardedTradingEngine

java.lang.Object
com.quantfinlib.trading.ShardedTradingEngine
All Implemented Interfaces:
AutoCloseable

public final class ShardedTradingEngine extends Object implements 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 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 shard
      busySpin - spin-wait consumers (latency) vs park (cores)
      gateFactory - builds each shard's risk gate (limits per shard)
  • Method Details

    • registerSymbol

      public int registerSymbol(String symbol, int... shards)
      Registers a symbol on the given shard(s); returns the global handle used with publish(int, double, double, long). Setup path — call before start().
    • 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 via bus(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

      public HftMarketDataBus bus(int shard)
      Shard components, for wiring listeners/quoters and observability.
    • gate

      public HftRiskGate gate(int shard)
    • gateway

      public HftOrderGateway gateway(int shard)
    • gates

      public List<HftRiskGate> gates()
      All gates — the input to a GlobalRiskAggregator.
    • 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:
      close in interface AutoCloseable