diff --git a/deploy/profile-scripts/mofin_db.py b/deploy/profile-scripts/mofin_db.py index 618bf4fa..f82de1d8 100644 --- a/deploy/profile-scripts/mofin_db.py +++ b/deploy/profile-scripts/mofin_db.py @@ -693,6 +693,14 @@ def write_klines(conn: sqlite3.Connection, code: str, name: str, exchange, stype = "SZ", "A" # stocks 表(INSERT OR REPLACE) + # 2026-08-22 名称治理:name 缺失/等于代码时保留已有真名,避免 REPLACE 覆盖好数据 + if not name or str(name) == str(code): + try: + _r = conn.execute("SELECT name FROM stocks WHERE code=?", (str(code),)).fetchone() + if _r and _r[0] and _r[0] != str(code): + name = _r[0] + except Exception: + pass conn.execute( "INSERT OR REPLACE INTO stocks (code, name, exchange, type, updated_at) VALUES (?, ?, ?, ?, ?)", (code, name, exchange, stype, datetime.now().isoformat())) @@ -1085,6 +1093,39 @@ def query_latest_market(conn: sqlite3.Connection) -> dict: # 通用工具 # ═══════════════════════════════════════════════════════════════════ +def fetch_stock_name_tencent(code: str) -> str | None: + """腾讯 quote 单票查名(数据层专用,2026-08-22 名称治理)。 + + A股按 6/9→sh、其余→sz;港股5位0/1开头→hk。查到真名返回,查不到返回 None。 + """ + import urllib.request + code = str(code).strip() + if not code: + return None + if len(code) == 5 and code[0] in "01": + sym = "hk" + code + elif code[0] in "69": + sym = "sh" + code + else: + sym = "sz" + code + try: + url = f"http://qt.gtimg.cn/q={sym}" + req = urllib.request.Request(url, headers={"User-Agent": "Mozilla/5.0"}) + with urllib.request.urlopen(req, timeout=5) as resp: + text = resp.read().decode("gbk", errors="ignore") + # 格式: v_sh600110="1~诺德股份~600110~..." + if '="' in text and "~" in text: + payload = text.split('="', 1)[1] + parts = payload.split("~") + if len(parts) > 1: + name = parts[1].strip() + if name and name != code: + return name + except Exception: + pass + return None + + def get_price_from_db(code: str) -> tuple[float | None, float | None]: """从 DB 读取最新价格(price_monitor 维护)。 返回 (price, change_pct) 或 (None, None)