2026-07-24 14:20:54 +08:00
|
|
|
|
-- ============================================================================
|
2026-07-27 09:49:05 +08:00
|
|
|
|
-- astock-kg 因子插槽接口:只读视图 v2(供 akg-factor-bridge 消费)
|
2026-07-24 14:20:54 +08:00
|
|
|
|
-- ----------------------------------------------------------------------------
|
2026-07-27 09:49:05 +08:00
|
|
|
|
-- 相对 v1 的变更(2026-07-26 评审):
|
|
|
|
|
|
-- ① v_factor_transmission:n_paths → n_sources(distinct 源数),修「变长边每种
|
|
|
|
|
|
-- 长度各返回一条 + 三桶间不去重」导致的路径重复计数;n_paths_raw 保留作观察。
|
|
|
|
|
|
-- ② v_factor_transmission:暴露 target / target_type / members_total / moved /
|
|
|
|
|
|
-- mkt_trade_date,让桥能自检上游截断与快照新鲜度。
|
|
|
|
|
|
-- ③ v_factor_events:补 doc_id / source_type / tier(供年报污染防护)。
|
|
|
|
|
|
-- ④ v_factor_universe / v_factor_consensus 逻辑未变,只补注释。
|
|
|
|
|
|
--
|
|
|
|
|
|
-- 应用:docker exec -i akg-postgres psql -U akg -d akg < sql/astock_kg_slot_views.sql
|
|
|
|
|
|
-- 幂等:全部 CREATE OR REPLACE。
|
|
|
|
|
|
--
|
|
|
|
|
|
-- ★ 数据安全性:本文件**只创建视图 + 加列 + 加索引**,不写、不改、不删任何一行数据。
|
|
|
|
|
|
-- claims / documents 一个字节都不动,之前抽取的成果全部保留,无需 replay、无需重抽。
|
|
|
|
|
|
-- 唯一的 DDL 变更是 transmission_candidates 加一个可空列(见文件末尾 ALTER 段),
|
|
|
|
|
|
-- 已存行取值 NULL,桥侧按 NULL 容忍(见 factors.build_transmission)。
|
2026-07-24 14:20:54 +08:00
|
|
|
|
-- ============================================================================
|
|
|
|
|
|
|
|
|
|
|
|
-- 0) 覆盖池 universe = 全部 industry_pools 成员 ts_code 并集
|
2026-07-27 09:49:05 +08:00
|
|
|
|
-- ⚠️ 注意(评审 §4):industry_pools 只存最新态、每周一 refresh_pools 自动长大。
|
|
|
|
|
|
-- 本视图是「当前态」,用它过滤历史子因子会引入成员性前视。
|
|
|
|
|
|
-- 子因子表建议不过此过滤(桥侧 SUBFACTOR_UNIVERSE=market),只在 akg_score 侧用。
|
2026-07-24 14:20:54 +08:00
|
|
|
|
CREATE OR REPLACE VIEW v_factor_universe AS
|
|
|
|
|
|
SELECT DISTINCT m->>'ts_code' AS ts_code
|
|
|
|
|
|
FROM industry_pools p
|
|
|
|
|
|
CROSS JOIN LATERAL jsonb_array_elements(COALESCE(p.members, '[]'::jsonb)) AS m
|
|
|
|
|
|
WHERE m->>'ts_code' IS NOT NULL AND m->>'ts_code' <> '';
|
|
|
|
|
|
|
2026-07-27 09:49:05 +08:00
|
|
|
|
|
2026-07-24 14:20:54 +08:00
|
|
|
|
-- 1) 一致预期(供 upside):consensus_daily 全 asof 行投影,桥按 trade_date 做 as-of。
|
2026-07-27 09:49:05 +08:00
|
|
|
|
-- n_orgs / n_reports_90d 一并给出——可作 upside 的可信度权重(当前桥未用)。
|
2026-07-24 14:20:54 +08:00
|
|
|
|
CREATE OR REPLACE VIEW v_factor_consensus AS
|
|
|
|
|
|
SELECT ts_code,
|
|
|
|
|
|
asof_date,
|
|
|
|
|
|
target_mid_avg,
|
|
|
|
|
|
eps_med,
|
|
|
|
|
|
np_med,
|
|
|
|
|
|
n_orgs,
|
|
|
|
|
|
n_reports_90d
|
|
|
|
|
|
FROM consensus_daily
|
|
|
|
|
|
WHERE target_mid_avg IS NOT NULL;
|
|
|
|
|
|
|
2026-07-27 09:49:05 +08:00
|
|
|
|
|
2026-07-24 14:20:54 +08:00
|
|
|
|
-- 2) 利好利空事件(供 event):EVENT 断言投影。
|
2026-07-27 09:49:05 +08:00
|
|
|
|
-- 评审 §6.5:补 doc_id + source_type。年报也带 company_ts_code 锚,而一份年报能抽
|
|
|
|
|
|
-- 十几条 EVENT(且含**历史**诉讼/处罚),桥侧必须按来源过滤或封顶,
|
|
|
|
|
|
-- 否则 S2 的负面否决闸会因一份年报否决掉一只好股。
|
|
|
|
|
|
-- ✅ 列名已核实(db/postgres/init.sql:12):documents.source_type,取值
|
|
|
|
|
|
-- annual_report / research_report / announcement / news / interactive_qa
|
|
|
|
|
|
-- 另补 tier(fact/opinion/market)—— 桥侧若想只信事实层事件,这里就够用。
|
2026-07-24 14:20:54 +08:00
|
|
|
|
CREATE OR REPLACE VIEW v_factor_events AS
|
|
|
|
|
|
SELECT d.meta->>'company_ts_code' AS ts_code,
|
|
|
|
|
|
c.disclosure_date,
|
|
|
|
|
|
c.qualifiers->>'event_type' AS event_type,
|
|
|
|
|
|
c.qualifiers->>'direction' AS direction,
|
|
|
|
|
|
c.qualifiers->>'scope' AS scope,
|
|
|
|
|
|
c.confidence,
|
2026-07-27 09:49:05 +08:00
|
|
|
|
c.tier,
|
|
|
|
|
|
c.dedup_key,
|
|
|
|
|
|
c.doc_id, -- 供「单文档封顶」用
|
|
|
|
|
|
d.source_type -- 供「只取公告」用
|
2026-07-24 14:20:54 +08:00
|
|
|
|
FROM claims c
|
|
|
|
|
|
JOIN documents d ON d.doc_id = c.doc_id
|
|
|
|
|
|
WHERE c.predicate = 'EVENT'
|
|
|
|
|
|
AND d.meta->>'company_ts_code' IS NOT NULL;
|
|
|
|
|
|
|
2026-07-27 09:49:05 +08:00
|
|
|
|
|
|
|
|
|
|
-- 3) 板块传导(供 transmission):transmission_candidates 的未动成员(quiet)摊平。
|
|
|
|
|
|
-- ★ 核心修复:n_sources = 指向该环节的 distinct 源数。
|
|
|
|
|
|
-- 原 n_paths = jsonb_array_length(paths) 是「被提及次数」——
|
|
|
|
|
|
-- cascade() 的变长边 *1..N 会把 A→B 与 A→X→B 各返回一条,
|
|
|
|
|
|
-- transmission_targets() 的 updown/supply/drives 三桶之间也不去重,
|
|
|
|
|
|
-- 于是同一 source 对同一 target 重复计入,而 n_paths 是 factor_value 的主量级。
|
|
|
|
|
|
-- 改成 distinct source 数,同时也更贴合传导模块自述的语义「多源汇聚=逻辑更硬」。
|
2026-07-24 14:20:54 +08:00
|
|
|
|
CREATE OR REPLACE VIEW v_factor_transmission AS
|
|
|
|
|
|
SELECT t.scan_date,
|
2026-07-27 09:49:05 +08:00
|
|
|
|
t.rank,
|
|
|
|
|
|
t.target,
|
|
|
|
|
|
t.target_type,
|
|
|
|
|
|
q->>'ts_code' AS ts_code,
|
|
|
|
|
|
(SELECT count(DISTINCT p->>'source')
|
|
|
|
|
|
FROM jsonb_array_elements(COALESCE(t.paths, '[]'::jsonb)) p) AS n_sources,
|
|
|
|
|
|
jsonb_array_length(COALESCE(t.paths, '[]'::jsonb)) AS n_paths_raw,
|
|
|
|
|
|
t.moved_ratio,
|
|
|
|
|
|
t.members_total, -- 桥用:== 上游 topic_context cap 时 moved_ratio 不可信
|
|
|
|
|
|
t.moved,
|
|
|
|
|
|
jsonb_array_length(COALESCE(t.quiet, '[]'::jsonb)) AS n_quiet_stored,
|
|
|
|
|
|
t.mkt_trade_date -- 桥用:≠ scan_date 说明用了陈旧 movers(可能为 NULL)
|
2026-07-24 14:20:54 +08:00
|
|
|
|
FROM transmission_candidates t
|
|
|
|
|
|
CROSS JOIN LATERAL jsonb_array_elements(COALESCE(t.quiet, '[]'::jsonb)) AS q
|
|
|
|
|
|
WHERE q->>'ts_code' IS NOT NULL AND q->>'ts_code' <> '';
|
2026-07-27 09:49:05 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
-- ============================================================================
|
|
|
|
|
|
-- 前置 ALTER(幂等,可反复跑)
|
|
|
|
|
|
-- ----------------------------------------------------------------------------
|
|
|
|
|
|
-- mkt_trade_date:记录本次扫描实际用到的 mkt_daily stock 快照日。
|
|
|
|
|
|
-- 动因(评审 §6.2):hotspot._latest_mkt 用 `max(trade_date) FROM mkt_daily`,
|
|
|
|
|
|
-- 不是 scan_date 的快照。17:30 sync_market 晚点时,18:15 的传导扫描会用 T−1 的
|
|
|
|
|
|
-- movers 写成 scan_date=T,桥完全无从察觉。落这一列后,桥可以自检并拒收。
|
|
|
|
|
|
-- ============================================================================
|
|
|
|
|
|
ALTER TABLE transmission_candidates
|
|
|
|
|
|
ADD COLUMN IF NOT EXISTS mkt_trade_date DATE;
|
|
|
|
|
|
|
|
|
|
|
|
-- 便于按环节回查与审计
|
|
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_tc_target ON transmission_candidates (target, scan_date);
|