#!/usr/bin/env python3 # -*- coding: utf-8 -*- """补 strategy_defs 的 trend 家族卡(2026-08-18) v_next / v8.1(trend_up 激活的顺势策略,映射 leader_scanner.py) 执行:/home/hmo/MoFin/venv/bin/python add_trend_defs.py """ import sqlite3, json, hashlib DB = "/home/hmo/MoFin/data/mofin.db" conn = sqlite3.connect(DB, timeout=30) conn.execute("PRAGMA busy_timeout=30000") def upsert(s): hp = hashlib.md5((s.get("key_params") or "").encode()).hexdigest()[:12] s2 = dict(s); s2["params_hash"] = hp; s2["updated_at"] = "2026-08-18 21:20:00"; s2["updated_by"] = "add_trend_defs.py" cols = ",".join(s2.keys()); ph = ",".join("?" * len(s2)) conn.execute( f"INSERT INTO strategy_defs ({cols}) VALUES ({ph}) ON CONFLICT(strategy_name) DO UPDATE SET " f"display_name=excluded.display_name, aliases=excluded.aliases, market=excluded.market, " f"regime=excluded.regime, family=excluded.family, summary=excluded.summary, " f"entry_logic=excluded.entry_logic, exit_logic=excluded.exit_logic, " f"key_params=excluded.key_params, review_focus=excluded.review_focus, " f"holding_style=excluded.holding_style, status=excluded.status, " f"retired_reason=excluded.retired_reason, superseded_by=excluded.superseded_by, " f"params_hash=excluded.params_hash, needs_review=excluded.needs_review, " f"doc_ref=excluded.doc_ref, scanner_file=excluded.scanner_file, " f"version=excluded.version, updated_at=excluded.updated_at, updated_by=excluded.updated_by", [s2[k] for k in s2]) print(f" + {s['strategy_name']} 已写入/更新") # v_next:趋势市龙头回调(trend_up 激活,映射 leader_scanner.py) upsert(dict( strategy_name="v_next", display_name="趋势市龙头回调买点", aliases=json.dumps(["v_next", "v_next4", "leader", "bull_trend"]), market="A", regime="trend_up", family="trend_momentum", summary="牛市(trend_up)买入龙头股回调到 MA20 附近的健康回调(dist_ma20∈[-3%,+2%]、RSI 45-65 强势未超买、量能配合、行业趋势共振),不追高。", entry_logic="dist_ma20∈[-3%,+2%](回调到MA20附近,不追高);RSI 45-65(强势但未超买);mcap_q>0.3(龙头非小盘);vol_ratio>0.8(量能配合);trend_aligned=1(趋势共振)。", exit_logic="跌破 MA20 下方 8% 止损(MA20×0.92);+15% 止盈(MA20×1.15,压力位);买入区 MA20×0.98~MA20。", key_params=json.dumps({"dist_ma20_range": [-3,2], "rsi_range": [45,65], "mcap_q_min": 0.3, "vol_ratio_min": 0.8, "trend_aligned": 1, "tp_pct": 0.15, "sl_pct": 0.08, "regime": "trend_up"}), review_focus="①牛市温区是否延续(trend_up→其他=龙头策略失效,需切换)②回调买点是否仍成立(价格还在MA20附近吗)③RSI是否仍强势未超买④量能是否配合⑤跌破MA20止损位合理性", holding_style="趋势持有(龙头主升浪,回调即买点)", status="active", version="v_next", scanner_file="leader_scanner.py", doc_ref="", )) # v8.1:波段先出再进(trend_up 激活的顺势波段) upsert(dict( strategy_name="v8.1", display_name="顺势波段先出再进", aliases=json.dumps(["v8.1", "v8"]), market="A", regime="trend_up", family="trend_momentum", summary="趋势市顺势波段:上升趋势中回调买入,波段顶部先出、回踩再进(波段先出再进),吃趋势主升的波段利润。", entry_logic="上升趋势(trend_up)中的回调买点;趋势共振 + 技术位支撑买入;避免追高。", exit_logic="波段顶部先出(压力位/超买);回踩支撑再进;跌破趋势线止损。", key_params=json.dumps({"regime": "trend_up", "mode": "swing_band"}), review_focus="①趋势是否延续(trend_up)②当前在波段哪个位置(顶部该出/回调该进)③止损/止盈空间④温区切换风险", holding_style="波段(顺势,先出再进)", status="active", version="v8.1", scanner_file="leader_scanner.py", doc_ref="", )) # 更新候选目录引用(batch_reassess 的 _CANDIDATES 加 v_next/v8.1) # 在 parse_response 的 _CANDIDATES 里补 conn.commit() n = conn.execute("SELECT COUNT(*) FROM strategy_defs").fetchone()[0] print(f"\nstrategy_defs 共 {n} 张卡:") for r in conn.execute("SELECT strategy_name, display_name, regime, status FROM strategy_defs ORDER BY strategy_name").fetchall(): print(f" {r[0]} | {r[1]} | {r[2]} | {r[3]}") conn.close()