Timeframe
1h
Direction
Long Only
Stoploss
-6.0%
Trailing Stop
No
ROI
0m: 6.0%, 240m: 3.0%, 480m: 1.0%
Interface Version
3
Startup Candles
30
Indicators
3
freqtrade/freqtrade-strategies
Strategy 003 author@: Gerald Lonlas github@: https://github.com/freqtrade/freqtrade-strategies
import talib.abstract as ta
from pandas import DataFrame
from freqtrade.strategy import IStrategy, IntParameter, DecimalParameter
class BbRsiStrategy(IStrategy):
"""
布林带均值回归策略(4h)
逻辑:
买入:价格跌破布林带下轨 + RSI 超卖 + 成交量放大
→ 预期价格回归中轨
卖出:价格触及布林带中轨(止盈)或上轨(激进止盈)
适合震荡行情,与趋势策略互补。
"""
INTERFACE_VERSION = 3
timeframe = "1h"
can_short = False
# 均值回归目标:价格回归布林带中轨约有 2~3% 收益
minimal_roi = {
"0": 0.06, # 立即止盈 6%
"240": 0.03, # 持仓 240 分钟(1根4h K线)达到 3% 止盈
"480": 0.01, # 持仓 2 根 K线达到 1% 止盈
}
stoploss = -0.06 # 止损 6%
# 不用追踪止损,均值回归到目标就走
trailing_stop = False
startup_candle_count = 30
# Hyperopt 参数范围
buy_rsi = IntParameter(20, 40, default=30, space="buy")
sell_rsi = IntParameter(55, 80, default=65, space="sell")
bb_std = DecimalParameter(1.5, 3.0, default=2.0, decimals=1, space="buy")
def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
# RSI
dataframe["rsi"] = ta.RSI(dataframe, timeperiod=14)
# 布林带:预计算所有 Hyperopt 可能用到的标准差档位(1.5~3.0,步长0.1)
import numpy as np
for std in np.arange(1.5, 3.1, 0.1):
std = round(std, 1)
upper, mid, lower = ta.BBANDS(
dataframe["close"], timeperiod=20, nbdevup=std, nbdevdn=std
)
dataframe[f"bb_upper_{std}"] = upper
dataframe[f"bb_mid_{std}"] = mid
dataframe[f"bb_lower_{std}"] = lower
# 成交量均线(过滤低流动性)
dataframe["volume_mean"] = dataframe["volume"].rolling(20).mean()
# ATR(衡量波动率,避免在低波动期入场)
dataframe["atr"] = ta.ATR(dataframe, timeperiod=14)
return dataframe
def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
std = self.bb_std.value
dataframe.loc[
(
(dataframe["close"] < dataframe[f"bb_lower_{std}"]) & # 价格跌破下轨
(dataframe["rsi"] < self.buy_rsi.value) & # RSI 超卖
(dataframe["volume"] > dataframe["volume_mean"]) & # 成交量放大,信号有效
(dataframe["atr"] > 0) # 确保有波动
),
"enter_long",
] = 1
return dataframe
def populate_exit_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
std = self.bb_std.value
dataframe.loc[
(
(dataframe["close"] > dataframe[f"bb_mid_{std}"]) | # 价格回归中轨,止盈
(dataframe["rsi"] > self.sell_rsi.value) # RSI 超买
),
"exit_long",
] = 1
return dataframe