SORY
A smart order router for crypto, in a Python package.
Aggregate order books across every venue you trade, then execute against the best all-in price — fees included. Two lines to get a consolidated book, one call to route an order.
pip install sory
The whole integration
import asyncio
from decimal import Decimal
from sory import SoryClient
config = {
"market_data": {
"exchanges": ["binance", "okx", "bybit"],
"symbols": ["BTC/USDT"],
"aggregated": True,
},
"fees_bps": "fees.toml",
}
async def main() -> None:
async with SoryClient(config=config, licence_key="...") as sory:
# A consolidated, fee-adjusted book across all three venues.
book = sory.book("BTC/USDT")
print(book.best_bid.price, book.best_ask.price, book.best_ask.venue)
# One call. SORY splits it across venues on best all-in price.
order = await sory.place(
symbol="BTC/USDT",
side="buy",
qty=Decimal("2"),
type="market",
max_slippage_bps=15,
)
print(order.filled, order.achieved_price, order.plan.allocations)
asyncio.run(main())
That is the integration. No adapters to write, no per-venue special cases, no WebSocket plumbing.
What it does
Two things, well:
Market data — one consolidated order book across any number of venues, with fees applied, venue health tracked, and VWAP depth on request.
Execution — one order, split across venues on best all-in price, with hard price bounds and a full account of what was filled where and why.
It is deliberately not an OEMS. No balances, no positions, no PnL, no trade database. SORY plugs into whatever already owns those — which is why it takes about ten minutes to drop into an existing system.
What people use it for
| Best execution | Sweep the consolidated book instead of guessing which venue is cheapest. |
| Arbitrage and basis | One book, every venue, fee-adjusted — the spread you see is the spread you get. |
| Hedging | Fill on one venue, hedge across the others in a single call. |
| Market making | Quote passively, hedge the fill, keep the rebate with post_only. |
| Unwinds and liquidations | Size against real aggregate depth, with a slippage bound that holds. |
| Execution algos | TWAP, VWAP, POV — build the schedule, let SORY handle each slice. |
| Research and monitoring | Consolidated depth and the trade tape, as a normal Python stream. |
Why fee-aware routing matters
Routing on quoted prices is routing on the wrong number:
venue A: ask 100.00, your taker fee 20 bps -> all-in 100.200
venue B: ask 100.05, your taker fee 1 bp -> all-in 100.060 <- actually cheaper
Venue A looks better and costs more. SORY compares all-in prices everywhere, using your negotiated fees from a config file — never a published retail tier, which is usually nowhere near what you actually pay.
What you get
| Consolidated book | Any number of venues merged into one, fee-adjusted, best price first. |
| Venue health | Online / Stale / Offline. A silent feed is treated as a fault, not a quiet market — and never routed to. |
| Fee-inclusive routing | Splits on best all-in price, and reports every venue it considered, excluded, and why. |
| Hard price bounds | Limit price, or max_slippage_bps. Nothing sweeps to arbitrary depth. |
| Full reconciliation | requested == filled + unfilled, always, with a reason. Remainders are never silently dropped. |
| VWAP depth | The price to fill 1, 5, 10 units — and the limit price needed to achieve it. |
| Unified liquidity | Pool BTC/USD, BTC/USDC and BTC/USDT into one book. |
Decimal throughout |
No float rounding anywhere near a price, size or fee. |
| Dry run | Every path runs end to end without sending. |
Venues
Around 100 spot and perpetual venues are supported, including Binance, OKX, Bybit, Coinbase, Kraken, Bitget, KuCoin, Gate, HTX, Crypto.com, Bullish, MEXC, Bitstamp, Bitfinex, Hyperliquid, Deribit and BitMEX.
Venue ids and symbols follow a single convention across all of them — BTC/USDT for spot,
BTC/USDT:USDT for a perp — so adding a venue to your config is one string.
Documentation
introduction · configuration · market data · routing · execution · fees · venues · licensing
Licence
SORY is commercial software, unlocked with a licence key — see licensing. The source is MIT; see LICENSE.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file sory-4.0.0.tar.gz.
File metadata
- Download URL: sory-4.0.0.tar.gz
- Upload date:
- Size: 75.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
uv/0.7.8
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f1323006d0b458037e3d0cc454f26a2b91381852bbaa3602e6b0a56700d84171
|
|
| MD5 |
c43c5849938099d20999fd3c4f3bd24a
|
|
| BLAKE2b-256 |
dd11f0f7c00ada145ab614880885a7fb0bd42113a7ae2f430f764a842eda2231
|
File details
Details for the file sory-4.0.0-py3-none-any.whl.
File metadata
- Download URL: sory-4.0.0-py3-none-any.whl
- Upload date:
- Size: 65.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
uv/0.7.8
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5c0388e93a3857aa2bc13dc75e330e87ad594be037df9f55e78f4953f923596b
|
|
| MD5 |
35a81744b873c3dcb0b471a3fd8418b3
|
|
| BLAKE2b-256 |
e1b9dd16355715513872d4e3d3f6cd2543184fac2c1d0c795c836e7aabb17f7b
|