From 8526976cb005373470d45eff51fe07bb9f3719b0 Mon Sep 17 00:00:00 2001 From: Beast Trader Date: Mon, 8 Jun 2026 00:00:00 +0800 Subject: [PATCH] =?UTF-8?q?v1.6:=20=E7=BB=93=E6=9E=84=E7=AA=81=E7=A0=B4?= =?UTF-8?q?=E5=9B=9E=E6=B5=8B=E9=AA=8C=E8=AF=81=E7=89=88=20+=206=E6=9D=A1?= =?UTF-8?q?=E4=BB=B6=E5=85=A5=E5=9C=BA=E4=BD=93=E7=B3=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- strategy.py | 105 ++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 74 insertions(+), 31 deletions(-) diff --git a/strategy.py b/strategy.py index 7b0b9aa..8ae5563 100644 --- a/strategy.py +++ b/strategy.py @@ -1,5 +1,5 @@ """ -Structure Flow Strategy v1.5 +Structure Flow Strategy v1.6 ======================= 变更记录: v1.0 (2026-06-07): 纯价格结构策略,D1定方向→4H定位→1H入场 @@ -7,10 +7,11 @@ Structure Flow Strategy v1.5 v1.2 (2026-06-07): Entry Candle止损,bug导致50笔硬止损全亏 v1.3 (2026-06-07): ATR动态止损,结果-63.72%,胜率20.2% v1.4 (2026-06-07): 回归纯价格结构止损,+140.71%,胜率38.7% - v1.5 (2026-06-07): ===== 参数调优 ===== - - stoploss -5% → -15%,释放结构止损空间 - - max_stop_dist 3% → 5%,增加交易频率 - 其他逻辑与v1.4完全相同 + v1.5 (2026-06-07): 参数调优(stoploss -5%→-15%, max_stop_dist 3%→5%),+140.83% + v1.6 (2026-06-07): ===== 入场质量优化 ===== + - 6-bar冷却期:信号后6h内不重复入场(防止连挨多刀) + - 活支撑/阻力检查:S/R必须被最近测试并守住才算有效 + 设计原则:不降频,只砍最差的那几笔重复入场 """ from datetime import datetime @@ -21,17 +22,19 @@ from freqtrade.strategy import IStrategy, IntParameter, informative from freqtrade.persistence import Trade -class StructureFlowStrategyV15(IStrategy): +class StructureFlowStrategyV16(IStrategy): """ - Structure Flow Strategy v1.5 — 纯价格结构,零指标 + Structure Flow Strategy v1.6 — 纯价格结构,零指标 - v1.5改动(相对于v1.4): - - stoploss -5% → -15%(硬止损放宽,让结构止损真正生效) - - max_stop_dist 3% → 5%(增加交易频率) + v1.6改动(相对于v1.5): + 1. 6-bar冷却期:同方向信号触发后,6h内禁止同向再入场 + → 解决"同一天同一个价位挨两刀"的问题 + 2. 活支撑/阻力检查:4H Swing Point 必须被价格测试并守住才有效 + → 解决"在死支撑上入场"的问题 """ can_short = True - stoploss = -0.15 # v1.5: -5% → -15% + stoploss = -0.15 use_custom_stoploss = True minimal_roi = {"0": 100} max_open_trades = 1 @@ -44,8 +47,9 @@ class StructureFlowStrategyV15(IStrategy): swing_lookback_d1 = IntParameter(8, 14, default=10, space="buy") swing_lookback_h4 = IntParameter(5, 10, default=8, space="buy") pin_bar_wick_ratio = IntParameter(50, 70, default=60, space="buy") - # v1.5: 默认值从30→50(3%→5%) max_stop_dist = IntParameter(20, 50, default=50, space="buy") + # v1.6 新增 + cooldown_bars = IntParameter(3, 12, default=6, space="buy") # ===================== # 工具:Swing Point 检测 @@ -209,6 +213,30 @@ class StructureFlowStrategyV15(IStrategy): dataframe["resistance"] = structure["resistance"] dataframe["in_demand"] = structure["in_demand"] dataframe["in_supply"] = structure["in_supply"] + + # ================================ + # v1.6 新增:活支撑/阻力检查 + # ================================ + # 支撑"活"的条件:在最近3根4H bar内,low 触及 support ±0.5% + # 并且收盘价在支撑之上(即测试后撑住了) + touched_support = ( + (dataframe["low"] <= dataframe["support"] * 1.005) & + (dataframe["low"] >= dataframe["support"] * 0.995) + ) + held_support = dataframe["close"] > dataframe["support"] + support_tested_and_held = touched_support & held_support + # 在过去3根4H bar内有至少一次"测试并守住" + dataframe["support_alive"] = support_tested_and_held.rolling(3, min_periods=1).max() > 0 + + # 阻力"活"的条件:high 触及 resistance ±0.5% 且 close 在阻力之下 + touched_resistance = ( + (dataframe["high"] >= dataframe["resistance"] * 0.995) & + (dataframe["high"] <= dataframe["resistance"] * 1.005) + ) + held_resistance = dataframe["close"] < dataframe["resistance"] + resistance_tested_and_held = touched_resistance & held_resistance + dataframe["resistance_alive"] = resistance_tested_and_held.rolling(3, min_periods=1).max() > 0 + return dataframe # ================================================================ @@ -240,6 +268,7 @@ class StructureFlowStrategyV15(IStrategy): "trend_up_1d", "trend_down_1d", "trend_up_4h", "trend_down_4h", "in_demand_4h", "in_supply_4h", + "support_alive_4h", "resistance_alive_4h", "bullish_signal", "bearish_signal", ] for col in bool_cols: @@ -257,24 +286,24 @@ class StructureFlowStrategyV15(IStrategy): 入场逻辑(1H 时间框架)。 做多条件: - 1. D1 上升结构(trend_up_1d)— 宏观方向 - 2. 4H 需求区域(in_demand_4h)— 在支撑附近 + 1. D1 上升结构(trend_up_1d) + 2. 4H 需求区域(in_demand_4h) 3. 1H 看涨 K 线形态(bullish_signal) - 4. 止损距离 ≤ max_stop_dist% — 赔率过滤(v1.5: 默认5%) - - 做空条件: - 1. D1 下降结构(trend_down_1d) - 2. 4H 供给区域(in_supply_4h) - 3. 1H 看跌 K 线形态(bearish_signal) 4. 止损距离 ≤ max_stop_dist% + 5. [v1.6] 支撑位是"活"的(support_alive_4h) + 6. [v1.6] 6h内没有过同方向入场信号(冷却期) + + 做空条件对称。 """ max_dist = self.max_stop_dist.value / 100.0 + cooldown = self.cooldown_bars.value # NaN 安全处理 bool_cols = [ "trend_up_1d", "trend_down_1d", "trend_up_4h", "trend_down_4h", "in_demand_4h", "in_supply_4h", + "support_alive_4h", "resistance_alive_4h", "bullish_signal", "bearish_signal", ] for col in bool_cols: @@ -284,25 +313,41 @@ class StructureFlowStrategyV15(IStrategy): # ── 做多 ── long_stop_dist = (dataframe["open"] - dataframe["support_4h"]) / dataframe["open"] - long_conditions = ( + long_base = ( dataframe["trend_up_1d"] & dataframe["in_demand_4h"] & dataframe["bullish_signal"] & (long_stop_dist <= max_dist) - & (long_stop_dist > 0.003) # 至少0.3%距离(避免support就在眼前) + & (long_stop_dist > 0.003) ) + + # v1.6: 活支撑 — 支撑必须在最近3根4H内被测试并守住 + long_base = long_base & dataframe["support_alive_4h"] + + # v1.6: 冷却期 — 过去N根1H bar内没有过满足条件的做多信号 + long_recent = long_base.rolling(cooldown, min_periods=1).max().shift(1) == 0 + long_conditions = long_base & long_recent + dataframe.loc[long_conditions, "enter_long"] = 1 # ── 做空 ── short_stop_dist = (dataframe["resistance_4h"] - dataframe["open"]) / dataframe["open"] - short_conditions = ( + short_base = ( dataframe["trend_down_1d"] & dataframe["in_supply_4h"] & dataframe["bearish_signal"] & (short_stop_dist <= max_dist) & (short_stop_dist > 0.003) ) + + # v1.6: 活阻力 — 阻力必须在最近3根4H内被测试并守住 + short_base = short_base & dataframe["resistance_alive_4h"] + + # v1.6: 冷却期 — 过去N根1H bar内没有过满足条件的做空信号 + short_recent = short_base.rolling(cooldown, min_periods=1).max().shift(1) == 0 + short_conditions = short_base & short_recent + dataframe.loc[short_conditions, "enter_short"] = 1 return dataframe @@ -344,8 +389,6 @@ class StructureFlowStrategyV15(IStrategy): support_4h / resistance_4h 随新Swing Point自动更新, 天然形成追踪止损效果。 - - v1.5: 硬止损从-5%放宽到-15%,让结构止损真正生效。 """ dataframe, _ = self.dp.get_analyzed_dataframe(pair, self.timeframe) if dataframe is None or len(dataframe) == 0: @@ -356,20 +399,16 @@ class StructureFlowStrategyV15(IStrategy): if not trade.is_short: support = last.get("support_4h", np.nan) if pd.isna(support) or support <= 0: - return -0.02 # fallback - # 止损 = support_4h 下方 0.1% + return -0.02 sl_price = support * 0.999 sl_ratio = (sl_price / current_rate) - 1.0 - # v1.5: 硬止损从-5% → -15% return max(sl_ratio, -0.15) else: resistance = last.get("resistance_4h", np.nan) if pd.isna(resistance) or resistance <= 0: - return 0.02 # fallback - # 止损 = resistance_4h 上方 0.1% + return 0.02 sl_price = resistance * 1.001 sl_ratio = 1.0 - (sl_price / current_rate) - # v1.5: 硬止损从+5% → +15% return min(sl_ratio, 0.15) # ===================== @@ -388,5 +427,9 @@ class StructureFlowStrategyV15(IStrategy): "bullish_pinbar": {"color": "green", "type": "scatter"}, "bearish_pinbar": {"color": "red", "type": "scatter"}, }, + "filters": { + "support_alive_4h": {"color": "green", "type": "line"}, + "resistance_alive_4h": {"color": "red", "type": "line"}, + }, }, }