# -*- coding: utf-8 -*- """ =================================== Market data schemas =================================== """ from typing import Optional, List from pydantic import BaseModel, Field class MarketIndex(BaseModel): """Market index data""" code: str = Field(..., description="Index code") name: str = Field(..., description="Index name") price: float = Field(..., description="Current price") change: Optional[float] = Field(None, description="Change amount") change_percent: Optional[float] = Field(None, description="Change percent") volume: Optional[float] = Field(None, description="Volume") amount: Optional[float] = Field(None, description="Amount") class UpDownStats(BaseModel): """Up/down statistics""" up_count: int = Field(..., description="Number of rising stocks") down_count: int = Field(..., description="Number of falling stocks") flat_count: int = Field(..., description="Number of flat stocks") limit_up_count: int = Field(..., description="Number of limit up stocks") limit_down_count: int = Field(..., description="Number of limit down stocks") total_count: int = Field(..., description="Total count") class SectorMomentum(BaseModel): """Sector momentum data""" code: str = Field(..., description="Sector code") name: str = Field(..., description="Sector name") momentum_score: float = Field(..., description="Momentum score") change_percent: float = Field(..., description="Change percent") turnover_rate: Optional[float] = Field(None, description="Turnover rate") leading_stock: Optional[str] = Field(None, description="Leading stock code") leading_stock_name: Optional[str] = Field(None, description="Leading stock name") momentum_value: Optional[float] = Field(None, description="Momentum value (n²/N)") momentum_value_change: Optional[float] = Field(None, description="Momentum value change from previous") rank: Optional[int] = Field(None, description="Current rank") rank_change: Optional[int] = Field(None, description="Rank change from previous") class StockMomentum(BaseModel): """Stock momentum recommendation""" code: str = Field(..., description="Stock code") name: str = Field(..., description="Stock name") momentum_score: float = Field(..., description="Momentum score") change_percent: float = Field(..., description="Change percent") sector: Optional[str] = Field(None, description="Belonging sector") recommendation: Optional[str] = Field(None, description="Recommendation level") class NewHighLowStock(BaseModel): """New high/low stock""" code: str = Field(..., description="Stock code") name: str = Field(..., description="Stock name") price: float = Field(..., description="Current price") change_percent: float = Field(..., description="Change percent") days_to_high: Optional[int] = Field(None, description="Days to new high") days_to_low: Optional[int] = Field(None, description="Days to new low") high_date: Optional[str] = Field(None, description="High date") low_date: Optional[str] = Field(None, description="Low date") class PriceDistribution(BaseModel): """Price distribution statistics""" range_label: str = Field(..., description="Price range label") count: int = Field(..., description="Stock count in this range") percent: float = Field(..., description="Percentage") class SentimentIndicator(BaseModel): """Market sentiment indicator""" name: str = Field(..., description="Indicator name") value: float = Field(..., description="Current value") change: Optional[float] = Field(None, description="Change from previous") level: Optional[str] = Field(None, description="Sentiment level (high/medium/low)") description: Optional[str] = Field(None, description="Description") class MarketOverview(BaseModel): """Market overview response""" indices: List[MarketIndex] = Field(default_factory=list, description="Major indices") updown_stats: UpDownStats = Field(..., description="Up/down statistics") sentiment: List[SentimentIndicator] = Field(default_factory=list, description="Sentiment indicators") update_time: str = Field(..., description="Update time") class SectorListResponse(BaseModel): """Sector list response""" items: List[SectorMomentum] = Field(default_factory=list, description="Sector list") total: int = Field(..., description="Total count") class StockMomentumResponse(BaseModel): """Stock momentum response""" items: List[StockMomentum] = Field(default_factory=list, description="Stock list") total: int = Field(..., description="Total count") class NewHighLowResponse(BaseModel): """New high/low response""" new_high: List[NewHighLowStock] = Field(default_factory=list, description="New high stocks") new_low: List[NewHighLowStock] = Field(default_factory=list, description="New low stocks") high_count: int = Field(..., description="Total new high count") low_count: int = Field(..., description="Total new low count") class PriceDistributionResponse(BaseModel): """Price distribution response""" items: List[PriceDistribution] = Field(default_factory=list, description="Distribution items") total_count: int = Field(..., description="Total stock count") class KLineChartResponse(BaseModel): """K-line chart data for ECharts""" categoryData: List[str] = Field(default_factory=list, description="Date list") values: List[List[float]] = Field(default_factory=list, description="K-line values [open, close, low, high, volume]") volumes: List[List[float]] = Field(default_factory=list, description="Volume data [index, volume, change_sign]") stock_name: Optional[str] = Field(None, description="Stock name")