Files

97 lines
3.4 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""hk_flow_collector.py — 港股个股资金流采集(补12维面板 flow5/flow1
数据源:东财 push2delay 港股资金流接口(secid=116.{code},已验证可用)
https://push2delay.eastmoney.com/api/qt/stock/fflow/kline/get?secid=116.00700&klt=101&lmt=60
klines 格式: ["2026-08-14,主力流入,主力流出"]
写入:hk_flow_daily 表(code/date/flow_in/flow_out,主力资金流)
调度:每日盘后(资金流刷新)
限速:0.3s/只,620只约5分钟。
"""
import json
import sqlite3
import sys
import time
import urllib.request
# ── 消息通道统一路由(broadcast/xmpp by delivery) ──
try:
from messenger import install_stdio_hook as _msh
_msh()
except Exception:
pass
DB_PATH = "/home/hmo/MoFin/data/mofin.db"
UA = "Mozilla/5.0"
SLEEP = 0.3
DAYS = 60 # 拉60日资金流(够 flow5/flow1
def fetch_hk_flow(code, days=DAYS):
"""东财港股个股资金流历史(每日主力流入/流出,万元)"""
url = (f"https://push2delay.eastmoney.com/api/qt/stock/fflow/kline/get?"
f"lmt={days}&klt=101&secid=116.{code}&fields1=f1,f2,f3&fields2=f51,f52,f53")
req = urllib.request.Request(url, headers={"User-Agent": UA})
opener = urllib.request.build_opener(urllib.request.ProxyHandler({}))
with opener.open(req, timeout=15) as r:
text = r.read().decode("utf-8", errors="replace")
data = json.loads(text)
klines = (data.get("data") or {}).get("klines") or []
out = []
for k in klines:
parts = k.split(",")
if len(parts) < 3:
continue
try:
out.append((parts[0], float(parts[1]), float(parts[2])))
except (ValueError, TypeError):
pass
return out
def main():
conn = sqlite3.connect(DB_PATH, timeout=30)
conn.execute("PRAGMA busy_timeout=30000")
conn.execute("""
CREATE TABLE IF NOT EXISTS hk_flow_daily (
code TEXT NOT NULL, date TEXT NOT NULL,
flow_in REAL, flow_out REAL,
PRIMARY KEY (code, date)
)""")
codes = [r[0] for r in conn.execute(
"SELECT code FROM hk_connect_stocks WHERE is_active=1 ORDER BY code").fetchall()]
print(f"港股资金流采集:{len(codes)}× {DAYS} 日", flush=True)
ok = fail = 0
t0 = time.time()
for idx, code in enumerate(codes):
try:
rows = fetch_hk_flow(code)
if not rows:
fail += 1
continue
for d, fin, fout in rows:
conn.execute(
"INSERT OR REPLACE INTO hk_flow_daily (code, date, flow_in, flow_out) "
"VALUES (?,?,?,?)", (code, d, fin, fout))
ok += 1
if (idx + 1) % 100 == 0:
conn.commit()
print(f" [{idx+1}/{len(codes)}] ok={ok} fail={fail} | {time.time()-t0:.0f}s", flush=True)
except Exception as e:
fail += 1
if fail <= 5:
print(f" FAIL {code}: {str(e)[:60]}", flush=True)
time.sleep(SLEEP)
conn.commit()
n = conn.execute("SELECT COUNT(*), COUNT(DISTINCT code) FROM hk_flow_daily").fetchone()
conn.close()
print(f"\n完成:ok={ok} fail={fail} 耗时{time.time()-t0:.0f}s", flush=True)
print(f"hk_flow_daily: {n[0]} 条, {n[1]} 只", flush=True)
return 0
if __name__ == "__main__":
sys.exit(main())