数据模型总览
概述
系统使用 SQLAlchemy ORM 管理 215 张表(按 backend/app/models/*.py 的 __tablename__ 去重统计),覆盖行情、基本面、事件、量化、宏观、配置、多源治理七大领域。模型定义位于 backend/app/models/:
| 模型模块 | 表数 | 内容 |
|---|---|---|
db_models.py | 126 | 主力业务表(行情/财务/事件/自选/AI/策略/任务…) |
fox_models.py | 35 | fox 治理层 6 + 融合层 21 + 市场级旁路 3 |
fox_models_ods.py | 15 | fox 前缀 ODS 中间表(快照/量化/信号池,非融合层) |
stg_models.py | 14 | STG 清洗贴源层(一融合类型一 STG 表) |
sse_*.py / szse_*.py / exchange_models.py | 22 | 沪深交易所 ODS 与 fox_exchange_* 统一 DWD |
task_models.py | 3 | 任务中心执行→步骤→日志三级留痕 |
表数是「是否漏注册」的对账基准,改动模型后请同步本表;用
grep -c __tablename__ backend/app/models/*.py可一条命令复核。
实体关系总览
表分组说明
一、行情数据(4 张表)
| 表名 | 模型 | 主键/唯一键 | 更新频率 | 说明 |
|---|---|---|---|---|
fox_kline_daily | FoxKlineDaily | (code, date) | T+1 日终 | 日K线 OHLCV + adj_factor(复权因子,替代原 kline_daily ODS 表) |
tdx_kline_minute | KlineMinute | (code, bar_time) | 盘中实时 | 分钟K线(TDX TCP 5 分钟周期持久化) |
fox_quote_snapshot | FoxQuoteSnapshot | (code, date) | 盘中实时 | 实时行情快照(价格/涨跌幅/成交量等)。业务读取已收敛至 fox_valuation |
valuation_snapshot | — | 已删除 | 估值维度已由 fox_valuation 融合表统一管理,扩展字段改由 calc_valuation() API 获取 |
二、资金数据(3 张表)
| 表名 | 模型 | 主键/唯一键 | 更新频率 | 说明 |
|---|---|---|---|---|
fox_fund_flow_daily | FoxFundFlowDaily | (code, date) | T+1 日终 | 日线资金流向(主力/散户净流入) |
em_northbound_daily | NorthboundDaily | (date) | T+1 日终 | 北向资金日级汇总 |
em_margin_trading | MarginTrading | (code, date) | T+1 盘前 | 融资融券余额/买入/偿还 |
三、基本面数据(4 张表)
| 表名 | 模型 | 主键/唯一键 | 更新频率 | 说明 |
|---|---|---|---|---|
finance_report | — | 已删除 | 原核心财务指标表,与 sina_financial_indicator 同源(均为新浪 API),冗余中间表。融合器已改为直接读取 sina_financial_indicator(主源)+ tdx_finance_snapshot(兜底)。ORM + DDL + 前端映射已移除 | |
sina_financial_statement | FinancialStatement | (code, report_period) | 季报发布后 | 三表数据(资产负债表/利润表/现金流量表) |
financial_indicator | FinancialIndicator | (code, report_period) | 季报发布后 | 扩展财务指标(30+字段),现为 fox_finance_indicator 融合器唯一主源 |
stock_issue_info | StockIssueInfo | (code) | 不定期 | 发行信息(发行价/发行量/承销商等) |
stock_holding_org | StockHoldingOrg | (code, report_period) | 季报发布后 | 机构持股汇总(基金/券商/保险等) |
四、事件数据(9 张表)
| 表名 | 模型 | 主键/唯一键 | 更新频率 | 说明 |
|---|---|---|---|---|
cninfo_announcement | Announcement | (title, pub_date) | 每日 | 公司公告(标题/类型/PDF链接) |
stock_news | — | 已删除 | 新闻维度已由 fox_news 融合表(纯 API 驱动)统一管理;ORM/DDL 先行移除,物理表残留 10 行于 2026-08-22 DROP | |
em_research_report | ResearchReport | (code, publish_date, org) | 每日 | 券商研报(评级/目标价/摘要) |
em_dragon_tiger | DragonTiger | (code, date, trade_type) | T+1 晚间 | 龙虎榜(买卖席位/金额) |
em_block_trade | BlockTrade | (code, date) | T+1 晚间 | 大宗交易(成交价/数量/买卖方) |
em_dividend_history | DividendHistory | (code, ex_date) | 不定期 | 分红送转历史 |
em_lockup_expiry | LockupExpiry | (code, date) | 不定期 | 限售解禁预告 |
em_holder_num | HolderNum | (code, date) | 季报/年报后 | 股东人数变化 |
em_concept_block | ConceptBlock | (code, block_name) | 不定期 | 概念板块归属 |
五、股东与预测(6 张表)
| 表名 | 模型 | 主键/唯一键 | 更新频率 | 说明 |
|---|---|---|---|---|
em_top_float_holder | TopFloatHolder | (code, report_period, rank) | 季报后 | 十大流通股东明细 |
em_earnings_forecast | EarningsForecast | (code, report_period, org) | 不定期 | 分析师盈利预测 |
em_earnings_express | EarningsExpress | (code, report_period) | 季报前 | 业绩快报(预告) |
em_executive_holding | ExecutiveHolding | (code, change_date, name) | 不定期 | 高管持股变动 |
em_org_survey | OrgSurvey | (code, survey_date, org) | 不定期 | 机构调研记录 |
em_fund_holding | FundHolding | (code, report_period, fund_code) | 季报后 | 基金持仓明细 |
六、量化数据(6 张表)
| 表名 | 模型 | 主键/唯一键 | 更新频率 | 说明 |
|---|---|---|---|---|
fox_stock_indicators_daily | FoxStockIndicatorsDaily | (code, date) | T+1 日终 | 技术指标日频(MACD/RSI/BOLL等,fox 引擎统一管理) |
fox_stock_pattern_daily | FoxStockPatternDaily | (code, date) | T+1 日终 | K线形态识别(锤子线/吞没等单根组合 + 老鸭头/圆弧底/杯柄/双底结构形态,见 services/quant/structural_patterns.py;fox 引擎统一管理) |
fox_stock_cyq_daily | FoxStockCyqDaily | (code, date) | T+1 日终 | 筹码分布(获利盘/套牢盘/集中度) |
fox_indicator_signal_pool | FoxIndicatorSignalPool | (code, date, signal_type) | T+1 日终 | 多指标共振信号池(超买/超卖二次筛选) |
em_stock_selection_daily | StockSelectionDaily | (code, date) | T+1 日终 | 东财选股器全市场宽表(selection_sync 任务写入,约 200 指标的高价值子集) |
fox_strategy_pick_daily | FoxStrategyPickDaily | (code, date, strategy) | T+1 日终 | 策略精选标的(fox 引擎统一管理) |
七、基础与配置(5 张表)
| 表名 | 模型 | 主键/唯一键 | 更新频率 | 说明 |
|---|---|---|---|---|
fox_stock_master | FoxStockMaster | (code) | 每日/手动 | 全A股主数据(融合表;原 stock_base_info 149 字段 ODS 表已于 2026-08-22 移除) |
fox_stock_f10_info | FoxStockF10Info | (code) | 不定期 | F10 公司概况(成立日期/简介/主营/34字段)。业务读取已收敛至 fox_company_profile(仅 fuser 输入保留) |
app_portfolio_stocks | PortfolioStock | (id) | 实时 | 自选股持仓管理 |
app_sync_log | SyncLog | (id) | 每次操作 | 数据同步操作日志(兼容层,以 app_task_run 为准) |
app_config | SysConfig | (config_key) | 运行时 | 系统配置键值存储 |
已退役:
stock_info(早期遗留表,2026-08-22 删除);stock_base_info(149 字段 TDX 全量导出表, 2026-08-22 移除,读取统一走fox_stock_master/fox_stock_wide,写入侧仅存 410 兼容端点)。
数据更新频率与时效性
| 数据类型 | 最佳更新时机 | 时效窗口 | 过期判定 |
|---|---|---|---|
| 日K线/行情/估值/资金流 | 交易日 15:05 | T 或 T-1 | > T-1(交易日)/ > T-3(周末) |
| 融资融券 | 交易日 08:30 | T-1 | > T-1 |
| 龙虎榜/大宗交易/公告 | 交易日 18:30 | T | > T-1 |
| 财务报告/指标/股东 | 季报发布日 | 最新季报 | 下一季报发布后 |
| 新闻/研报 | 持续更新 | 当天 | > 3 天 |
| 量化指标/选股 | 交易日 16:30-17:30 | T | > T-1 |
时效性检查接口:GET /datamgr/stats/freshness
数据存储最佳实践
UPSERT 策略
绝大多数下载器采用"查 → 有则更新,无则插入"模式,核心表使用 MySQL INSERT ... ON DUPLICATE KEY UPDATE:
- K线/行情/资金流:按 (code, date) 唯一键 UPSERT,同一天多次下载不产生重复行
- 公告/新闻:按 (title, pub_date)/(title, pub_time) 去重,防止历史数据重同步时 duplicate key
- 分钟K线:MySQL 原生批量 UPSERT(100条/批),
(code, bar_time, period)唯一键
Session 管理
下载器统一使用 _require_db() context manager:
with _require_db() as db:
if db is None:
return {"status": "failed", "message": "数据库不可用"}
# ... 查询/写入操作 ...
重试机制
下载器的外部 API 调用通过 downloaders/base.py::_with_retry() 包装:按异常文本关键字(timeout/connection/reset/refused/network/dns/temporary/too many)判定可重试,最多重试 2 次,等待 (attempt+1) × 2s(即 2s → 4s)。
数据校验
download_quote: 校验 price ∈ [0.01, 10000]、change_pct ∈ [-20, 20],异常值记录 warning 不阻塞写入FoxKlineDaily.adj_factor: 默认 1.0 标记"未复权",为后续前复权计算预留接口(原KlineDaily已迁移至此,date 字段改为 String(10) YYYY-MM-DD 格式)
增量迁移
database.py 的 _migrate_add_columns() 在启动时幂等检测并添加缺失字段(如 adj_factor),避免手动 ALTER TABLE;_migrate_add_indexes() 同步补齐存量表新增索引(inspector 查缺后 CREATE INDEX,MySQL 无 IF NOT EXISTS 语法;create_all 对已存在表不补索引,须显式迁移),两者均挂接 ensure_tables() 启动流程,backend/init_db.sql DDL 保持一致。
已落地的索引迁移:idx_fox_kline_daily_updated_at(fox_kline_daily(updated_at),2026-08-22)——/datamgr/stats 对每张表查 MAX(updated_at)(queries.py),fox_kline_daily 数十万行无索引时全表扫描拖慢数据管理页,加索引后聚合查询走覆盖扫描。
多源数据治理层(fox_ 前缀)
用于规范化管理多数据源(腾讯/TDX/东财/同花顺/新浪/巨潮等)获取的数据,与各源落地表(em_/ths_/tencent_/tdx_/cninfo_/sina_)解耦。整体分两层:
- 治理层(6 张):数据源注册表/代码映射/同步任务/ETL 批次/获取记录/质量记录,专注元数据、血缘与质量治理。
- 融合层(DWD)(21 张,
fox_engine/writer/registry.py::FOX_FUSERS一一对应):个股维度 12 张 ——fox_stock_master/fox_company_profile/fox_finance_indicator/fox_valuation/fox_industry/fox_holder/fox_dividend/fox_dragon_tiger/fox_margin/fox_block_trade/fox_announcement/fox_news;时序与市场维度 7 张 ——fox_kline_daily/fox_kline_bar/fox_index_daily/fox_industry_index_daily/fox_stock_wide/fox_market_daily/fox_market_dpyt;宏观维度 2 张 ——fox_macro_indicator(多源宏观指标:当期值 +trend_json历史序列,国内多源与东财海外混装)由 16:15macro_sync产出、fox_macro_release(宏观数据发布日历:国内按发布规则推算发布日并标schedule_basis="rule",海外取东财真实PUBLISH_DATE)由 16:25macro_calendar_sync产出,日历必须晚于指标(国内事件的 actual/previous 是零 HTTP 读fox_macro_indicator回填的)。由backend/app/services/fox_engine/统一数据引擎(写路径writer/一融合类型一条注册声明 + 通用执行器run_fuser,读路径engine.py分级 TTL 缓存)对多个源表做交叉验证后 UPSERT 写入;应用读取优先走融合层(如stock_service.get_stock_base_info先查 fox_ 表,命中则跳过实时回退,省网络请求)。时序融合层(fox_index_daily/fox_kline_bar/fox_kline_daily)仅承载日级及以上低频 K 线,分钟级/盘中 bar 不纳入。fox_market_dpyt(大盘云图个股快照,JRJ dpyt 行业树 + 全市场 6 列行情)。另有市场级旁路表:fox_market_snapshot(5 类盘后定型快照)、fox_market_turnover_daily(两市成交额逐日累积)、social_sentiment_daily(个股社交情绪日快照,纯本地源离线优先),以及列式的fox_market_daily(总成交额/主力净流入/涨跌停/市场宽度,日终定型),均由fox_market_data.py统一读写。
应用读取切换清单(按“融合表字段覆盖度 ≥ 原读取链路”逐类切换,未覆盖回退原链路):
| 读取链路 | 切换后行为 | 状态 |
|---|---|---|
stock_service.get_stock_base_info | 先查 fox_stock_master/fox_company_profile,命中跳过实时回退 | ✅ 已切换(首批) |
stock_service 财务指标 | 先查 fox_finance_indicator | ✅ 已切换(首批) |
signal_layer.holder_num_change(股东户数) | fox_holder 优先,未覆盖回退东财 datacenter → 同花顺 F10 | ✅ 已切换(本批) |
api/portfolio /holdings 持仓分红 | fox_dividend 优先,未覆盖回退 DividendHistory 源表 | ✅ 已切换(本批) |
ai_tools.tools_market 个股新闻工具 | 统一走 fox_news 融合表(stock_news 已删除) | ✅ 已切换 |
portfolio_analytics 估值分位分析 | 已切换至 FoxValuation 融合表 | ✅ 已切换 |
KLineSection 周期 K(周/月/季/年) | 优先读 /datamgr/fox/stock/{code}/kline-bar(fox_kline_bar,腾讯前复权真实周期 K, | ✅ 已切换(2026-08-19) |
signal_layer.margin_trading(两融) | 保留东财实时链(fox_margin 缺 rzche/rqmcl/rqchl 三字段,前端契约覆盖度不足) | ❌ 不切换 |
signal_layer.dragon_tiger_board(龙虎榜) | 保留东财实时链(fox_dragon_tiger 缺买卖席位/机构统计明细) | ❌ 不切换 |
| 公告展示 | 无存量应用读取点(仅 fox 端点 /datamgr/fox/stock/{code}/announcements) | ➖ 无需切换 |
模型定义见 backend/app/models/fox_models.py,data_type 与 fallback_registry.py 的 key 对齐,source_code 与数据源铁律(AGENTS.md)对齐。
八、多源治理(30 张表)
治理层 6 张:
| 表名 | 模型 | 主键/唯一键 | 说明 |
|---|---|---|---|
fox_data_source | FoxDataSource | (source_code) | 数据源注册表:元数据/优先级(1a=10/1b=20/2=30/3=40)/风控等级 |
fox_code_map | FoxCodeMap | UNIQUE(source_code, source_symbol) | 证券代码跨源映射:标准6位码 ↔ 东财secucode/腾讯qtcode/TDX市场号/巨潮orgId |
fox_sync_task | FoxSyncTask | (id) | 同步任务日志(增强版 app_sync_log,补充数据源/数据类型/批次) |
fox_data_batch | FoxDataBatch | UNIQUE(batch_id) | ETL 批次管理(一次批量同步的元数据;trigger_type ∈ manual/scheduled/api,对应手动 /fox/sync、定时 fox_daily_sync、下载后自动触发三类入口,batch_id 贯穿下游任务与落库血缘) |
fox_data_record | FoxDataRecord | (id) | 数据获取记录:降级链实际执行轨迹(谁提供→落哪张表→是否降级→耗时);batch_id 关联批次,target_table 由融合器模型推导,支撑“下载批次 → 融合任务 → 落库表”血缘审计 |
fox_data_quality | FoxDataQuality | (id) | 数据质量记录:断档检测/完整性/时效性/字段校验结果落库(含融合交叉验证冲突) |
融合层(DWD)21 张(与 FOX_FUSERS 一一对应,个股 12 + 时序/市场 7 + 宏观 2):
| 表名 | 模型 | 主键/唯一键 | 说明 |
|---|---|---|---|
fox_stock_master | FoxStockMaster | (code) | 融合层:股票主数据(简称/全称/行业/地域/上市日期/股本/员工数/股东数),主源 TDX 证券列表 + 腾讯行情 + TDX 财务快照,交叉源 tdx_finance_snapshot/fox_stock_f10_info/ths_f10_profile |
fox_company_profile | FoxCompanyProfile | (code) | 融合层:公司概况(主营/注册资本/法人/网站/地址/介绍),主源 fox_stock_f10_info,次源 ths_f10_profile |
fox_finance_indicator | FoxFinanceIndicator | (code, report_period) | 融合层:财务指标(营收/净利/毛利率/ROE/EPS 等),主源 sina_financial_indicator(items_json),兜底源 tdx_finance_snapshot,每股指标保留近 8 期 |
fox_valuation | FoxValuation | (code) | 融合层:估值快照(PE/PB/总市值/最新价),主源 fox_quote_snapshot,扩展字段 pe_fwd/peg/eps_cur/eps_next/cagr_pct/analyst_count 来自 calc_valuation() API;snapshots_json 列存储近 20 日估值快照数组(供 get_valuation 历史序列),PE/PB 负值(亏损股)记质量日志不升行级 |
fox_industry | FoxIndustry | (code) | 融合层:行业归属多口径(腾讯一级 industry 主源 TDX 证券列表 + 东财 em_industry + 通达信 tdx_industry + 申万代码 sw_l1/sw_l2);sw_l1/sw_l2 只存申万代码(801010/801012),名称映射走 sw_index_meta,代码列禁写名称;主源纯数字/缺失时次源兜底记 warning |
fox_holder | FoxHolder | (code, date) | 融合层:股东户数历史(东财 em_holder_num 全历史主源 + tdx_finance_snapshot 最新期补充),单位:户/股 |
fox_dividend | FoxDividend | (code, ex_date) | 融合层:分红送转历史(主源 em_dividend_history),bonus_rmb 每 10 股派息口径(源表每股 ×10),负值置空记质量日志 |
fox_dragon_tiger | FoxDragonTiger | (code, date, reason) | 融合层:龙虎榜事件(东财 em_dragon_tiger 主源 + 同花顺 ths_f10_lhb 横向补充 close/next_change_pct/buy_amt/sell_amt),net_buy 单位为万元,同日多上榜原因可共存 |
fox_margin | FoxMargin | (code, date) | 融合层:融资融券日级(东财 em_margin_trading 主源 + 同花顺 ths_f10_rzrq 交叉验证 rzye/rzrqye、补充 fin_ratio_pct/loan_volume),金额单位为元 |
fox_block_trade | FoxBlockTrade | (code, date, buyer, seller, price, volume) | 融合层:大宗交易事件(东财 em_block_trade 主源 + 同花顺 ths_f10_dzjy 横向补充 close/premium_pct),金额单位为元;价量无效跳过记质量日志 |
fox_announcement | FoxAnnouncement | (code, pub_date, title) | 融合层:公告事件(巨潮 cninfo_announcement 主源单源标准化,备源 szse_official/em_announcement 待接入),标题/日期任一为空无法构成主键则跳过记质量日志 |
fox_news | FoxNews | (code, pub_time, title) | 融合层:个股新闻(eastmoney API 主源透传 news + ths_f10_news 同花顺研报 JSON 展开补录 research,标题等价去重),研报带 rating/researcher。纯 API 驱动,不依赖 stock_news ODS 表 |
fox_index_daily | FoxIndexDaily | (code, date) | 时序融合层:大盘指数日线(腾讯 HTTP 主源 tencent_kline(period=day) 不复权,核心清单 index_code_map() 18 只:A股 14 + 恒生/道指/纳指/标普),volume 为指数口径股/手 |
fox_kline_bar | FoxKlineBar | (code, period, date) | 时序融合层:多周期 K 线(腾讯 HTTP 主源前复权,period 仅 week/month 直接拉取各 240 根,quarter/year 由月线内存聚合),日 K 走 fox_kline_daily,分钟级不纳入;全市场同步上限 _KLINE_BAR_FULL_MARKET_LIMIT=6000 |
fox_kline_daily | FoxKlineDaily | (code, date) | 时序融合层:日 K 线(腾讯 HTTP 前复权主源),quant_calc 三类指标的计算底表 |
fox_industry_index_daily | FoxIndustryIndexDaily | (class_system, industry_code, date) | 时序融合层:申万行业指数日线(官方 index_publish 主源,class_system ∈ sw_l1/sw_l2,一级 31 + 二级 124;OHLC 为官方点位、amount_yi 取官方 bargainsum 亿元、pct_chg 取官方 markup),行业成交额占比/历史分位底表 |
fox_stock_wide | FoxStockWide | (code) | 快照宽表:全市场行情+估值单行宽表(TDX 证券列表/财务 + 腾讯批量行情),行情中心、榜单 L1、selection_sync 的上游 |
fox_market_daily | FoxMarketDaily | (date) | 市场级:总成交额/主力净流入/涨跌停/市场宽度(JRJ + TDX,日终定型,列式) |
fox_market_dpyt | FoxMarketDpyt | (code, date) | 市场级:大盘云图个股快照(JRJ dpyt 行业树 + 全市场 6 列行情) |
fox_macro_indicator | FoxMacroIndicator | (scope, indicator) | 融合层:宏观指标最新一期(国内 macro_china/macro_data/bond_yield_sources 多源 + 海外东财 RPT_ECONOMICVALUE_*,9 个 scope 域批量)。🔴 取「最新已公布」期而非 series[-1](东财为下一场会议预建空值排期行,实测 107 项里 60 项的最新行是它);快照式覆盖写、不做增量跳过判断 |
fox_macro_release | FoxMacroRelease | (scope, indicator, period_key) | 融合层:宏观发布日历。国内发布日按稳定规律推算(schedule_basis="rule",前端标「预计」)、海外取东财真实 PUBLISH_DATE。🔴 主键是数据期而非发布日:规则修正须原地改同一行,否则旧错日期永远洗不掉;actual/previous 零 HTTP 读 fox_macro_indicator 回填,fill_only_cols 保证人工备注不被更新分支清掉 |
fox_macro_history | FoxMacroHistory | (scope, indicator, as_of) | 融合层:国内月/季频宏观指标的长历史(CPI/PMI/M2 2008 起、PPI/GDP 2006 起),驱动判读回放与「宏观维度 × 行业暴露」矩阵——fox_macro_indicator 每指标只留近 36 期,回放深度它给不出。🔴 三条口径:① 列名/取值全部复用 macro_indicator._INDICATOR_DEFS(另写一份映射早晚「快照一个值、历史另一个值」);② 日频不落、不足 3 期不落(判读层对日频只回看 5 期,20 年日频换不来回放样本),落库前按 DECIMAL(20,6) 量化,否则每晚把 36 行判成"修订";③ 读路径合并同日期以快照为准、历史只 prepend「严格早于快照最早一期」的那一段——往快照窗口中间插点会动到判读的比较基准,等于第二个写入者改当日结论 |
旁路 3 张:fox_market_snapshot(5 类盘后定型快照)、fox_market_turnover_daily(两市成交额逐日累积)、social_sentiment_daily(个股社交情绪日快照)。
融合引擎(fox_engine)
统一数据引擎位于 backend/app/services/fox_engine/,按"一融合类型一条注册声明对应一张 fox_ 表"组织(FOX_FUSERS 声明式注册,21 条):
- 写路径(ETL)
fox_engine/writer/:base.py(工具原语_cross_text/_cross_number+upsert_rows+run_fuser通用执行器,含空交付判定与 200 只/次进度回写)、fusers/(21 个融合器模块,每模块对应一张 fox_ 表,另有_raw_heal.py事件类 RAW 过期自愈、_em_fallback.py东财兜底)、registry.py(FOX_FUSERS声明式注册表 +sync_*入口 +get_fox_status)、batch.py(open/close_fox_batch批次血缘)、freshness.py(股票级新鲜度过滤,跳过已达最近交易日数据的股票)、seeds.py(seed_data_sources数据源注册表幂等播种)、db.py(SessionLocal/db_available 单一 DB 接入点,测试可 patch)。 - 读路径(调用)
fox_engine/engine.py:FoxDataEngine实现FoxDataProviderProtocol(interface.py),分级 TTL 进程缓存(估值 300s / 财务主数据 600s / 事件类 1800s / 静态类 3600s),invalidate()供写路径完成后清缓存。 - 统一调用(独立数据引擎服务面)
fox_engine/interfaces.py+call.py:FOX_INTERFACES接口注册表(183 个接口声明式元数据:名称/维度/参数/返回结构/TTL/读写属性,与 Protocol 一一对应)+call(interface, **params)统一动态调用(Tushare pro.xxx 模式)+interface_catalog()能力清单(machine-readable,供外部应用自发现)+call_stats()接口级调用统计。exceptions.py定义引擎异常体系(FoxEngineError→UnknownInterfaceError/InvalidParameterError/InterfaceNotAllowedError/DataUnavailableError),call()严格模式与引擎静默降级并存:参数/接口错误抛异常,数据异常保持返回空值(兼容现有消费方)。 - 门面
fox_engine/__init__.py:fox全局单例 +call/interface_catalog/call_stats+ 写路径 re-export,消费方统一from app.services.fox_engine import fox(依赖抽象而非实现)。 - 市场级接口
fox_market_data.py:盘中实时(TDX TCP)→ 盘后fox_market_daily自动路由。
交叉验证与质量:
- 交叉验证原语:
_cross_text(去空白/全角转半角/一端包含另一端判等价)、_cross_number(相对容差 1%~5%,比值 >10 倍判主源数量级异常反取次源)。 - 质量记录:冲突/异常写
fox_data_quality(check_type=validation),同 code 同字段同日去重。 - 融合器要点:valuation(腾讯 quote 主 + 东财估值扩展)、industry(行业多口径,sw_l1/sw_l2 只写代码)、holder(东财全历史 + TDX 最新期补充)、dividend(每股 → 每 10 股单位换算)、dragon_tiger(东财主源 + 同花顺数据中心横向补充)、margin(东财主源 + 同花顺交叉验证)、block_trade(东财主源 + 同花顺横向补充,价量无效跳过)、announcement(巨潮单源标准化,备源待接入)、news(东财新闻主源 + 同花顺研报补录,标题去重)、industry_index(申万官方直拉,已追平最近交易日则跳过 HTTP)、macro_indicator(9 个 scope 域批量、取最新已公布期)、macro_release(国内规则推算 + 海外真实排期,主键为数据期);
sync_all()依次执行FOX_FUSERS全部 21 个融合类型,幂等 UPSERT,fox_data_source种子含 11 源(tencent/tdx/eastmoney/ths/sina/cninfo/baidu/sse/szse/cls/jrj)。 - 幂等:MySQL
ON DUPLICATE KEY UPDATE批量 UPSERT(500 条/批),可随时重跑。 - 触发方式:①
POST /api/v1/datamgr/fox/sync(全量/指定 codes,trigger_type=manual);② 下载自动触发——download_stock_all/download_batch完成后按本次下载类型映射(_FOX_FUSION_BY_TASK,44 下载类型 → 14 融合类型,无映射类型跳过)自动调sync_by_types融合对应类别,trigger_type=api,结果入results["fox_fusion"],失败不影响下载;③ 定时任务按数据源域拆三个(trigger_type=scheduled,均幂等可重复、由fox_stock_master枚举全市场代码、带股票级新鲜度过滤)——fox_kline_sync15:40 K线域、fox_daily_sync16:00 事件+市场+估值域(13 类)、fox_wide_sync16:20 快照宽表域;④GET /api/v1/datamgr/fox/status查看状态。三类入口均自动创建批次(open_fox_batch/close_fox_batch),batch_id 贯穿fox_sync_task与fox_data_record。
建表方式:database/init.sql 与 backend/init_db.sql 均含 DDL 与数据源种子数据;应用启动时 ensure_tables() 亦会自动 create_all(幂等)。
无前缀生产表与 fox_ 融合层的关系
无前缀表(sina_*/tdx_*/cninfo_*/stock_* 等)为 ODS 源表(早期单源架构产物,命名沿用历史),承担 fox_ 融合层的主源/次源角色,不可移除(移除则重融合无源可取)。quote_snapshot/fund_flow_daily 已更名至 fox_quote_snapshot/fox_fund_flow_daily(fox 引擎统一命名与管理):
| ODS 源表 | fox_ 融合表 | 角色 |
|---|---|---|
| stock_f10_info→fox_stock_f10_info | fox_company_profile | 主源(业务读取已收敛至 fox 门面) |
| sina_financial_indicator | fox_finance_indicator | 主源(items_json 包含全部 8 个融合字段) |
| tdx_finance_snapshot | fox_finance_indicator | 兜底源 |
| fox_quote_snapshot | fox_valuation | 估值主源(业务读取已收敛至 fox 门面)。注意:该表按需逐股写入,当日通常仅 3~7 行,不可用于全市场榜单/分布类聚合(2026-09-10 涨幅榜改造已移出该表) |
| cninfo_announcement | fox_announcement | 主源 |
| fox_kline_daily | 已删除(2026-08-22 DROP,代码已全量迁移至 fox_kline_daily 融合表,数据由腾讯 HTTP 融合器/下载器直接写入 fox_kline_daily) |
读取面接管说明:主数据/公司概况/估值快照的业务读取面已被 fox 融合层接管——应用读取统一走 fox 门面(fox.get_valuation/fox.get_stock_profile 等),门面内部以 fox_ 融合表优先、源表兜底。stock_base_info 已整体移除(2026-08-22,149 字段 TDX 全量导出表),其原有职责由 fox_stock_master + fox_stock_wide 承担,data_manager/stock_base.py 的导入/同步函数与 /datamgr/stock-base/* 写端点保留签名但恒返回 deprecated。财务数据读取统一走 fox.get_finance,门面内部以 fox_ 融合表优先、sina_financial_indicator 兜底(7 天新鲜度窗口)。源表现在仅承担两项职责:上游输入(data_manager 下载器持续喂数据)与兜底(fox 融合层未覆盖/不足时回读),业务层不再直接查询源表。
全市场榜单读取口径(2026-09-10 涨幅榜改造):hot_stocks(首页/市场看板「涨幅榜」)统一为全市场涨幅榜 TOP N 口径,降级链:L1 fox_stock_wide(全市场宽表,updated_at >= 最近交易日 新鲜度门禁 + 有效行数 ≥ 1000)→ L2 腾讯全市场实时批量(tencent_market_top_gainers,约 10 批次,进程内 5 分钟/休市 30 分钟缓存,不依赖盘后任务)→ L3 fox_quote_snapshot(自选/被查看股票样本榜)→ L4 东财涨幅榜 → L5 雪球人气榜(口径不同,响应带 source_label 显性标注,前端按口径切换标题)。fox_quote_snapshot 因"按需逐股写入、当日仅数行"不再承担该榜单主源。
fox 融合空交付判定(2026-09-10):run_fuser 在"候选集非空却 0 行落库"时记 failed + 质量记录(empty_delivery),不再静默 success。此前 fox_stock_wide 于 2026-09-09 15:29 任务记录 success 但 success=0,导致 sched.fox_wide_sync.last_success_date 被标记为当日、错过补跑机制不再重试,宽表实际停更 16 天(2026-08-25 → 2026-09-10 手工复跑恢复 5568 行)。配套修复:TDX 批量财务的逐只回退增加连续失败熔断(_FINANCE_FALLBACK_MAX_STREAK=5)、故障冷却期内 _find_data_returning_host 快速返回 None——全市场宽表融合由实测 314s 降到 50s(同源只拉取一次)。
退役表:finance_report(核心财务指标,2026-08-22 删除)— 与 sina_financial_indicator 同源(均为新浪 API),finance_report 只是对新浪数据做了字段名映射后的冗余落库。融合器已改为直接读取 sina_financial_indicator(items_json 包含全部 8 个字段)+ tdx_finance_snapshot 兜底。ORM + DDL + 前端映射 + 下载器已移除。valuation_snapshot(估值日级快照,2026-08-22 删除)— 估值维度已由 fox_valuation 融合表统一管理,扩展字段(pe_fwd/peg/eps_cur/eps_next/cagr_pct/analyst_count)改由 calc_valuation() API 直接获取,不再写入/读取 ODS 表。ORM + DDL + 前端映射已移除。stock_news(个股新闻快照,2026-08-22 删除)— 新闻维度已由 fox_news 融合表统一管理,东财新闻主源改由 eastmoney_stock_news() API 直接获取(纯 API 驱动),不再写入/读取 ODS 表。ORM + DDL + 前端映射已移除。market_snapshot(通用快照持久层,2026-08-22 退役)— 5 类盘后定型数据(sentiment/distribution/industry_rank/hot_stocks/sector_treemap)已迁移至 fox_market_snapshot(date+data_type 双主键,fox 层统一管理),fund_flow 由 fox_market_daily 列式接管。业务读写统一走 fox.get_market_snapshot / fox.persist_market_snapshot 门面。announcement(无前缀旧表,ORM 更名 cninfo_announcement 前遗留,代码零引用、无 DDL)已于 2026-08-19 将 10 行数据迁移至 cninfo_announcement 并融合进 fox_announcement 后 DROP;fund_flow_daily 已更名 fox_fund_flow_daily(2026-08-22 fox 引擎统一管理),量化 5 表(stock_indicators_daily 等)无 fox 对应,保留原链路。cls_telegram(财联社快讯,早期落库设计;电报已改 cls_telegraph.py 实时接口不落库,代码零引用、表 0 行)已于 2026-08-21 清理(backend/init_db.sql DDL + db_models.py ORM + 前端 tableNames 死映射 + DROP TABLE)。kline_daily(日K线 ODS 表,2026-08-22 DROP)— 代码已全量迁移至 fox_kline_daily(ORM FoxKlineDaily),融合器从腾讯 HTTP 拉取前复权日K线直接写入 fox_kline_daily,下载器亦直接写入本表,旧表 47670 行历史数据无需迁移(腾讯 API 可随时重拉)。DDL + ORM 已移除。