Execution Updates WebSocket API
The Execution Updates WebSocket API provides real-time updates on strategy execution, trade status, and position changes. This endpoint delivers live streaming data for active trading strategies and their associated executions.
Endpoint Information
WebSocket URL
wss://api.algotest.in/ws/execution-updates
Protocol
- Type: WebSocket (RFC 6455)
- Format: JSON messages
- Encoding: UTF-8
Authentication
Authentication is required using JWT tokens via Cookie headers.
Required Headers
Cookie: access_token_cookie={{your_jwt_token}}
Parameters:
- {{your_jwt_token}}: Your valid JWT access token obtained from the Authentication API
Authentication Example
import websocket
# Create WebSocket connection with JWT authentication
ws = websocket.WebSocketApp(
"wss://api.algotest.in/ws/execution-updates",
header=["Cookie: access_token_cookie=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."],
on_open=lambda ws: print("Connected to execution updates"),
on_message=lambda ws, message: print(f"Received: {message}"),
on_error=lambda ws, error: print(f"Error: {error}"),
on_close=lambda ws, *args: print("Connection closed")
)
# Start the connection
ws.run_forever()
Connection Lifecycle
1. Connection Establishment
Upon successful authentication, the WebSocket connection will be established and you'll start receiving execution update messages.
2. Message Flow
- Inbound: Real-time execution updates (JSON objects)
- Outbound: No client-to-server messages required
Message Format
Messages are JSON arrays of execution objects. Each element in the array has the following structure:
Execution Object Schema
| Field | Type | Description |
|---|---|---|
_id |
string |
Unique execution identifier |
name |
string |
Strategy name |
creation_ts |
string |
Strategy creation timestamp |
last_activation_ts |
string |
Last activation timestamp |
check_after_ts |
string |
Next check timestamp |
active_on_server |
boolean |
Server activation status |
broker |
string |
Broker identifier (ObjectId string) |
broker_type |
string |
Broker type enumeration |
config |
object |
Execution configuration object |
entry_time |
string |
Entry timestamp |
exit_time |
string |
Exit timestamp |
external_start |
string|null |
External signal source |
is_shared |
boolean |
Whether execution is shared |
free_execution |
boolean |
Whether execution is free |
is_ra_algo |
boolean |
Whether it's a risk-adjusted algorithm |
legs |
array |
Array of execution legs |
portfolio |
object|null |
Portfolio information |
reentry_time_restriction |
string|null |
Reentry time restrictions |
status |
string |
Current strategy status |
strategy_id |
string |
Strategy identifier (ObjectId string) |
ticker |
string |
Trading symbol/ticker |
skip_initial_candles |
integer |
Number of initial candles to skip |
notifications |
array |
Array of notification messages (optional) |
trades |
array |
Array of trade objects (optional) |
ongoing_trade |
string |
Current active trade ID |
Sample Message (array)
[
{
"_id": "6847ae7a98098cafd7e4153e",
"name": "multi Chartink Testing STG_Chartink 1",
"creation_ts": "2025-06-10 09:33:06.741000",
"last_activation_ts": "2025-07-08 08:45:00.172000",
"check_after_ts": "2025-07-08 09:15:05",
"active_on_server": true,
"broker": "6150514bf6533f4eb5d7c6b8",
"broker_type": "Broker.Dummy",
"config": {
"ExecutionConfig": {
"LikeBacktester": true,
"MarginAutoSquareOff": true,
"LotMultiplier": 1,
"LegsConfig": {
"og_leg_1": {
"Product": "ProductType.NRML",
"Reference": "PriceReferenceType.Trade",
"EntryOrder": {
"Config": {
"Type": "OrderType.Market"
},
"Delay": 0
},
"ExitOrder": {
"Config": {
"Type": "OrderType.Market"
},
"Delay": 0
}
}
}
},
"Ticker": "NSE_SBIN",
"TakeUnderlyingFromCash": true,
"TrailSLtoBreakeven": null,
"SquareOffAllLegs": false,
"LegConfigs": {
"og_leg_1": {
"PositionType": "PositionType.Buy",
"ContractType": {
"StrikeParameter": 0,
"EntryKind": null,
"Option": "XX",
"Expiry": null
},
"Lots": 10,
"LegMomentum": null,
"LegTarget": {
"Type": "LegTgtSLType.Percentage",
"Value": 5.0,
"Reentry": null
},
"LegStopLoss": {
"Type": "LegTgtSLType.Percentage",
"Value": 2.0,
"Reentry": null,
"Trail": null
}
}
},
"IdleLegConfigs": {},
"OverallSL": null,
"OverallTgt": null,
"LockAndTrail": null,
"OverallTrailSL": null,
"OverallMomentum": null
},
"entry_time": "2025-06-10 09:33:05.978000",
"exit_time": "2025-08-09 09:35:00",
"external_start": "ChartinkMultiStock",
"is_shared": false,
"free_execution": false,
"is_ra_algo": false,
"legs": [
{
"id": "6847ae7a98098cafd7e4153e_leg_1",
"status": 1.0,
"token": "NSE_3045",
"symbol": "SBIN",
"quantity": 10,
"lot_size": 1,
"position": "PositionType.Buy",
"option": "XX",
"expiry_date": null,
"strike": 0.0,
"last_saw_price": 806.75,
"entry_trade": {
"trigger_timestamp": "2025-06-10 09:33:06.890000",
"trigger_price": 820.35,
"underlying_trigger_price": 820.35,
"price": 820.35,
"quantity": 10,
"underlying_at_trade": 820.35,
"traded_timestamp": "2025-06-10 09:33:07.103000",
"exchange_timestamp": "2025-06-10 09:33:07.103381"
},
"exit_trade": null,
"is_reentered_leg": false,
"transactions": {},
"current_transaction_id": null,
"display_sl_value": 803.943,
"display_target_value": 861.3675000000001
}
],
"portfolio": {
"portfolio": "6847aa3ab3cc265c0b41f29d",
"group_id": "6847aa3ab3cc265c0b41f29d",
"group_name": "Chartink 1"
},
"reentry_time_restriction": null,
"status": "StrategyStatus.Live",
"strategy_id": "6847aafef96bcbfb323b0863",
"ticker": "NSE_SBIN",
"skip_initial_candles": 0,
"notifications": [],
"trades": [
{
"id": "6847ae7a98098cafd7e4153e_trade_1",
"ongoing_legs": [
"6847ae7a98098cafd7e4153e_leg_1"
],
"initial_absolute_premium": null,
"reenter_legs": [],
"completed_legs": [],
"lock_activated": false,
"trail_sl": null,
"exit_reason": null,
"display_sl_value": null,
"display_target_value": null
}
],
"ongoing_trade": "6847ae7a98098cafd7e4153e_trade_1"
}
]
Data Types and Enumerations
Strategy Status Values
StrategyStatus.Live- Strategy is live and actively executingStrategyStatus.Stopped- Strategy has been stoppedStrategyStatus.Error- Strategy encountered an errorStrategyStatus.SquaredOff- Strategy positions are squared off/completed
Position Types
PositionType.Buy- Buy/Long positionPositionType.Sell- Sell/Short position
Code Examples
Basic WebSocket Connection
import websocket
import json
import logging
# Configure logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
def on_message(ws, message):
"""Handle incoming execution update messages (array of objects)"""
try:
updates = json.loads(message) # Expecting a JSON array
if isinstance(updates, dict):
updates = [updates]
for execution_update in updates:
logger.info(f"Received execution update: {execution_update.get('_id')}")
strategy_name = execution_update.get('name')
status = execution_update.get('status')
broker = execution_update.get('broker')
print(f"Strategy: {strategy_name}")
print(f"Status: {status}")
print(f"Broker: {broker}")
# Handle different strategy statuses
if status == 'StrategyStatus.Live':
print(f"β
Strategy {strategy_name} is actively running")
handle_running_strategy(execution_update)
elif status == 'StrategyStatus.SquaredOff':
print(f"π― Strategy {strategy_name} squared off")
handle_completed_strategy(execution_update)
elif status == 'StrategyStatus.Error':
print(f"β Strategy {strategy_name} encountered an error")
handle_error_strategy(execution_update)
elif status == 'StrategyStatus.Stopped':
print(f"βΈοΈ Strategy {strategy_name} has been stopped")
handle_stopped_strategy(execution_update)
except json.JSONDecodeError as e:
logger.error(f"Failed to parse message: {e}")
except Exception as e:
logger.error(f"Error processing message: {e}")
def on_error(ws, error):
"""Handle WebSocket errors"""
logger.error(f"WebSocket error: {error}")
def on_close(ws, close_status_code, close_msg):
"""Handle WebSocket connection close"""
logger.info(f"WebSocket closed: {close_status_code} - {close_msg}")
def on_open(ws):
"""Handle WebSocket connection open"""
logger.info("Connected to execution updates WebSocket")
print("π Successfully connected to AlgoTest execution updates")
# Create WebSocket connection
def connect_to_execution_updates(jwt_token):
"""Connect to the execution updates WebSocket"""
ws = websocket.WebSocketApp(
"wss://api.algotest.in/ws/execution-updates",
header=[f"Cookie: access_token_cookie={jwt_token}"],
on_open=on_open,
on_message=on_message,
on_error=on_error,
on_close=on_close
)
# Start the WebSocket connection
ws.run_forever()
return ws
# Helper functions for handling different strategy states
def handle_running_strategy(execution_update):
"""Process running strategy updates"""
legs = execution_update.get('legs', [])
for leg in legs:
if leg.get('entry_trade'):
entry_price = leg['entry_trade'].get('price')
current_price = leg.get('last_saw_price')
print(f" Leg {leg['id']}: Entry @ {entry_price}, Current @ {current_price}")
def handle_completed_strategy(execution_update):
"""Process completed strategy updates"""
trades = execution_update.get('trades', [])
for trade in trades:
completed_legs = trade.get('completed_legs', [])
print(f" Trade {trade['id']}: {len(completed_legs)} legs completed")
def handle_error_strategy(execution_update):
"""Process error strategy updates"""
notifications = execution_update.get('notifications', [])
for notification in notifications:
print(f" Error: {notification}")
def handle_stopped_strategy(execution_update):
"""Process stopped strategy updates"""
exit_time = execution_update.get('exit_time')
if exit_time:
print(f" Stopped at: {exit_time}")
else:
print(f" Strategy manually stopped")
# Usage example
if __name__ == "__main__":
JWT_TOKEN = "YOUR_JWT_TOKEN_HERE" # Replace with your actual token
connect_to_execution_updates(JWT_TOKEN)