From d70ecc3d6c3b34ea17dacfe4296999e2153d0b9a Mon Sep 17 00:00:00 2001 From: zlt Date: Fri, 24 Jul 2026 15:07:31 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=B9=E5=99=A8=E5=8C=96=E6=94=B9=E9=80=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .env.example | 5 +++-- factors.py | 23 +++++++++++++++++++---- run.py | 7 +++++-- 3 files changed, 27 insertions(+), 8 deletions(-) diff --git a/.env.example b/.env.example index 3000400..db2caa7 100644 --- a/.env.example +++ b/.env.example @@ -29,8 +29,9 @@ FACTOR_MYSQL_DB= # PRICE_MYSQL_USER= # PRICE_MYSQL_PASSWORD= # PRICE_MYSQL_DB= -# gp_day_data 的股票代码列名(待实机核实:可能是 ts_code 或 symbol) -PRICE_CODE_COL=ts_code +# gp_day_data 的股票代码列名(平台实测=symbol)。代码会自动兜底逐个试(symbol/ts_code), +# 这里填对可省一次试探查询。 +PRICE_CODE_COL=symbol # 可选:用平台 REST 注册因子时填(留空=直连 ③ 写 factor_metadata) # FACTOR_API_BASE=http://192.168.16.155:8000 diff --git a/factors.py b/factors.py index 9344f72..3bd5f8b 100644 --- a/factors.py +++ b/factors.py @@ -53,6 +53,24 @@ def build_heat(start, end): return df[["trade_date", "stock_code", "factor_value"]] +def _read_gp_price(start, end): + """gp_day_data 现价:代码列名不定(平台实测=symbol,非 ts_code)——照 rsi_14d_etl + 惯例按候选列逐个试,用第一个能查通的。""" + cands = [config.PRICE_CODE_COL] + [c for c in ("symbol", "ts_code") + if c != config.PRICE_CODE_COL] + last = None + for c in cands: + try: + df = db.read_mysql("price", + f"SELECT `timestamp` AS trade_date, `{c}` AS ts_code, close " + f"FROM gp_day_data WHERE `timestamp` BETWEEN %s AND %s", (start, end)) + print(f" (upside 现价用 gp_day_data.{c})") + return df + except Exception as e: # noqa: BLE001 —— 列名不对就换下一个候选 + last = e + raise RuntimeError(f"gp_day_data 代码列都不行(试了 {cands}): {last!r}") + + # ---------------------------------------------------------------- 预期空间 def build_upside(start, end): """upside = 一致预期目标价中枢 / 当日现价 − 1(as-of:现价日取 asof<=当日最新一致预期)。 @@ -64,10 +82,7 @@ def build_upside(start, end): cons = cons[cons["ts_code"].isin(uni)].copy() if cons.empty: return _EMPTY - col = config.PRICE_CODE_COL - price = db.read_mysql("price", - f"SELECT `timestamp` AS trade_date, `{col}` AS ts_code, close " - f"FROM gp_day_data WHERE `timestamp` BETWEEN %s AND %s", (start, end)) + price = _read_gp_price(start, end) if price.empty: return _EMPTY price["close"] = pd.to_numeric(price["close"], errors="coerce") diff --git a/run.py b/run.py index b980507..5e153a7 100644 --- a/run.py +++ b/run.py @@ -80,8 +80,11 @@ def cmd_build(which, mode, start, end, date): if code not in factors.BUILDERS: raise SystemExit(f"未知因子: {code}(可选: {list(factors.FACTORS)} 或 all)") print(f"[{code}] {mode} {start} ~ {end}") - df = factors.BUILDERS[code](start, end) - common.write_factor(factors.FACTORS[code], df, mode) + try: + df = factors.BUILDERS[code](start, end) + common.write_factor(factors.FACTORS[code], df, mode) + except Exception as e: # noqa: BLE001 —— 一路失败不拖累其余(批量容错) + print(f" ❌ {code} 失败: {e!r}") def main():