Methods

Every method below is defined on Market; the perpetual-only group needs a PerpMarket. The same names exist on Exchange, TradingVenue and TradingMarkets with a leading market_id, which is the form shown here. Every type they return is catalogued in Types. Examples assume:

from tribulnation.sdk import MarketSDK

sdk = MarketSDK.load('sdk.toml')

Public market data

depth

depth(market_id, /, *, levels=None) -> Book

Fetch the market order book, bids and asks best-first.

Args

  • levels: Cap the number of levels per side. None returns the full book.
book = await sdk.depth('binance:spot:BTCUSDT', levels=5)
bid = book.best_bid.price if book.bids else None
ask = book.best_ask.price if book.asks else None
print(bid, ask)
60123.00 60124.10
book = await sdk.depth('bit2me:spot:BTC/EUR', levels=5)
bid = book.best_bid.price if book.bids else None
ask = book.best_ask.price if book.asks else None
print(bid, ask)
60123.00 60124.10
book = await sdk.depth('bitget:spot:BTCUSDT', levels=5)
bid = book.best_bid.price if book.bids else None
ask = book.best_ask.price if book.asks else None
print(bid, ask)
60123.00 60124.10
book = await sdk.depth('bybit:spot:BTCUSDT', levels=5)
bid = book.best_bid.price if book.bids else None
ask = book.best_ask.price if book.asks else None
print(bid, ask)
60123.00 60124.10
book = await sdk.depth('coinbase:spot:BTC-USD', levels=5)
bid = book.best_bid.price if book.bids else None
ask = book.best_ask.price if book.asks else None
print(bid, ask)
60123.00 60124.10
book = await sdk.depth('dydx:perp:BTC-USD', levels=5)
bid = book.best_bid.price if book.bids else None
ask = book.best_ask.price if book.asks else None
print(bid, ask)
60123.00 60124.10
book = await sdk.depth('hyperliquid:spot:UBTC/USDC:142', levels=5)
bid = book.best_bid.price if book.bids else None
ask = book.best_ask.price if book.asks else None
print(bid, ask)
60095.20 60096.50
book = await sdk.depth('kraken:spot:XBTUSD', levels=5)
bid = book.best_bid.price if book.bids else None
ask = book.best_ask.price if book.asks else None
print(bid, ask)
60123.00 60124.10
book = await sdk.depth('kucoin:spot:BTC-USDT', levels=5)
bid = book.best_bid.price if book.bids else None
ask = book.best_ask.price if book.asks else None
print(bid, ask)
60123.00 60124.10
book = await sdk.depth('mexc:spot:BTCUSDT', levels=5)
bid = book.best_bid.price if book.bids else None
ask = book.best_ask.price if book.asks else None
print(bid, ask)
60123.00 60124.10

depth_stream

depth_stream(market_id, /, *, levels=None, queue_size=1, overflow='latest') -> AsyncContextManager[AsyncIterable[Book]]

Subscribe to the market order book.

A venue fans one shared upstream out to every subscriber through a bounded per-subscriber queue. The defaults keep only the freshest book; pass overflow='fail' with a larger queue_size to capture every book. The polling fallback used by generic markets ignores both.

Args

  • levels: Cap the number of levels per side. None streams the full book.
  • queue_size: Books buffered for this subscriber.
  • overflow: 'latest' silently drops stale books when the buffer is full; 'fail' raises NetworkError instead, so you can reconnect.
async with sdk.depth_stream('binance:spot:BTCUSDT') as books:
  async for book in books:
    bid = book.best_bid.price if book.bids else None
    ask = book.best_ask.price if book.asks else None
    print(bid, ask)
60123.40 60124.00
60123.50 60124.00
60122.90 60123.60
60123.10 60123.90
async with sdk.depth_stream('bit2me:spot:BTC/EUR') as books:
  async for book in books:
    bid = book.best_bid.price if book.bids else None
    ask = book.best_ask.price if book.asks else None
    print(bid, ask)
60123.40 60124.00
60123.50 60124.00
60122.90 60123.60
60123.10 60123.90
async with sdk.depth_stream('bitget:spot:BTCUSDT') as books:
  async for book in books:
    bid = book.best_bid.price if book.bids else None
    ask = book.best_ask.price if book.asks else None
    print(bid, ask)
60123.40 60124.00
60123.50 60124.00
60122.90 60123.60
60123.10 60123.90
async with sdk.depth_stream('bybit:spot:BTCUSDT') as books:
  async for book in books:
    bid = book.best_bid.price if book.bids else None
    ask = book.best_ask.price if book.asks else None
    print(bid, ask)
60123.40 60124.00
60123.50 60124.00
60122.90 60123.60
60123.10 60123.90
async with sdk.depth_stream('coinbase:spot:BTC-USD') as books:
  async for book in books:
    bid = book.best_bid.price if book.bids else None
    ask = book.best_ask.price if book.asks else None
    print(bid, ask)
60123.40 60124.00
60123.50 60124.00
60122.90 60123.60
60123.10 60123.90
async with sdk.depth_stream('dydx:perp:BTC-USD') as books:
  async for book in books:
    bid = book.best_bid.price if book.bids else None
    ask = book.best_ask.price if book.asks else None
    print(bid, ask)
60123.40 60124.00
60123.50 60124.00
60122.90 60123.60
60123.10 60123.90
async with sdk.depth_stream('hyperliquid:spot:UBTC/USDC:142') as books:
  async for book in books:
    bid = book.best_bid.price if book.bids else None
    ask = book.best_ask.price if book.asks else None
    print(bid, ask)
60095.60 60096.20
60095.70 60096.20
60095.10 60095.80
60095.30 60096.10
async with sdk.depth_stream('kraken:spot:XBTUSD') as books:
  async for book in books:
    bid = book.best_bid.price if book.bids else None
    ask = book.best_ask.price if book.asks else None
    print(bid, ask)
60123.40 60124.00
60123.50 60124.00
60122.90 60123.60
60123.10 60123.90
async with sdk.depth_stream('kucoin:spot:BTC-USDT') as books:
  async for book in books:
    bid = book.best_bid.price if book.bids else None
    ask = book.best_ask.price if book.asks else None
    print(bid, ask)
60123.40 60124.00
60123.50 60124.00
async with sdk.depth_stream('mexc:spot:BTCUSDT') as books:
  async for book in books:
    bid = book.best_bid.price if book.bids else None
    ask = book.best_ask.price if book.asks else None
    print(bid, ask)
60123.40 60124.00
60123.50 60124.00
60122.90 60123.60
60123.10 60123.90

rules

rules(market_id, /, *, refetch=False) -> Rules

Fetch the market rules: tick and step sizes, fees, min/max, rounding helpers.

Cached after the first call.

Args

  • refetch: Fetch again even if the rules are already cached.
rules = await sdk.rules('binance:spot:BTCUSDT')
price = rules.round_price(Decimal('60123.456'))
print(rules.tick_size, rules.step_size)
0.10 0.00001
rules = await sdk.rules('bit2me:spot:BTC/EUR')
price = rules.round_price(Decimal('60123.456'))
print(rules.tick_size, rules.step_size)
0.10 0.00001
rules = await sdk.rules('bitget:spot:BTCUSDT')
price = rules.round_price(Decimal('60123.456'))
print(rules.tick_size, rules.step_size)
0.10 0.00001
rules = await sdk.rules('bybit:spot:BTCUSDT')
price = rules.round_price(Decimal('60123.456'))
print(rules.tick_size, rules.step_size)
0.10 0.00001
rules = await sdk.rules('coinbase:spot:BTC-USD')
price = rules.round_price(Decimal('60123.456'))
print(rules.tick_size, rules.step_size)
0.10 0.00001
rules = await sdk.rules('dydx:perp:BTC-USD')
price = rules.round_price(Decimal('60123.456'))
print(rules.tick_size, rules.step_size)
0.10 0.00001
rules = await sdk.rules('hyperliquid:spot:UBTC/USDC:142')
price = rules.round_price(Decimal('60123.456'))
print(rules.tick_size, rules.step_size)
0.001 0.00001
rules = await sdk.rules('kraken:spot:XBTUSD')
price = rules.round_price(Decimal('60123.456'))
print(rules.tick_size, rules.step_size)
0.10 0.00001
rules = await sdk.rules('kucoin:spot:BTC-USDT')
price = rules.round_price(Decimal('60123.456'))
print(rules.tick_size, rules.step_size)
0.10 0.000001
rules = await sdk.rules('mexc:spot:BTCUSDT')
price = rules.round_price(Decimal('60123.456'))
print(rules.tick_size, rules.step_size)
0.10 0.00001

Account trading data

fees

fees(market_id, /, *, refetch=False) -> Fees

Fetch the selected market's account rates without a standard-rate fallback.

Combined spot standard/tax/special commissions; USD-M ordinary-order rates. Optional BNB payment discounts and RPI orders excluded.

fees = await sdk.fees('binance:spot:BTCUSDT')
print(fees.taker_buy, fees.taker_sell)
Decimal('0.001') Decimal('0.001')

Symbol-scoped Classic or UTA account rates.

fees = await sdk.fees('bitget:spot:BTCUSDT')
print(fees.taker_buy, fees.taker_sell)
Decimal('0.001') Decimal('0.001')

Symbol-scoped account rates, including the account's applicable fee tier.

fees = await sdk.fees('bybit:spot:BTCUSDT')
print(fees.taker_buy, fees.taker_sell)
Decimal('0.001') Decimal('0.001')

INTX only; cost-plus and unresolved GST adjustments are unsupported. Spot pricing remains unsupported.

fees = await sdk.fees('coinbase:intx:BTC-PERP-INTX')
print(fees.taker_buy, fees.taker_sell)
Decimal('0.001') Decimal('0.001')

Account tier, market fee holidays and staking adjustments with protocol rounding.

fees = await sdk.fees('dydx:perp:BTC-USD')
print(fees.taker_buy, fees.taker_sell)
Decimal('0.001') Decimal('0.001')

Native USDC perpetuals only; HIP-3 and spot require additional verified fee metadata.

fees = await sdk.fees('hyperliquid::BTC')
print(fees.taker_buy, fees.taker_sell)
Decimal('0.001') Decimal('0.001')

Account TradeVolume schedule, converted from percent to fractions.

fees = await sdk.fees('kraken:spot:XBTUSD')
print(fees.taker_buy, fees.taker_sell)
Decimal('0.001') Decimal('0.001')

Spot only with MX deduction disabled; personal perpetual fees are unsupported.

fees = await sdk.fees('mexc:spot:BTCUSDT')
print(fees.taker_buy, fees.taker_sell)
Decimal('0.001') Decimal('0.001')

Public market data

candles

candles(market_id, /, interval, start, end) -> AsyncIterable[Sequence[Candle]]

Fetch the market's historical trade candles, paginated: async-iterate the pages.

Ordering within and across pages follows the venue. Opening timestamps are not repeated across pages; page sizes can vary. Candle.time is always the open time; prices and volumes are Decimal, quote_volume and trades are None where the venue reports none. Only trade candles: mark and index series are not exposed. A candle may still be forming; an elapsed interval does not guarantee immutable data.

Each implementation declares the widths it serves in Market.CANDLE_INTERVALS; any other interval raises ValueError before a request is made.

Args

  • interval: Candle width, one of '1m', '5m', '15m', '1h', '4h', '1d'.
  • start: Inclusive lower bound on opening time, as a timezone-aware datetime.
  • end: Exclusive upper bound on opening time, as a timezone-aware datetime. Equal bounds produce no candles.

Spot and USD-M, every contract interval, 1000 per page with [start, end) filtering.

async for page in sdk.candles('binance:spot:BTCUSDT', '1h', start, end):
  for candle in page:
    print(candle.time, candle.open, candle.close)
2025-01-03 08:00:00+00:00 60124.10 60151.30
2025-01-03 09:00:00+00:00 60151.30 60099.00

Bounded windows continue through empty slots; no synthetic candles. Native order, JSON-number prices converted to decimals.

async for page in sdk.candles('bit2me:spot:BTC/EUR', '1h', start, end):
  for candle in page:
    print(candle.time, candle.open, candle.close)
2025-01-03 08:00:00+00:00 60123.40 60150.00
2025-01-03 09:00:00+00:00 60150.00 60098.20

Spot and supported perpetual exchanges; required aware half-open bounds. Native page order, no synthetic rows.

async for page in sdk.candles('bitget:spot:BTCUSDT', '1h', start, end):
  for candle in page:
    print(candle.time, candle.open, candle.close)
2025-01-03 08:00:00+00:00 60123.40 60150.00
2025-01-03 09:00:00+00:00 60150.00 60098.20

Native newest-first pages, filtered to required [start, end) bounds without buffering the full history.

async for page in sdk.candles('bybit:spot:BTCUSDT', '1h', start, end):
  for candle in page:
    print(candle.time, candle.open, candle.close)
2025-01-03 08:00:00+00:00 60122.80 60149.50
2025-01-03 09:00:00+00:00 60149.50 60097.60

Required [start, end) bounds, swept in windows of 299 candle opens because the venue caps each range. Native row order; quote_volume is None, and hours with no trades are absent rather than zero.

async for page in sdk.candles('coinbase:spot:BTC-USD', '1h', start, end):
  for candle in page:
    print(candle.time, candle.open, candle.close)
2025-01-03 08:00:00+00:00 60120.55 60148.02
2025-01-03 09:00:00+00:00 60148.02 60096.11

Native newest-first pages, filtered to required [start, end) bounds without buffering the full history.

async for page in sdk.candles('dydx:perp:BTC-USD', '1h', start, end):
  for candle in page:
    print(candle.time, candle.open, candle.close)
2025-01-03 08:00:00+00:00 60118.00 60146.00
2025-01-03 09:00:00+00:00 60146.00 60094.00

Spot and perpetuals in native order. Only the latest 5000 candles per interval are retained by the venue; quote volume is not reported.

async for page in sdk.candles('hyperliquid:spot:UBTC/USDC:142', '1h', start, end):
  for candle in page:
    print(candle.time, candle.open, candle.close)
2025-01-03 08:00:00+00:00 60123.40 60150.00
2025-01-03 09:00:00+00:00 60150.00 60098.20

Spot retains its recent OHLC window (720 documented; 721 observed). Perpetuals use bounded 2000-open trade Charts windows. Both support all six intervals and aware half-open bounds; neither guarantees complete archive coverage.

async for page in sdk.candles('kraken:spot:XBTUSD', '1h', start, end):
  for candle in page:
    print(candle.time, candle.open, candle.close)
2025-01-03 08:00:00+00:00 60123.40 60150.00
2025-01-03 09:00:00+00:00 60150.00 60098.20

Classic spot and linear perpetuals; 1500/200-row time windows, all six SDK intervals, aware half-open bounds. Sparse rows remain absent; historical availability varies by product and interval.

async for page in sdk.candles('kucoin:spot:BTC-USDT', '1h', start, end):
  for candle in page:
    print(candle.time, candle.open, candle.close)
2025-01-03 08:00:00+00:00 60123.40 60150.00
2025-01-03 09:00:00+00:00 60150.00 60098.20

Required [start, end) bounds. Pages of 500, the cap MEXC really serves.

async for page in sdk.candles('mexc:spot:BTCUSDT', '1h', start, end):
  for candle in page:
    print(candle.time, candle.open, candle.close)
2025-01-03 08:00:00+00:00 60123.40 60150.00
2025-01-03 09:00:00+00:00 60150.00 60098.20

Bulk market data

tickers

tickers(exchange, *, markets=None, settings={}) -> Mapping[str, Ticker]

Fetch a top-of-book snapshot for many markets at once.

Defined on the exchange, not on a single market. The default fans out over the individual markets with asyncio.gather; venues that can fetch the whole universe in one request override it, which yields a consistent cross-section at one instant instead of a snapshot spread over minutes of wall clock.

Args

  • exchange: <account_id>:<exchange_id>.
  • markets: Market IDs to fetch. None fetches every market of the exchange.
  • settings: Venue-specific ticker settings.

Returns A mapping of market ID to its Ticker.

snapshot = await sdk.tickers('binance:spot')
'BTCUSDT': Ticker(last=Decimal('60123.40'), bid=Decimal('60123.00'), ask=Decimal('60124.10')),
snapshot = await sdk.tickers('bit2me:spot')
'BTC/EUR': Ticker(last=Decimal('60123.40'), bid=Decimal('60123.00'), ask=Decimal('60124.10')),
snapshot = await sdk.tickers('bitget:spot')
'BTCUSDT': Ticker(last=Decimal('60123.40'), bid=Decimal('60123.00'), ask=Decimal('60124.10')),
snapshot = await sdk.tickers('bybit:spot')
'BTCUSDT': Ticker(last=Decimal('60123.40'), bid=Decimal('60123.00'), ask=Decimal('60124.10')),

Authenticated access is recommended: quotes are batched in groups of up to 100 products. Explicit public=True accounts without resolved credentials use one public book request per selected product. Available credentials are still preferred. Coinbase is not a default account; select markets to limit public request volume. Authentication errors never trigger an automatic fallback.

snapshot = await sdk.tickers('coinbase:spot')
'BTC-USD': Ticker(last=Decimal('60123.40'), bid=Decimal('60123.00'), ask=Decimal('60124.10')),
snapshot = await sdk.tickers('dydx:perp')
'BTC-USD': Ticker(last=Decimal('60123.40'), bid=Decimal('60123.00'), ask=Decimal('60124.10')),
snapshot = await sdk.tickers('hyperliquid:spot')
'UBTC/USDC:142': Ticker(last=Decimal('60095.90'), bid=Decimal('60095.20'), ask=Decimal('60096.50')),
snapshot = await sdk.tickers('kraken:spot')
'XBTUSD': Ticker(last=Decimal('60123.40'), bid=Decimal('60123.00'), ask=Decimal('60124.10')),

Credential-free spot and linear perpetual tickers; quantities use base units.

snapshot = await sdk.tickers('kucoin:spot')
'BTC-USDT': Ticker(last=Decimal('60123.40'), bid=Decimal('60123.00'), ask=Decimal('60124.10')),
snapshot = await sdk.tickers('mexc:spot')
'BTCUSDT': Ticker(last=Decimal('60123.40'), bid=Decimal('60123.00'), ask=Decimal('60124.10')),
'ETHUSDT': Ticker(last=Decimal('3210.50'), bid=Decimal('3210.20'), ask=Decimal('3210.80')),

perp_stats

perp_stats(exchange, *, markets=None, settings={}) -> Mapping[str, PerpStats]

Fetch a pricing and funding snapshot for many perpetual markets at once.

Index and mark price, predicted funding, next funding time and interval, and open interest per market. Like tickers, the default fans out per market; venues that can fetch the whole universe in one request override it, so the cross-section is consistent, which is what cross-market basis and funding analysis needs.

Args

  • exchange: <account_id>:<exchange_id>.
  • markets: Market IDs to fetch. None fetches every market of the exchange.
  • settings: Venue-specific settings.

Returns A mapping of market ID to its PerpStats.

USD-M perpetuals; bulk price/funding plus per-market open-interest reads. Component observations are not atomic.

stats = await sdk.perp_stats('binance:usdm')
{'BTCUSDT': PerpStats(index=Decimal('60120.00'), mark=Decimal('60125.50'),
                       funding=Decimal('0.0001'), open_interest=Decimal('812.4'))}

USDT, USDC and Classic coin-margined perpetuals. UTA coin is unsupported.

stats = await sdk.perp_stats('bitget:usdt')
{'BTCUSDT': PerpStats(index=Decimal('60120.00'), mark=Decimal('60125.50'),
                       funding=Decimal('0.0001'), open_interest=Decimal('812.4'))}

Linear perpetuals only.

stats = await sdk.perp_stats('bybit:perp')
{'BTCUSDT': PerpStats(index=Decimal('60120.00'), mark=Decimal('60125.50'),
                       funding=Decimal('0.0001'), open_interest=Decimal('812.4'))}

INTX perpetuals, not domestic dated futures; explicit public=True accounts use the public product catalogue.

stats = await sdk.perp_stats('coinbase:intx')
{'BTC-PERP-INTX': PerpStats(index=Decimal('60120.00'), mark=Decimal('60125.50'),
                       funding=Decimal('0.0001'), open_interest=Decimal('812.4'))}

Fetched for the whole universe in one request.

stats = await sdk.perp_stats('dydx:perp')
{'BTC-USD': PerpStats(index=Decimal('60120.00'), mark=Decimal('60125.50'),
                       funding=Decimal('0.0001'), open_interest=Decimal('812.4'))}

Fetched for the whole universe in one request.

stats = await sdk.perp_stats('hyperliquid:')
{'BTC': PerpStats(index=Decimal('60110.50'), mark=Decimal('60116.00'),
                       funding=Decimal('0.00012'), open_interest=Decimal('634.9'))}

Public linear perpetual index, mark and base-unit open interest; optional funding fields remain unset.

stats = await sdk.perp_stats('kraken:perp')
{'PF_XBTUSD': PerpStats(index=Decimal('60120.00'), mark=Decimal('60125.50'),
                       funding=None, open_interest=Decimal('812.4'))}

Linear perpetual index, mark and base-unit open interest; funding fields are unset. Use next_funding for the dedicated public funding snapshot.

stats = await sdk.perp_stats('kucoin:perp')
{'XBTUSDTM': PerpStats(index=Decimal('60120.00'), mark=Decimal('60125.50'),
                       funding=None, open_interest=Decimal('812.4'))}

Public perpetual metadata; account-specific futures permissions are not needed for this method.

stats = await sdk.perp_stats('mexc:perp')
{'BTC_USDT': PerpStats(index=Decimal('60120.00'), mark=Decimal('60125.50'),
                       funding=Decimal('0.0001'), open_interest=Decimal('812.4'))}

Your account data

query_order

query_order(market_id, /, id) -> OrderState | None

Fetch the state of the order with the given ID.

The base implementation scans open_orders(), so it only finds open orders unless the venue overrides it.

state = await sdk.query_order('binance:spot:BTCUSDT', '4834937')
OrderState(id='4834937', price=Decimal('59500'), qty=Decimal('0.01'),
           filled_qty=Decimal('0'), active=True)
state = await sdk.query_order('bit2me:spot:BTC/EUR', '00000000-0000-4000-8000-000000000001')
OrderState(id='00000000-0000-4000-8000-000000000001', price=Decimal('59500'), qty=Decimal('0.01'),
           filled_qty=Decimal('0'), active=True)
state = await sdk.query_order('bitget:spot:BTCUSDT', '4834937')
OrderState(id='4834937', price=Decimal('59500'), qty=Decimal('0.01'),
           filled_qty=Decimal('0'), active=True)
state = await sdk.query_order('bybit:spot:BTCUSDT', '00000000-0000-4000-8000-000000000001')
OrderState(id='00000000-0000-4000-8000-000000000001', price=Decimal('59500'), qty=Decimal('0.01'),
           filled_qty=Decimal('0'), active=True)
state = await sdk.query_order('coinbase:spot:BTC-USD', '00000000-0000-4000-8000-000000000001')
OrderState(id='00000000-0000-4000-8000-000000000001', price=Decimal('59500'), qty=Decimal('0.01'),
           filled_qty=Decimal('0'), active=True)

Overrides the base scan and can return filled and canceled states too.

state = await sdk.query_order('dydx:perp:BTC-USD', 'Ci0KK2R5ZHgxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXE2NndtODIVAQAAABhA')
OrderState(id='Ci0KK2R5ZHgxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXE2NndtODIVAQAAABhA', price=Decimal('59500'), qty=Decimal('0.01'),
           filled_qty=Decimal('0'), active=True)
state = await sdk.query_order('hyperliquid:spot:UBTC/USDC:142', '184920371')
OrderState(id='184920371', price=Decimal('59480'), qty=Decimal('0.02'),
           filled_qty=Decimal('0'), active=True)
state = await sdk.query_order('kraken:spot:XBTUSD', 'OABC12-DE345-FGHI61')
OrderState(id='OABC12-DE345-FGHI61', price=Decimal('59500'), qty=Decimal('0.01'),
           filled_qty=Decimal('0'), active=True)
state = await sdk.query_order('mexc:spot:BTCUSDT', '4834937')
OrderState(id='4834937', price=Decimal('59500'), qty=Decimal('0.01'),
           filled_qty=Decimal('0'), active=True)

open_orders

open_orders(market_id, /) -> Sequence[OrderState]

Fetch your currently open orders.

orders = await sdk.open_orders('binance:spot:BTCUSDT')
[OrderState(id='4834937', price=Decimal('59500'),
             qty=Decimal('0.01'), filled_qty=Decimal('0'), active=True)]
orders = await sdk.open_orders('bit2me:spot:BTC/EUR')
[OrderState(id='00000000-0000-4000-8000-000000000001', price=Decimal('59500'),
             qty=Decimal('0.01'), filled_qty=Decimal('0'), active=True)]
orders = await sdk.open_orders('bitget:spot:BTCUSDT')
[OrderState(id='4834937', price=Decimal('59500'),
             qty=Decimal('0.01'), filled_qty=Decimal('0'), active=True)]
orders = await sdk.open_orders('bybit:spot:BTCUSDT')
[OrderState(id='00000000-0000-4000-8000-000000000001', price=Decimal('59500'),
             qty=Decimal('0.01'), filled_qty=Decimal('0'), active=True)]
orders = await sdk.open_orders('coinbase:spot:BTC-USD')
[OrderState(id='00000000-0000-4000-8000-000000000001', price=Decimal('59500'),
             qty=Decimal('0.01'), filled_qty=Decimal('0'), active=True)]
orders = await sdk.open_orders('dydx:perp:BTC-USD')
[OrderState(id='Ci0KK2R5ZHgxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXE2NndtODIVAQAAABhA', price=Decimal('59500'),
             qty=Decimal('0.01'), filled_qty=Decimal('0'), active=True)]
orders = await sdk.open_orders('hyperliquid:spot:UBTC/USDC:142')
[OrderState(id='184920371', price=Decimal('59480'),
             qty=Decimal('0.02'), filled_qty=Decimal('0'), active=True)]
orders = await sdk.open_orders('kraken:spot:XBTUSD')
[OrderState(id='OABC12-DE345-FGHI61', price=Decimal('59500'),
             qty=Decimal('0.01'), filled_qty=Decimal('0'), active=True)]
orders = await sdk.open_orders('mexc:spot:BTCUSDT')
[OrderState(id='4834937', price=Decimal('59500'),
             qty=Decimal('0.01'), filled_qty=Decimal('0'), active=True)]

trades_history

trades_history(market_id, /, start, end) -> AsyncIterable[Sequence[Trade]]

Fetch your fills over a window, paginated: async-iterate the pages.

Args

  • start: Start of the window (inclusive).
  • end: End of the window (inclusive).
trades = []
async for page in sdk.trades_history('binance:spot:BTCUSDT', start, end):
  for trade in page:
    trades.append(trade)
    print(trade.price, trade.qty)
60123.40 0.01
60050.00 -0.02
trades = []
async for page in sdk.trades_history('bit2me:spot:BTC/EUR', start, end):
  for trade in page:
    trades.append(trade)
    print(trade.price, trade.qty)
60123.40 0.01
60050.00 -0.02
trades = []
async for page in sdk.trades_history('bitget:spot:BTCUSDT', start, end):
  for trade in page:
    trades.append(trade)
    print(trade.price, trade.qty)
60123.40 0.01
60050.00 -0.02
trades = []
async for page in sdk.trades_history('bybit:spot:BTCUSDT', start, end):
  for trade in page:
    trades.append(trade)
    print(trade.price, trade.qty)
60123.40 0.01
60050.00 -0.02
trades = []
async for page in sdk.trades_history('coinbase:spot:BTC-USD', start, end):
  for trade in page:
    trades.append(trade)
    print(trade.price, trade.qty)
60123.40 0.01
60050.00 -0.02
trades = []
async for page in sdk.trades_history('dydx:perp:BTC-USD', start, end):
  for trade in page:
    trades.append(trade)
    print(trade.price, trade.qty)
60123.40 0.01
60050.00 -0.02
trades = []
async for page in sdk.trades_history('hyperliquid:spot:UBTC/USDC:142', start, end):
  for trade in page:
    trades.append(trade)
    print(trade.price, trade.qty)
60095.60 0.01
60040.00 -0.02
trades = []
async for page in sdk.trades_history('kraken:spot:XBTUSD', start, end):
  for trade in page:
    trades.append(trade)
    print(trade.price, trade.qty)
60123.40 0.01
60050.00 -0.02
trades = []
async for page in sdk.trades_history('mexc:spot:BTCUSDT', start, end):
  for trade in page:
    trades.append(trade)
    print(trade.price, trade.qty)
60123.40 0.01
60050.00 -0.02

trades_stream

trades_stream(market_id, /, *, queue_size=1000, overflow='fail') -> AsyncContextManager[AsyncIterable[Trade]]

Subscribe to your real-time fills.

Same fan-out as depth_stream, but the defaults buffer generously and fail on overflow rather than dropping your own fills silently.

Args

  • queue_size: Trades buffered for this subscriber.
  • overflow: 'fail' raises NetworkError when the buffer is full; 'latest' silently keeps only the newest trade.
async with sdk.trades_stream('binance:spot:BTCUSDT') as trades:
  async for trade in trades:
    print(trade.price, trade.qty)
60123.40 0.01
60124.00 -0.02
60125.10 0.05
async with sdk.trades_stream('bit2me:spot:BTC/EUR') as trades:
  async for trade in trades:
    print(trade.price, trade.qty)
60123.40 0.01
60124.00 -0.02
60125.10 0.05
async with sdk.trades_stream('bitget:spot:BTCUSDT') as trades:
  async for trade in trades:
    print(trade.price, trade.qty)
60123.40 0.01
60124.00 -0.02
60125.10 0.05
async with sdk.trades_stream('bybit:spot:BTCUSDT') as trades:
  async for trade in trades:
    print(trade.price, trade.qty)
60123.40 0.01
60124.00 -0.02
60125.10 0.05
async with sdk.trades_stream('coinbase:spot:BTC-USD') as trades:
  async for trade in trades:
    print(trade.price, trade.qty)
60123.40 0.01
60124.00 -0.02
60125.10 0.05
async with sdk.trades_stream('dydx:perp:BTC-USD') as trades:
  async for trade in trades:
    print(trade.price, trade.qty)
60123.40 0.01
60124.00 -0.02
60125.10 0.05
async with sdk.trades_stream('hyperliquid:spot:UBTC/USDC:142') as trades:
  async for trade in trades:
    print(trade.price, trade.qty)
60096.80 0.01
60097.40 -0.02
60098.50 0.05
async with sdk.trades_stream('kraken:spot:XBTUSD') as trades:
  async for trade in trades:
    print(trade.price, trade.qty)
60123.40 0.01
60124.00 -0.02
60125.10 0.05
async with sdk.trades_stream('mexc:spot:BTCUSDT') as trades:
  async for trade in trades:
    print(trade.price, trade.qty)
60123.40 0.01
60124.00 -0.02
60125.10 0.05

position

position(market_id, /) -> Position

Fetch your open position in the market, as a signed size in base units.

On a perpetual market this is the same data as perp_position(), typed as the base Position.

pos = await sdk.position('binance:spot:BTCUSDT')
Position(size=Decimal('0.014'))
pos = await sdk.position('bit2me:spot:BTC/EUR')
Position(size=Decimal('0.014'))
pos = await sdk.position('bitget:spot:BTCUSDT')
Position(size=Decimal('0.014'))
pos = await sdk.position('bybit:spot:BTCUSDT')
Position(size=Decimal('0.014'))
pos = await sdk.position('coinbase:spot:BTC-USD')
Position(size=Decimal('0.014'))
pos = await sdk.position('dydx:perp:BTC-USD')
Position(size=Decimal('0.014'))
pos = await sdk.position('hyperliquid:spot:UBTC/USDC:142')
Position(size=Decimal('0.5'))
pos = await sdk.position('kraken:spot:XBTUSD')
Position(size=Decimal('0.014'))
pos = await sdk.position('mexc:spot:BTCUSDT')
Position(size=Decimal('0.014'))

collateral

collateral(id, /) -> Collateral

Fetch the collateral bucket backing a market, or an exchange's own bucket.

A bucket is a set of markets sharing one collateral pool and one liquidation event; an exchange is one bucket. Market-level calls are mode-aware: a cross-margin market reports the exchange bucket, an isolated market its own. Risk never aggregates across buckets. Venues without collateral support raise NotImplementedError.

Args

  • id: <account_id>:<exchange_id> for the exchange bucket, or <account_id>:<exchange_id>:<market_id> for the bucket backing that market.
c = await sdk.collateral('binance:spot:BTCUSDT')
Collateral(equity=Decimal('10240.55'), free_collateral=Decimal('8120.00'))
c = await sdk.collateral('bit2me:spot:BTC/EUR')
Collateral(equity=Decimal('10240.55'), free_collateral=Decimal('8120.00'))
c = await sdk.collateral('bitget:spot:BTCUSDT')
Collateral(equity=Decimal('10240.55'), free_collateral=Decimal('8120.00'))
c = await sdk.collateral('bybit:spot:BTCUSDT')
Collateral(equity=Decimal('10240.55'), free_collateral=Decimal('8120.00'))
c = await sdk.collateral('coinbase:spot:BTC-USD')
Collateral(equity=Decimal('10240.55'), free_collateral=Decimal('8120.00'))
c = await sdk.collateral('dydx:perp:BTC-USD')
Collateral(equity=Decimal('10240.55'), free_collateral=Decimal('8120.00'))
c = await sdk.collateral('hyperliquid:spot:UBTC/USDC:142')
Collateral(equity=Decimal('9875.20'), free_collateral=Decimal('7640.00'))
c = await sdk.collateral('kraken:spot:XBTUSD')
Collateral(equity=Decimal('10240.55'), free_collateral=Decimal('8120.00'))
c = await sdk.collateral('mexc:spot:BTCUSDT')
Collateral(equity=Decimal('10240.55'), free_collateral=Decimal('8120.00'))

available_notional

available_notional(market_id, /) -> Decimal

Fetch the maximum notional position you could open right now.

Spot: the free quote-token balance. Perps: available collateral times the market's maximum leverage. This is opening capacity, deliberately separate from collateral(), which is about liquidation distance.

notional = await sdk.available_notional('binance:spot:BTCUSDT')
Decimal('8120.00')
notional = await sdk.available_notional('bit2me:spot:BTC/EUR')
Decimal('8120.00')
notional = await sdk.available_notional('bitget:spot:BTCUSDT')
Decimal('8120.00')
notional = await sdk.available_notional('bybit:spot:BTCUSDT')
Decimal('8120.00')
notional = await sdk.available_notional('coinbase:spot:BTC-USD')
Decimal('8120.00')
notional = await sdk.available_notional('dydx:perp:BTC-USD')
Decimal('8120.00')
notional = await sdk.available_notional('hyperliquid:spot:UBTC/USDC:142')
Decimal('7640.00')
notional = await sdk.available_notional('kraken:spot:XBTUSD')
Decimal('8120.00')
notional = await sdk.available_notional('mexc:spot:BTCUSDT')
Decimal('8120.00')

Trading

place_order

place_order(market_id, /, order, *, settings={}) -> OrderResponse

Place an order in the market.

LIMIT rests at price unless settings request another time-in-force. POST_ONLY is maker-only: the venue rejects or cancels rather than taking liquidity. MARKET executes immediately with price as the worst acceptable limit; venues without native market orders send an aggressive non-resting (IOC) limit, and fills may be partial. A venue that can't honor the requested semantics raises rather than placing a materially different order.

Args

  • order: qty in signed base units (positive buys, negative sells), price, and type.
  • settings: Venue-specific options keyed by venue name, e.g. {'dydx': {...}}; see each venue page for accepted keys.
order = {'type': 'LIMIT', 'qty': 0.01, 'price': 60_000}
response = await sdk.place_order('bit2me:spot:BTC/EUR', order)
OrderResponse(id='00000000-0000-4000-8000-000000000001', details={...})
order = {'type': 'LIMIT', 'qty': 0.01, 'price': 60_000}
response = await sdk.place_order('bybit:spot:BTCUSDT', order)
OrderResponse(id='00000000-0000-4000-8000-000000000001', details={...})
order = {'type': 'LIMIT', 'qty': 0.01, 'price': 60_000}
response = await sdk.place_order('coinbase:spot:BTC-USD', order)
OrderResponse(id='00000000-0000-4000-8000-000000000001', details={...})
order = {'type': 'LIMIT', 'qty': 0.01, 'price': 60_000}
response = await sdk.place_order('dydx:perp:BTC-USD', order)
OrderResponse(id='Ci0KK2R5ZHgxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXE2NndtODIVAQAAABhA', details={...})
order = {'type': 'LIMIT', 'qty': 0.01, 'price': 60_000}
response = await sdk.place_order('hyperliquid:spot:UBTC/USDC:142', order)
OrderResponse(id='184920371', details={...})
order = {'type': 'LIMIT', 'qty': 0.01, 'price': 60_000}
response = await sdk.place_order('mexc:spot:BTCUSDT', order)
OrderResponse(id='4834937', details={...})

place_orders

place_orders(market_id, /, orders, *, settings={}) -> Sequence[OrderResponse]

Place several orders concurrently: one response per order, in input order.

Args

  • orders: The orders to place, each as for place_order.
  • settings: Venue-specific options, applied to every order.
orders = [
  {'type': 'LIMIT', 'qty': 0.01, 'price': 60_000},
  {'type': 'LIMIT', 'qty': 0.01, 'price': 59_500},
]
responses = await sdk.place_orders('bit2me:spot:BTC/EUR', orders)
[OrderResponse(id='00000000-0000-4000-8000-000000000001', details={...}), OrderResponse(id='00000000-0000-4000-8000-000000000002', details={...})]
orders = [
  {'type': 'LIMIT', 'qty': 0.01, 'price': 60_000},
  {'type': 'LIMIT', 'qty': 0.01, 'price': 59_500},
]
responses = await sdk.place_orders('bybit:spot:BTCUSDT', orders)
[OrderResponse(id='00000000-0000-4000-8000-000000000001', details={...}), OrderResponse(id='00000000-0000-4000-8000-000000000002', details={...})]
orders = [
  {'type': 'LIMIT', 'qty': 0.01, 'price': 60_000},
  {'type': 'LIMIT', 'qty': 0.01, 'price': 59_500},
]
responses = await sdk.place_orders('coinbase:spot:BTC-USD', orders)
[OrderResponse(id='00000000-0000-4000-8000-000000000001', details={...}), OrderResponse(id='00000000-0000-4000-8000-000000000002', details={...})]
orders = [
  {'type': 'LIMIT', 'qty': 0.01, 'price': 60_000},
  {'type': 'LIMIT', 'qty': 0.01, 'price': 59_500},
]
responses = await sdk.place_orders('dydx:perp:BTC-USD', orders)
[OrderResponse(id='Ci0KK2R5ZHgxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXE2NndtODIVAQAAABhA', details={...}), OrderResponse(id='Ci0KK2R5ZHgxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXE2NndtODIVAgAAABhA', details={...})]
orders = [
  {'type': 'LIMIT', 'qty': 0.01, 'price': 60_000},
  {'type': 'LIMIT', 'qty': 0.01, 'price': 59_500},
]
responses = await sdk.place_orders('hyperliquid:spot:UBTC/USDC:142', orders)
[OrderResponse(id='184920371', details={...}), OrderResponse(id='184920372', details={...})]

cancel_order

cancel_order(market_id, /, id, *, settings={}) -> Any

Cancel an order in the market.

Args

  • id: The order ID, as returned by place_order.
  • settings: Venue-specific options keyed by venue name.
await sdk.cancel_order('bit2me:spot:BTC/EUR', '00000000-0000-4000-8000-000000000001')
print('Cancellation request completed')
Cancellation request completed
await sdk.cancel_order('bybit:spot:BTCUSDT', '00000000-0000-4000-8000-000000000001')
print('Cancellation request completed')
Cancellation request completed
await sdk.cancel_order('coinbase:spot:BTC-USD', '00000000-0000-4000-8000-000000000001')
print('Cancellation request completed')
Cancellation request completed
await sdk.cancel_order('dydx:perp:BTC-USD', 'Ci0KK2R5ZHgxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXE2NndtODIVAQAAABhA')
print('Cancellation request completed')
Cancellation request completed
await sdk.cancel_order('hyperliquid:spot:UBTC/USDC:142', '184920371')
print('Cancellation request completed')
Cancellation request completed
await sdk.cancel_order('mexc:spot:BTCUSDT', '4834937')
print('Cancellation request completed')
Cancellation request completed

cancel_orders

cancel_orders(market_id, /, ids, *, settings={}) -> Any

Cancel several orders concurrently.

Args

  • ids: The order IDs to cancel.
  • settings: Venue-specific options, applied to every cancel.
await sdk.cancel_orders('bit2me:spot:BTC/EUR', ['00000000-0000-4000-8000-000000000001', '00000000-0000-4000-8000-000000000002'])
print('Cancellation request completed')
Cancellation request completed
await sdk.cancel_orders('bybit:spot:BTCUSDT', ['00000000-0000-4000-8000-000000000001', '00000000-0000-4000-8000-000000000002'])
print('Cancellation request completed')
Cancellation request completed
await sdk.cancel_orders('coinbase:spot:BTC-USD', ['00000000-0000-4000-8000-000000000001', '00000000-0000-4000-8000-000000000002'])
print('Cancellation request completed')
Cancellation request completed
await sdk.cancel_orders('dydx:perp:BTC-USD', ['Ci0KK2R5ZHgxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXE2NndtODIVAQAAABhA', 'Ci0KK2R5ZHgxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXE2NndtODIVAgAAABhA'])
print('Cancellation request completed')
Cancellation request completed
await sdk.cancel_orders('hyperliquid:spot:UBTC/USDC:142', ['184920371', '184920372'])
print('Cancellation request completed')
Cancellation request completed
await sdk.cancel_orders('mexc:spot:BTCUSDT', ['4834937', '4834938'])
print('Cancellation request completed')
Cancellation request completed

cancel_open_orders

cancel_open_orders(market_id, /, *, settings={}) -> Any

Cancel everything open_orders() returns.

Args

  • settings: Venue-specific options keyed by venue name.
await sdk.cancel_open_orders('bit2me:spot:BTC/EUR')
print('Cancellation request completed')
Cancellation request completed
await sdk.cancel_open_orders('bybit:spot:BTCUSDT')
print('Cancellation request completed')
Cancellation request completed
await sdk.cancel_open_orders('coinbase:spot:BTC-USD')
print('Cancellation request completed')
Cancellation request completed
await sdk.cancel_open_orders('dydx:perp:BTC-USD')
print('Cancellation request completed')
Cancellation request completed
await sdk.cancel_open_orders('hyperliquid:spot:UBTC/USDC:142')
print('Cancellation request completed')
Cancellation request completed
await sdk.cancel_open_orders('mexc:spot:BTCUSDT')
print('Cancellation request completed')
Cancellation request completed

Perpetual-only

index

index(market_id, /) -> Decimal

Fetch the market index (oracle) price.

price = await sdk.index('binance:usdm:BTCUSDT')
Decimal('60120.00')
price = await sdk.index('bitget:usdt:BTCUSDT')
Decimal('60120.00')
price = await sdk.index('bybit:perp:BTCUSDT')
Decimal('60120.00')
price = await sdk.index('coinbase:intx:BTC-PERP-INTX')
Decimal('60120.00')
price = await sdk.index('dydx:perp:BTC-USD')
Decimal('60120.00')
price = await sdk.index('hyperliquid::BTC')
Decimal('60110.50')
price = await sdk.index('kraken:perp:PF_XBTUSD')
Decimal('60120.00')
price = await sdk.index('kucoin:perp:XBTUSDTM')
Decimal('60120.00')
price = await sdk.index('mexc:perp:BTC_USDT')
Decimal('60120.00')

next_funding

next_funding(market_id, /) -> NextFunding

Fetch the upcoming funding rate, time and interval.

.annualized extrapolates the rate to a yearly figure.

funding = await sdk.next_funding('binance:usdm:BTCUSDT')
print(funding.rate, funding.annualized)
0.0001 0.1095
funding = await sdk.next_funding('bitget:usdt:BTCUSDT')
print(funding.rate, funding.annualized)
0.0001 0.1095
funding = await sdk.next_funding('bybit:perp:BTCUSDT')
print(funding.rate, funding.annualized)
0.0001 0.1095
funding = await sdk.next_funding('coinbase:intx:BTC-PERP-INTX')
print(funding.rate, funding.annualized)
0.0001 0.876
funding = await sdk.next_funding('dydx:perp:BTC-USD')
print(funding.rate, funding.annualized)
0.0001 0.876
funding = await sdk.next_funding('hyperliquid::BTC')
print(funding.rate, funding.annualized)
0.00012 1.0512
funding = await sdk.next_funding('kucoin:perp:XBTUSDTM')
print(funding.rate, funding.annualized)
0.0001 0.1095
funding = await sdk.next_funding('mexc:perp:BTC_USDT')
print(funding.rate, funding.annualized)
0.0001 0.1095

funding_rates

funding_rates(market_id, /, start=None, end=None) -> AsyncIterable[Sequence[FundingRate]]

Fetch the market's public funding rate history, paginated.

Each FundingRate may also carry the premium (mark vs. index) it was computed from.

Args

  • start: Start of the window (inclusive). None fetches from the earliest available.
  • end: End of the window (inclusive). None means everything since start.
async for page in sdk.funding_rates('binance:usdm:BTCUSDT', start, end):
  for rate in page:
    print(rate.time, rate.rate)
2025-01-03 16:00:00 0.0001
2025-01-03 08:00:00 0.00012
async for page in sdk.funding_rates('bitget:usdt:BTCUSDT', start, end):
  for rate in page:
    print(rate.time, rate.rate)
2025-01-03 16:00:00 0.0001
2025-01-03 08:00:00 0.00012
async for page in sdk.funding_rates('bybit:perp:BTCUSDT', start, end):
  for rate in page:
    print(rate.time, rate.rate)
2025-01-03 16:00:00 0.0001
2025-01-03 08:00:00 0.00012
async for page in sdk.funding_rates('coinbase:intx:BTC-PERP-INTX', start, end):
  for rate in page:
    print(rate.time, rate.rate)
2025-01-03 16:00:00 0.0001
2025-01-03 08:00:00 0.00012
async for page in sdk.funding_rates('dydx:perp:BTC-USD', start, end):
  for rate in page:
    print(rate.time, rate.rate)
2025-01-03 16:00:00 0.0001
2025-01-03 08:00:00 0.00012
async for page in sdk.funding_rates('hyperliquid::BTC', start, end):
  for rate in page:
    print(rate.time, rate.rate)
2025-01-03 16:00:00 0.00012
2025-01-03 08:00:00 0.00011

Native historical relative rates; SDK settlement time is period start plus one hour. Inclusive bounds apply to settlement time; an omitted start includes all retained rows.

async for page in sdk.funding_rates('kraken:perp:PF_XBTUSD', start, end):
  for rate in page:
    print(rate.time, rate.rate)
2025-01-03 16:00:00 0.0001
2025-01-03 08:00:00 0.00012
async for page in sdk.funding_rates('kucoin:perp:XBTUSDTM', start, end):
  for rate in page:
    print(rate.time, rate.rate)
2025-01-03 16:00:00 0.0001
2025-01-03 08:00:00 0.00012
async for page in sdk.funding_rates('mexc:perp:BTC_USDT', start, end):
  for rate in page:
    print(rate.time, rate.rate)
2025-01-03 16:00:00 0.0001
2025-01-03 08:00:00 0.00012

funding_payments

funding_payments(market_id, /, start, end) -> AsyncIterable[Sequence[FundingPayment]]

Fetch your own settled funding cashflows over a window, paginated.

Paid is positive, received is negative, in quote units. Credential-scoped, unlike funding_rates.

Args

  • start: Start of the window (inclusive).
  • end: End of the window (inclusive).
async for page in sdk.funding_payments('bybit:perp:BTCUSDT', start, end):
  for payment in page:
    print(payment.time, payment.amount)
2025-01-03 16:00:00 -1.24
2025-01-03 08:00:00 0.86
async for page in sdk.funding_payments('dydx:perp:BTC-USD', start, end):
  for payment in page:
    print(payment.time, payment.amount)
2025-01-03 16:00:00 -1.24
2025-01-03 08:00:00 0.86
async for page in sdk.funding_payments('hyperliquid::BTC', start, end):
  for payment in page:
    print(payment.time, payment.amount)
2025-01-03 16:00:00 -1.05
2025-01-03 08:00:00 0.74

perp_position

perp_position(market_id, /) -> PerpPosition

Fetch your open perpetual position: signed size plus average entry_price.

pos = await sdk.perp_position('bitget:usdt:BTCUSDT')
PerpPosition(size=Decimal('0.5'), entry_price=Decimal('58230.10'))
pos = await sdk.perp_position('bybit:perp:BTCUSDT')
PerpPosition(size=Decimal('0.5'), entry_price=Decimal('58230.10'))
pos = await sdk.perp_position('coinbase:intx:BTC-PERP-INTX')
PerpPosition(size=Decimal('0.5'), entry_price=Decimal('58230.10'))
pos = await sdk.perp_position('dydx:perp:BTC-USD')
PerpPosition(size=Decimal('0.5'), entry_price=Decimal('58230.10'))
pos = await sdk.perp_position('hyperliquid::BTC')
PerpPosition(size=Decimal('0.3'), entry_price=Decimal('58190.40'))

perp_collateral

perp_collateral(id, /) -> PerpCollateral

Fetch the perpetual collateral bucket, with maintenance-margin risk fields.

Same bucket model and routing as collateral(), plus initial_margin, maintenance_margin, leverage, margin_mode, and the initial_ratio and maintenance_ratio properties. You can't open more at initial_ratio >= 1; liquidation is at maintenance_ratio >= 1.

Args

  • id: <account_id>:<exchange_id> for the exchange bucket, or <account_id>:<exchange_id>:<market_id> for the bucket backing that market.
c = await sdk.perp_collateral('bitget:usdt:BTCUSDT')
print(c.maintenance_ratio)
PerpCollateral(equity=Decimal('10240.55'), leverage=Decimal('2.10'), ...)
0.183  # maintenance_ratio -- liquidation at 1.0
c = await sdk.perp_collateral('bybit:perp:BTCUSDT')
print(c.maintenance_ratio)
PerpCollateral(equity=Decimal('10240.55'), leverage=Decimal('2.10'), ...)
0.183  # maintenance_ratio -- liquidation at 1.0
c = await sdk.perp_collateral('coinbase:intx:BTC-PERP-INTX')
print(c.maintenance_ratio)
PerpCollateral(equity=Decimal('10240.55'), leverage=Decimal('2.10'), ...)
0.183  # maintenance_ratio -- liquidation at 1.0
c = await sdk.perp_collateral('dydx:perp:BTC-USD')
print(c.maintenance_ratio)
PerpCollateral(equity=Decimal('10240.55'), leverage=Decimal('2.10'), ...)
0.183  # maintenance_ratio -- liquidation at 1.0
c = await sdk.perp_collateral('hyperliquid::BTC')
print(c.maintenance_ratio)
PerpCollateral(equity=Decimal('9875.20'), leverage=Decimal('1.85'), ...)
0.201  # maintenance_ratio -- liquidation at 1.0