refactor: 统一价格入口 mo_data.get_price() - 22个脚本移除自拉腾讯API

所有价格获取统一走 mo_data.get_price() / get_prices_batch():
  - 优先读 live_prices(DB) → 无/过期才调 stock_quote(API) → 自动写回DB
  - 22个脚本全部替换:branch_scanner chip_factors divergence_detector
    market_screener mo_provider mofin_collect monitor_300308 300308_monitor
    multi_timeframe refresh_macro_context stale_detector stale_push_wlin
    stock_profile strategy_evaluator strategy_lifecycle strategy_review
    strategy-staleness-check technical_analysis xiaoguo_signal_consumer
    collect_evaluation_data
This commit is contained in:
知微
2026-07-08 23:54:01 +08:00
parent 0e21a3ae83
commit 9fef32413b
46 changed files with 5530 additions and 21994 deletions
+7 -38
View File
@@ -14,20 +14,17 @@
输出:写入 decisions.json 的 evaluation 字段 + accuracy_stats.json
"""
import json
import urllib.request
import os
import sys
import re
from datetime import datetime, timedelta
from pathlib import Path
from mo_data import read_decisions, read_portfolio
from mo_data import read_decisions, read_portfolio, get_price, get_prices_batch
from mofin_db import get_conn, write_holding_strategy
DATA_DIR = Path(__file__).parent.parent / "data"
ACCURACY_PATH = DATA_DIR / "accuracy_stats.json"
UA = "Mozilla/5.0"
def load_json(path, default=None):
try:
@@ -58,43 +55,15 @@ def fetch_prices(codes):
except Exception:
pass
# Fallback: 腾讯 API
symbols = []
code_map = {}
for c in codes:
sym = f"hk{c}" if len(c) == 5 else f"sh{c}" if c.startswith(("5", "6", "9")) else f"sz{c}"
symbols.append(sym)
code_map[sym] = c
url = f"http://qt.gtimg.cn/q={','.join(symbols)}"
# Fallback: mo_data.get_prices_batch
try:
req = urllib.request.Request(url, headers={"User-Agent": UA})
resp = urllib.request.urlopen(req, timeout=10)
text = resp.read().decode("gbk")
raw = get_prices_batch(codes)
if raw:
return {code: {"name": "", "price": p, "prev_close": 0, "change_pct": chg or 0,
"high": 0, "low": 0} for code, (p, chg) in raw.items()}
except Exception as e:
print(f"行情拉取失败: {e}", file=sys.stderr)
return {}
prices = {}
for line in text.strip().split("\n"):
line = line.strip()
if not line or "=" not in line:
continue
raw = line.split("=", 1)[1].strip().strip('"').strip(";")
fields = raw.split("~")
if len(fields) < 33:
continue
sym = line.split("=", 1)[0].strip().lstrip("v_")
orig = code_map.get(sym)
if not orig:
continue
prices[orig] = {
"name": fields[1],
"price": float(fields[3]) if fields[3] else 0,
"prev_close": float(fields[4]) if fields[4] else 0,
"change_pct": float(fields[32]) if fields[32] else 0,
"high": float(fields[33]) if fields[33] else 0,
"low": float(fields[34]) if fields[34] else 0,
}
return prices
return {}
def parse_tech_snapshot(decision):