Smart Order Routing - Buckets
Smart order routing across exchanges: trade the same market everywhere it is listed, at the best price.
- Fragmented liquidity. The same market is often listed on several exchanges, each with its own book, fees and price.
- One order book. A bucket merges those listings' books into one.
- Best price. Every order is routed to wherever the price is best after fees, never worse than the price you set.
Say you want to buy 500 YES. Here is what each exchange has for sale:
| Exchange | For sale |
|---|---|
| Kalshi | 200 at 0.40, then 300 at 0.46 |
| Polymarket | 300 at 0.42, then 200 at 0.47 |
What 500 YES costs, before fees:
| Where you buy | Cost | Average price |
|---|---|---|
| Kalshi only | $218 | 0.436 |
| Polymarket only | $220 | 0.440 |
| Bucket of both | $206 | 0.412 |
The bucket buys the cheapest shares on each exchange: 200 on Kalshi at 0.40 and 300 on Polymarket at 0.42. That is $12 less than the best single exchange.
synpath serve), which must be running and hold credentials for every member exchange.Members and flip
A bucket is a list of markets. Set flip: true on a listing that asks the question the other way round; its NO then counts as the bucket's YES. All prices are in bucket terms. If you want to use Synpath to find the same market on other exchanges, use Match market.
How an order is routed
- Books from every member are merged and priced net of each exchange's fees.
- Size goes to the best price first, up to the worst price you accept, respecting each exchange's tick and minimum size.
- Each part is sent to its exchange at the price it was found at. The parts never add up to more than your size.
- As parts fill or books move, the rest is re-routed to wherever the best price now is.
- Orders survive a restart of the server and are never placed twice.
An order on a bucket is a market order: it takes what the members offer, at or better than the worst price you set in price, and does not sit on the book at that price waiting for sellers.
Example
from synpath import BucketMember, Client, OrderRequest
client = Client(server="http://127.0.0.1:8000") # your self-hosted server (synpath serve)
bucket = await client.create_bucket(book="alpha", name="Fed cut in September", members=[
BucketMember(market_id="kalshi:KXFEDDECISION-26SEP-C25"),
BucketMember(market_id="polymarket:2252244", flip=True),
])
order = await client.create_order(OrderRequest(
market_id=bucket.market_id, side="buy", amount=500, type="market", price="0.45", # 0.45: the worst price you accept
))
report = await client.fetch_bucket_order(bucket.id, order.id) # filled, average, per exchangeCreating a bucket or trading it needs trade on every member exchange; reading needs view.

