28d1606947
5 wrapper(ak_eod daily19:00估值+财务摘要/ak_quarter财报季三表+预告快报/ ak_events daily19:30龙虎榜+大宗+两融+解禁 per-date当日/ak_stock weekly周六 北向+股本+十大股东/index_monthly 16号成份股3源+migrate+merge)+register_akshare _schtasks(/m APR,MAY,SEP,NOV财报季)+verify_akshare_e2e; 均unset proxy+夜间避封IP
76 lines
2.7 KiB
Python
76 lines
2.7 KiB
Python
#!/usr/bin/env python3
|
|
# -*- coding: utf-8 -*-
|
|
"""verify_akshare_e2e.py — akshare 低频 schtask E2E 验证(VPS 跑)。
|
|
验: static/ 各表文件数+最新mtime / events/ per-date 类 parquet / constituent_unified 行数+3source / bs_index_constituent_old 完好。
|
|
stdout 行缓冲(ssh 非交互块缓冲兼容)。
|
|
"""
|
|
import datetime
|
|
import sqlite3
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
sys.stdout.reconfigure(line_buffering=True)
|
|
|
|
BASE = Path(r"C:\sanguo_vnpy_v2\data")
|
|
ok, warn = [], []
|
|
|
|
# 1. static/ 各表文件数 + 最新 mtime
|
|
print("===== static/ 各表 =====")
|
|
for sub in ["valuation", "financial_abstract", "balance", "income", "cashflow",
|
|
"northbound", "share_capital", "top_holders"]:
|
|
d = BASE / "static" / sub
|
|
if not d.exists():
|
|
warn.append(f"static/{sub} MISSING")
|
|
print(f" {sub}: MISSING")
|
|
continue
|
|
fs = list(d.glob("*.parquet"))
|
|
if not fs:
|
|
warn.append(f"static/{sub} 0 parquet")
|
|
print(f" {sub}: 0")
|
|
continue
|
|
mt = max(f.stat().st_mtime for f in fs)
|
|
latest = datetime.datetime.fromtimestamp(mt).strftime("%Y-%m-%d %H:%M")
|
|
print(f" {sub}: {len(fs)} parquet, latest={latest}")
|
|
ok.append(f"static/{sub}")
|
|
|
|
# 2. events/ per-date 类
|
|
print("\n===== events/ per-date 类 =====")
|
|
for sub in ["dragon_tiger", "block_trade", "margin_sse", "restricted"]:
|
|
d = BASE / "events" / sub
|
|
if not d.exists():
|
|
warn.append(f"events/{sub} MISSING(ak-events 未跑或当日无数据)")
|
|
print(f" {sub}: MISSING")
|
|
continue
|
|
fs = list(d.glob("*.parquet"))
|
|
print(f" {sub}: {len(fs)} parquet")
|
|
if fs:
|
|
ok.append(f"events/{sub}")
|
|
|
|
# 3. constituent_unified + _old
|
|
print("\n===== constituent_unified + _old =====")
|
|
c = sqlite3.connect(str(BASE / "quant_trading.db"), timeout=60)
|
|
try:
|
|
c.execute("PRAGMA busy_timeout = 60000")
|
|
n = c.execute("SELECT COUNT(*) FROM constituent_unified").fetchone()[0]
|
|
src = c.execute("SELECT source, COUNT(*) FROM constituent_unified GROUP BY source").fetchall()
|
|
print(f" constituent_unified: {n} rows, sources={src}")
|
|
if n >= 7110 and len(src) >= 3:
|
|
ok.append("constituent_unified>=7110+3source")
|
|
else:
|
|
warn.append(f"constituent_unified {n}<7110 或 source<3 {src}")
|
|
try:
|
|
nold = c.execute("SELECT COUNT(*) FROM bs_index_constituent_old").fetchone()[0]
|
|
print(f" bs_index_constituent_old: {nold} rows (baostock 历史时点完好)")
|
|
if nold > 0:
|
|
ok.append("_old intact")
|
|
except Exception as e:
|
|
warn.append(f"_old 查询失败 {e}")
|
|
finally:
|
|
c.close()
|
|
|
|
print("\n===== SUMMARY =====")
|
|
print(f"OK: {len(ok)} WARN: {len(warn)}")
|
|
for w in warn:
|
|
print(f" WARN {w}")
|
|
print("VERIFY DONE")
|