""" SOL5mStrategy_ShortTerm - 真正的短线交易策略 核心特征: ★ 使用5分钟快速EMA交叉(EMA9/EMA21)作为信号源 ★ 无延迟入场,信号出现立即入场 ★ 小止损(-1%),快速止盈(+0.8%) ★ 平均持仓时间:15-60分钟 ★ 交易频率:每天5-20笔 逻辑: - 5分钟K线,EMA9/EMA21交叉入场 - RSI过滤(避免极端超买超卖) - 成交量确认 - 快速止盈止损,不持仓过夜 使用命令: freqtrade backtesting -c ./user_data/Chan/config/Local_Test.json \ --strategy SOL5mStrategy_ShortTerm --strategy-path ./user_data/Chan/strategies \ --timerange=20250301- """ import logging from datetime import datetime from typing import Optional import talib.abstract as ta from pandas import DataFrame from freqtrade.strategy import IStrategy logger = logging.getLogger(__name__) class SOL5mStrategy_ShortTerm(IStrategy): INTERFACE_VERSION: int = 3 # === 基础配置 === timeframe = "5m" # 使用5分钟K线 can_short = True startup_candle_count: int = 100 # 小止损(-1%),适合短线 stoploss = -0.01 use_custom_stoploss = False # Trailing stop:盈利0.5%后激活,回撤0.3%退出 trailing_stop = True trailing_stop_positive = 0.003 # 回撤0.3%触发退出 trailing_stop_positive_offset = 0.005 # 盈利0.5%后才开始追踪 trailing_only_offset_is_reached = True # ROI:快速止盈,从0.8%逐步递减 minimal_roi = { "0": 0.008, # 0.8% 立即止盈 "15": 0.005, # 15分钟后 0.5% "30": 0.003, # 30分钟后 0.3% "60": 0.001, # 60分钟后 0.1% "120": 0, # 120分钟后不设止盈(但trailing会保护) } order_types = { "entry": "market", "exit": "market", "stoploss": "market", "stoploss_on_exchange": False, } def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: """计算快速EMA交叉信号""" # 快速EMA(9)和慢速EMA(21) dataframe["ema_fast"] = ta.EMA(dataframe, timeperiod=9) dataframe["ema_slow"] = ta.EMA(dataframe, timeperiod=21) # RSI用于过滤极端情况 dataframe["rsi"] = ta.EMA(dataframe, timeperiod=14) # 成交量均线用于确认 dataframe["volume_mean"] = dataframe["volume"].rolling(window=20).mean() # 上穿:本根 EMA9 > EMA21,上一根 EMA9 ≤ EMA21 dataframe["ema_cross_up"] = ( (dataframe["ema_fast"] > dataframe["ema_slow"]) & (dataframe["ema_fast"].shift(1) <= dataframe["ema_slow"].shift(1)) ) # 下穿:本根 EMA9 < EMA21,上一根 EMA9 ≥ EMA21 dataframe["ema_cross_down"] = ( (dataframe["ema_fast"] < dataframe["ema_slow"]) & (dataframe["ema_fast"].shift(1) >= dataframe["ema_slow"].shift(1)) ) return dataframe def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: """5分钟EMA交叉立即入场,无延迟""" # 做多:EMA9上穿EMA21 + RSI > 45(避免极端超卖)+ 成交量确认 dataframe.loc[ (dataframe["ema_cross_up"] == True) & (dataframe["rsi"] > 45) & # RSI过滤,避免极端超卖 (dataframe["volume"] > dataframe["volume_mean"] * 0.8), # 成交量确认(稍微宽松) ["enter_long", "enter_tag"], ] = (1, "ema9x21_long") # 做空:EMA9下穿EMA21 + RSI < 55(避免极端超买)+ 成交量确认 dataframe.loc[ (dataframe["ema_cross_down"] == True) & (dataframe["rsi"] < 55) & # RSI过滤,避免极端超买 (dataframe["volume"] > dataframe["volume_mean"] * 0.8), # 成交量确认 ["enter_short", "enter_tag"], ] = (1, "ema9x21_short") return dataframe def populate_exit_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: """不使用信号退出,完全依赖 ROI / trailing stop / 硬止损""" 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