因子平台直接消费基座的视图
Go to file
zlt 459028231c 去除免责声明 2026-07-30 13:02:43 +08:00
.idea 初始化提交 2026-07-24 14:20:54 +08:00
config 选股计划开发 2026-07-30 10:46:11 +08:00
docs R4: run.py plan 每日选股计划首版 + score 档位步长修正(10→20) 2026-07-30 12:44:56 +08:00
sql 验证和联调 2026-07-27 10:41:19 +08:00
.env.example 历史深度数据探查 2026-07-27 09:49:05 +08:00
.gitignore 历史深度数据探查 2026-07-27 09:49:05 +08:00
Dockerfile 初始化提交 2026-07-24 14:20:54 +08:00
README.md 历史深度数据探查 2026-07-27 10:03:45 +08:00
apply_views.py 历史深度数据探查 2026-07-27 10:03:45 +08:00
common.py 历史深度数据探查 2026-07-27 09:49:05 +08:00
config.py G2+R3: 赛道映射模块 + akg_gate/akg_score 合成因子(07-30 三拍落地) 2026-07-30 12:01:11 +08:00
db.py 初始化提交 2026-07-24 14:20:54 +08:00
docker-compose.yml 容器化改造 2026-07-24 14:57:11 +08:00
factors.py R4: run.py plan 每日选股计划首版 + score 档位步长修正(10→20) 2026-07-30 12:44:56 +08:00
freeze.py 历史深度数据探查 2026-07-27 09:49:05 +08:00
plan.py 去除免责声明 2026-07-30 13:02:43 +08:00
probe.py probe: corr 节去 scipy 依赖,修 07-30 首跑崩点 2026-07-30 10:00:55 +08:00
requirements.txt G2+R3: 赛道映射模块 + akg_gate/akg_score 合成因子(07-30 三拍落地) 2026-07-30 12:01:11 +08:00
run.py plan v2: 每主题限额(默认5, 防单板块刷屏) + 预期空间列现算兜底 2026-07-30 12:55:24 +08:00
tracks.py R4: run.py plan 每日选股计划首版 + score 档位步长修正(10→20) 2026-07-30 12:44:56 +08:00

README.md

akg-factor-bridge

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

设计与决策依据见本工程根目录 量化因子导出与合成设计.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

用法(全程 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 上游截断体检阈值,命中只告警不拦截

网络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

未完成(设计 §8 里程碑)

  • G2config/frontier_tracks.yml + tracks.py + data/track_members.csv (赛道门槛 C需要基座先出第五/六个插槽视图 v_factor_segment_members / v_factor_segment_edges——industry_pools 成员级没有 segment/layer图谱在 Neo4j
  • G3:漏斗合成 akg_score + akg_gate0/1 全池出行,让平台分层能读出门槛的价值)。
  • G4回填与仪表盘upside 历史重建走「给基座 sync_consensusasof 参数」)。