147 lines
4.0 KiB
Python
147 lines
4.0 KiB
Python
"""
|
|
Abstract DataSource interface.
|
|
|
|
Inspired by TradingView's Datafeed API with extensions for flexible column schemas
|
|
and AI-native metadata.
|
|
"""
|
|
|
|
from abc import ABC, abstractmethod
|
|
from typing import Callable, List, Optional
|
|
|
|
from .schema import DatafeedConfig, HistoryResult, SearchResult, SymbolInfo
|
|
|
|
|
|
class DataSource(ABC):
|
|
"""
|
|
Abstract base class for time-series data sources.
|
|
|
|
Provides a standardized interface for:
|
|
- Symbol search and metadata retrieval
|
|
- Historical data queries (time-based, paginated)
|
|
- Real-time data subscriptions
|
|
|
|
All data rows must have a timestamp. Additional columns are flexible
|
|
and described via ColumnInfo metadata.
|
|
"""
|
|
|
|
@abstractmethod
|
|
async def get_config(self) -> DatafeedConfig:
|
|
"""
|
|
Get datafeed configuration and capabilities.
|
|
|
|
Called once during initialization to understand what this data source
|
|
supports (resolutions, exchanges, search, etc.).
|
|
|
|
Returns:
|
|
DatafeedConfig describing this datafeed's capabilities
|
|
"""
|
|
pass
|
|
|
|
@abstractmethod
|
|
async def search_symbols(
|
|
self,
|
|
query: str,
|
|
type: Optional[str] = None,
|
|
exchange: Optional[str] = None,
|
|
limit: int = 30,
|
|
) -> List[SearchResult]:
|
|
"""
|
|
Search for symbols matching a text query.
|
|
|
|
Args:
|
|
query: Free-text search string
|
|
type: Optional filter by instrument type
|
|
exchange: Optional filter by exchange
|
|
limit: Maximum number of results
|
|
|
|
Returns:
|
|
List of matching symbols with basic metadata
|
|
"""
|
|
pass
|
|
|
|
@abstractmethod
|
|
async def resolve_symbol(self, symbol: str) -> SymbolInfo:
|
|
"""
|
|
Get complete metadata for a symbol.
|
|
|
|
Called after a symbol is selected to retrieve full information including
|
|
supported resolutions, column schema, trading session, etc.
|
|
|
|
Args:
|
|
symbol: Symbol identifier
|
|
|
|
Returns:
|
|
Complete SymbolInfo including column definitions
|
|
|
|
Raises:
|
|
ValueError: If symbol is not found
|
|
"""
|
|
pass
|
|
|
|
@abstractmethod
|
|
async def get_bars(
|
|
self,
|
|
symbol: str,
|
|
resolution: str,
|
|
from_time: int,
|
|
to_time: int,
|
|
countback: Optional[int] = None,
|
|
) -> HistoryResult:
|
|
"""
|
|
Get historical bars for a symbol and resolution.
|
|
|
|
Time range is specified in Unix timestamps (seconds). If more data is
|
|
available beyond the requested range, the result should include a
|
|
nextTime value for pagination.
|
|
|
|
Args:
|
|
symbol: Symbol identifier
|
|
resolution: Time resolution (e.g., "1", "5", "60", "1D")
|
|
from_time: Start time (Unix timestamp in seconds)
|
|
to_time: End time (Unix timestamp in seconds)
|
|
countback: Optional limit on number of bars to return
|
|
|
|
Returns:
|
|
HistoryResult with bars, column schema, and pagination info
|
|
|
|
Raises:
|
|
ValueError: If symbol or resolution is not supported
|
|
"""
|
|
pass
|
|
|
|
@abstractmethod
|
|
async def subscribe_bars(
|
|
self,
|
|
symbol: str,
|
|
resolution: str,
|
|
on_tick: Callable[[dict], None],
|
|
) -> str:
|
|
"""
|
|
Subscribe to real-time bar updates.
|
|
|
|
The callback will be invoked with new bar data as it becomes available.
|
|
The data dict will match the column schema from resolve_symbol().
|
|
|
|
Args:
|
|
symbol: Symbol identifier
|
|
resolution: Time resolution
|
|
on_tick: Callback function receiving bar data dict
|
|
|
|
Returns:
|
|
Subscription ID for later unsubscribe
|
|
|
|
Raises:
|
|
ValueError: If symbol or resolution is not supported
|
|
"""
|
|
pass
|
|
|
|
@abstractmethod
|
|
async def unsubscribe_bars(self, subscription_id: str) -> None:
|
|
"""
|
|
Unsubscribe from real-time updates.
|
|
|
|
Args:
|
|
subscription_id: ID returned from subscribe_bars()
|
|
"""
|
|
pass
|