import talib.abstract as ta from pandas import DataFrame from freqtrade.strategy import IStrategy, IntParameter class EmaRsiStrategy(IStrategy): """ 策略逻辑: 买入:EMA20 > EMA50(上升趋势)且 RSI < 40(回调超卖) 卖出:RSI > 70(超买)或 EMA20 跌破 EMA50(趋势反转) """ INTERFACE_VERSION = 3 timeframe = "1h" can_short = False # 持仓目标收益:持仓超过60分钟达到1%就止盈,0分钟达到4%就止盈 minimal_roi = { "60": 0.01, "0": 0.04, } # 止损 5% stoploss = -0.05 # 追踪止损:价格上涨后锁定利润 trailing_stop = True trailing_stop_positive = 0.01 # 盈利1%后启动追踪 trailing_stop_positive_offset = 0.02 # 盈利2%时才激活 # 计算指标前需要预热的K线数量 startup_candle_count = 50 # Hyperopt 参数范围(后续可以用超参优化自动寻找最优值) buy_rsi = IntParameter(25, 45, default=40, space="buy") sell_rsi = IntParameter(60, 80, default=70, space="sell") def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: # 趋势判断:双EMA dataframe["ema20"] = ta.EMA(dataframe, timeperiod=20) dataframe["ema50"] = ta.EMA(dataframe, timeperiod=50) # 动量判断:RSI dataframe["rsi"] = ta.RSI(dataframe, timeperiod=14) # 成交量均线(过滤低流动性信号) dataframe["volume_mean"] = dataframe["volume"].rolling(20).mean() return dataframe def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: dataframe.loc[ ( (dataframe["ema20"] > dataframe["ema50"]) & # 上升趋势 (dataframe["rsi"] < self.buy_rsi.value) & # RSI 超卖回调 (dataframe["volume"] > dataframe["volume_mean"]) # 成交量高于均值,信号更可靠 ), "enter_long", ] = 1 return dataframe def populate_exit_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: dataframe.loc[ ( (dataframe["rsi"] > self.sell_rsi.value) | # RSI 超买 (dataframe["ema20"] < dataframe["ema50"]) # 趋势反转 ), "exit_long", ] = 1 return dataframe