Portfolio Updates¶
The portfolio REST endpoints return portfolio snapshots. Use the portfolio update WebSocket when your application needs realtime portfolio changes such as position or holding updates.
WebSocket URL¶
After authentication, call GET /userinfo and read env_info.order_service_ws_url from the response. Use the returned URL for the authenticated session.
{
"env_info": {
"order_service_ws_url": "wss://api.nubra.io/oms-socket-latest/ws"
}
}
The UAT URL is returned by the same response when the session is created in UAT. Do not hardcode a WebSocket host or use the older user_ws_url value for portfolio updates.
Connect¶
Append the session token as the token query parameter when opening the WebSocket:
wss://api.nubra.io/oms-socket-latest/ws?token=<session_token>
Subscribe¶
Send this text message after the connection is opened:
subscribe <session_token> direct_portfolio NOTIFICATION_DIRECT_PORTFOLIO_UPDATE
No instrument-level subscription is required for portfolio updates.
Message Envelope¶
Portfolio update payloads are binary protobuf Any messages. The server sends an outer Any whose value contains another Any. The inner Any.type_url ends with:
PortfolioResponse
The inner Any.value is the PortfolioResponse protobuf payload.
message Any {
string type_url = 1;
bytes value = 2;
}
Payload: PortfolioResponse Proto¶
The SDK 0.5.2 protobuf schema defines the portfolio update payload as:
message PortfolioResponse {
PositionsResponse position_response = 1;
HoldingsResponse holding_response = 2;
PositionsResponseV2 position_response_v2 = 3;
}
message HoldingsResponse {
string client_code = 1;
HoldingStats holding_stats = 2;
repeated Holding holdings = 3;
int64 refresh_timestamp = 4;
}
message PositionsResponseV2 {
string client_code = 1;
PositionStatsV2 position_stats = 2;
repeated PositionStructV2 positions = 3;
int64 refresh_timestamp = 4;
}
message PositionStatsV2 {
int64 total_pnl = 1;
float total_pnl_chg = 2;
int64 today_pnl = 3;
}
position_response_v2 is the V3 position view. holding_response is the holdings view. The legacy position_response field may also be present in the protobuf envelope.
Position Fields and Enums¶
The V3 position entries use the following schema:
message PositionStructV2 {
int64 ref_id = 1;
string zanskar_name = 2;
string display_name = 3;
string derivative_type = 4;
int32 strike_price = 5;
int32 lot_size = 6;
ExchangeType exchange = 7;
string asset = 8;
string symbol = 9;
string asset_type = 10;
OrderDeliveryType delivery_type = 11;
OrderSide order_side = 12;
PositionStatus status = 13;
int32 buy_qty = 14;
int32 sell_qty = 15;
int32 net_qty = 16;
int32 ltp = 17;
int32 avg_price = 18;
int32 avg_buy_price = 19;
int32 avg_sell_price = 20;
int64 pnl = 21;
float pnl_chg = 22;
int64 pnl_today = 23;
float pnl_chg_today = 24;
string position_id = 25;
repeated PositionOrderInfo orders = 26;
int32 tick_size = 27;
}
enum PositionStatus {
POSITION_STATUS_INVALID = 0;
POSITION_STATUS_OPEN = 1;
POSITION_STATUS_CLOSED = 2;
}
Use the enum values exactly as defined by the protobuf schema. POSITION_STATUS_OPEN identifies an open position and POSITION_STATUS_CLOSED identifies a closed position.
Message Format¶
Portfolio updates are binary protobuf messages. The logical payload is a PortfolioResponse containing the current holding and position views:
PortfolioResponse
├── holding_response
│ ├── client_code
│ ├── holding_stats
│ ├── holdings[]
│ └── refresh_timestamp
└── position_response_v2
├── client_code
├── position_stats
├── positions[]
└── refresh_timestamp
Use the decoded position and holding fields to refresh the relevant portfolio view. The message is an update notification, not a JSON response.
Snapshot APIs vs Updates¶
| Need | API or stream |
|---|---|
| Fetch the current positions snapshot | GET /sentinel/portfolio/positions |
| Fetch the current holdings snapshot | GET /sentinel/portfolio/holdings |
| Fetch the current funds and margin snapshot | GET /sentinel/portfolio/user_funds_and_margin |
| Receive realtime position and holding changes | Portfolio update WebSocket |
Important Rules¶
Important Rules
- Read
order_service_ws_urlfrom/userinfofor the active session. - Append the session token as the
tokenquery parameter. - Send
direct_portfolio NOTIFICATION_DIRECT_PORTFOLIO_UPDATEas the subscription target. - Expect binary protobuf messages, not JSON messages.
- Keep the connection alive and reconnect after a close or network failure.
- Re-authenticate when the session token expires.
- Do not send browser-only headers, cookies, or SDK-only headers.