127 lines
4.5 KiB
Python
127 lines
4.5 KiB
Python
"""Pydantic 数据模型"""
|
|
|
|
from pydantic import BaseModel
|
|
from datetime import datetime
|
|
|
|
|
|
class StockQuote(BaseModel):
|
|
ts_code: str
|
|
name: str
|
|
price: float
|
|
pct_chg: float
|
|
volume: float # 成交量(手)
|
|
amount: float # 成交额(万元)
|
|
turnover_rate: float # 换手率 %
|
|
pe: float | None = None
|
|
pb: float | None = None
|
|
circ_mv: float | None = None # 流通市值(亿)
|
|
total_mv: float | None = None # 总市值(亿)
|
|
volume_ratio: float | None = None # 量比
|
|
high: float | None = None
|
|
low: float | None = None
|
|
open: float | None = None
|
|
pre_close: float | None = None
|
|
limit_up: float | None = None
|
|
limit_down: float | None = None
|
|
amplitude: float | None = None # 振幅 %
|
|
|
|
|
|
class CapitalFlow(BaseModel):
|
|
ts_code: str
|
|
trade_date: str
|
|
buy_elg_amount: float = 0 # 特大单买入(万)
|
|
sell_elg_amount: float = 0
|
|
buy_lg_amount: float = 0 # 大单买入(万)
|
|
sell_lg_amount: float = 0
|
|
buy_md_amount: float = 0 # 中单买入(万)
|
|
sell_md_amount: float = 0
|
|
buy_sm_amount: float = 0 # 小单买入(万)
|
|
sell_sm_amount: float = 0
|
|
net_mf_amount: float = 0 # 主力净流入(万)
|
|
|
|
@property
|
|
def main_net_inflow(self) -> float:
|
|
"""主力净流入 = 特大单净买 + 大单净买"""
|
|
return (self.buy_elg_amount - self.sell_elg_amount +
|
|
self.buy_lg_amount - self.sell_lg_amount)
|
|
|
|
@property
|
|
def total_amount(self) -> float:
|
|
return (self.buy_elg_amount + self.sell_elg_amount +
|
|
self.buy_lg_amount + self.sell_lg_amount +
|
|
self.buy_md_amount + self.sell_md_amount +
|
|
self.buy_sm_amount + self.sell_sm_amount)
|
|
|
|
|
|
class SectorInfo(BaseModel):
|
|
sector_code: str
|
|
sector_name: str
|
|
pct_change: float = 0 # 涨跌幅 %
|
|
capital_inflow: float = 0 # 主力净流入(万)
|
|
limit_up_count: int = 0 # 涨停数
|
|
days_continuous: int = 0 # 连续资金流入天数
|
|
heat_score: float = 0 # 热度综合评分
|
|
stage: str = "mid" # 板块阶段: early/mid/late/end
|
|
|
|
|
|
class MarketTemperature(BaseModel):
|
|
trade_date: str
|
|
up_count: int = 0 # 上涨家数
|
|
down_count: int = 0 # 下跌家数
|
|
limit_up_count: int = 0 # 涨停数(自然涨停)
|
|
limit_down_count: int = 0 # 跌停数
|
|
max_streak: int = 0 # 最高连板
|
|
broken_rate: float = 0 # 炸板率 %
|
|
index_above_ma20: bool = False # 上证在 MA20 上方
|
|
temperature: float = 0 # 综合温度 0-100
|
|
|
|
|
|
class TechnicalSignal(BaseModel):
|
|
ts_code: str
|
|
name: str = ""
|
|
ma_bullish: bool = False # 均线多头排列
|
|
volume_breakout: bool = False # 放量突破
|
|
macd_golden: bool = False # MACD金叉
|
|
rsi_healthy: bool = False # RSI健康区间
|
|
pullback_support: bool = False # 缩量回踩支撑
|
|
big_yang: bool = False # 底部放量长阳
|
|
boll_support: bool = False # 布林带下轨支撑
|
|
score: float = 0 # 技术面总分
|
|
signal_count: int = 0 # 满足的信号数量
|
|
|
|
# 位置安全评估(防追高)
|
|
rally_pct_5d: float = 0 # 近5日累计涨幅
|
|
rally_pct_10d: float = 0 # 近10日累计涨幅
|
|
distance_from_high: float = 0 # 距离60日高点 %(负=已回调)
|
|
position_score: float = 50 # 位置安全得分 0-100
|
|
|
|
# 价格参考
|
|
support_price: float | None = None # 支撑位
|
|
resist_price: float | None = None # 压力位
|
|
stop_loss_price: float | None = None # 止损价
|
|
|
|
|
|
class Recommendation(BaseModel):
|
|
ts_code: str
|
|
name: str
|
|
sector: str
|
|
score: float # 综合评分
|
|
market_temp_score: float
|
|
sector_score: float
|
|
capital_score: float
|
|
technical_score: float
|
|
position_score: float = 50 # 位置安全得分
|
|
valuation_score: float = 50 # 估值安全得分
|
|
signal: str # BUY / SELL / HOLD
|
|
entry_price: float | None = None
|
|
target_price: float | None = None
|
|
stop_loss: float | None = None
|
|
reasons: list[str] = []
|
|
risk_note: str = ""
|
|
level: str = "" # 强烈推荐/推荐/观望/回避
|
|
strategy: str = "momentum" # momentum(强中选强) / potential(潜在启动)
|
|
llm_analysis: str = "" # LLM 深度分析
|
|
llm_score: float | None = None # AI 评分 1-10
|
|
scan_session: str = ""
|
|
created_at: datetime | None = None
|