diff --git a/deploy/profile-scripts/price_monitor.py b/deploy/profile-scripts/price_monitor.py index b5159d11..25f5cd92 100644 --- a/deploy/profile-scripts/price_monitor.py +++ b/deploy/profile-scripts/price_monitor.py @@ -608,7 +608,16 @@ def run_once(round_label=""): # === 第三步:买入区偏离检测 + 自动重评 === reassesed_codes = [] # 先做急跌检测(仅持仓,自选股不推送暴跌告警) - holdings_codes = {d["code"] for d in active if (d.get("shares") or 0) > 0} + holdings_codes = set() + for d in active: + shares = d.get("shares", 0) + if isinstance(shares, (int, float)): + if shares > 0: + holdings_codes.add(d["code"]) + else: + # 非数值shares(如被错误写入的字符串),兜底处理 + holdings_codes.add(d["code"]) + print(f" [WARN] {d.get('code')} shares为非数值({shares!r}),视为持仓处理", flush=True) for d in active: code = d["code"] # 非持仓跳过 diff --git a/mofin_db.py b/mofin_db.py index 98ff7177..6e4ba6ab 100644 --- a/mofin_db.py +++ b/mofin_db.py @@ -1180,6 +1180,12 @@ def write_holding_strategy(conn, code: str, name: str, data: dict, except: pass + # ── 类型守卫:shares 必须是数值,防止字符串写入导致下游崩溃 ── + _shares = data.get('shares', 0) + if not isinstance(_shares, (int, float)): + print(f" [TYPE GUARD] {code} shares类型异常({type(_shares).__name__}={_shares!r}),重置为0", flush=True) + _shares = 0 + # DELETE + INSERT conn.execute("DELETE FROM holding_strategies WHERE code=?", (code,)) conn.execute(""" @@ -1199,7 +1205,7 @@ def write_holding_strategy(conn, code: str, name: str, data: dict, """, ( code, name, data.get('version', 1), data.get('price'), data.get('cost'), - data.get('shares', 0), data.get('stop_loss'), data.get('take_profit'), + _shares, data.get('stop_loss'), data.get('take_profit'), data.get('entry_low'), data.get('entry_high'), currency, data.get('strategy_type', 'holding'), data.get('action'), data.get('timing_signal'), data.get('rr_ratio'),