- Add DataLoader Protocol + Registry with market-level fallback chains - New data sources: AKShare (A-shares/US/HK/futures, free) and CCXT (100+ crypto exchanges) - Auto-fallback: tushare unavailable -> akshare; OKX unavailable -> CCXT - Zero-config: all markets work without any API keys - New web_search tool (DuckDuckGo) for web information retrieval - Skill categorization: 68 skills organized into 7 categories (data-source, strategy, analysis, asset-class, crypto, flow, tool) - New data-routing meta-skill for intelligent data source selection - Registry self-initializes via _ensure_registered() — no manual imports needed - Pattern detection returns market type instead of source name (decoupled) - runner.py loads .env via dotenv for reliable token access
41 lines
996 B
Python
41 lines
996 B
Python
"""DataLoader Protocol and shared exceptions for all data source loaders."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from typing import Protocol, runtime_checkable
|
|
|
|
import pandas as pd
|
|
|
|
|
|
class NoAvailableSourceError(Exception):
|
|
"""Raised when no data source is available for a given market."""
|
|
|
|
|
|
@runtime_checkable
|
|
class DataLoaderProtocol(Protocol):
|
|
"""Interface that every data source loader must satisfy."""
|
|
|
|
name: str
|
|
markets: set[str]
|
|
requires_auth: bool
|
|
|
|
def is_available(self) -> bool:
|
|
"""Check whether this data source is usable (token present, network ok, etc.)."""
|
|
...
|
|
|
|
def fetch(
|
|
self,
|
|
codes: list[str],
|
|
start_date: str,
|
|
end_date: str,
|
|
*,
|
|
interval: str = "1D",
|
|
fields: list[str] | None = None,
|
|
) -> dict[str, pd.DataFrame]:
|
|
"""Fetch OHLCV data.
|
|
|
|
Returns:
|
|
Mapping ``{symbol: DataFrame(trade_date, open, high, low, close, volume)}``.
|
|
"""
|
|
...
|