from pydantic import BaseModel from typing import Optional, List from datetime import datetime # ========== 品种相关 ========== class ProductInfo(BaseModel): id: int product_code: str product_name: str exchange: str multiplier: Optional[int] = None price_tick: Optional[float] = None category: Optional[str] = None is_active: Optional[bool] = None contract_count: int = 0 main_contract: Optional[str] = None class Config: from_attributes = True class ProductTreeItem(BaseModel): """品种树节点""" product_code: str product_name: str exchange: str category: str contracts: List[dict] # [{"symbol": "rb2401", "year_month": "2024-01", "is_main": true}] class ProductTreeResponse(BaseModel): """品种树响应""" categories: List[dict] # [{"category": "能源化工", "products": [...]}] # ========== 合约相关 ========== class ContractInfo(BaseModel): id: int symbol: str exchange: str name: Optional[str] = None product: Optional[str] = None multiplier: Optional[int] = None price_tick: Optional[float] = None is_active: Optional[bool] = None year_month: Optional[str] = None delivery_month: Optional[int] = None is_main: Optional[bool] = None open_interest: Optional[int] = None class Config: from_attributes = True class ContractListResponse(BaseModel): total: int items: List[ContractInfo] # ========== K线相关 ========== class KlineItem(BaseModel): trade_time: datetime open: Optional[float] = None high: Optional[float] = None low: Optional[float] = None close: Optional[float] = None volume: Optional[int] = None turnover: Optional[float] = None open_interest: Optional[int] = None class Config: from_attributes = True class KlineRequest(BaseModel): symbol: str period: str = "daily" # daily/weekly/5m/15m/30m/60m start_date: Optional[str] = None # YYYY-MM-DD or YYYY-MM-DD HH:MM:SS end_date: Optional[str] = None limit: int = 500 # 默认返回最近500条 class KlineResponse(BaseModel): symbol: str period: str total: int items: List[KlineItem] class BatchSyncRequest(BaseModel): """批量同步K线请求""" symbols: List[str] # 合约列表 period: str = "daily" # daily/weekly/5m/15m/30m/60m start_date: str # YYYY-MM-DD end_date: str # YYYY-MM-DD class BatchSyncResult(BaseModel): """批量同步结果""" total: int # 总合约数 success: int # 成功数 failed: int # 失败数 total_records: int # 总记录数 details: List[dict] # 详细信息 # ========== 数据源相关 ========== class DataSourceConfigItem(BaseModel): id: int source_name: str display_name: Optional[str] = None is_enabled: bool priority: int status: str error_msg: Optional[str] = None last_sync_time: Optional[datetime] = None class Config: from_attributes = True class DataSourceConfigUpdate(BaseModel): is_enabled: Optional[bool] = None config_json: Optional[dict] = None priority: Optional[int] = None class DataSourceCreate(BaseModel): source_name: str display_name: Optional[str] = None config_json: Optional[dict] = None priority: int = 0 class DataSourceStatus(BaseModel): source_name: str is_enabled: bool status: str error_msg: Optional[str] = None last_sync_time: Optional[datetime] = None # ========== 通用 ========== class ApiResponse(BaseModel): code: int = 0 message: str = "ok" data: Optional[dict] = None class HealthResponse(BaseModel): status: str services: dict version: str