> ## Documentation Index
> Fetch the complete documentation index at: https://docs.0xmonaco.com/llms.txt
> Use this file to discover all available pages before exploring further.

# V1.0.46

# Monaco Protocol SDK v1.0.46

This release adds two things: a post-execution transaction cost analysis (TCA) report for TWAP parent orders — realized average price scored against the arrival price and a window-TWAP benchmark, with signed basis points for both — and a typed `sdk.ws.instruments()` subscription for the public `instrument` WebSocket channel that shipped server-side in v1.0.45, which until now was reachable only over the raw WebSocket protocol. Both surfaces are additive; nothing existing changes shape, so the upgrade is drop-in with no action required.

## Added

### TWAP transaction cost analysis (`getTwapOrderTca`)

`sdk.trading.getTwapOrderTca(twapOrderId)` (`GET /api/v1/orders/twap/{twapOrderId}/tca`; gRPC `OrdersService.GetTwapOrderTca`) returns a post-execution TCA report for a **terminal** TWAP parent — available once the parent is `COMPLETED` or `CANCELLED`; a non-terminal parent returns `400`. The report scores the parent's realized average price against two references over its **active window** (`windowStartAt` to `windowTerminalAt` — the actual start-to-terminal span, never the planned end): the **arrival price** (the reference series' latest minute bucket closing at or before the window start) and the **window-TWAP benchmark** (the average reference price over the window's sealed minute buckets). `benchmarkSource` names the one series both references came from — `risk_mark_1m` for marked pairs, with `ohlcv_1m_close` as the spot fallback. The two derived scores, `slippageVsArrivalBps` and `performanceVsBenchmarkBps`, are signed basis points at 4 decimal places, and **positive always means the execution beat the reference** — a BUY filled below it, a SELL above it.

Two things to read carefully:

* `realizedAvgPrice` is `executedNotional / executedQuantity`, **gross of fees** — the price the fills traded at, deliberately excluding taker fees and maker rebates so it compares cleanly against price benchmarks.
* The six analytics fields (`realizedAvgPrice`, `arrivalPrice`, `benchmarkTwapPrice`, `benchmarkSource`, and both bps fields) are **optional and omitted from the response body — the key is absent, not sent as `null` — whenever that field cannot be computed honestly**, and each has its own condition. `realizedAvgPrice` comes straight from the fills and is absent only when nothing executed. The three reference fields are absent when no reference series qualified: an arrival bucket staler than 5 minutes is rejected, the benchmark requires at least 90% coverage of the window's sealed minute buckets, and a window too short to seal a single bucket is not scoreable. Each bps field is absent when either of its inputs is — so a parent that filled but had no qualifying reference series still reports `realizedAvgPrice`, just no scores. The structural fields (`twapOrderId`, `tradingPairId`, `state`, `side`, `totalQuantity`, `executedQuantity`, `shortfallQuantity`, and the window bounds) are always present, so a report is self-describing and closes the fill-rate arithmetic without a second lookup.

Owner scoping matches the rest of the TWAP surface: another user's parent returns a `404` byte-identical to an unknown ID, and delegated-agent sessions are rejected. `@0xmonaco/types` ships the `GetTwapOrderTcaResponse` interface. See [Trading](/sdk/typescript/trades#twap-orders) and [TWAP Orders](/trading-mechanics/twap-orders).

### Typed `sdk.ws.instruments()` WebSocket subscription

`sdk.ws.instruments(handler, tradingPairId?)` is a typed subscription for the public `instrument` channel: market lifecycle and configuration changes — listings, delistings, and edits to tick size, quantity step, order-size bounds, or category. The perp-only leverage/margin-rate bounds are carried in every frame's full config but are payload only: an edit to those margin parameters alone does not emit a frame. Omit `tradingPairId` for all markets or pass one to filter. Handlers receive the typed `InstrumentEvent` from `@0xmonaco/types`; every frame carries the market's **full current configuration** as a terminal-state snapshot — never an additive delta — with `changedFields` naming what the mutation touched, and the subscribe-time snapshot of the active-pair list is fanned out to the handler as one event per market before the live diffs. A subscriber joining a channel the client already holds is replayed the current baseline from a local cache (the server snapshots only genuinely new wire subscriptions), so every subscriber gets the baseline regardless of ordering. The channel itself shipped server-side in v1.0.45 and was previously reachable only over a raw WebSocket connection with hand-mapped snake\_case keys. See [WebSockets](/sdk/typescript/websockets#instruments-channel).

## Upgrade

```bash theme={null}
npm install @0xmonaco/core@1.0.46 @0xmonaco/types@1.0.46 @0xmonaco/react@1.0.46 @0xmonaco/contracts@1.0.46
# or bun
bun add @0xmonaco/core@1.0.46 @0xmonaco/types@1.0.46 @0xmonaco/react@1.0.46 @0xmonaco/contracts@1.0.46
```

The MCP server ships at `1.0.46` too; it runs via `npx -y @0xmonaco/mcp-server`, so restarting your assistant picks up the new version. Every SDK bump is a patch release. Both new surfaces are additive — a new TCA endpoint and a typed helper for an existing channel — so existing request and wire shapes are unchanged and the upgrade is drop-in; adopt them only if you want them. When you do read a TCA report, handle the absent-key case for the six analytics fields — a report with only the structural fields is a valid answer, not an error.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.