因子平台直接消费基座的视图
Go to file
zlt 3fb25fe1ad 候选卡加论断质量标注:陈旧度、来源集中、疑似误抽、未结分歧
这四项都只在卡上提示,不参与三门槛判决。

起因是同一张卡上的双标:吸筹评分超过三十个交易日就判陈旧,而研报论断此前
只有"披露日不晚于数据日"这一个上界,永不过期。09-03 实测 442 只带论断的票,
论断披露日中位 05-05,超过 90 天的 166 只(37.6%),超过一年的 22 只——这些
论断会原样打印成理由,读的人看不出它已经很旧了。

另外三项同样来自当日实测:267 只票带多条论断,其中 77 只(29%)的论断全部
出自同一份研报,那份研报一旦过时或本身有偏,这票的整条研究证据一起失效;
213 条被逻辑评析标为疑似误抽;未结的方向分歧当日是 0 条但视图里有这一列。

改动三处:
- sources.py 多取 disputed 与 review_flag 两列,并在按票截断之前算质量画像。
  必须在截断前算——截断后只剩最近三条,"这票一共几份来源"就统计不出来了。
- card.py 把画像转成缺失项里的提示文字,另出一个 logic_quality 键供下游用。
- config.py 加陈旧线 LOGIC_STALE_DAYS,默认 90 天,写明与吸筹日龄上限的可比关系。

测试:候选卡 14 例、取数层 9 例,本地全套通过(test_xxl_trigger 缺 fastapi 是
本机环境所致,与本次改动无关)。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-04 08:59:11 +08:00
.idea 初始化提交 2026-07-24 14:20:54 +08:00
config 原六个加脑机接口、氢能、深海科技、固态电池;太空光伏收进商业航空航天 2026-07-31 09:20:44 +08:00
docs 方案同步:09-03 进度小结、论断来源集中与 PMS 缺两个键两条新核实、调度待办 2026-09-03 17:23:35 +08:00
sql 数据基座因果论断与研判结论两张只读视图(v_factor_logic、v_factor_judgement),09-03 已在基座库建成 2026-09-03 11:35:57 +08:00
.DS_Store 候选卡加论断质量标注:陈旧度、来源集中、疑似误抽、未结分歧 2026-09-04 08:59:11 +08:00
.env.example 选股计划入池逻辑 2026-08-03 14:02:13 +08:00
.gitignore 历史深度数据探查 2026-07-27 09:49:05 +08:00
CLAUDE.md 选股系统接通分析结论:候选卡读因果论断作证据线、关注判决细化为系统无法判断、计划环境段加市场四项、入池上下文补证据字段、复盘加四份名单与三套对照台账对表两节 2026-09-03 11:44:16 +08:00
Dockerfile 初始化提交 2026-07-24 14:20:54 +08:00
README.md 选股系统:日频行业观点快照与覆盖率读数 2026-09-03 16:07:02 +08:00
api.py 选股系统接通分析结论:候选卡读因果论断作证据线、关注判决细化为系统无法判断、计划环境段加市场四项、入池上下文补证据字段、复盘加四份名单与三套对照台账对表两节 2026-09-03 11:44:16 +08:00
apply_views.py 历史深度数据探查 2026-07-27 10:03:45 +08:00
card.py 候选卡加论断质量标注:陈旧度、来源集中、疑似误抽、未结分歧 2026-09-04 08:59:11 +08:00
chain_diag.py 产业链细化逻辑 2026-08-05 10:24:44 +08:00
common.py 选股系统接通分析结论:候选卡读因果论断作证据线、关注判决细化为系统无法判断、计划环境段加市场四项、入池上下文补证据字段、复盘加四份名单与三套对照台账对表两节 2026-09-03 11:44:16 +08:00
config.py 候选卡加论断质量标注:陈旧度、来源集中、疑似误抽、未结分歧 2026-09-04 08:59:11 +08:00
db.py 选股计划入池逻辑 2026-08-03 14:02:13 +08:00
docker-compose.yml 计划 API:桥容器常驻改 uvicorn(:8300),GET /plan 取每日选股计划; 2026-07-30 14:09:02 +08:00
factors.py 处理选股方案,目的是和数据底座一致 2026-08-17 15:27:45 +08:00
freeze.py 选股系统接通分析结论:候选卡读因果论断作证据线、关注判决细化为系统无法判断、计划环境段加市场四项、入池上下文补证据字段、复盘加四份名单与三套对照台账对表两节 2026-09-03 11:44:16 +08:00
judgement.py 选股系统:日频行业观点快照与覆盖率读数 2026-09-03 16:07:02 +08:00
judgement_coverage.py 选股系统:日频行业观点快照与覆盖率读数 2026-09-03 16:07:02 +08:00
plan.py 候选卡加论断质量标注:陈旧度、来源集中、疑似误抽、未结分歧 2026-09-04 08:59:11 +08:00
plan_reconcile.py 处理pms系统对接 2026-08-18 16:01:40 +08:00
plan_review.py 选股系统接通分析结论:候选卡读因果论断作证据线、关注判决细化为系统无法判断、计划环境段加市场四项、入池上下文补证据字段、复盘加四份名单与三套对照台账对表两节 2026-09-03 11:44:16 +08:00
pool.py 选股系统接通分析结论:候选卡读因果论断作证据线、关注判决细化为系统无法判断、计划环境段加市场四项、入池上下文补证据字段、复盘加四份名单与三套对照台账对表两节 2026-09-03 11:44:16 +08:00
probe.py probe: corr 节去 scipy 依赖,修 07-30 首跑崩点 2026-07-30 10:00:55 +08:00
regime.py 选股系统接通分析结论:候选卡读因果论断作证据线、关注判决细化为系统无法判断、计划环境段加市场四项、入池上下文补证据字段、复盘加四份名单与三套对照台账对表两节 2026-09-03 11:44:16 +08:00
requirements.txt 选股计划入池逻辑 2026-08-03 14:02:13 +08:00
run.py 选股系统:日频行业观点快照与覆盖率读数 2026-09-03 16:07:02 +08:00
score_lab.py 处理选股方案,目的是和数据底座一致 2026-08-17 15:27:45 +08:00
sources.py 候选卡加论断质量标注:陈旧度、来源集中、疑似误抽、未结分歧 2026-09-04 08:59:11 +08:00
test_card.py 候选卡加论断质量标注:陈旧度、来源集中、疑似误抽、未结分歧 2026-09-04 08:59:11 +08:00
test_judgement_snapshot.py 选股系统:日频行业观点快照与覆盖率读数 2026-09-03 16:07:02 +08:00
test_market_context.py 候选卡加论断质量标注:陈旧度、来源集中、疑似误抽、未结分歧 2026-09-04 08:59:11 +08:00
test_plan_verdict.py 处理pms系统对接 2026-08-18 16:01:40 +08:00
test_pool_logic.py 选股系统接通分析结论:候选卡读因果论断作证据线、关注判决细化为系统无法判断、计划环境段加市场四项、入池上下文补证据字段、复盘加四份名单与三套对照台账对表两节 2026-09-03 11:44:16 +08:00
test_regime.py 候选卡上线第一批:计划装配联入判决与证据线、当日 JSON 快照带版本戳、候选单与关注环节两节;接口顶层加 generated_at/plan_version/regime/snapshot 与访问日志(主榜观察档装配排序裁剪不动);取数层 sources.py;环境标签 regime.py 只展示分组;调度加 regime-append 步骤;入池加来源标记、切片与候选优先开关(默认关);方案文档同步 2026-09-02 16:39:52 +08:00
test_xxl_trigger.py 通过调度系统接入 2026-08-03 16:33:23 +08:00
tracks.py 原六个加脑机接口、氢能、深海科技、固态电池;太空光伏收进商业航空航天 2026-07-31 09:20:44 +08:00
version.py 候选卡判决模块与离线单测;候选卡三张只读视图 SQL(独立文件);.git 文件解析版本号;坏信号集合桥内归一到 card.py 2026-09-02 16:26:09 +08:00
xxl.py 选股系统:日频行业观点快照与覆盖率读数 2026-09-03 16:07:02 +08:00

README.md

akg-factor-bridge

astock-kg知识图谱基座quant_factor_service(通用因子平台)之间的因子导出桥。 把基座的四路产出(分析师预期空间 / 热度 / 利好利空事件 / 板块传导)做成符合平台规范的 子因子;复合因子 akg_score 在桥内用自洽的景气度漏斗算出,平台只负责注册/存储/ 调度/评价,不参与合成。

设计与决策依据见本工程 docs/量化因子导出与合成设计.mdv2.0,唯一事实源)。 ⚠️ astock-kg/docs/ 下的同名文档还是 v1讲的是已被推翻的平台拟合合成方案,别读。 本工程不 import 基座或平台任何代码,只靠 .env 里三处数据库连接工作, 可单独部署于任意能连通三库的服务器。

架构(基座出视图,桥算因子与合成,平台管存储与评价)

astock-kg 基座 PG ── 只读视图sql/astock_kg_slot_views.sql
   v_factor_universe / v_factor_consensus / v_factor_events / v_factor_transmission
        │                          (热度不经基座:桥直连 153 读 stock_fund_heat_scores
        ▼
akg-factor-bridge读视图+热度 → 四路日截面变换 → 【漏斗合成 akg_score】
        → 转前缀码 SH600000 → 写平台 t_factor_akg_* + 注册 factor_metadata
        → 每日冻结输入快照 data/frozen/freeze.py
        ▼
平台 quant_factor_service当普通 single 因子 → 评价(RankIC/分层)=仪表盘 / 调度 / 下游消费
  • 基座只暴露数据、不算因子;桥承载全部因子建模(极性表、衰减、门槛、权重); 平台不感知 astock-kg。
  • universe = KG 覆盖池(v_factor_universe = 全部 industry_pools 成员并集)。 ⚠️ 它是当前态且每周一自动长大——子因子是否受它限制由 SUBFACTOR_UNIVERSE 控制。

四个子因子

factor_code 口径 缺失
akg_upside t_factor_akg_upside 目标价中枢/现价1as-of backward NaN无覆盖不出行
akg_heat t_factor_akg_heat 热度分 0~1最新批次T+1 到达) NaN
akg_event t_factor_akg_event Σ 事件极性×时间衰减(仅公告来源、单文档封顶 不出行
akg_transmission t_factor_akg_transmission distinct 源数×(1已动比例) 不出行(合成侧填 0

选股计划入池2026-08-03

python run.py push-pool 把每日计划写进 Mongo 股票池分组group_code=AKG_PLAN 决策系统每晚认知扫描按分组并集覆盖 → 候选票自动获得夜间推理(支撑/压力/定性), PMS 的参考位、择时执行区间、研判上下文由此可用。入池=当日计划(强传导前20)∪持仓; 掉榜未恶化留池观察;无持仓、不在计划且形态恶化 → 移入回收站 stock_recycle_bin 持仓永不出池。规则、时间线、部署与判收见 docs/选股计划入池_对接说明.md

日频行业观点快照2026-09-03只写不判

python run.py judgement-snapshot [--date D] 把数据基座当前这一版产业研判与环节评析 (视图 v_factor_judgement)抄进选股系统自己的表 t_akg_judgement_snapshot,每个计划日 每个主题或环节一行。为什么要抄:那张评析表按主题唯一,重评时整行覆盖并把生成时间改成当前, 库里永远只有最新一版,查不到"这个观点上一次是什么样、什么时候变的";而逻辑状态四态里 "采信倾向从偏多变成偏空"这条判据依赖的正是这种变化,版本史只能由读的一方自己攒。

这一步只写不判:不产生判决、不改排序、不拦任何票。迁移与陈旧的口径写在行上——只有材料指纹 input_version)变化才算一次迁移(migrated=1stale_days 归零),指纹没变而日期变老 只累加陈旧天数(migrated=0);本表第一次见到的主题 migrated 留空。落点选平台因子库而不是 数据基座,因为桥对基座只有只读账号,且这是选股系统的派生记录不是基座事实;表名不带 t_factor_ 前缀,免得平台的因子清单把它当因子表收进去。细节见 judgement.py 模块说明。

表由代码首次运行时自动建(CREATE TABLE IF NOT EXISTS)。若代理不允许自动建表, 在平台因子库(FACTOR_MYSQL_* 指向的那个库,即写 t_factor_akg_* 的同一个)手工执行 judgement.py_CREATE_TABLE 的那段语句,两处逐字相同。

用法(全程 Docker不在宿主机直跑

# 0) 基座视图建一次/改一次。**按你在哪台机器上选一条**——桥是跨机部署的独立单元,
#    部署它的服务器上通常没有 astock-kg 的容器。
#    (a) 在桥这边(推荐,无需 psql 客户端,用桥自己的 AKG_PG_* 连接):
docker compose exec -T akg-factor-bridge python run.py apply-views --dry-run   # 先看要跑哪几条
docker compose exec -T akg-factor-bridge python run.py apply-views
#        ⚠️ 需要 DDL 权限。日常只读账号会报 permission denied用基座 owner 跑这一次:
#        docker compose exec -T -e AKG_PG_USER=<owner> -e AKG_PG_PASSWORD=<pw> \
#          akg-factor-bridge python run.py apply-views
#        (必须用 -e 传进容器;写在 docker 前面只影响宿主机进程)
#    (b) 在桥这边、想用原生 psql一次性容器不装客户端
#        set -a; . ./.env; set +a
#        docker run --rm -i -e PGPASSWORD="$AKG_PG_PASSWORD" postgres:16-alpine \
#          psql -h "$AKG_PG_HOST" -p "${AKG_PG_PORT:-5432}" -U "$AKG_PG_USER" -d "$AKG_PG_DB" \
#          -v ON_ERROR_STOP=1 < sql/astock_kg_slot_views.sql
#    (c) 在 astock-kg 那台机器上(把本文件带过去):
#        docker exec -i akg-postgres psql -U akg -d akg < sql/astock_kg_slot_views.sql

# 1) 配连接(地址填「桥容器可达」的:跨机=LAN IP与基座同机同网=服务名,见下「网络」)
cp .env.example .env && vim .env

# 2) 构建并起桥容器(常驻)
docker compose up -d --build

# 3) 连通性 + 视图版本 + 数据前沿自检
docker compose exec akg-factor-bridge python run.py views

# 3.5) G1 体检(只读:池结构 / 行情年表 / upside 分布 / 三项相关矩阵与权重体检)
docker compose exec akg-factor-bridge python run.py probe
docker compose exec akg-factor-bridge python run.py probe --section corr   # 单跑某节
#      price 节全表聚合,可能 1~3 分钟corr 节直接回答「0.5/0.3/0.2 是混合还是传导优先」

# 4) 注册 + 跑因子(幂等,可重跑)
docker compose exec akg-factor-bridge python run.py register
docker compose exec akg-factor-bridge python run.py build akg_heat --mode daily --date 2026-07-24
docker compose exec akg-factor-bridge python run.py build all --mode history --start 2024-01-01 --end 2026-07-24

# 5) 输入冻结daily 构建会自动跑一次;也可单独补)
docker compose exec akg-factor-bridge python run.py freeze --date 2026-07-24

生产触发:宿主 cron 或平台 XXL-JOB → docker exec akg_factor_bridge python run.py build all --mode daily(跑完自动冻结)。

❄️ 输入冻结freeze.py——为什么每天都要跑

桥内写入幂等,但上游不是:传导的 quiet 集合依赖 Neo4j 返回序(基座 Cypher 无 ORDER BY)、industry_pools 只存最新态且每周一长大、gp_day_data 是前复权且 锚在最新日(每次除权历史 close 被整体重写)、consensus_daily 会被重跑覆盖。

所以「可复现」唯一诚实可达的定义是:能从冻结的输入重算出同一个值data/frozen/<日期>/ 每天存一份 universe / 传导原始行 / 一致预期 / 当日收盘 / 热度

  • 当日算出的因子值 + manifest.json行数、告警、git rev

它一次性满足:判收标准的「重跑不产生漂移」、「赛道成员快照可审计」、以及未来任何回溯 需求(含设计 §10 里 GRU 复活所需的「≥1 年 live 传导史」——那个计时器只在开始存快照 的那天启动)。manifest.json 才是可 diff 的审计线,建议 git 跟踪 manifest、忽略数据文件。

运行旋钮(.env,全部可留空取默认)

变量 默认 作用
SUBFACTOR_UNIVERSE pool 子因子是否受覆盖池限制。market 可避免成员性前视与周一跳变(设计评审 §4 建议)
EVENT_SOURCE_TYPES announcement 事件只认哪些 documents.source_type。默认只认公告——年报会把历史诉讼记成披露日的当日负面事件
EVENT_MAX_PER_DOC 3 单文档最多贡献几条事件(一份年报能抽十几条)
PRICE_CHUNK_DAYS 31 行情按月分块读取,防长区间回填 OOM
WRITE_CHUNK_ROWS 50000 因子表分块提交,防单事务过大
FROZEN_ROOT /app/data/frozen 冻结落点
UPSTREAM_MEMBER_CAP / UPSTREAM_QUIET_CAP 30 / 12 上游截断体检阈值,命中只告警不拦截
JUDGEMENT_SNAPSHOT_TABLE t_akg_judgement_snapshot 日频行业观点快照落哪张表(平台因子库)
JUDGEMENT_SCOPES industry,segment 抄哪几类评析簇:产业研判与环节评析。个股与概念评析默认不抄
JUDGEMENT_PREV_LOOKBACK_DAYS 60 比对上一版时往前看几个自然日,超窗按第一次见到处理

网络Docker

桥要连三处,按「桥部署在哪」定地址:

  • 跨机部署(默认,推荐):三处都用 LAN IP/域名(.env 里填)。默认 bridge 网络即可 出网到 LAN——前提是基座 PG、153、平台 MySQL 都对该服务器可达。
  • 与基座同机同网:让桥加入 astock-kg 的 compose 网络,用服务名 postgres 连基座 PG (取消 docker-compose.yml 里 networks 段的注释,填 astock-kg 的网络名)。

已知的上游约束(桥修不了,但会显式告警)

build akg_transmission 时若看到下列告警,是基座侧的问题,需在 astock-kg 修:

  1. quiet 存满 12 条 —— transmission.pyquiet[:12] 是给旁批/展示用的, 却把因子的结构上限锁在 12 候选 × 12 成员 = 144 行/日。改法:落库存全量, 旁批仍只喂前 12。
  2. members_total >= 30 —— 基座 graph_store.topic_context 的 Cypher 是 LIMIT $cap(默认 30ORDER BY,于是 moved_ratio 建立在一个任意顺序的 ≤30 抽样上,同日重跑结果可能不同。改法:加 ORDER BY、cap 提到 200。
  3. mkt_trade_date ≠ scan_date —— hotspot._latest_mkt 取的是 max(trade_date) FROM mkt_daily 而非 scan_date 当天的快照。17:30 sync_market 晚点时18:15 的传导扫描会用 T1 的 movers 写成今日戳。改法:_latest_mkttrade_date 参数 + scan 开头加新鲜度断言。

(另:gp_sector_daily / gp_market_sentiment 当前空表、t_signal_daily_results 05-15 停更 → hotspot 的板块级异动源整个缺失,这才是传导每日只有几十行的主因。 要提传导覆盖,优先补 gp_sector_daily,比调任何参数都有用。)

⚠️ 待实机核实项

  1. 三库连通性python run.py views 七项全 才算通。
  2. 视图版本views 会打印 n_sources / mkt_trade_date / source_type 是否就绪; 有 说明 sql/astock_kg_slot_views.sql 还没应用到基座(桥会自动退回旧口径并告警)。
  3. factor_metadataregister 自适应实际列写入;若无 factor_type 列,平台 /mining/factors/all 可能查不到本因子(会打印告警),需与平台侧确认。
  4. 事件极性/方向factors.EVENT_POLARITY / EVENT_DIR 是草案(设计 §9-5 增减持 的增/减方向若 qualifiers.direction 里没有会落 0需确认基座 EVENT 的方向 存在哪个 qualifier 键。半衰期 10 交易日 / 窗口 60 交易日可调。
  5. 事件交易日龄近似v1 用自然日×(5/7) 折算交易日龄,非精确交易日历——够用, 后续可换真实交易日历向量化。
  6. documents.source_type 实际取值:默认白名单是 announcement。若基座里公告的 source_type 不是这个字符串,事件因子会被过滤成空(会显式告警),按实际值改 EVENT_SOURCE_TYPES

HTTP 接口(桥常驻 API端口 8300全部只读除 refresh

端点 作用
GET /health 存活探针2026-09-03 起带 pool_topPOOL_TOPpool_maxPOOL_MAX供 PMS 池深探针比对
GET /plan/dates?limit=30 有计划文件的日期清单
GET /plan?date=&format=json|md&top=&obs_top= 当日选股计划(基座今日页 /plan/today 与 PMS 下单候选都读它)。顶层 regime(区制)与 market(两市成交额、广度、融资、恐贪四项)都只从当日快照读,快照缺失为空;每行的判决类字段 2026-09-03 起多 basis(判决依据)与 logic(因果论断带出处)
POST /plan/refresh?date= 重生成当日计划文件
GET /plan/verdict?codes=300750,SH600438&date= 逐票『计划判决』2026-08-18 PMS 对接加decisionmain/observe/reject/absent+ 与命令行 plan_reconcile 逐字同口径的 verdict_text + score/rank/tier/赛道/图谱证据。单票数据异常或代码形态认不出只报该票 error不崩整批
GET|POST /api/v1/xxl/daily-build?key=&steps=&date= XXL-JOB 平台触发盘前链build→plan→push-pool白名单步骤、单实例互斥、回调结案.env 不配 XXL_TRIGGER_KEY 则整组禁用

逐票对账的命令行形态(同一段判决代码): docker compose exec -T akg-factor-bridge python plan_reconcile.py 300750 [--date 2026-08-04]

里程碑状态(设计 §8

  • G2 赛道门槛 config/frontier_tracks.yml + tracks.py,三路映射 (环节锚 > 链锚 > 主题弱锚),基座插槽视图 v_factor_segment_members 已就位。
  • G3 漏斗合成 07-30 拍板):akg_gate + akg_scoreFACTORS build all 一并日更;两锚三档 + 两段式组内分。
  • G4 回填与仪表盘(未完成)upside 历史重建走「给基座 sync_consensusasof 参数」,动工前先与基座侧排期。