SDK
Python SDK
The official Python client for the Liquid Trading API — automatic signing, typed models, and structured error handling.
Installation
Linkpip install liquidtrading-pythonuv add liquidtrading-pythonRequires Python 3.9+.
Quick Start
Linkfrom liquidtrading import LiquidClient
client = LiquidClient(
api_key="lq_...",
api_secret="sk_...",
)
ticker = client.get_ticker("BTC-PERP")
print(ticker.mark_price)Client Configuration
Linkfrom liquidtrading import LiquidClient
client = LiquidClient(
api_key="lq_...",
api_secret="sk_...",
base_url="https://api.liquid.trade", # default
timeout=30.0, # seconds
max_retries=0, # retries for GET on 429/5xx
)| Parameter | Type | Default | Description |
|---|---|---|---|
| api_key | str | — | Your Liquid API key |
| api_secret | str | — | Your Liquid API secret |
| base_url | str | https://api.liquid.trade | REST API base URL |
| timeout | float | 30.0 | Request timeout in seconds |
| max_retries | int | 0 | Retry count for GET requests on 429 and 5xx |
Retries use exponential backoff with jitter and respect Retry-After headers. Only GET requests are retried — mutations are never automatically retried.
Market Data
Link| Method | Returns | Description |
|---|---|---|
| get_markets() | list[dict] | All tradeable markets with symbol, ticker, exchange, max_leverage |
| get_ticker(symbol) | Ticker | Mark price, 24h volume, 24h change, funding rate |
| get_orderbook(symbol, depth=20) | Orderbook | L2 snapshot with bids and asks (price, size, count per level) |
| get_candles(symbol, interval, limit, start, end) | list[Candle] | OHLCV candles (intervals: 1m, 5m, 15m, 30m, 1h, 4h, 1d) |
# Get all markets
markets = client.get_markets()
# Get ticker
ticker = client.get_ticker("ETH-PERP")
print(f"ETH: {ticker.mark_price} | Funding: {ticker.funding_rate}")
# Get order book
book = client.get_orderbook("BTC-PERP", depth=10)
print(f"Spread: {book.asks[0].price - book.bids[0].price}")
# Get 1h candles
candles = client.get_candles("BTC-PERP", interval="1h", limit=24)Account
Linkaccount = client.get_account()
print(f"Equity: {account.equity}")
print(f"Available: {account.available_balance}")
for pos in client.get_positions():
print(f"{pos.symbol} {pos.side} | PnL: {pos.unrealized_pnl}")Orders
Link| Method | Returns | Description |
|---|---|---|
| place_order(...) | Order | Place market or limit order |
| get_open_orders() | list[OpenOrder] | All currently open orders |
| get_order(order_id) | Order | Fetch specific order by ID |
| cancel_order(order_id) | bool | Cancel single order |
| cancel_all_orders() | int | Cancel all open orders, returns count |
# Market buy with TP/SL
order = client.place_order(
symbol="BTC-PERP",
side="buy",
type="market",
size=100.0, # USD notional
leverage=2,
tp=72000.0,
sl=68000.0,
)
print(f"Filled: {order.order_id}")
# Limit sell
limit = client.place_order(
symbol="ETH-PERP",
side="sell",
type="limit",
size=50.0,
price=4200.0,
leverage=3,
)
# Cancel
client.cancel_order(limit.order_id)| Parameter | Type | Required | Description |
|---|---|---|---|
| symbol | str | Yes | Market symbol |
| side | str | Yes | buy or sell |
| type | str | No | market (default) or limit |
| size | float | Yes | USD notional (must be > 0) |
| price | float | Limit only | Required for limit orders |
| leverage | int | No | 1-200 (default 1) |
| time_in_force | str | No | gtc (default) or ioc |
| tp | float | No | Take-profit trigger |
| sl | float | No | Stop-loss trigger |
| reduce_only | bool | No | Only reduce existing position |
Positions
Link| Method | Returns | Description |
|---|---|---|
| close_position(symbol, size=None) | CloseResult | Full close if size omitted, partial close in coin units |
| set_tp_sl(symbol, tp=None, sl=None) | TpSlResult | Set or update take-profit and/or stop-loss |
| update_leverage(symbol, leverage, is_cross=False) | LeverageResult | Update leverage (1-200) and margin mode |
| update_margin(symbol, amount) | MarginResult | Adjust isolated margin (positive adds, negative removes) |
# Close entire position
client.close_position("BTC-PERP")
# Partial close (0.025 BTC, not USD)
client.close_position("BTC-PERP", size=0.025)
# Update TP/SL
client.set_tp_sl("BTC-PERP", tp=75000.0, sl=65000.0)
# Change leverage
client.update_leverage("ETH-PERP", leverage=10, is_cross=False)place_order uses USD notional for size. close_position uses coin units for partial closes (e.g. 0.025 BTC). Omit size to close the entire position.
Error Handling
LinkAll API exceptions inherit from LiquidError. The SDK also raises ValueError for client-side validation failures before the request is sent.
from liquidtrading import LiquidClient
from liquidtrading.errors import (
InvalidApiKeyError,
InvalidSignatureError,
InsufficientScopeError,
InsufficientBalanceError,
OrderRejectedError,
SymbolNotFoundError,
RateLimitError,
ValidationError,
)
client = LiquidClient(api_key="lq_...", api_secret="sk_...")
try:
client.place_order("BTC-PERP", "buy", size=100, leverage=2)
except InvalidApiKeyError:
print("Check your API key")
except InvalidSignatureError:
print("Check your API secret")
except InsufficientScopeError:
print("Key needs TRADE scope")
except InsufficientBalanceError:
print("Not enough balance")
except OrderRejectedError as exc:
print(f"Exchange rejected: {exc.message}")
except SymbolNotFoundError:
print("Invalid symbol — call get_markets() to list valid symbols")
except RateLimitError as exc:
print(f"Retry after {exc.retry_after}s")
except ValidationError as exc:
print(f"Bad request: {exc.message}")| Exception | When |
|---|---|
| AuthenticationError | Base class for all auth failures (401) |
| InvalidApiKeyError | API key does not exist or is disabled |
| InvalidSignatureError | HMAC signature mismatch |
| ExpiredTimestampError | Timestamp outside 5s skew window |
| ReplayedNonceError | Nonce already used |
| ForbiddenError | Base class for permission errors (403) |
| InsufficientScopeError | Key lacks required scope |
| IpForbiddenError | Request from non-whitelisted IP |
| NotFoundError | Resource not found (e.g. bad order ID) |
| SymbolNotFoundError | Trading symbol does not exist |
| ValidationError | Invalid request parameters (422) |
| InsufficientBalanceError | Not enough balance for order |
| OrderRejectedError | Exchange rejected the order |
| RateLimitError | Rate limit exceeded (has retry_after attribute) |
| ServerError | Internal server error (500) |
| ExchangeError | Upstream exchange error (502) |
| ServiceUnavailableError | Service temporarily unavailable (503) |
| GatewayTimeoutError | Upstream timeout (504) |
| TimeoutError | Request timed out (client-side) |
| ConnectionError | Network unreachable (client-side) |
Client-side validation catches: invalid side, invalid type, invalid time_in_force, leverage out of range, non-positive size, and missing limit price — before sending the request.
Models
LinkThe SDK exports typed dataclass models. Numeric values from the API (serialized as strings) are automatically converted to Python floats.
| Category | Models |
|---|---|
| Market Data | Market, Ticker, Orderbook, OrderbookLevel, Candle |
| Account | Account, Balance, CrossMargin, Position |
| Orders | Order, OpenOrder |
| Positions | CloseResult, TpSlResult, MarginResult, LeverageResult |