-
Notifications
You must be signed in to change notification settings - Fork 1
WebSocket Integration
- Introduction
- WebSocket Connection Lifecycle Management
- Authentication Protocols
- Message Parsing Strategies
- Event Handler Implementation
- Data Translation to TradingView Format
- Reconnection Logic with Exponential Backoff
- Connection State Management for Multiple Subscribers
- Security Considerations
- Debugging and Monitoring Techniques
PyTradingView provides a comprehensive framework for integrating real-time data streaming through WebSocket connections to external data sources. The system is designed to bridge TradingView's frontend with backend data providers, enabling real-time market data visualization. The architecture leverages asynchronous Python with FastAPI and WebSocket support to handle bidirectional communication between the frontend and data sources. This document details the implementation of WebSocket integration for real-time data streaming, focusing on connection management, data translation, and robust error handling to ensure reliable data delivery to TradingView charts and widgets.
The WebSocket connection lifecycle in PyTradingView is managed through the TVDatafeed class, which serves as the foundation for all data integration. The lifecycle begins with the onReady callback, which initializes the datafeed configuration and establishes the connection framework. The TVDatafeed class maintains subscriber registries for both bar data and quote data, tracking active connections through listener GUIDs. When a client subscribes to real-time data via subscribeBars or subscribeQuotes, the system registers the subscription in the appropriate dictionary (_subscribers or _quote_subscribers) with references to the symbol information, resolution, and callback functions. The unsubscribe methods (unsubscribeBars and unsubscribeQuotes) handle connection termination by removing entries from these registries. The BADatafeed implementation demonstrates how to extend this base functionality by overriding the subscribeBars method to initiate actual WebSocket connections to external data sources like Binance.
flowchart TD
A[Client Request] --> B{Subscription Type}
B --> |Bars| C[subscribeBars]
B --> |Quotes| D[subscribeQuotes]
C --> E[Register in _subscribers]
D --> F[Register in _quote_subscribers]
E --> G[Initiate WebSocket Connection]
F --> G
G --> H[Start Message Processing]
H --> I[Data Streaming]
J[Unsubscribe Request] --> K{Subscription Type}
K --> |Bars| L[unsubscribeBars]
K --> |Quotes| M[unsubscribeQuotes]
L --> N[Remove from _subscribers]
M --> O[Remove from _quote_subscribers]
N --> P[Close WebSocket Connection]
O --> P
**Diagram sources **
PyTradingView's architecture supports authentication protocols through the configuration system and secure connection handling. While the base implementation does not include specific authentication mechanisms, it provides the framework for implementing secure connections. The TVDatafeedConfiguration class can be extended to include authentication parameters such as API keys, tokens, or other credentials required by external data sources. The BADatafeed example shows how to configure data sources with exchange information, which can be extended to include authentication details. For WebSocket connections requiring authentication, developers should implement the authentication sequence in the subscribeBars method before establishing the data streaming connection. This typically involves sending an authentication message with credentials immediately after the WebSocket connection is established, waiting for an authentication confirmation from the server before proceeding with subscription requests.
Message parsing in PyTradingView is handled through callback functions that process incoming WebSocket messages and translate them into TradingView-compatible data structures. The system supports both JSON and binary message formats through Python's standard libraries and third-party packages. For JSON messages, the built-in json module is used to parse incoming data, while binary messages can be processed using struct or other binary parsing libraries. The TVSubscribeBarsCallback and TVQuotesCallback types define the function signatures for handling parsed messages. When a message is received, it is first validated for structure and content, then parsed into the appropriate data model (TVBar for price bars or TVDatafeedQuoteValues for quotes). The parsed data is then passed to the registered callback function, which updates the TradingView chart or widget. Error handling is implemented through TVDatafeedErrorCallback to manage parsing failures and malformed messages.
flowchart TD
A[Incoming WebSocket Message] --> B{Message Format}
B --> |JSON| C[json.loads()]
B --> |Binary| D[struct.unpack()]
B --> |Other| E[Custom Parser]
C --> F[Validate Structure]
D --> F
E --> F
F --> G{Valid?}
G --> |Yes| H[Map to TV Data Model]
G --> |No| I[TVDatafeedErrorCallback]
H --> J[TVSubscribeBarsCallback or TVQuotesCallback]
I --> K[Log Error]
**Diagram sources **
PyTradingView implements robust event handling through the on_message, on_error, and on_close callbacks, which are critical for maintaining stable WebSocket connections. The on_message handler processes incoming data by parsing the message payload and dispatching it to the appropriate callback function based on the message type. The on_error handler captures connection issues and protocol errors, logging them for debugging and triggering appropriate recovery actions. The on_close handler manages connection termination, whether planned or unexpected, by cleaning up resources and potentially initiating reconnection logic. These handlers are implemented as methods in the datafeed classes, with the TVDatafeed base class providing the framework and specific implementations like BADatafeed overriding them to provide concrete behavior. The event handlers work in conjunction with the subscriber registries to ensure that messages are delivered to the correct callbacks based on the subscription context.
The translation of incoming WebSocket messages to TradingView-compatible formats is a core function of the PyTradingView datafeed system. Incoming market data is converted into TVBar objects for price bars and TVDatafeedQuoteValues objects for real-time quotes. The TVBar class represents OHLCV (Open, High, Low, Close, Volume) data with a timestamp in milliseconds since Unix epoch, while TVDatafeedQuoteValues contains current price information including last price, bid, ask, and volume. When a WebSocket message is received, it is parsed and mapped to these data structures before being passed to the appropriate callback function. The translation process ensures that data from external sources conforms to TradingView's expectations, enabling seamless integration with the charting library. This translation layer abstracts the differences between various data source formats, providing a consistent interface to the frontend.
classDiagram
class TVBar {
+int time
+float open
+float high
+float low
+float close
+Optional[float] volume
+to_dict() dict
}
class TVDatafeedQuoteValues {
+Optional[float] ch
+Optional[float] chp
+Optional[str] short_name
+Optional[str] exchange
+Optional[str] description
+Optional[float] lp
+Optional[float] ask
+Optional[float] bid
+Optional[float] spread
+Optional[float] open_price
+Optional[float] high_price
+Optional[float] low_price
+Optional[float] prev_close_price
+Optional[float] volume
+Optional[str] original_name
}
class TVQuoteData {
+QuoteStatus s
+str n
+Union[TVDatafeedQuoteValues, dict] v
}
TVQuoteData --> TVDatafeedQuoteValues : "contains"
**Diagram sources **
PyTradingView implements reconnection logic with exponential backoff to handle transient connection failures and maintain data continuity. While the base TVDatafeed class does not include built-in reconnection mechanisms, it provides the framework for implementing them in derived classes like BADatafeed. The reconnection strategy involves detecting connection failures through the on_error and on_close handlers, then attempting to re-establish the connection with increasing delays between attempts. The exponential backoff algorithm starts with a short initial delay (e.g., 100ms) and doubles the delay after each failed attempt, up to a maximum threshold (e.g., 30 seconds). This approach prevents overwhelming the server with rapid reconnection attempts during outages while ensuring prompt recovery when the connection is restored. The reconnection logic preserves subscription state, ensuring that all active subscriptions are re-established after a successful reconnection.
PyTradingView manages connection state for multiple subscribers through centralized registries in the TVDatafeed class. The _subscribers dictionary tracks all active bar data subscriptions, with listener GUIDs as keys and subscription details as values, while the _quote_subscribers dictionary performs the same function for quote data subscriptions. Each subscription entry contains references to the symbol information, resolution, and callback functions, enabling the system to route incoming data to the appropriate handlers. When multiple subscribers request data for the same symbol and resolution, the system can optimize by maintaining a single WebSocket connection and multicasting the data to all interested parties. The unsubscribe methods ensure proper cleanup of subscription state, preventing memory leaks and ensuring accurate connection counting. This state management system enables efficient handling of complex subscription scenarios with overlapping requests.
classDiagram
class TVDatafeed {
-Optional[TVDatafeedConfiguration] _configuration
-Dict[str, Any] _subscribers
-Dict[str, Any] _quote_subscribers
+onReady(callback)
+subscribeBars(symbolInfo, resolution, onTick, listenerGuid, onResetCacheNeededCallback)
+unsubscribeBars(listenerGuid)
+subscribeQuotes(symbols, fastSymbols, onRealtimeCallback, listenerGUID)
+unsubscribeQuotes(listenerGUID)
}
class Subscription {
+TVLibrarySymbolInfo symbolInfo
+ResolutionString resolution
+TVSubscribeBarsCallback onTick
+Callable[[], None] onReset
}
class QuoteSubscription {
+List[str] symbols
+List[str] fastSymbols
+TVQuotesCallback callback
}
TVDatafeed --> Subscription : "contains"
TVDatafeed --> QuoteSubscription : "contains"
**Diagram sources **
Security for WebSocket connections in PyTradingView is addressed through SSL/TLS configuration and message validation. The system leverages Python's standard library and third-party packages to establish secure WebSocket connections (wss://) with external data sources. SSL/TLS certificates are validated by default, ensuring encrypted communication between the client and server. Message validation is implemented through type checking and structure verification before processing incoming data. The TVDatafeed system includes error callbacks (TVDatafeedErrorCallback) to handle invalid messages and potential security issues. For authentication, API keys and tokens should be stored securely and transmitted over encrypted connections. Input validation is performed on all incoming messages to prevent injection attacks and ensure data integrity. The system also supports CORS configuration through FastAPI middleware, allowing fine-grained control over which domains can access the WebSocket endpoints.
PyTradingView provides comprehensive debugging and monitoring capabilities through logging and connection diagnostics. The system uses Python's logging module to record connection events, message processing, and errors at appropriate severity levels. The TVDatafeed class logs subscription and unsubscription events, while the BADatafeed implementation logs real-time subscription attempts. For monitoring message throughput, developers can implement custom logging in the on_message handler to track message rates and latency. Connection diagnostics can be performed by examining the subscriber registries to verify active subscriptions and their callback functions. The system also supports callback registration for chart readiness events, enabling developers to trace the connection initialization sequence. For production environments, these logging mechanisms can be integrated with external monitoring systems to provide real-time visibility into datafeed performance and reliability.