From d972553b6e344a9afa464cba614157803743199e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=9F=A5=E5=BE=AE?= Date: Tue, 14 Jul 2026 11:08:07 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20divergence=5Fdetector=20=E6=94=B9?= =?UTF-8?q?=E7=94=A8=E6=96=B0=E6=B5=AAAPI=E7=9B=B4=E6=8E=A5=E8=8E=B7?= =?UTF-8?q?=E5=8F=96=E6=8C=87=E6=95=B0=E6=95=B0=E6=8D=AE=EF=BC=88=E5=8E=9F?= =?UTF-8?q?mo=5Fdata=E4=B8=8D=E6=94=AF=E6=8C=81=E6=8C=87=E6=95=B0=E4=BB=A3?= =?UTF-8?q?=E7=A0=81=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/divergence_detector.py | 62 ++++++++++++++++++++++++++++------ 1 file changed, 51 insertions(+), 11 deletions(-) diff --git a/scripts/divergence_detector.py b/scripts/divergence_detector.py index b0594bae..b146aa53 100644 --- a/scripts/divergence_detector.py +++ b/scripts/divergence_detector.py @@ -14,9 +14,7 @@ divergence_detector.py — 跨市场背离监测器(no_agent) - 状态文件 macro_divergence_state.json - no_agent: 有信号才出声 """ -import sys, json, re, datetime, os - -from mo_data import get_price, get_prices_batch +import sys, json, re, datetime, os, requests from pathlib import Path BASE = Path("/home/hmo/MoFin") @@ -42,27 +40,69 @@ DIVERGENCE_MODERATE = 3.0 # >3% → moderate信号 STREAK_DAYS = 3 # 连涨/连跌3天 → 信号 def fetch_indices(): - """获取所有指数实时数据(通过 mo_data.get_prices_batch)""" - symbols = list(INDEX_CODES.values()) + """获取所有指数实时数据(直接调用新浪API,mo_data不支持指数代码)""" + import requests + sina_map = { + "sh000001": "s_sh000001", + "sz399001": "s_sz399001", + "sz399006": "s_sz399006", + "sh000688": "s_sh000688", + "sh000016": "s_sh000016", + "sh000300": "s_sh000300", + "hkHSI": "rt_hkHSI", + "hkHSCEI": "rt_hkHSCEI", + } + url = "http://hq.sinajs.cn/list=" + ",".join(sina_map.values()) + headers = {"Referer": "https://finance.sina.com.cn"} try: - raw = get_prices_batch(symbols) - if not raw: - return {} + r = requests.get(url, headers=headers, timeout=10) + r.encoding = "gbk" except Exception as e: print(f"[DIVERGE] 采集失败: {e}", file=sys.stderr) return {} indices = {} - for sym, (price, change_pct) in raw.items(): + for line in r.text.strip().split("\n"): + line = line.strip() + if not line: + continue + # Parse: var hq_str_XXXX="fields,..."; + try: + var_name = line.split('"')[0].rsplit("_", 1)[-1].rstrip("=") + fields = line.split('"')[1].split(",") + except (IndexError, ValueError): + continue + + # Find the symbol + sym = None + for s, sn in sina_map.items(): + if sn.endswith(var_name): + sym = s + break + if not sym: + continue + + if sym.startswith("hk"): + # HK: name,price,open,high,low,prev_close,change,change_pct,... + name = fields[1] + price = float(fields[2]) if fields[2] else 0 + change_pct = float(fields[8]) if len(fields) > 8 and fields[8] else 0 + else: + # A-share: name,price,change,change_pct,... + name = fields[0] + price = float(fields[1]) if fields[1] else 0 + change_pct = float(fields[3]) if len(fields) > 3 and fields[3] else 0 + indices[sym] = { - "name": "", + "name": name, "price": price, "close": 0, "change_pct": change_pct, "high": 0, "low": 0, - "timestamp": "", + "timestamp": datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"), } + return indices def load_history():