61 lines
2.2 KiB
Python
61 lines
2.2 KiB
Python
#!/usr/bin/env python3
|
|
"""fundamentals_refresh.py — 腾讯实时基本面批量刷新 stock_fundamentals
|
|
字段映射(实测600519): 39=PE(TTM) 44=总市值(亿) 45=流通市值(亿) 46=PB
|
|
EPS(TTM) = 现价/PE。限速0.15s/只。
|
|
"""
|
|
import sqlite3, subprocess, time
|
|
|
|
# ── 消息通道统一路由(broadcast/xmpp by delivery) ──
|
|
try:
|
|
from messenger import install_stdio_hook as _msh
|
|
_msh()
|
|
except Exception:
|
|
pass
|
|
|
|
DB = "/home/hmo/MoFin/data/mofin.db"
|
|
|
|
def prefix(code):
|
|
c = str(code)
|
|
if len(c) == 5:
|
|
return "hk"
|
|
return "sh" if c.startswith(("6", "9")) else "sz"
|
|
|
|
def main():
|
|
conn = sqlite3.connect(DB)
|
|
codes = [r[0] for r in conn.execute(
|
|
"SELECT DISTINCT code FROM holding_strategies WHERE status='active'")]
|
|
print(f"刷新 {len(codes)} 只基本面...")
|
|
ok = fail = 0
|
|
for i, code in enumerate(codes, 1):
|
|
try:
|
|
r = subprocess.run(["curl", "-s", f"http://qt.gtimg.cn/q={prefix(code)}{code}"],
|
|
capture_output=True, timeout=8)
|
|
parts = r.stdout.decode("gbk", errors="ignore").split("~")
|
|
if len(parts) < 47 or not parts[3]:
|
|
fail += 1
|
|
continue
|
|
price = float(parts[3])
|
|
pe = float(parts[39]) if parts[39] else 0
|
|
mcap_t = float(parts[44]) if parts[44] else 0
|
|
mcap_f = float(parts[45]) if parts[45] else 0
|
|
pb = float(parts[46]) if parts[46] else 0
|
|
eps = round(price / pe, 2) if pe > 0 else 0
|
|
conn.execute(
|
|
"INSERT OR REPLACE INTO stock_fundamentals (code, pe, pb, eps, mcap_total, mcap_flow, updated_at) "
|
|
"VALUES (?,?,?,?,?,?,datetime('now','localtime'))",
|
|
(code, pe, pb, eps, mcap_t, mcap_f))
|
|
ok += 1
|
|
except Exception:
|
|
fail += 1
|
|
if i % 30 == 0:
|
|
conn.commit()
|
|
print(f" {i}/{len(codes)} ok={ok} fail={fail}")
|
|
time.sleep(0.15)
|
|
conn.commit()
|
|
total = conn.execute("SELECT COUNT(*) FROM stock_fundamentals").fetchone()[0]
|
|
print(f"完成: ok={ok} fail={fail}, 表总数={total}")
|
|
conn.close()
|
|
|
|
if __name__ == "__main__":
|
|
main()
|