fix: review修复 — 补回last_df_ts、枚举替换魔数、移除死代码

- SymbolState 补回 last_df_ts,无效新K线时跳过管线
- _bi_id 添加 start_klc None 防护
- last_bi.dir.value == 1 改为 Chan_BI_DIR.UP 枚举比较
- notify.py 移除未使用的 register_bsp_keys

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
jackyu66git
2026-05-26 12:56:17 +08:00
co-authored by Claude Opus 4.7
parent 78d02cf2ef
commit 743c5d342e
+21 -9
View File
@@ -27,6 +27,7 @@ _PARENT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
if _PARENT not in sys.path: if _PARENT not in sys.path:
sys.path.insert(0, _PARENT) sys.path.insert(0, _PARENT)
from ChanPivotMonitor import ChanPivotMonitor from ChanPivotMonitor import ChanPivotMonitor
from ChanEnum import Chan_BI_DIR
logging.basicConfig( logging.basicConfig(
level=logging.INFO, level=logging.INFO,
@@ -40,8 +41,10 @@ def _short(symbol: str) -> str:
return symbol.split(":")[0].replace("/", "") return symbol.split(":")[0].replace("/", "")
def _bi_id(bi) -> tuple: def _bi_id(bi) -> Optional[tuple]:
"""笔的稳定标识,基于首K线时间戳。""" """笔的稳定标识,基于首K线时间戳。"""
if bi.start_klc is None:
return None
return (bi.start_klc.start_time,) return (bi.start_klc.start_time,)
@@ -50,6 +53,7 @@ class SymbolState:
symbol: str symbol: str
pivot_monitor: ChanPivotMonitor = field(default_factory=ChanPivotMonitor) pivot_monitor: ChanPivotMonitor = field(default_factory=ChanPivotMonitor)
last_bi_id: Optional[tuple] = None # 上次检查过的最后一笔 ID last_bi_id: Optional[tuple] = None # 上次检查过的最后一笔 ID
last_df_ts: object = None # 最新已处理的 K 线时间戳
first_run: bool = True first_run: bool = True
@@ -85,22 +89,30 @@ class BSPMonitor:
logger.warning(f"[{name}] DataFrame 为空") logger.warning(f"[{name}] DataFrame 为空")
return return
# 2. 运行缠论管线 # 2. 检查是否有新 K 线
latest_ts = df.iloc[-1]["timestamp"]
if st.last_df_ts and latest_ts <= st.last_df_ts:
return
st.last_df_ts = latest_ts
# 3. 运行缠论管线
try: try:
engine = ChanEngine(df) engine = ChanEngine(df)
except Exception as e: except Exception as e:
logger.error(f"[{name}] 缠论计算失败: {e}", exc_info=True) logger.error(f"[{name}] 缠论计算失败: {e}", exc_info=True)
return return
# 3. 获取已确认的笔 # 4. 获取已确认的笔
confirmed = [b for b in engine.bi_list if b.is_sure] confirmed = [b for b in engine.bi_list if b.is_sure]
if len(confirmed) < 2: if len(confirmed) < 2:
return return
last_bi = confirmed[-1] last_bi = confirmed[-1]
current_bi_id = _bi_id(last_bi) current_bi_id = _bi_id(last_bi)
if current_bi_id is None:
return
# 4. 首轮:记录状态,不推送 # 5. 首轮:记录状态,不推送
if st.first_run: if st.first_run:
st.first_run = False st.first_run = False
st.last_bi_id = current_bi_id st.last_bi_id = current_bi_id
@@ -111,16 +123,16 @@ class BSPMonitor:
) )
return return
# 5. 检测新笔 # 6. 检测新笔
if current_bi_id == st.last_bi_id: if current_bi_id == st.last_bi_id:
return # 无新笔,跳过 return # 无新笔,跳过
st.last_bi_id = current_bi_id st.last_bi_id = current_bi_id
bi_dir = "⬆️" if last_bi.dir == Chan_BI_DIR.UP else "⬇️"
logger.info(f"[{name}] 新笔确认 — #{len(confirmed)} " logger.info(f"[{name}] 新笔确认 — #{len(confirmed)} "
f"{'⬆️' if last_bi.dir.value == 1 else '⬇️'} " f"{bi_dir} 高度: ${last_bi.height:.2f}")
f"高度: ${last_bi.height:.2f}")
# 6. 检查上一笔终点是否为 BSP # 7. 检查上一笔终点是否为 BSP
prev_bi = confirmed[-2] prev_bi = confirmed[-2]
bsp = engine.get_bsp_for_bi(prev_bi) bsp = engine.get_bsp_for_bi(prev_bi)
if bsp: if bsp:
@@ -130,7 +142,7 @@ class BSPMonitor:
if send_bsp_alert(msg, bsp_key=key): if send_bsp_alert(msg, bsp_key=key):
logger.info(f"[{name}] ✅ BSP: {key}") logger.info(f"[{name}] ✅ BSP: {key}")
# 7. 中枢特征更新 # 8. 中枢特征更新
pivot_state = st.pivot_monitor.update(engine.bi_zs_list) pivot_state = st.pivot_monitor.update(engine.bi_zs_list)
if pivot_state: if pivot_state:
logger.info( logger.info(