fix: divergence_detector 改用新浪API直接获取指数数据(原mo_data不支持指数代码)
This commit is contained in:
@@ -14,9 +14,7 @@ divergence_detector.py — 跨市场背离监测器(no_agent)
|
|||||||
- 状态文件 macro_divergence_state.json
|
- 状态文件 macro_divergence_state.json
|
||||||
- no_agent: 有信号才出声
|
- no_agent: 有信号才出声
|
||||||
"""
|
"""
|
||||||
import sys, json, re, datetime, os
|
import sys, json, re, datetime, os, requests
|
||||||
|
|
||||||
from mo_data import get_price, get_prices_batch
|
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
BASE = Path("/home/hmo/MoFin")
|
BASE = Path("/home/hmo/MoFin")
|
||||||
@@ -42,27 +40,69 @@ DIVERGENCE_MODERATE = 3.0 # >3% → moderate信号
|
|||||||
STREAK_DAYS = 3 # 连涨/连跌3天 → 信号
|
STREAK_DAYS = 3 # 连涨/连跌3天 → 信号
|
||||||
|
|
||||||
def fetch_indices():
|
def fetch_indices():
|
||||||
"""获取所有指数实时数据(通过 mo_data.get_prices_batch)"""
|
"""获取所有指数实时数据(直接调用新浪API,mo_data不支持指数代码)"""
|
||||||
symbols = list(INDEX_CODES.values())
|
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:
|
try:
|
||||||
raw = get_prices_batch(symbols)
|
r = requests.get(url, headers=headers, timeout=10)
|
||||||
if not raw:
|
r.encoding = "gbk"
|
||||||
return {}
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"[DIVERGE] 采集失败: {e}", file=sys.stderr)
|
print(f"[DIVERGE] 采集失败: {e}", file=sys.stderr)
|
||||||
return {}
|
return {}
|
||||||
|
|
||||||
indices = {}
|
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] = {
|
indices[sym] = {
|
||||||
"name": "",
|
"name": name,
|
||||||
"price": price,
|
"price": price,
|
||||||
"close": 0,
|
"close": 0,
|
||||||
"change_pct": change_pct,
|
"change_pct": change_pct,
|
||||||
"high": 0,
|
"high": 0,
|
||||||
"low": 0,
|
"low": 0,
|
||||||
"timestamp": "",
|
"timestamp": datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
|
||||||
}
|
}
|
||||||
|
|
||||||
return indices
|
return indices
|
||||||
|
|
||||||
def load_history():
|
def load_history():
|
||||||
|
|||||||
Reference in New Issue
Block a user