""" SOL5mStrategyV6 - 趋势跟随策略 V6(基于V5改进) 核心改进: - 去掉trend_reversal退出(V5中54笔全亏 -611 USDT) - 完全依赖 ROI + trailing_stop + stoploss 管理退出 - 更激进的trailing:1.5%盈利后激活,0.6%回撤 - 保持V5的入场逻辑(EMA排列 + 回调入场 + RSI + MACD + ADX) """ from datetime import datetime from typing import Optional import talib.abstract as ta from pandas import DataFrame from freqtrade.persistence import Trade from freqtrade.strategy import IStrategy class SOL5mStrategyV6(IStrategy): INTERFACE_VERSION: int = 3 timeframe = "15m" can_short = True startup_candle_count: int = 200 # 止损 stoploss = -0.025 use_custom_stoploss = False # 更激进的trailing stop trailing_stop = True trailing_stop_positive = 0.006 # 0.6% 回撤止盈 trailing_stop_positive_offset = 0.015 # 1.5% 盈利后激活 trailing_only_offset_is_reached = True # ROI minimal_roi = { "0": 0.04, # 4%直接止盈 "60": 0.03, # 1小时后 3% "180": 0.02, # 3小时后 2% "360": 0.01, # 6小时后 1% "720": 0.005, # 12小时后 0.5% "1440": 0, # 24小时后保本 } order_types = { "entry": "market", "exit": "market", "stoploss": "market", "stoploss_on_exchange": False, } def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: # EMA趋势 dataframe["ema20"] = ta.EMA(dataframe, timeperiod=20) dataframe["ema50"] = ta.EMA(dataframe, timeperiod=50) dataframe["ema100"] = ta.EMA(dataframe, timeperiod=100) # RSI dataframe["rsi"] = ta.RSI(dataframe, timeperiod=14) # MACD macd = ta.MACD(dataframe, fastperiod=12, slowperiod=26, signalperiod=9) dataframe["macd"] = macd["macd"] dataframe["macdsignal"] = macd["macdsignal"] dataframe["macdhist"] = macd["macdhist"] # ADX (趋势强度) dataframe["adx"] = ta.ADX(dataframe, timeperiod=14) return dataframe def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: # 做多条件(与V5相同) dataframe.loc[ (dataframe["ema20"] > dataframe["ema50"]) & (dataframe["ema50"] > dataframe["ema100"]) & (dataframe["close"] <= dataframe["ema20"] * 1.005) & (dataframe["close"] >= dataframe["ema50"]) & (dataframe["rsi"] > 40) & (dataframe["rsi"] < 65) & (dataframe["macdhist"] > 0) & (dataframe["adx"] > 20), ["enter_long", "enter_tag"], ] = (1, "trend_pullback_long") # 做空条件(与V5相同) dataframe.loc[ (dataframe["ema20"] < dataframe["ema50"]) & (dataframe["ema50"] < dataframe["ema100"]) & (dataframe["close"] >= dataframe["ema20"] * 0.995) & (dataframe["close"] <= dataframe["ema50"]) & (dataframe["rsi"] < 60) & (dataframe["rsi"] > 35) & (dataframe["macdhist"] < 0) & (dataframe["adx"] > 20), ["enter_short", "enter_tag"], ] = (1, "trend_pullback_short") return dataframe def populate_exit_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: # 不使用信号退出,完全依赖 ROI + trailing + stoploss return dataframe def leverage( self, pair: str, current_time: datetime, current_rate: float, proposed_leverage: float, max_leverage: float, entry_tag: Optional[str], side: str, **kwargs, ) -> float: return 1.0