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. Theconditional_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
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) × quantityas 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.
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
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.
