-
Notifications
You must be signed in to change notification settings - Fork 1
Custom Datafeed Integration
- Introduction
- Core Data Structures
- Required Methods for Custom Datafeed Implementation
- Implementation Example
- Advanced Topics
- Security Considerations
- Performance Optimization
- Testing and Development
- Conclusion
This document provides comprehensive guidance on implementing custom datafeed integrations with PyTradingView by extending the TVDatafeed class. The framework enables developers to connect to various market data sources and deliver real-time and historical financial data to TradingView charts. The implementation requires understanding of key data structures, required interface methods, and the TVBridge communication system that connects Python backend with web frontend components.
The TVBar class represents a single bar of OHLCV (Open, High, Low, Close, Volume) data for a specific time period. This structure is fundamental for both historical data retrieval and real-time bar updates.
classDiagram
class TVBar {
+int time
+float open
+float high
+float low
+float close
+Optional[float] volume
+to_dict() dict
}
The TVLibrarySymbolInfo class contains comprehensive metadata about trading instruments, including exchange information, trading sessions, price formatting, and supported resolutions. This information is crucial for proper chart configuration and display.
classDiagram
class TVLibrarySymbolInfo {
+str name
+str description
+str type
+str session
+str exchange
+str listed_exchange
+Timezone timezone
+SeriesFormat format
+int pricescale
+int minmov
+Optional[str] ticker
+Optional[bool] has_intraday
+Optional[List[ResolutionString]] supported_resolutions
+Optional[int] volume_precision
}
This configuration object defines the capabilities and options supported by the datafeed implementation, including available exchanges, supported timeframes, and feature flags.
classDiagram
class TVDatafeedConfiguration {
+Optional[List[TVExchange]] exchanges
+Optional[List[ResolutionString]] supported_resolutions
+Optional[bool] supports_marks
+Optional[bool] supports_time
+Optional[bool] supports_timescale_marks
+Optional[List[TVDatafeedSymbolType]] symbols_types
+Optional[Dict[str, str]] symbols_grouping
}
The onReady method provides datafeed configuration to the TradingView library. This method should return a TVDatafeedConfiguration object that specifies the capabilities of your datafeed implementation.
This method enables symbol search functionality in the TradingView interface. It should return a list of TVSearchSymbolResultItem objects matching the user's search criteria.
sequenceDiagram
participant UI as "TradingView UI"
participant Datafeed as "Custom Datafeed"
UI->>Datafeed : searchSymbols(userInput, exchange, symbolType)
Datafeed->>Datafeed : Filter symbols based on criteria
Datafeed->>UI : onResult(results)
The resolveSymbol method converts a symbol name into complete instrument metadata by returning a TVLibrarySymbolInfo object. This information is used to configure the chart properly.
This method retrieves historical bar data for a specified symbol, timeframe, and time range. It should return both the bar data and metadata about the result set.
sequenceDiagram
participant Chart as "TradingView Chart"
participant Datafeed as "Custom Datafeed"
Chart->>Datafeed : getBars(symbolInfo, resolution, periodParams)
Datafeed->>MarketAPI : Request historical data
MarketAPI-->>Datafeed : Return OHLCV data
Datafeed->>Datafeed : Transform to TVBar objects
Datafeed->>Chart : onResult(bars, metadata)
This method establishes a subscription for real-time bar updates. The implementation should maintain subscriber state and push new bars to the onTick callback when they become available.
The following example demonstrates a complete implementation of a custom datafeed class that connects to a market data API, transforms the data into the required format, and pushes updates through the TVBridge system.
classDiagram
class CustomMarketDatafeed {
+TVDatafeedConfiguration _configuration
+Dict[str, Any] _subscribers
+Dict[str, Any] _quote_subscribers
+__init__()
+onReady(callback)
+searchSymbols(userInput, exchange, symbolType, onResult)
+resolveSymbol(symbolName, onResolve, onError, extension)
+getBars(symbolInfo, resolution, periodParams, onResult, onError)
+subscribeBars(symbolInfo, resolution, onTick, listenerGuid, onResetCacheNeededCallback)
+unsubscribeBars(listenerGuid)
+_connect_to_market_api()
+_transform_api_data(raw_data)
+_push_realtime_update(bar)
+_handle_network_reconnection()
}
CustomMarketDatafeed --|> TVDatafeed : "extends"
The data transformation process converts raw market data from the external API into the TVBar format required by TradingView.
flowchart TD
Start([Raw Market Data]) --> Validate["Validate Data Integrity"]
Validate --> FormatCheck{"Data Format Correct?"}
FormatCheck --> |No| HandleError["Log Error and Skip"]
FormatCheck --> |Yes| Transform["Transform to TVBar Format"]
Transform --> TimeConversion["Convert Timestamp to UTC"]
TimeConversion --> PriceScale["Apply Price Scaling"]
PriceScale --> VolumeCheck["Validate Volume Data"]
VolumeCheck --> Complete["Create TVBar Object"]
Complete --> End([Ready for Charting])
HandleError --> End
The framework supports multiple timeframes through the ResolutionString type. Custom datafeeds must properly handle various resolution formats including minute-based (1, 5, 15), hourly (60, 240), and daily/weekly/monthly (1D, 1W, 1M) intervals.
Proper management of subscription lifecycles is critical for resource efficiency and preventing memory leaks. The framework provides unsubscribe methods that should be implemented to clean up resources when users navigate away from charts.
sequenceDiagram
participant Chart as "TradingView Chart"
participant Datafeed as "Custom Datafeed"
participant WebSocket as "Market Data WebSocket"
Chart->>Datafeed : subscribeBars()
Datafeed->>WebSocket : Connect if not already connected
Datafeed->>Datafeed : Store subscription reference
Chart->>Datafeed : unsubscribeBars()
Datafeed->>Datafeed : Remove subscription reference
Datafeed->>WebSocket : Disconnect if no remaining subscriptions
Robust error recovery mechanisms are essential for maintaining data integrity during network interruptions. The implementation should include automatic reconnection logic with exponential backoff and proper error handling.
flowchart TD
Start([Network Request]) --> Execute["Execute API Call"]
Execute --> Success{"Request Successful?"}
Success --> |Yes| Complete["Process Data"]
Success --> |No| Backoff["Apply Exponential Backoff"]
Backoff --> RetryCount{"Max Retries Exceeded?"}
RetryCount --> |Yes| Fail["Return Error to Client"]
RetryCount --> |No| Wait["Wait Before Retry"]
Wait --> Execute
Complete --> End([Success])
Fail --> End
When implementing custom datafeeds, security considerations are paramount, especially when handling API keys and sensitive market data. API credentials should be stored securely using environment variables or secure configuration management systems rather than hardcoding them in source files. All network communications should use HTTPS/TLS encryption to protect data in transit. Additionally, implement proper input validation to prevent injection attacks and ensure that error messages do not leak sensitive information about the internal system architecture.
High-frequency data streaming requires careful performance optimization. Implement efficient data caching strategies using appropriate data structures to minimize memory usage when storing large historical datasets. For real-time updates, consider using asynchronous programming patterns to prevent blocking operations. Optimize data serialization and deserialization processes, and implement data compression when appropriate. Use connection pooling for database access and implement efficient algorithms for data processing and transformation.
Effective testing of custom datafeeds involves simulating various market conditions and edge cases. Implement unit tests for data transformation logic and integration tests for API connectivity. Use mock objects to simulate market data APIs during development to avoid rate limiting and costs. Create test scenarios that cover normal operation, network failures, data anomalies, and high-load conditions. The framework's logging capabilities should be leveraged to monitor datafeed behavior during testing.
Implementing custom datafeed integrations with PyTradingView requires understanding the framework's architecture and properly implementing the required interfaces. By extending the TVDatafeed class and implementing the necessary methods, developers can connect to various market data sources and deliver both historical and real-time financial data to TradingView charts. Attention to data structure requirements, proper error handling, security considerations, and performance optimization is essential for creating robust and reliable datafeed implementations.