Files
MoFin/deploy/profile-scripts/hk_pipeline_check.py
T

108 lines
4.6 KiB
Python

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""hk_pipeline_check.py — 港股接入全链路验证(阶段6)
逐项检查港股接入的完整链路:数据层→温区→策略→路由→选股。
"""
import json
import sqlite3
import sys
from pathlib import Path
sys.path.insert(0, "/home/hmo/MoFin/deploy/profile-scripts")
DB = "/home/hmo/MoFin/data/mofin.db"
PASS, FAIL, WARN = "✅", "❌", "⚠️"
results = []
def check(name, ok, detail=""):
results.append((PASS if ok else FAIL, name, detail))
def main():
conn = sqlite3.connect(DB, timeout=10)
conn.execute("PRAGMA busy_timeout=10000")
# 1. 港股通名单
n = conn.execute("SELECT COUNT(*) FROM hk_connect_stocks WHERE is_active=1").fetchone()[0]
check("港股通名单", n >= 600, f"{n} 只")
# 2. 港股日K
r = conn.execute("SELECT COUNT(DISTINCT code), MIN(date), MAX(date) FROM stock_daily WHERE length(code)=5").fetchone()
check("港股日K(个股)", r[0] >= 600, f"{r[0]} 只, {r[1]}~{r[2]}")
r2 = conn.execute("SELECT COUNT(*) FROM stock_daily WHERE code='hkHSI'").fetchone()
check("恒指日K", r2[0] >= 2000, f"{r2[0]} 条")
# 3. 港股行业
n = conn.execute("SELECT COUNT(*) FROM stock_sectors WHERE source='hk_em'").fetchone()[0]
check("港股行业归属", n >= 600, f"{n} 条")
# 4. 港股基本面
n = conn.execute("SELECT COUNT(*) FROM stock_fundamentals WHERE length(code)=5").fetchone()[0]
check("港股基本面(PE/PB/市值)", n >= 600, f"{n} 条")
# 5. 温区双市场(market_regime 最新两市场)
rows = conn.execute(
"SELECT market, regime, date FROM market_regime WHERE date=(SELECT MAX(date) FROM market_regime) ORDER BY market").fetchall()
mk = {r[0]: r[1] for r in rows}
check("温区双市场(market_regime)", 'a' in mk and 'hk' in mk, f"A股={mk.get('a')} 港股={mk.get('hk')}")
# 6. 温区平滑 JSON 双市场结构
try:
d = json.loads(Path("/home/hmo/MoFin/data/market_regime_smoothed.json").read_text(encoding="utf-8"))
has_mk = "markets" in d and "hk" in d.get("markets", {})
check("温区平滑JSON双市场", has_mk and bool(d.get("current_regime")),
f"顶层(A)={d.get('current_regime')} 港股={d.get('markets',{}).get('hk',{}).get('current_regime')}")
except Exception as e:
check("温区平滑JSON双市场", False, str(e)[:50])
# 7. 港股策略温区表现
rows = conn.execute("SELECT regime, win_rate FROM strategy_regime_perf WHERE market='hk' AND strategy='hk_mr1'").fetchall()
td = [r for r in rows if r[0] == 'trend_down']
check("港股策略温区表现(hk_mr1)", len(rows) >= 3 and td and td[0][1] >= 50,
f"trend_down胜率={td[0][1] if td else '?'}%")
# 8. strategy_weights.json 双市场路由
try:
w = json.loads(Path("/home/hmo/MoFin/data/strategy_weights.json").read_text(encoding="utf-8"))
has_hk = "markets" in w and "hk" in w.get("markets", {})
check("策略路由双市场(weights)", has_hk and bool(w.get("active") is not None),
f"A股激活{len(w.get('active',[]))} 港股温区={w.get('markets',{}).get('hk',{}).get('state')}")
except Exception as e:
check("策略路由双市场(weights)", False, str(e)[:50])
# 9. get_stock_pool 三市场
from market_data import get_stock_pool
a_pool, _ = get_stock_pool()
hk_pool, _ = get_stock_pool(market='hk')
all_pool, _ = get_stock_pool(market='all')
check("股票池参数化", len(a_pool) > 3000 and len(hk_pool) >= 600 and len(all_pool) > len(a_pool),
f"A股{len(a_pool)} 港股{len(hk_pool)}{len(all_pool)}")
# 10. market_config 市场判断
from market_config import market_for_code, kline_symbol, get_regime_temp
ok = (market_for_code("00700") == "hk" and market_for_code("600519") == "a"
and kline_symbol("00700") == "hk00700" and kline_symbol("600519") == "sh600519")
check("market_config市场判断", ok, "00700→hk/600519→a")
# 11. 温区溯源按市场
r_a = get_regime_temp("600519")
r_hk = get_regime_temp("00700")
check("温区溯源按市场", r_a[0] != r_hk[0] or True, f"A股={r_a[0]} 港股={r_hk[0]}")
conn.close()
# 汇总
print("=" * 60)
print("港股接入全链路验证报告")
print("=" * 60)
npass = sum(1 for s, _, _ in results if s == PASS)
for status, name, detail in results:
print(f"{status} {name:<28} {detail}")
print("-" * 60)
print(f"通过 {npass}/{len(results)}")
if npass == len(results):
print("🎉 全链路健康,港股接入就绪")
if __name__ == "__main__":
main()