""" chan_enhance.py —— 缠论系统增强(查漏补缺) · 纯函数版(非Hook) """ from __future__ import annotations W_REVERSAL = 1.0 W_TRAP = 0.85 W_RELAY = 0.6 W_UNKNOWN = 0.7 # 第16课 六种基本走势 → 买法分类的中文名(配合英文 method 一起展示) METHOD_CN = { 'reversal': '反转式(下跌+盘整+上涨 / 趋势底背驰一买, 力度最强, 权重最高)', 'trap': '陷阱式(下跌+上涨, 空头陷阱式二买, 中等力度)', 'relay': '中继式(上涨+盘整+上涨, 三买, 趋势中继)', 'unknown': '未分类', } WEAK_ARM_GAIN = 0.04 WEAK_GIVEBACK = 0.22 L92_EXIT_ENABLE = False L92_EXIT_FLOATING_MAX = 0.015 L92_ZD_BREAK_BUF = 0.0 def classify_buy_method(sig_kind, ml) -> str: sig = ml.daily.signal if (ml and ml.daily) else None dg = getattr(sig, 'diverge_grade', None) if sig is not None else None if sig_kind == 'B1': return 'reversal' if sig_kind == 'B3': return 'relay' if sig_kind == 'B2': # L37 背驰分辨: 只有"趋势背驰"(≥2个同向中枢后的背驰)才是标准的趋势转折, # 对应第16课"下跌+盘整+上涨"反转式买法; 盘整背驰力度弱, 仍按陷阱式处理。 if (dg is not None and getattr(dg, 'grade', '') == 'STRONG' and getattr(dg, 'is_trend_divergence', False)): return 'reversal' return 'trap' return 'unknown' def l37_divergence_note(ml) -> str: """L37 背驰分辨(区分背驰段构成): 趋势背驰=至少两个同向中枢后的背驰, 转折级别高; 盘整背驰=单中枢内的力度衰竭, 只保证回拉中枢, 不保证反转。""" sig = ml.daily.signal if (ml and ml.daily) else None dg = getattr(sig, 'diverge_grade', None) if sig is not None else None if dg is None or getattr(dg, 'grade', 'NONE') == 'NONE': return '' if getattr(dg, 'is_trend_divergence', False): return (f'第37课: 趋势背驰({getattr(dg, "n_trend_pivots", "?")}个同向中枢), ' f'转折至少回拉至最后一个中枢, 大概率反转 → 可按反转式买法重仓') return ('第37课: 盘整背驰(背驰段内仅1个中枢), 只保证回拉中枢一次, ' '不保证趋势反转 → 轻仓短打, 回拉到中枢即考虑兑现') def buy_method_weight(sig_kind, ml): method = classify_buy_method(sig_kind, ml) wmap = {'reversal': W_REVERSAL, 'trap': W_TRAP, 'relay': W_RELAY, 'unknown': W_UNKNOWN} return method, wmap.get(method, W_UNKNOWN) def recompute_evo(ml) -> str: sig = ml.daily.signal if (ml and ml.daily) else None if sig is not None: evo = (sig.extras or {}).get('post_evolution', '') if evo: return evo dv = ml.daily if ml else None if dv is not None and dv.zd is not None and dv.zg is not None: if ml.cur_price < dv.zd: return 'case1_extend' return '' def weak_evo_giveback(pos, ml, default_giveback): evo = recompute_evo(ml) if ml is not None else (pos.get('post_evo') or '') if evo == 'case1_extend': return WEAK_ARM_GAIN, WEAK_GIVEBACK return None, default_giveback def l92_should_exit(pos, ml, close_p, floating): if not L92_EXIT_ENABLE or ml is None or ml.daily is None: return None if floating > L92_EXIT_FLOATING_MAX: return None zd = ml.daily.zd if zd is None: return None if close_p < zd * (1 - L92_ZD_BREAK_BUF) and close_p > pos.get('stop_px', 0): return ('L92_EXIT', f'第92课中枢震荡监视器: 现价{close_p:.3f}已破日线中枢下沿ZD{zd:.3f}' f'(向下变盘) 且浮盈仅{floating:+.1%} → 提前减仓, 不等磨到结构止损') return None def predict_enhance(ml) -> dict: out = {} if ml is None or ml.daily is None: return out sig_kind = ml.final_kind or '' if sig_kind in ('B1', 'B2', 'B3'): method, weight = buy_method_weight(sig_kind, ml) out['buy_method'] = method out['buy_method_cn'] = METHOD_CN.get(method, method) out['suggest_weight'] = weight out['l16_note'] = f'第16课: 买法分类={method}〔{METHOD_CN.get(method, method)}〕, 建议仓位权重{weight:.2f}' l37 = l37_divergence_note(ml) if l37: out['l37_note'] = l37 evo = recompute_evo(ml) if evo: out['post_evolution'] = evo out['evo_hint'] = ('第29课: 最弱形态(反弹/回落未回中枢), 持有宜收紧移动止盈, 尽快兑现' if evo == 'case1_extend' else '第29课: 形态较强(回到中枢), 可持有等三买/趋势延续') zd = ml.daily.zd if zd is not None and ml.cur_price < zd: out['l92_warn'] = f'第92课: 现价{ml.cur_price:.3f}已在日线中枢下沿ZD{zd:.3f}下方 → 向下变盘预警' return out