止损
止损功能是为了限制损失。这是通过在价格下跌到某个点以下时出售资产来实现的。
静态止损
最简单的止损是静态止损。这是一个固定的百分比,如果价格下跌到该百分比以下,资产将被出售。
class MyStrategy(IStrategy):
stoploss = -0.10 # 10% 止损
使用这种配置,如果价格下跌 10% 或更多,Freqtrade 将出售资产。
跟踪止损
跟踪止损是一种更高级的止损形式,它会随着价格上涨而"跟踪"价格。
基本跟踪止损
class MyStrategy(IStrategy):
stoploss = -0.10
trailing_stop = True
这将创建一个跟踪止损,从 -10% 开始,并在价格上涨时跟踪价格。
跟踪止损偏移
class MyStrategy(IStrategy):
stoploss = -0.10
trailing_stop = True
trailing_stop_positive = 0.02 # 当利润达到 2% 时开始跟踪
仅在利润时跟踪
class MyStrategy(IStrategy):
stoploss = -0.10
trailing_stop = True
trailing_stop_positive = 0.02
trailing_only_offset_is_reached = True # 仅在达到偏移时开始跟踪
交易所上的止损
某些交易所支持在交易所上设置止损订单。
class MyStrategy(IStrategy):
stoploss = -0.10
stoploss_on_exchange = True
stoploss_on_exchange_interval = 60 # 每 60 秒检查一次
交易所止损的优势
- 即使机器人离线也能工作
- 减少延迟
- 某些交易所提供更好的执行
交易所止损的缺点
- 不是所有交易所都支持
- 某些交易所的实现可能有限制
- 调试更困难
自定义止损
您可以实现自定义止损逻辑,该逻辑可以基于各种因素动态调整止损。
from freqtrade.persistence import Trade
def custom_stoploss(self, pair: str, trade: Trade, current_time: datetime,
current_rate: float, current_profit: float, **kwargs) -> float:
"""
自定义止损逻辑
返回:
- 正值或 None:不更改止损
- 负值:新的止损值
"""
# 基于时间的止损
trade_duration = current_time - trade.open_date_utc
if trade_duration < timedelta(minutes=20):
# 前 20 分钟:紧止损
return -0.05
elif trade_duration < timedelta(hours=2):
# 2 小时内:标准止损
return -0.10
elif current_profit > 0:
# 盈利时:收紧止损
if current_profit > 0.20:
return -0.02 # 保护 20% 利润
elif current_profit > 0.10:
return -0.05 # 保护 10% 利润
elif current_profit > 0.05:
return -0.07 # 保护 5% 利润
# 长期持有:放宽止损
return -0.15
基于指标的止损
def custom_stoploss(self, pair: str, trade: Trade, current_time: datetime,
current_rate: float, current_profit: float, **kwargs) -> float:
"""基于技术指标的动态止损"""
dataframe, _ = self.dp.get_analyzed_dataframe(pair, self.timeframe)
last_candle = dataframe.iloc[-1].squeeze()
# 基于 ATR 的止损
if 'atr' in last_candle:
atr_stop = last_candle['atr'] * 2 / current_rate
return -atr_stop
# 基于布林带的止损
if 'bb_lowerband' in last_candle:
bb_stop = (current_rate - last_candle['bb_lowerband']) / current_rate
return -max(bb_stop, 0.02) # 最小 2% 止损
return self.stoploss
基于成交量的止损
def custom_stoploss(self, pair: str, trade: Trade, current_time: datetime,
current_rate: float, current_profit: float, **kwargs) -> float:
"""基于成交量的动态止损"""
dataframe, _ = self.dp.get_analyzed_dataframe(pair, self.timeframe)
last_candle = dataframe.iloc[-1].squeeze()
# 计算平均成交量
avg_volume = dataframe['volume'].rolling(20).mean().iloc[-1]
if last_candle['volume'] < avg_volume * 0.5:
# 成交量低时收紧止损
return -0.05
elif last_candle['volume'] > avg_volume * 2:
# 成交量高时放宽止损
return -0.15
return self.stoploss
止损和 ROI 的交互
止损和最小 ROI 可以一起工作。机器人将在以下情况下退出:
- 达到止损水平
- 达到最小 ROI 目标
- 收到退出信号
class MyStrategy(IStrategy):
minimal_roi = {
"0": 0.20, # 20% 立即退出
"30": 0.15, # 30 分钟后 15%
"60": 0.10, # 60 分钟后 10%
"120": 0.05 # 120 分钟后 5%
}
stoploss = -0.10 # 10% 止损
止损的最佳实践
1. 基于市场波动性设置止损
def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
# 计算 ATR 用于动态止损
dataframe['atr'] = ta.ATR(dataframe, timeperiod=14)
dataframe['atr_percent'] = dataframe['atr'] / dataframe['close']
return dataframe
def custom_stoploss(self, pair: str, trade: Trade, current_time: datetime,
current_rate: float, current_profit: float, **kwargs) -> float:
dataframe, _ = self.dp.get_analyzed_dataframe(pair, self.timeframe)
last_candle = dataframe.iloc[-1].squeeze()
# 基于 ATR 的动态止损
if 'atr_percent' in last_candle:
dynamic_stop = last_candle['atr_percent'] * 2
return -max(dynamic_stop, 0.02) # 最小 2%
return self.stoploss
2. 分级止损
def custom_stoploss(self, pair: str, trade: Trade, current_time: datetime,
current_rate: float, current_profit: float, **kwargs) -> float:
"""分级止损系统"""
if current_profit >= 0.30:
return -0.05 # 30% 利润时,5% 止损
elif current_profit >= 0.20:
return -0.07 # 20% 利润时,7% 止损
elif current_profit >= 0.10:
return -0.10 # 10% 利润时,10% 止损
elif current_profit >= 0.05:
return -0.12 # 5% 利润时,12% 止损
elif current_profit >= 0.02:
return -0.15 # 2% 利润时,15% 止损
return -0.20 # 默认 20% 止损
3. 时间衰减止损
def custom_stoploss(self, pair: str, trade: Trade, current_time: datetime,
current_rate: float, current_profit: float, **kwargs) -> float:
"""时间衰减止损"""
trade_duration = current_time - trade.open_date_utc
hours = trade_duration.total_seconds() / 3600
# 随时间放宽止损
if hours < 1:
return -0.05 # 第一小时:5%
elif hours < 4:
return -0.08 # 4 小时内:8%
elif hours < 12:
return -0.12 # 12 小时内:12%
else:
return -0.15 # 超过 12 小时:15%
止损测试和验证
回测中的止损
# 在回测中测试不同的止损设置
freqtrade backtesting --strategy MyStrategy --timerange 20230101-20231231
止损分析
使用绘图功能分析止损效果:
freqtrade plot-dataframe --strategy MyStrategy -p BTC/USDT --timerange 20230101-20230201
止损优化
使用超参优化寻找最佳止损参数:
from skopt.space import Real
class MyStrategy(IStrategy):
stoploss = -0.10
def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
return dataframe
# 超参优化空间
stoploss_space = Real(-0.25, -0.02, name='stoploss')
常见止损错误
1. 止损过紧
# 错误:止损过紧,容易被噪音触发
stoploss = -0.02 # 2% 可能太紧
2. 止损过宽
# 错误:止损过宽,可能导致大额亏损
stoploss = -0.50 # 50% 可能太宽
3. 忽略市场条件
# 改进:根据市场波动性调整止损
def custom_stoploss(self, pair: str, trade: Trade, current_time: datetime,
current_rate: float, current_profit: float, **kwargs) -> float:
# 考虑市场波动性
dataframe, _ = self.dp.get_analyzed_dataframe(pair, self.timeframe)
volatility = dataframe['close'].pct_change().rolling(20).std().iloc[-1]
# 高波动性时放宽止损
if volatility > 0.03: # 3% 日波动性
return -0.15
else:
return -0.08
下一步
现在您了解了止损,可能想要学习关于插件系统。您的下一步是阅读插件文档。