backend redesign

This commit is contained in:
2026-03-11 18:47:11 -04:00
parent 8ff277c8c6
commit e99ef5d2dd
210 changed files with 12147 additions and 155 deletions

View File

@@ -0,0 +1,146 @@
"""
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