Portfolio Stream
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
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.
Recommended Usage Pattern
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:
- Fetch current state via REST — call the relevant REST endpoints to get your current orders and positions before subscribing:
- Retrieve Orders — returns all active orders for an account
- Retrieve Positions / PnL — returns current positions and P&L
- 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.
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:
| Value | Description |
|---|---|
"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:
| Field | Type | Description |
|---|---|---|
ts | number | Unix timestamp in milliseconds |
accountId | string | The account the update belongs to |
action | string | Always "update" for data messages |
subscription | string | Either "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
| Field | Type | Description |
|---|---|---|
accountId | string | Account the order belongs to |
canceledQuantity | number | Quantity canceled |
clientOrderId | string | Client-assigned order identifier |
executed | number | Total quantity executed so far |
lastPrice | number | Price of the most recent fill |
lastQuantity | number | Quantity of the most recent fill |
lastUpdated | string | ISO 8601 timestamp of the last update |
leavesQuantity | number | Remaining open quantity |
limitPrice | number | Limit price of the order |
maxDisplayQuantity | number | Maximum displayed quantity (reserve/iceberg orders) |
openClose | string | "Open" or "Close" |
orderQuantity | number | Total ordered quantity |
orderStatus | string | Current order status (e.g. "Filled", "Canceled", "Accepted") |
orderType | string | Order type (e.g. "Limit", "Market") |
pegDifference | number | Peg offset value |
pegOffsetType | string | Peg offset type (e.g. "Price") |
priceAvg | number | Volume-weighted average fill price |
priceStop | number | Stop price (if applicable) |
route | string | Routing destination (e.g. "SIM") |
securityType | string | Security type (e.g. "Stock") |
side | string | "Buy" or "Sell" |
startTime | string | ISO 8601 timestamp when the order was placed |
strikePrice | number | Strike price for options (0.0 for equities) |
symbol | string | Ticker symbol |
text | string | Free-text order notes or routing tag |
timeInForce | string | Time in force (e.g. "Day", "GTC") |
tradedSymbol | string | Symbol 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
| Field | Type | Description |
|---|---|---|
id | string | Unique position identifier |
accountId | string | Account the position belongs to |
createdDate | string | ISO 8601 timestamp when the position was first opened |
dayOvernight | string | "Day" or "Overnight" |
priceAvg | number | Average cost basis of the position |
priceClose | number | Previous close price (0.0 if intraday position) |
priceOpen | number | Price at which the position was opened |
priceStrike | number | Strike price for options (0.0 for equities) |
putCall | string | "Put", "Call", or "None" for equities |
securityType | string | Security type (e.g. "Stock") |
shares | number | Current position size (negative for short positions) |
side | string | "Long" or "Short" |
symbol | string | Ticker symbol |
updatedDate | string | ISO 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.