"""Pydantic 数据校验模型""" from datetime import datetime from typing import List, Optional from pydantic import BaseModel, Field # ===== 采集请求 ===== class BatchFetchRequest(BaseModel): """批量获取数据请求""" symbols: List[str] = Field(..., description="品种合约列表,如 ['SN2504', 'AG2506']") data_type: str = Field(default="futures", description="数据类型: futures / stock") periods: List[str] = Field( default=["5min", "15min", "30min", "60min", "daily"], description="周期列表: 5min / 15min / 30min / 60min / daily" ) # ===== 数据响应 ===== class CandleItem(BaseModel): """单根K线""" datetime: str open: float high: float low: float close: float volume: float class TimeframeData(BaseModel): """一个周期的数据""" period: str candles: List[CandleItem] candle_count: int fetched_at: str class SymbolDataResponse(BaseModel): """单个品种的数据响应""" symbol: str data_type: str current_price: Optional[float] = None timeframes: List[TimeframeData] source: str = "cache|live" class BatchFetchResponse(BaseModel): """批量获取响应""" success: List[str] = Field(default_factory=list, description="成功的品种") failed: List[str] = Field(default_factory=list, description="失败的品种") details: dict = Field(default_factory=dict, description="每个品种的详细数据") class LatestDataResponse(BaseModel): """获取最新数据响应""" symbol: str data_type: str period: str candles: List[CandleItem] candle_count: int current_price: Optional[float] = None fetched_at: str is_fresh: bool = Field(description="数据是否在缓存有效期内") # ===== 定时任务 ===== class CreateTaskRequest(BaseModel): """创建定时任务请求""" symbol: str = Field(..., description="品种合约代码") data_type: str = Field(default="futures", description="数据类型") periods: str = Field( default="5min,15min,30min,60min,daily", description="需要定时获取的周期,逗号分隔" ) interval_seconds: int = Field( default=300, ge=30, le=86400, description="轮询间隔(秒),范围 30~86400" ) task_type: str = Field(default="interval", description="任务类型: interval, daily, once") run_time: Optional[str] = Field(default=None, description="执行时间,格式 HH:MM") class TaskInfo(BaseModel): """任务信息""" id: int symbol: str data_type: str periods: List[str] interval_seconds: int task_type: str = Field(default="interval", description="任务类型: interval, daily, once") enabled: bool running: bool = Field(description="当前是否正在运行") last_run: Optional[str] = None last_status: Optional[str] = None next_run: Optional[str] = Field(default=None, description="下次执行时间") created_at: str updated_at: str class TaskListResponse(BaseModel): tasks: List[TaskInfo] total: int