You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

125 lines
5.7 KiB

# -*- 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")