Skip to main content

Portfolio Stream

Beta

The WebSocket API is currently in beta. Features and endpoints are subject to change.

Overview

The Portfolio Stream provides real-time updates for active orders and position changes driven by order activity (fills, cancellations, etc.) for one or more accounts.

Endpoint: wss://webapi.tradezero.com/stream/portfolio

Price-driven position updates

Position updates caused by price changes (mark-to-market) are delivered by the PnL Stream, not this endpoint. The Portfolio Stream only reflects position changes resulting from order activity.

The Portfolio Stream delivers incremental changes — it does not send a full snapshot of your current orders or positions when you first connect. The recommended pattern is:

  1. Fetch current state via REST — call the relevant REST endpoints to get your current orders and positions before subscribing:
  2. Subscribe to the Portfolio Stream — then connect and subscribe to receive real-time changes as they occur.

This approach avoids polling the REST endpoints repeatedly and ensures your local state stays in sync with the minimum number of requests.

tip

Establish your WebSocket connection and start buffering incoming messages before you fetch the REST snapshot. This prevents any updates that arrive between the REST call completing and the WebSocket connecting from being missed.

Usage

Step 1: Connect and Authenticate

Connect to the Portfolio endpoint and authenticate as described in the Introduction page.

Upon successful authentication you will receive a meta confirmation message:

{
"ts": 1771861718189,
"accountId": "YOUR_ACCOUNT",
"action": "meta",
"requestConfirmed": true
}

Step 2: Subscribe to an Account

After authentication, subscribe to portfolio updates by sending an account ID and the list of subscriptions you want:

{
"accountId": "YOUR_ACCOUNT_ID",
"subscriptions": ["Order", "Position"]
}

You can subscribe to either or both streams:

ValueDescription
"Order"Real-time updates to active orders (accepted, filled, canceled, etc.)
"Position"Real-time changes to positions driven by order activity

Real-Time Updates

All update messages share the same top-level envelope:

FieldTypeDescription
tsnumberUnix timestamp in milliseconds
accountIdstringThe account the update belongs to
actionstringAlways "update" for data messages
subscriptionstringEither "Order" or "Position"

1. Order Updates

Received whenever an order changes state (e.g. accepted, partially filled, filled, canceled).

{
"ts": 1771864795549,
"accountId": "JARLETUAT",
"action": "update",
"subscription": "Order",
"order": {
"accountId": "JARLETUAT",
"canceledQuantity": 0.0,
"clientOrderId": "0223043705907.34",
"executed": 1.0,
"lastPrice": 398.41,
"lastQuantity": 1.0,
"lastUpdated": "2026-02-23T16:39:55.2586072+00:00",
"leavesQuantity": 0.0,
"limitPrice": 398.41,
"maxDisplayQuantity": 0.0,
"openClose": "Open",
"orderQuantity": 1.0,
"orderStatus": "Filled",
"orderType": "Limit",
"pegDifference": 0.0,
"pegOffsetType": "Price",
"priceAvg": 398.41,
"priceStop": 0.0,
"route": "SIM",
"securityType": "Stock",
"side": "Buy",
"startTime": "2026-02-23T16:37:05.9092992+00:00",
"strikePrice": 0.0,
"symbol": "TSLA",
"text": "CTDL_SIM",
"timeInForce": "Day",
"tradedSymbol": "TSLA"
}
}

Order Field Definitions

FieldTypeDescription
accountIdstringAccount the order belongs to
canceledQuantitynumberQuantity canceled
clientOrderIdstringClient-assigned order identifier
executednumberTotal quantity executed so far
lastPricenumberPrice of the most recent fill
lastQuantitynumberQuantity of the most recent fill
lastUpdatedstringISO 8601 timestamp of the last update
leavesQuantitynumberRemaining open quantity
limitPricenumberLimit price of the order
maxDisplayQuantitynumberMaximum displayed quantity (reserve/iceberg orders)
openClosestring"Open" or "Close"
orderQuantitynumberTotal ordered quantity
orderStatusstringCurrent order status (e.g. "Filled", "Canceled", "Accepted")
orderTypestringOrder type (e.g. "Limit", "Market")
pegDifferencenumberPeg offset value
pegOffsetTypestringPeg offset type (e.g. "Price")
priceAvgnumberVolume-weighted average fill price
priceStopnumberStop price (if applicable)
routestringRouting destination (e.g. "SIM")
securityTypestringSecurity type (e.g. "Stock")
sidestring"Buy" or "Sell"
startTimestringISO 8601 timestamp when the order was placed
strikePricenumberStrike price for options (0.0 for equities)
symbolstringTicker symbol
textstringFree-text order notes or routing tag
timeInForcestringTime in force (e.g. "Day", "GTC")
tradedSymbolstringSymbol actually traded (may differ for options)

2. Position Updates

Received whenever a position is created or modified as a result of an order fill.

{
"ts": 1771864795549,
"accountId": "JARLETUAT",
"action": "update",
"subscription": "Position",
"position": {
"id": "7260223163955259000",
"accountId": "JARLETUAT",
"createdDate": "2026-02-23T16:39:55.2588684+00:00",
"dayOvernight": "Day",
"priceAvg": 398.41,
"priceClose": 0.0,
"priceOpen": 398.41,
"priceStrike": 0.0,
"putCall": "None",
"securityType": "Stock",
"shares": 1.0,
"side": "Long",
"symbol": "TSLA",
"updatedDate": "2026-02-23T16:39:55.2588696+00:00"
}
}

Position Field Definitions

FieldTypeDescription
idstringUnique position identifier
accountIdstringAccount the position belongs to
createdDatestringISO 8601 timestamp when the position was first opened
dayOvernightstring"Day" or "Overnight"
priceAvgnumberAverage cost basis of the position
priceClosenumberPrevious close price (0.0 if intraday position)
priceOpennumberPrice at which the position was opened
priceStrikenumberStrike price for options (0.0 for equities)
putCallstring"Put", "Call", or "None" for equities
securityTypestringSecurity type (e.g. "Stock")
sharesnumberCurrent position size (negative for short positions)
sidestring"Long" or "Short"
symbolstringTicker symbol
updatedDatestringISO 8601 timestamp of the most recent update

Multiple Account Subscriptions

You can subscribe to multiple accounts by sending additional subscription messages:

{
"accountId": "ANOTHER_ACCOUNT_ID",
"subscriptions": ["Order", "Position"]
}

Each account subscription is independent and will deliver its own stream of updates.