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:
@@ -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):
|
||||
|
||||
Reference in New Issue
Block a user