""" grid_seeker v6.4 数据库模型 — 6 张数据表 + 1 张评分结果表 所有模型继承 core.database.BaseModel,复用现有 SQLite 连接。 """ from peewee import ( CharField, DateField, FloatField, IntegerField, CompositeKey, TextField, ) from core.database import BaseModel, db # ============================================================ # 1. kline_stock — 个股日K线 # ============================================================ class KlineStock(BaseModel): stock_code = CharField(max_length=10) # 纯数字6位 trade_date = DateField() open = FloatField() high = FloatField() low = FloatField() close = FloatField() volume = FloatField() # 成交量(股) class Meta: primary_key = CompositeKey('stock_code', 'trade_date') indexes = ( (('stock_code', 'trade_date'), False), ) # ============================================================ # 2. stocks — 股票基础信息 # ============================================================ class StockInfo(BaseModel): code = CharField(max_length=12, primary_key=True) # 带 SH/SZ/BJ 前缀 name = CharField(max_length=32) exchange = CharField(max_length=4) # SH / SZ / BJ list_date = DateField(null=True) listing_status = CharField(max_length=16, default='normal') # normal / delisted / ST total_share = FloatField(null=True) # 总股本(股) float_share = FloatField(null=True) # 流通股本(股) share_updated_at = DateField(null=True) # 股本数据同步时间 # ============================================================ # 3. industry — 股票-行业映射 # ============================================================ class IndustryMapping(BaseModel): code = CharField(max_length=6, primary_key=True) # 纯数字6位 industry_name = CharField(max_length=64, index=True) industry_classification = CharField(max_length=32) # 行业分类体系名称 update_date = DateField() # ============================================================ # 4. kline_index — 指数日K线 # ============================================================ class KlineIndex(BaseModel): index_code = CharField(max_length=10) # 指数代码(6位数字) trade_date = DateField() open = FloatField() high = FloatField() low = FloatField() close = FloatField() volume = FloatField() class Meta: primary_key = CompositeKey('index_code', 'trade_date') indexes = ( (('index_code', 'trade_date'), False), ) # ============================================================ # 5. market_regime_daily — 市场状态(本地计算) # ============================================================ class MarketRegimeDaily(BaseModel): trade_date = DateField(primary_key=True) advancers = FloatField(default=0) # 当日上涨家数 decliners = FloatField(default=0) # 当日下跌家数 advance_ratio = FloatField(default=0) # 涨跌比 = advancers/(advancers+decliners) turnover = FloatField(default=0) # 全市场成交额 turnover_avg_5d = FloatField(default=0) # 5日滚动均量 turnover_ratio_5d = FloatField(default=0) # 量比 = turnover/turnover_avg_5d source = CharField(max_length=32, default='qmt') is_extreme_panic = IntegerField(default=0) # advance_ratio<0.2 且 turnover_ratio_5d>1.5 # ============================================================ # 6. sector_features_daily — 行业聚合指数(本地计算) # ============================================================ class SectorFeaturesDaily(BaseModel): trade_date = DateField() sector_name = CharField(max_length=64) # 与 industry.industry_name 对应 sector_ret = FloatField(default=0) # 行业日收益率(均值) sector_amplitude = FloatField(default=0) # 行业平均振幅 close = FloatField(default=100) # 行业指数(基值100) ema10 = FloatField(default=0) ema20 = FloatField(default=0) ema200 = FloatField(default=0) score = IntegerField(default=0) # 趋势评分 0/1/2 class Meta: primary_key = CompositeKey('trade_date', 'sector_name') # ============================================================ # 7. ScoringResult — 评分结果(模型输出写入表) # ============================================================ class ScoringResult(BaseModel): stock_code = CharField(max_length=6) # 纯数字6位 trade_date = DateField() # 评分日 predicted_profit = FloatField(default=0) # 最终预测利润(=stacking_probability) rank_predicted_rounds = FloatField(null=True) # Rank 模型输出 top_elite_prob = FloatField(null=True) # Top 模型输出 stacking_probability = FloatField(null=True) # Stacking 模型输出 score_rank = IntegerField(default=0) # 排名 candidate_count = IntegerField(default=0) # 候选股总数 class Meta: primary_key = CompositeKey('stock_code', 'trade_date') # ============================================================ # 8. PendingPoolAction — 待执行股票池操作(阶段一标记,阶段二执行) # ============================================================ class PendingPoolAction(BaseModel): """pending_pool_actions 表 — T日标记的操作,待 T+1 执行""" action_date = DateField() # T日日期(标记日期) action_type = CharField(max_length=20) # 'eliminate' | 'liquidate' stock_code = CharField(max_length=6) # 股票代码 reason = TextField(null=True) # 淘汰原因描述 class Meta: primary_key = CompositeKey('action_date', 'action_type', 'stock_code') # ============================================================ # 建表 # ============================================================ ALL_SCORING_TABLES = [ KlineStock, StockInfo, IndustryMapping, KlineIndex, MarketRegimeDaily, SectorFeaturesDaily, ScoringResult, PendingPoolAction, ] db.create_tables(ALL_SCORING_TABLES)