Skip to main content

Monaco Protocol SDK v0.8.21

This release adds a new endpoint for fetching a single conditional (TP/SL) order by ID, ships a substantial update to realized-PnL accounting semantics, and fixes three correctness bugs: taker fee fields on filled orders reporting the wrong rate, cross-margin simulation failing before the first cross order, and ambiguous parent margin-account orders silently routing through the wrong path. The conditional_orders WebSocket channel now also gates on authentication at subscribe time.

Added

Get a conditional order by ID

A new endpoint fetches a single TP/SL conditional order directly by its UUID:
  • REST — GET /api/v1/orders/conditional/{conditionalOrderId}
  • TypeScript SDK — sdk.trading.getConditionalOrder(conditionalOrderId)
  • React SDK — useTrade().getConditionalOrder(conditionalOrderId)
  • gRPC — OrdersService.GetConditionalOrder
The returned ConditionalOrder is the same type produced by listConditionalOrders. The takeProfitOrderId and stopLossOrderId fields on a createOrder response are conditional order UUIDs queryable via this method.

Changed

Realized PnL accounting semantics

getPortfolioStats (pnl) and getPortfolioChart (the "pnl" metric) now apply updated realized-PnL semantics as part of the unrealized-PnL rollout:
  • Spot withdrawals are fair-value disposals — withdrawing a spot asset books (last trade price − average cost) × quantity as realized PnL, rather than treating the outflow as cash-neutral.
  • Deposits and withdrawals use last trade price — cost-basis entries and disposal prices are now pinned to the last observed trade price for the pair in event order, instead of the covering 1-minute candle close.
  • Pre-first-trade transfers are PnL-neutral — any deposit or withdrawal that occurs before the first trade on a pair does not generate realized PnL.
  • Short-entry fees reduce short profits — fees paid on short position entry now reduce the profit of that short, rather than inflating it.
Response shape is unchanged; the pnl values will reflect the corrected accounting going forward.

Fixed

Taker order fee fields reported flat rate instead of tier rate

A filled order’s fee response fields — monacoTakerFee, totalTakerFees, and takerTotalPayment — previously reported the trading pair’s flat fee column rather than the tier-resolved rate that was actually debited at settlement. These fields now match the balance movement. Clients on a fee tier whose rate differs from the flat column will see corrected values; no request or response fields changed.

Cross-margin simulation failed before the first cross order

POST /api/v1/margin/risk-buckets/simulate-order-risk (sdk.marginAccounts.simulateRiskBucketOrderRisk) with marginMode: "CROSS" previously returned an error when the user had no active cross risk bucket. The endpoint now uses the same deterministic cross risk bucket ID and first-use auto-collateral estimate as live order placement, so you can safely preflight a cross order before the bucket exists. No request or response fields changed.

Ambiguous parent margin-account orders now fail fast

POST /api/v1/orders and POST /api/v1/orders/batch-create for a parent margin-account order that omits marginMode and does not provide an isolated risk-bucket selector previously silently routed through the isolated risk-bucket path. These requests now return a client error. Pass marginMode: "CROSS" or marginMode: "ISOLATED" for all parent margin-account margin orders. No request or response fields changed.

Security

conditional_orders WebSocket channel now requires authentication at subscribe time

The conditional_orders WebSocket channel (sdk.ws.conditionalOrders) now requires authentication when subscribing, matching the behavior of all other user-scoped channels (orders, balances, positions, movements, liquidations). Event delivery was already owner-scoped — this closes the subscribe-gate gap. No subscription API changes; unauthenticated subscribe attempts are now rejected.

Upgrade

The only breaking-adjacent change in this release is the conditional_orders subscribe gate: unauthenticated subscribers will now receive a rejection instead of connecting successfully. Ensure your app authenticates before calling sdk.ws.conditionalOrders(...). All other changes are additive or behavioral corrections with no shape changes.