Skip to main content

SORY

A smart order router for crypto, in a Python package.

One order book across every venue you trade, then execute against the best all-in price — fees included. One config 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 = {
    "licence_key": "...",
    "symbol": "BTC/USDT",
    "exchanges": ["binance", "okx", "bybit"],
    "fees_bps": "fees.toml",
    "fee_offset": {"binance": "taker", "okx": "taker", "bybit": "taker"},
}


async def main() -> None:
    async with SoryClient(config) as sory:
        # A consolidated, fee-adjusted book across all three venues.
        book = sory.book()
        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(side="buy", qty=Decimal("2"), order_type="market")
        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 your fees applied where you ask, venue health tracked, VWAP depth and the trade tape on request.

Execution — a market order split across venues on best all-in price, or a limit order resting on the venue you name, with a full account of what 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 in one call.
Unwinds and liquidations Size against real aggregate depth, and see the remainder you could not fill.
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 own fee tier from a config file — never a venue's published rate, which is usually the entry-level tier and not what you 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.
One config One symbol per client. Two symbols is two clients, one line each.
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.
Trade tape Every venue, streamed in parallel with the book.
Decimal throughout No float rounding anywhere near a price, size or fee.
Dry run One flag on place(): routes, validates and builds every venue order, then stops before sending.
Open orders Ask the venues what is still resting — the whole recovery story after a restart.
MCP server pip install "sory[mcp]" and an agent can read books and plan orders, read-only by default.

Venues

Binance, OKX, Bybit, Coinbase, Kraken, Bitget, KuCoin, Gate, HTX, Crypto.com, Bullish, Bitstamp, Bitfinex, Hyperliquid and Deribit, among others — the full list is generated from the registry, so it is never out of date.

Venue ids and symbols follow a single convention across all of them — BTC/USDT for spot, BTC/USDT:USDT for a perp — so putting a venue on a card is one string. Omit exchanges entirely and SORY uses every venue that lists the symbol. Need one that is not listed? Ask for it — new venues land on almost every release.

Try it

playground.sory.pro — build a config and run it against live order books, in your browser.

Documentation

introduction · configuration · market data · routing · execution · fees · market making · errors · MCP server · 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

sory-5.1.1.tar.gz (91.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

sory-5.1.1-py3-none-any.whl (65.6 kB view details)

Uploaded Python 3

File details

Details for the file sory-5.1.1.tar.gz.

File metadata

  • Download URL: sory-5.1.1.tar.gz
  • Upload date:
  • Size: 91.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.12.4 {"installer":{"name":"uv","version":"0.12.4","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for sory-5.1.1.tar.gz
Algorithm Hash digest
SHA256 8c02e5263aad6c631839fc37c32f1c98a538d4d5c2d7fcceadbf4b070228fca7
MD5 3698994f95fabcc7cf916179f4db3246
BLAKE2b-256 6cd9d968db454f0244bd30b4502e1a18b75d06ab7d113bc6af0ae19232a20ffc

See more details on using hashes here.

File details

Details for the file sory-5.1.1-py3-none-any.whl.

File metadata

  • Download URL: sory-5.1.1-py3-none-any.whl
  • Upload date:
  • Size: 65.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.12.4 {"installer":{"name":"uv","version":"0.12.4","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for sory-5.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 a129c5c48410c7ef52e3a8d367a085a34d3a20abc26d22f7ca5e1bb03138f3b0
MD5 a1c444624a5a409d3fdfa6f5f640b5aa
BLAKE2b-256 ef95ab022d01d92e00074ea72e41dbd0e739150f4b336d6e4f44ac6d8b0515e0

See more details on using hashes here.

Release history Release notifications | RSS feed

5.3.3

2 files

5.3.2

2 files

5.3.1

2 files

5.3.0

2 files

5.2.1

2 files

5.2.0

2 files

5.1.2

2 files

This release

5.1.1 This release

2 files

5.0.3

2 files

5.0.2

2 files

5.0.1

2 files

5.0.0

2 files

4.0.0

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page