How to Configure WebSocket Streaming for Real-Time Market Data in Fincept Terminal

Fincept Terminal streams live market data through a Qt-based WebSocketClient wrapper that handles TLS, automatic reconnection, and heartbeat ping/pong, while broker-specific implementations like ZerodhaWebSocket and AngelOneWebSocket manage authentication, subscription batching, and binary payload parsing via Qt signals.

The Fincept-Corporation/FinceptTerminal repository provides a modular C++ architecture for connecting to Indian brokerage WebSocket feeds. To configure WebSocket streaming for real-time market data, you instantiate broker-specific clients that wrap the core transport layer, manage instrument tokens, and emit typed tick structures through Qt's signal-slot mechanism.

Core Architecture

Fincept Terminal separates concerns into four distinct layers to ensure reliable market data delivery:

Transport Layer (WebSocketClient)

At the foundation lies WebSocketClient, defined in fincept-qt/src/network/websocket/WebSocketClient.h and implemented in WebSocketClient.cpp. This class wraps QWebSocket and provides:

  • Automatic reconnection with exponential backoff using reconnect_timer_ and reconnect_attempts_
  • TLS encryption and certificate handling for secure broker connections
  • Ping/pong heartbeat management to keep idle connections alive
  • Error propagation through error_occurred signals

The client caps reconnection attempts at MAX_RECONNECT_ATTEMPTS (10) and automatically triggers resubscribe_all() upon successful reconnection.

Broker Implementations

Each supported broker implements a specialized client that inherits from QObject and aggregates a WebSocketClient:

Both implementations expose a symmetric public API (open(), close(), subscribe(), unsubscribe(), set_subscriptions()) and emit tick_received signals containing parsed structures (ZerodhaTick, AoTick).

Instrument Enrichment

The InstrumentService singleton (fincept-qt/src/trading/instruments/InstrumentService.h) maps numeric tokens to human-readable symbols, exchanges, and instrument metadata before ticks reach the UI layer.

Setting Up Zerodha KiteTicker

To stream from Zerodha, instantiate ZerodhaWebSocket with your API credentials and connect to the tick signals:

// MyWidget.cpp
#include "trading/websocket/ZerodhaWebSocket.h"
#include <QVector>

MyWidget::MyWidget(QWidget *parent) : QWidget(parent)
{
    // Initialize with credentials
    auto *ws = new fincept::trading::ZerodhaWebSocket(
        QStringLiteral("YOUR_API_KEY"),
        QStringLiteral("YOUR_ACCESS_TOKEN"),
        this);

    // Connect tick handler
    connect(ws, &fincept::trading::ZerodhaWebSocket::tick_received,
            this, &MyWidget::onZerodhaTick);

    // Monitor connection state
    connect(ws, &fincept::trading::ZerodhaWebSocket::connected,
            this, [](){ qInfo() << "Zerodha WS connected"; });
    connect(ws, &fincept::trading::ZerodhaWebSocket::disconnected,
            this, [](){ qInfo() << "Zerodha WS disconnected"; });

    ws->open();                                 // Establish WebSocket
    ws->subscribe({256265, 260105});           // Subscribe to tokens
}

Key implementation details from ZerodhaWebSocket.cpp:

  • Tokens are batched in groups of 200 (kBatchSize) to respect API limits
  • The client automatically requests full-depth mode via send_mode messages
  • Binary payloads are parsed into ZerodhaTick structures containing LTP, volume, and depth data

Configuring Angel One SmartStream

Angel One requires a feed token in addition to API credentials and supports multiple subscription modes:

#include "trading/websocket/AngelOneWebSocket.h"

void MyAlgo::startStreaming()
{
    auto *ws = new fincept::trading::AngelOneWebSocket(
        QStringLiteral("YOUR_API_KEY"),
        QStringLiteral("YOUR_CLIENT_CODE"),
        QStringLiteral("YOUR_FEED_TOKEN"),
        this);

    connect(ws, &fincept::trading::AngelOneWebSocket::tick_received,
            this, &MyAlgo::processAoTick);

    ws->open();   // Opens socket and sends authentication frame
    
    // Subscribe with specific mode
    QVector<fincept::trading::AngelOneWebSocket::Subscription> subs;
    subs.append({QStringLiteral("2885"),
                 fincept::trading::AoExchangeType::NSE_CM});
    ws->subscribe(subs, fincept::trading::AoSubMode::FullDepth);
}

The AngelOneWebSocket class deduplicates subscriptions using subscribed_keys_ and parses little-endian binary packets according to the SmartStream protocol specification.

Handling Reconnections and Errors

Both broker clients inherit robust reconnection logic from WebSocketClient. When the socket encounters an error:

  1. The reconnect_timer_ schedules a new connection attempt
  2. Exponential backoff delays prevent server hammering
  3. Upon successful reconnection, on_connected() automatically calls resubscribe_all() to restore previous subscriptions

To monitor connection health in your application:

connect(ws, &fincept::trading::ZerodhaWebSocket::error_occurred,
        this, [](const QString &error){ 
            qWarning() << "WebSocket error:" << error; 
        });

Managing Instrument Subscriptions

Subscription Limits:

  • Zerodha: Maximum 200 tokens per subscription message (batched automatically)
  • Angel One: No explicit limit, but deduplication occurs via subscribed_keys_

Dynamic Subscription Management: Update subscriptions without closing the connection:

// Clear existing and set new batch
ws->clear_subscriptions();
ws->set_subscriptions({256265, 260105, 26009});

Token Enrichment: Raw ticks contain numeric tokens. The InstrumentService enriches these with symbol names and exchange information before the tick_received signal emits, allowing UI components to display human-readable labels without additional lookups.

Summary

  • Use WebSocketClient as the transport foundation located in fincept-qt/src/network/websocket/WebSocketClient.h for automatic reconnection and heartbeat management
  • Instantiate broker-specific classes (ZerodhaWebSocket or AngelOneWebSocket) to handle protocol-specific authentication and binary parsing
  • Connect to tick_received signals to receive enriched market data structures in your UI or algorithmic components
  • Leverage automatic batching for Zerodha subscriptions (200 tokens per batch) and deduplication for Angel One
  • Implement connected and disconnected handlers to monitor the 10-attempt exponential backoff reconnection strategy

Frequently Asked Questions

What brokers does Fincept Terminal support for WebSocket streaming?

The codebase currently implements WebSocket streaming for Zerodha (KiteTicker) and Angel One (SmartStream) through ZerodhaWebSocket and AngelOneWebSocket respectively. Both classes are located in the fincept-qt/src/trading/websocket/ directory and expose identical public APIs for subscription management.

How does the automatic reconnection mechanism work?

The WebSocketClient class maintains a QTimer (reconnect_timer_) and attempt counter (reconnect_attempts_) that implements exponential backoff when connections drop. It attempts reconnection up to MAX_RECONNECT_ATTEMPTS (10 times) and automatically triggers resubscribe_all() upon successful reconnection to restore previous instrument subscriptions without manual intervention.

What is the maximum number of instruments I can subscribe to simultaneously?

For Zerodha, the implementation automatically batches subscriptions into groups of 200 tokens (kBatchSize) due to API limitations. Angel One has no hardcoded limit in the client, though the subscribed_keys_ set prevents duplicate entries. You can call subscribe() multiple times to add instruments incrementally or use set_subscriptions() to replace the entire watchlist.

How do I handle authentication when configuring the WebSocket?

Authentication occurs during construction or initial connection. For Zerodha, pass your API_KEY and ACCESS_TOKEN to the ZerodhaWebSocket constructor. For Angel One, provide API_KEY, CLIENT_CODE, and FEED_TOKEN. The open() method then establishes the socket and transmits the authentication frame automatically before allowing subscription requests.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →