Async Python SDK for Binance USDM-M Futures, mirroring the shioaji SDK API shape.
If you already trade 台股期貨 via shioaji (永豐金), this gives you Binance crypto with the exact same API surface — same Contracts.Perp["BTCUSDT"], same Order(action="long"), same place_order(). Switch contracts, keep your strategy code.
| python-binance | binance-connector | binance-shioaji-sdk | |
|---|---|---|---|
| API shape | Binance-native | Binance-native | shioaji-mirrored |
| Async | partial | sync-only | async-first |
| TW quant familiar | ❌ | ❌ | ✅ |
| Code reuse with shioaji strategies | ❌ | ❌ | ✅ |
Pick this if you have shioaji muscle memory and want zero-friction crypto execution.
pip install git+https://github.com/Yeimaoz/binance-shioaji-sdk.git@v0.5.8import asyncio
from decimal import Decimal
from binance_shioaji_sdk import Binance
async def main():
api = Binance(testnet=True)
await api.login(api_key="...", secret_key="...")
# Identical to shioaji's api.Contracts.Futures[...] pattern
contract = api.Contracts.Perp["BTCUSDT"]
# Same Order construction
order = api.Order(price=50000, quantity=Decimal("0.001"), action="long", price_type="LMT")
trade = await api.place_order(contract, order) # → BinanceTrade composite
print(f"order_id: {trade.status.id}") # mirrors sj.Trade.status.id
print(f"status: {trade.status.status}") # BinanceOrderStatusEnum.Submitted
# NEW in v0.4.0: margin breakdown (mirror sj.margin())
account = api.futures_account
mg = await api.margin(account)
print(f"available_margin: {mg.available_margin}")
asyncio.run(main())account_balance()returnsBinanceAccountBalance(wasdict)list_positions()returnslist[BinanceFuturePosition](waslist[dict])place_order()returnsBinanceTradecomposite (wasOrderResponse— alias kept one release withDeprecationWarningvia__init__.py.__getattr__)funding_rate / funding_rate_history / open_interestreturn typed dataclasses (weredict)- All methods raise typed exceptions on REST failure (no silent zero-filled returns or
[]); new hierarchyBinanceSDKError → {BinanceMarketDataError, BinanceAccountError, BinanceAuthError} - NEW
margin(account) -> BinanceMarginmethod (mirrorsj.margin()) ExecutionReportrenamedBinanceFillReport(alias kept one release)- Order id moves from
trade.order.idstyle totrade.status.id(mirrors shioaji exactly) open_interest().timestampandfunding_rate_history[i].funding_timetype changed fromint(epoch ms) tostr(ISO 8601 UTC) — downstream code doingint(t)must migrate todatetime.fromisoformat(t)BinanceAuthErrorreparented from bareExceptiontoBinanceSDKErrorsubclass (unifiedexcept BinanceSDKErrorcatches all SDK errors)
This SDK exists so that one strategy file can work across TW futures (via shioaji) and Binance perps (via this lib) without rewriting order / contract / quote glue code. The internal Binance REST + WebSocket implementation is hidden behind a shioaji-shaped facade.
v0.5.8 — Working for testnet + mainnet futures. Login, contracts, market info, quotes, orders, account, async WS streaming.
Not yet implemented (open to PRs):
- Spot trading (futures-first for now)
- Sub-account / portfolio margin
- Options
These are intentional deviations from full shioaji parity, tracked for a future release:
-
Order.actionvocabulary: shioaji usesaction=Action.Buy/"Buy"/"Sell"; this SDK uses"long"/"short"(Binance-native semantics). Migration to shioaji vocabulary is deferred due to downstream impact (all callers and test fixtures must update simultaneously). Tracked for a future breaking version. -
list_trades()return type: design §3.6 specifiedlist[BinanceTrade]with a syntheticBinanceContractstub for history entries. At v0.5.8 this method still returnslist[OrderResponse]for API-continuity with existing consumers. The migration is tracked and will be completed in a future release. Until then,list_trades()also silently returns[]on REST errors (unlike other methods which raise typed exceptions). -
cancel_order()signature: shioaji'ssj.cancel_order(trade)accepts aTradeobject; this SDK requirescancel_order(symbol: str, order_id: str). Sinceplace_order()returns aBinanceTradecontainingcontract.symbolandstatus.id, a shim wrapper is straightforward. ATrade-accepting overload is tracked for a future release. -
Dual listenKey keepalive loops:
Binance(client.py) andQuote(quote.py) each maintain an independentlistenKeyand keepalive loop. The Quote's loop drives the actualORDER_TRADE_UPDATEuser stream; the client-layer loop is currently orphaned (its listenKey is never consumed by a WS connection). Consolidation to a single shared listenKey lifecycle is tracked for a future architectural PR.
Issues + PRs welcome. The API contract is shioaji parity: if shioaji has api.foo(...), this should provide bn.foo(...) with semantically equivalent behaviour where it makes sense for crypto futures.
Apache-2.0