104 lines
5.7 KiB
SQL
104 lines
5.7 KiB
SQL
-- astock-kg 候选卡插槽视图:三张只读视图,供 akg-factor-bridge 的候选卡与复盘消费。
|
||
-- 应用【桥机 155 · ~/project/akg-factor-bridge】:
|
||
-- docker compose exec -T akg-factor-bridge python run.py apply-views --file sql/astock_kg_card_views.sql --dry-run
|
||
-- docker compose exec -T -e AKG_PG_USER=<owner> -e AKG_PG_PASSWORD=<pw> \
|
||
-- akg-factor-bridge python run.py apply-views --file sql/astock_kg_card_views.sql
|
||
--
|
||
-- 与 sql/astock_kg_slot_views.sql 分开放:那份文件用 DROP + CREATE 且含 ALTER TABLE,
|
||
-- 整文件重跑会把生产在用的四张视图重删重建;本文件只用 CREATE OR REPLACE,反复应用无害。
|
||
-- 基座零代码:只读现有表 transmission_candidates、segment_members_projection、
|
||
-- segment_member_review、mkt_daily。应用时避开 06:10 的投影重建窗口。
|
||
-- 出处:docs/主观选股改进方案_2026-09-02.md 第 2.2 节第二项。
|
||
|
||
|
||
-- 一、已动成员视图 v_factor_transmission_moved
|
||
-- 被传导指向的环节(只认 Segment 目标;Concept 与 Company 目标的成员不在投影表里)的
|
||
-- 投影成员,减去传导台账里的未动名单 quiet,再减去复核账本判定"不属于本环节"的成员
|
||
-- (verdict = 'exclude',与基座 transmission.scan 在算已动之前的剔除口径一致)。
|
||
-- 连接键用投影表的原名 COALESCE(orig_segment_name, segment_name):投影期有改派重排,
|
||
-- 传导扫描用的目标名是图上原名。
|
||
-- 本视图只做集合差,不重算涨幅;"已动"的口径与基座 hotspot._movers_set 同源
|
||
-- (数据日涨幅达到 3%),涨幅本身从 v_factor_stock_daily 取。
|
||
-- 对账:按 (scan_date, target) 数本视图行数 + quiet 行数,与 transmission_candidates 的
|
||
-- members_total 比;不等的环节多半是基座扫描时成员集有上限(cap=200)而投影表没有,
|
||
-- 差异分"截断"与"真差异"两类,只对后者要求为零。
|
||
CREATE OR REPLACE VIEW v_factor_transmission_moved AS
|
||
WITH tc AS (
|
||
SELECT t.scan_date, t.rank, t.target, t.mkt_trade_date, t.chain_fit,
|
||
t.members_total, t.moved, t.moved_ratio,
|
||
(SELECT count(DISTINCT p->>'source')
|
||
FROM jsonb_array_elements(COALESCE(t.paths, '[]'::jsonb)) p) AS n_sources,
|
||
t.quiet
|
||
FROM transmission_candidates t
|
||
WHERE t.target_type = 'Segment'
|
||
),
|
||
quiet AS (
|
||
SELECT c.scan_date, c.target, q->>'ts_code' AS ts_code
|
||
FROM tc c
|
||
CROSS JOIN LATERAL jsonb_array_elements(COALESCE(c.quiet, '[]'::jsonb)) q
|
||
WHERE q->>'ts_code' IS NOT NULL AND q->>'ts_code' <> ''
|
||
),
|
||
members AS (
|
||
SELECT DISTINCT COALESCE(orig_segment_name, segment_name) AS seg,
|
||
ts_code, member_name, segment_name AS projected_segment
|
||
FROM segment_members_projection
|
||
WHERE ts_code IS NOT NULL AND ts_code <> ''
|
||
)
|
||
SELECT c.scan_date, c.target, c.rank, c.n_sources, c.chain_fit,
|
||
c.members_total, c.moved, c.moved_ratio, c.mkt_trade_date,
|
||
m.ts_code, m.member_name, m.projected_segment
|
||
FROM tc c
|
||
JOIN members m ON m.seg = c.target
|
||
LEFT JOIN quiet q
|
||
ON q.scan_date = c.scan_date AND q.target = c.target AND q.ts_code = m.ts_code
|
||
WHERE q.ts_code IS NULL
|
||
AND NOT EXISTS (
|
||
SELECT 1 FROM segment_member_review r
|
||
WHERE r.ts_code = m.ts_code AND r.segment_name = c.target AND r.verdict = 'exclude');
|
||
|
||
|
||
-- 二、个股日行情视图 v_factor_stock_daily
|
||
-- 候选卡"已启动"门槛(pct_change)与两条展示线(net_z 主力净额对自身二十日基线的
|
||
-- 标准化偏离、heat_chg 热度较往前第五个交易日的变化)的数据来源,只留行情列。
|
||
-- 吸筹不从这里取:基座落库的吸筹状态没有评分日,候选卡的吸筹三项只认决策系统结论表。
|
||
CREATE OR REPLACE VIEW v_factor_stock_daily AS
|
||
SELECT trade_date,
|
||
code AS ts_code,
|
||
(metrics->>'pct_change')::numeric AS pct_change,
|
||
(metrics->>'net_z')::numeric AS net_z,
|
||
(metrics->>'heat_chg')::numeric AS heat_chg,
|
||
(metrics->>'heat')::numeric AS heat,
|
||
(metrics->>'net_amount')::numeric AS net_amount
|
||
FROM mkt_daily
|
||
WHERE kind = 'stock';
|
||
|
||
|
||
-- 三、环节日行情视图 v_factor_segment_daily
|
||
-- 按投影表把个股日行情聚成环节行,只给原始值与成员明细集合;"主力净额前两名"、
|
||
-- "涨停近似(涨幅超 9.8%)"这类派生判断在桥的 card.py 算,不写进基座视图。
|
||
-- 投影表是当前态(每晨 06:10 删后插),历史日的成员集合带成员前视,复盘按冻结快照重建。
|
||
CREATE OR REPLACE VIEW v_factor_segment_daily AS
|
||
WITH members AS (
|
||
SELECT DISTINCT COALESCE(orig_segment_name, segment_name) AS seg, ts_code, member_name
|
||
FROM segment_members_projection
|
||
WHERE ts_code IS NOT NULL AND ts_code <> ''
|
||
)
|
||
SELECT s.trade_date,
|
||
p.seg AS segment_name,
|
||
count(*) AS members,
|
||
count(*) FILTER (WHERE s.pct_change >= 3) AS moved,
|
||
percentile_cont(0.5) WITHIN GROUP (ORDER BY s.pct_change) AS pct_median,
|
||
percentile_cont(0.5) WITHIN GROUP (ORDER BY s.heat_chg) AS heat_chg_median,
|
||
jsonb_agg(jsonb_build_object('ts_code', p.ts_code, 'name', p.member_name,
|
||
'pct', s.pct_change, 'net_amount', s.net_amount)
|
||
ORDER BY s.pct_change DESC NULLS LAST) AS members_detail
|
||
FROM members p
|
||
JOIN (
|
||
SELECT trade_date, code AS ts_code,
|
||
(metrics->>'pct_change')::numeric AS pct_change,
|
||
(metrics->>'heat_chg')::numeric AS heat_chg,
|
||
(metrics->>'net_amount')::numeric AS net_amount
|
||
FROM mkt_daily WHERE kind = 'stock'
|
||
) s ON s.ts_code = p.ts_code
|
||
GROUP BY s.trade_date, p.seg;
|