Skip to content

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 executing
  • StrategyStatus.Stopped - Strategy has been stopped
  • StrategyStatus.Error - Strategy encountered an error
  • StrategyStatus.SquaredOff - Strategy positions are squared off/completed

Position Types

  • PositionType.Buy - Buy/Long position
  • PositionType.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)