|
|
"""数据源适配器基类 - 对应Go的adapter/adapter.go"""
|
|
|
from abc import ABC, abstractmethod
|
|
|
from dataclasses import dataclass
|
|
|
from datetime import datetime
|
|
|
from typing import Callable, List, Optional
|
|
|
|
|
|
|
|
|
@dataclass
|
|
|
class TickData:
|
|
|
"""Tick数据"""
|
|
|
symbol: str
|
|
|
price: float
|
|
|
volume: int
|
|
|
time: int # Unix时间戳
|
|
|
|
|
|
|
|
|
@dataclass
|
|
|
class KLineData:
|
|
|
"""K线数据"""
|
|
|
symbol: str
|
|
|
time: int # Unix时间戳
|
|
|
open: float
|
|
|
high: float
|
|
|
low: float
|
|
|
close: float
|
|
|
volume: int
|
|
|
amount: float
|
|
|
open_interest: Optional[int] = None
|
|
|
|
|
|
# 股票特有字段
|
|
|
trade_date: Optional[str] = None # 交易日 (YYYY-MM-DD)
|
|
|
is_limit_up: Optional[bool] = None # 是否涨停
|
|
|
is_limit_down: Optional[bool] = None # 是否跌停
|
|
|
total_market_cap: Optional[float] = None # 总市值(元)
|
|
|
float_market_cap: Optional[float] = None # 流通市值(元)
|
|
|
inst_holding_ratio: Optional[float] = None # 机构持仓占比(%)
|
|
|
trading_days: Optional[int] = None # 可交易日数(从上市至今)
|
|
|
|
|
|
|
|
|
@dataclass
|
|
|
class SymbolInfo:
|
|
|
"""标的信息"""
|
|
|
symbol_id: str
|
|
|
name: str
|
|
|
exchange: str
|
|
|
underlying: str = "" # 期货品种代码
|
|
|
contract_month: str = ""
|
|
|
list_date: str = ""
|
|
|
delist_date: str = ""
|
|
|
|
|
|
|
|
|
@dataclass
|
|
|
class TradeCalData:
|
|
|
"""交易日历数据"""
|
|
|
date: datetime
|
|
|
is_trading_day: bool
|
|
|
has_night_session: bool = False
|
|
|
|
|
|
|
|
|
# Tick数据回调类型
|
|
|
TickCallback = Callable[[str, TickData], None]
|
|
|
|
|
|
|
|
|
class DataSourceAdapter(ABC):
|
|
|
"""数据源适配器接口"""
|
|
|
|
|
|
@abstractmethod
|
|
|
async def connect(self, config: dict) -> None:
|
|
|
"""建立连接"""
|
|
|
pass
|
|
|
|
|
|
@abstractmethod
|
|
|
async def subscribe_ticks(self, symbols: List[str], callback: TickCallback) -> None:
|
|
|
"""订阅实时Tick"""
|
|
|
pass
|
|
|
|
|
|
@abstractmethod
|
|
|
async def fetch_klines(
|
|
|
self,
|
|
|
symbol: str,
|
|
|
start: str,
|
|
|
end: str,
|
|
|
freq: str
|
|
|
) -> List[KLineData]:
|
|
|
"""拉取历史K线"""
|
|
|
pass
|
|
|
|
|
|
@abstractmethod
|
|
|
async def fetch_symbols(self, asset_type: str) -> List[SymbolInfo]:
|
|
|
"""获取标的列表"""
|
|
|
pass
|
|
|
|
|
|
@abstractmethod
|
|
|
async def fetch_trading_calendar(
|
|
|
self,
|
|
|
exchange: str,
|
|
|
start: str,
|
|
|
end: str
|
|
|
) -> List[TradeCalData]:
|
|
|
"""获取交易日历"""
|
|
|
pass
|
|
|
|
|
|
@abstractmethod
|
|
|
async def health_check(self) -> bool:
|
|
|
"""健康检查"""
|
|
|
pass
|
|
|
|
|
|
@abstractmethod
|
|
|
async def close(self) -> None:
|
|
|
"""关闭连接"""
|
|
|
pass
|