Lesson 24.2: Live Trading Stop Loss Operations Detailed Guide
⏱ Duration: 2 hours
🎯 Learning Objectives: Master various stop loss strategies, learn effective risk control in live trading
Course Overview
Stop loss is the most important risk control tool in live trading. A trading system without a stop loss strategy is like a car without brakes.
Key Focus of This Lesson:
Stop loss is not failure, but protection of capital to keep trading going.
This lesson will cover in detail:
- Implementation and application of various stop loss types
- Stop loss configuration in Freqtrade
- Dynamic and trailing stop losses
- Stop loss optimization techniques
Part 1: Stop Loss Types Explained
1.1 Fixed Stop Loss
1.1.1 Basic Concept
Fixed stop loss is the simplest stop loss method, setting a fixed percentage based on the entry price.
Calculation Formula:
Stop Loss Price = Entry Price × (1 - Stop Loss Percentage)
Example:
Entry Price: $30,000
Stop Loss: -5%
Stop Loss Price: $30,000 × (1 - 0.05) = $28,500
1.1.2 Freqtrade Configuration
{
"stoploss": -0.05,
"stoploss_type": "standard",
"stoploss_on_exchange": true,
"stoploss_on_exchange_interval": 60
}
Strategy Example:
class FixedStopLossStrategy(IStrategy):
# Set 5% fixed stop loss
stoploss = -0.05
def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
# Buy signal logic
return dataframe
1.1.3 Pros and Cons Analysis
Advantages:
✅ Simple and intuitive, easy to understand
✅ Simple calculation, low system overhead
✅ Suitable for beginners
✅ Stable performance in normal markets
Disadvantages:
❌ Cannot adapt to market volatility changes
❌ May be triggered by normal fluctuations
❌ May be too aggressive in high-volatility markets
❌ Cannot track profits
1.2 Dynamic Stop Loss
1.2.1 ATR-Based Stop Loss
ATR (Average True Range): Average True Range, measures market volatility.
Calculation Formula:
ATR = Average of true ranges over past N days
Stop Loss Price = Current Price - (ATR × N times multiplier)
Strategy Implementation:
import pandas as pd
import talib.abstract as ta
class ATRStopLossStrategy(IStrategy):
# Use dynamic stop loss
use_custom_stoploss = True
# Minimum stop loss
stoploss = -0.10
def custom_stoploss(self, pair: str, trade: 'Trade', current_time: datetime,
current_rate: float, current_profit: float, **kwargs) -> float:
# Get historical data
dataframe, _ = self.dp.get_analyzed_dataframe(pair, self.timeframe)
last_candle = dataframe.iloc[-1].squeeze()
# Calculate ATR
atr = last_candle['atr']
# Calculate dynamic stop loss (2×ATR)
atr_multiplier = 2
stoploss_pct = (atr * atr_multiplier) / current_rate
# Ensure stop loss does not exceed -15%
stoploss_pct = min(stoploss_pct, 0.15)
# Ensure stop loss is not less than -2%
stoploss_pct = max(stoploss_pct, 0.02)
return -stoploss_pct
def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
# Calculate ATR indicator
dataframe['atr'] = ta.ATR(dataframe, timeperiod=14)
return dataframe
1.2.2 Volatility-Based Stop Loss
Concept: Adjust stop loss distance based on historical volatility.
import numpy as np
class VolatilityStopLossStrategy(IStrategy):
use_custom_stoploss = True
stoploss = -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)
# Calculate standard deviation of 20-day returns
returns = dataframe['close'].pct_change().dropna()
volatility = returns.tail(20).std() * np.sqrt(252) # Annualized volatility
# Adjust stop loss based on volatility
if volatility > 0.5: # High volatility
multiplier = 2.0
elif volatility > 0.3: # Medium volatility
multiplier = 1.5
else: # Low volatility
multiplier = 1.0
base_stoploss = 0.03 # Base 3% stop loss
stoploss_pct = base_stoploss * multiplier
return -min(stoploss_pct, 0.15) # Maximum -15%
1.3 Trailing Stop Loss
1.3.1 Basic Principle
Trailing stop loss adjusts the stop loss price as price moves favorably, but never adjusts downward.
Example:
Entry Price: $30,000
Setting: 5% trailing stop loss
Price rises to $31,000: Stop loss adjusted to $29,450 ($31,000 × 0.95)
Price rises to $32,000: Stop loss adjusted to $30,400 ($32,000 × 0.95)
Price drops to $31,500: Stop loss remains $30,400
Price drops to $30,400: Stop loss triggered
1.3.2 Freqtrade Implementation
class TrailingStopLossStrategy(IStrategy):
# Enable trailing stop loss
trailing_stop = True
trailing_stop_positive = 0.01 # 1% trailing after profit
trailing_stop_positive_offset = 0.03 # Start trailing after 3% profit
trailing_only_offset_is_reached = True # Only start trailing after offset reached
def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
# Buy signals
return dataframe
Configuration Explanation:
-
trailing_stop: Enable trailing stop loss -
trailing_stop_positive: Trailing distance after profit -
trailing_stop_positive_offset: Profit threshold to start trailing -
trailing_only_offset_is_reached: Only start trailing after offset reached
1.3.3 Custom Trailing Stop Loss
class CustomTrailingStopLossStrategy(IStrategy):
use_custom_stoploss = True
stoploss = -0.10
def __init__(self, config: dict) -> None:
super().__init__(config)
# Store highest price for each trade
self.highest_prices = {}
def custom_stoploss(self, pair: str, trade: 'Trade', current_time: datetime,
current_rate: float, current_profit: float, **kwargs) -> float:
# Get trade ID
trade_id = trade.id
# Initialize highest price
if trade_id not in self.highest_prices:
self.highest_prices[trade_id] = trade.open_rate
# Update highest price
if current_rate > self.highest_prices[trade_id]:
self.highest_prices[trade_id] = current_rate
highest_price = self.highest_prices[trade_id]
# If current profit exceeds 3%, use trailing stop loss
if current_profit > 0.03:
# 2% trailing stop loss
trailing_distance = 0.02
stoploss_price = highest_price * (1 - trailing_distance)
stoploss_pct = (current_rate - stoploss_price) / current_rate
return -stoploss_pct
else:
# Otherwise use 5% fixed stop loss
return -0.05
Part 2: Advanced Stop Loss Strategies
2.1 Technical Indicator Stop Loss
2.1.1 Moving Average Stop Loss
class MAStopLossStrategy(IStrategy):
use_custom_stoploss = True
stoploss = -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()
# Use 20-day moving average as stop loss
ma20 = last_candle['ma20']
if current_rate > ma20:
# Current price above MA, use MA stop loss
stoploss_pct = (current_rate - ma20) / current_rate
return -min(stoploss_pct, 0.15)
else:
# Price below MA, use fixed stop loss
return -0.08
def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
dataframe['ma20'] = ta.SMA(dataframe, timeperiod=20)
dataframe['ma50'] = ta.SMA(dataframe, timeperiod=50)
return dataframe
2.1.2 Bollinger Bands Stop Loss
class BollingerStopLossStrategy(IStrategy):
use_custom_stoploss = True
stoploss = -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()
# Use Bollinger Band lower band as stop loss
lower_band = last_candle['bb_lowerband']
# Ensure stop loss price not lower than BB lower band
if current_rate > lower_band:
stoploss_pct = (current_rate - lower_band) / current_rate
return -min(stoploss_pct, 0.20)
else:
return -0.10
def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
bollinger = qtpylib.bollinger_bands(qtpylib.typical_price(dataframe), window=20, stds=2)
dataframe['bb_lowerband'] = bollinger['lower']
dataframe['bb_middleband'] = bollinger['mid']
dataframe['bb_upperband'] = bollinger['upper']
return dataframe
2.1.3 Support Level Stop Loss
class SupportStopLossStrategy(IStrategy):
use_custom_stoploss = True
stoploss = -0.15
def find_support_levels(self, dataframe: DataFrame):
"""Find support levels"""
# Simple support level identification: local lows
lows = dataframe['low']
# Find support levels (simplified version)
support_levels = []
for i in range(2, len(lows) - 2):
current_low = lows.iloc[i]
if (current_low < lows.iloc[i-1] and
current_low < lows.iloc[i-2] and
current_low < lows.iloc[i+1] and
current_low < lows.iloc[i+2]):
support_levels.append(current_low)
return sorted(support_levels, reverse=True)[:5] # Return top 5 support levels
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)
support_levels = self.find_support_levels(dataframe)
if support_levels:
# Use nearest support level as stop loss
nearest_support = support_levels[0]
if current_rate > nearest_support:
stoploss_pct = (current_rate - nearest_support) / current_rate
# At least 2% stop loss, maximum 15%
stoploss_pct = max(stoploss_pct, 0.02)
stoploss_pct = min(stoploss_pct, 0.15)
return -stoploss_pct
return -0.08 # Default stop loss
2.2 Time Stop Loss
2.2.1 Holding Time Stop Loss
import datetime
class TimeStopLossStrategy(IStrategy):
use_custom_stoploss = True
stoploss = -0.15
# Maximum holding time (hours)
max_hold_time = 24 # 24 hours
def custom_stoploss(self, pair: str, trade: 'Trade', current_time: datetime,
current_rate: float, current_profit: float, **kwargs) -> float:
# Calculate holding time
hold_time = current_time - trade.open_date
# If holding time exceeds limit, reduce stop loss
if hold_time > datetime.timedelta(hours=self.max_hold_time):
if current_profit > 0:
# Holding too long with profit, use small stop loss for quick exit
return -0.01
else:
# Holding too long with loss, stop loss exit
return -0.001
# Normal stop loss logic
if current_profit > 0.05:
return -0.03 # Profit over 5%, 3% stop loss
else:
return -0.08 # Default stop loss
2.2.2 Hourly Stop Loss
class HourlyStopLossStrategy(IStrategy):
use_custom_stoploss = True
stoploss = -0.15
def custom_stoploss(self, pair: str, trade: 'Trade', current_time: datetime,
current_rate: float, current_profit: float, **kwargs) -> float:
hour = current_time.hour
# Adjust stop loss based on time period
if 0 <= hour < 6: # Late night, lower volatility
if current_profit > 0:
return -0.02 # Tighter stop loss
else:
return -0.05
elif 6 <= hour < 12: # Morning session
return -0.08
elif 12 <= hour < 18: # Afternoon session, higher volatility
return -0.10
else: # Evening session
return -0.06
2.3 Combined Stop Loss Strategies
2.3.1 Multi-Condition Stop Loss
class CombinedStopLossStrategy(IStrategy):
use_custom_stoploss = True
stoploss = -0.20
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()
# 1. ATR stop loss
atr = last_candle['atr']
atr_stoploss = (atr * 2) / current_rate
# 2. Moving average stop loss
ma20 = last_candle['ma20']
if current_rate > ma20:
ma_stoploss = (current_rate - ma20) / current_rate
else:
ma_stoploss = 0.15
# 3. Time stop loss
hold_time = current_time - trade.open_date
if hold_time > datetime.timedelta(hours=12):
time_stoploss = 0.03 if current_profit > 0 else 0.08
else:
time_stoploss = 0.15
# 4. Profit trailing stop loss
if current_profit > 0.05:
trailing_stoploss = 0.02
else:
trailing_stoploss = 0.15
# Take the strictest stop loss (minimum value)
final_stoploss = min(atr_stoploss, ma_stoploss, time_stoploss, trailing_stoploss)
final_stoploss = max(final_stoploss, 0.02) # At least 2%
final_stoploss = min(final_stoploss, 0.20) # At most 20%
return -final_stoploss
def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
dataframe['atr'] = ta.ATR(dataframe, timeperiod=14)
dataframe['ma20'] = ta.SMA(dataframe, timeperiod=20)
return dataframe
Part 3: Stop Loss Execution Mechanisms
3.1 Local Stop Loss vs Exchange Stop Loss
3.1.1 Local Stop Loss
Features:
✅ High flexibility, can implement complex logic
✅ Does not consume exchange API limits
✅ Can monitor and adjust in real-time
❌ Depends on system stability
❌ Network issues may cause delays
❌ Requires system to run continuously
Configuration:
{
"stoploss_on_exchange": false,
"stoploss": -0.05
}
3.1.2 Exchange Stop Loss
Features:
✅ Reliable execution, not affected by local system
✅ Fast response speed
✅ Does not consume local resources
❌ Limited functionality, only supports basic stop loss
❌ Consumes API limits
❌ Less flexible adjustment
Configuration:
{
"stoploss_on_exchange": true,
"stoploss_on_exchange_interval": 60,
"stoploss": -0.05
}
3.2 Stop Loss Order Types
3.2.1 Stop Loss Market Order
# Set stop loss market order on exchange
def create_stop_market_order(exchange, symbol, amount, stop_price):
"""
Create stop loss market order
"""
try:
order = exchange.create_order(
symbol=symbol,
type='stop_market',
side='sell',
amount=amount,
params={'stopPrice': stop_price}
)
print(f"Stop loss market order created: {order['id']}")
print(f"Trigger price: ${stop_price}")
return order
except Exception as e:
print(f"Failed to create stop loss order: {e}")
return None
3.2.2 Stop Loss Limit Order
def create_stop_limit_order(exchange, symbol, amount, stop_price, limit_price):
"""
Create stop loss limit order
"""
try:
order = exchange.create_order(
symbol=symbol,
type='stop_limit',
side='sell',
amount=amount,
price=limit_price,
params={'stopPrice': stop_price}
)
print(f"Stop loss limit order created: {order['id']}")
print(f"Trigger price: ${stop_price}")
print(f"Limit price: ${limit_price}")
return order
except Exception as e:
print(f"Failed to create stop loss order: {e}")
return None
3.3 Stop Loss Monitoring and Adjustment
3.3.1 Stop Loss Status Monitoring
class StopLossMonitor:
def __init__(self):
self.active_stop_orders = {}
self.stop_history = []
def add_stop_order(self, trade_id, stop_price, order_type='market'):
"""Add stop loss order"""
self.active_stop_orders[trade_id] = {
'stop_price': stop_price,
'order_type': order_type,
'created_time': datetime.now(),
'adjusted_times': 0
}
def update_stop_price(self, trade_id, new_stop_price):
"""Update stop loss price"""
if trade_id in self.active_stop_orders:
old_price = self.active_stop_orders[trade_id]['stop_price']
self.active_stop_orders[trade_id]['stop_price'] = new_stop_price
self.active_stop_orders[trade_id]['adjusted_times'] += 1
print(f"Stop loss price updated: {old_price} → {new_stop_price}")
def check_stop_trigger(self, current_price, trade_id):
"""Check if stop loss is triggered"""
if trade_id not in self.active_stop_orders:
return False
stop_price = self.active_stop_orders[trade_id]['stop_price']
if current_price <= stop_price:
# Record stop loss history
self.stop_history.append({
'trade_id': trade_id,
'stop_price': stop_price,
'trigger_price': current_price,
'trigger_time': datetime.now(),
'order_type': self.active_stop_orders[trade_id]['order_type']
})
# Remove active stop loss
del self.active_stop_orders[trade_id]
return True
return False
def get_stop_statistics(self):
"""Get stop loss statistics"""
if not self.stop_history:
return None
total_stops = len(self.stop_history)
market_stops = len([s for s in self.stop_history if s['order_type'] == 'market'])
return {
'total_stops': total_stops,
'market_stops': market_stops,
'limit_stops': total_stops - market_stops,
'stop_efficiency': self.calculate_stop_efficiency()
}
def calculate_stop_efficiency(self):
"""Calculate stop loss efficiency"""
# Simplified calculation: difference between actual and set stop loss prices
if not self.stop_history:
return 0
total_slippage = 0
for stop in self.stop_history:
slippage = abs(stop['trigger_price'] - stop['stop_price']) / stop['stop_price']
total_slippage += slippage
avg_slippage = total_slippage / len(self.stop_history)
efficiency = max(0, 1 - avg_slippage) # Efficiency = 1 - average slippage
return efficiency
3.3.2 Dynamic Stop Loss Adjustment
def dynamic_stop_adjustment(trade, current_price, current_profit, indicators):
"""
Dynamically adjust stop loss based on market conditions
"""
original_stop = trade.stop_loss
# Adjust based on profit
if current_profit > 0.10:
# Profit over 10%, tighten stop loss
new_stop = current_price * 0.97 # 3% stop loss
elif current_profit > 0.05:
# Profit 5-10%, moderately tighten
new_stop = current_price * 0.95 # 5% stop loss
else:
# Small profit, keep original stop loss
new_stop = original_stop
# Adjust based on volatility
volatility = indicators.get('volatility', 0.02)
if volatility > 0.05: # High volatility
new_stop = min(new_stop, original_stop * 1.2) # Widen stop loss
elif volatility < 0.01: # Low volatility
new_stop = max(new_stop, original_stop * 0.8) # Tighten stop loss
# Adjust based on technical indicators
if indicators.get('trend') == 'strong_bullish':
new_stop = max(new_stop, current_price * 0.95) # Uptrend, widen stop loss
return new_stop
Part 4: Stop Loss Optimization Strategies
4.1 Stop Loss Backtest Analysis
4.1.1 Stop Loss Effectiveness Analysis
def analyze_stoploss_effectiveness(trades_dataframe):
"""
Analyze the effectiveness of stop loss strategies
"""
total_trades = len(trades_dataframe)
stopped_trades = trades_dataframe[trades_dataframe['stoploss_reason'].notna()]
# Stop loss trigger statistics
stop_count = len(stopped_trades)
stop_rate = stop_count / total_trades if total_trades > 0 else 0
# Loss avoided by stop loss
avg_stop_loss = stopped_trades['profit_ratio'].mean()
max_potential_loss = stopped_trades['max_drawdown'].mean()
loss_saved = max_potential_loss - avg_stop_loss
# Stop loss type distribution
stop_types = stopped_trades['stoploss_reason'].value_counts()
analysis = {
'total_trades': total_trades,
'stop_count': stop_count,
'stop_rate': stop_rate,
'avg_stop_loss': avg_stop_loss,
'loss_saved_per_trade': loss_saved,
'total_loss_saved': loss_saved * stop_count,
'stop_type_distribution': stop_types.to_dict()
}
return analysis
# Usage example
import pandas as pd
# Assume we have a trade record DataFrame
trades_df = pd.read_csv('backtest_results.csv')
analysis = analyze_stoploss_effectiveness(trades_df)
print(f"Total trades: {analysis['total_trades']}")
print(f"Stop loss triggers: {analysis['stop_count']}")
print(f"Stop loss trigger rate: {analysis['stop_rate']:.2%}")
print(f"Average loss avoided by stop loss: {analysis['loss_saved_per_trade']:.2%}")
print(f"Total loss avoided by stop loss: {analysis['total_loss_saved']:.2%}")
4.1.2 Different Stop Loss Strategy Comparison
def compare_stoploss_strategies(backtest_results):
"""
Compare performance of different stop loss strategies
"""
comparison = {}
for strategy_name, results in backtest_results.items():
trades = results['trades']
# Calculate key metrics
total_profit = trades['profit_abs'].sum()
win_rate = len(trades[trades['profit_abs'] > 0]) / len(trades)
max_drawdown = results['max_drawdown']
sharpe_ratio = results['sharpe']
# Stop loss related metrics
stopped_trades = trades[trades['stoploss_reason'].notna()]
stop_rate = len(stopped_trades) / len(trades)
avg_stop_loss = stopped_trades['profit_ratio'].mean() if len(stopped_trades) > 0 else 0
comparison[strategy_name] = {
'total_profit': total_profit,
'win_rate': win_rate,
'max_drawdown': max_drawdown,
'sharpe_ratio': sharpe_ratio,
'stop_rate': stop_rate,
'avg_stop_loss': avg_stop_loss
}
return comparison
# Visualize comparison
def plot_stoploss_comparison(comparison):
"""
Plot stop loss strategy comparison chart
"""
import matplotlib.pyplot as plt
strategies = list(comparison.keys())
metrics = ['total_profit', 'win_rate', 'max_drawdown', 'sharpe_ratio']
fig, axes = plt.subplots(2, 2, figsize=(15, 10))
axes = axes.ravel()
for i, metric in enumerate(metrics):
values = [comparison[s][metric] for s in strategies]
axes[i].bar(strategies, values)
axes[i].set_title(f'{metric.replace("_", " ").title()}')
axes[i].tick_params(axis='x', rotation=45)
plt.tight_layout()
plt.show()
4.2 Stop Loss Parameter Optimization
4.2.1 Stop Loss Percentage Optimization
def optimize_stoploss_percentage(strategy_class, timeframe, pair_list,
stoploss_range=[-0.02, -0.03, -0.04, -0.05, -0.06, -0.08, -0.10]):
"""
Optimize stop loss percentage
"""
results = {}
for stoploss in stoploss_range:
print(f"Testing stop loss: {stoploss:.1%}")
# Create strategy instance
strategy = strategy_class({
'strategy': strategy_class.__name__,
'stoploss': stoploss
})
# Run backtest
backtest_result = run_backtest(strategy, timeframe, pair_list)
results[str(stoploss)] = {
'total_profit': backtest_result['total_profit'],
'profit_mean': backtest_result['profit_mean'],
'win_rate': backtest_result['wins'] / backtest_result['total_trades'],
'max_drawdown': backtest_result['max_drawdown_abs'],
'sharpe': backtest_result['sharpe']
}
# Find optimal stop loss
best_stoploss = max(results.keys(),
key=lambda x: results[x]['sharpe'])
return {
'results': results,
'best_stoploss': best_stoploss,
'best_performance': results[best_stoploss]
}
4.2.2 Trailing Stop Loss Parameter Optimization
def optimize_trailing_stop(strategy_class, timeframe, pair_list,
trailing_offsets=[0.01, 0.02, 0.03, 0.04, 0.05],
trailing_stops=[0.005, 0.01, 0.015, 0.02]):
"""
Optimize trailing stop loss parameters
"""
results = {}
for offset in trailing_offsets:
for stop in trailing_stops:
print(f"Testing trailing parameters: offset={offset:.1%}, stop={stop:.1%}")
# Create strategy instance
strategy = strategy_class({
'strategy': strategy_class.__name__,
'trailing_stop': True,
'trailing_stop_positive_offset': offset,
'trailing_stop_positive': stop
})
# Run backtest
backtest_result = run_backtest(strategy, timeframe, pair_list)
key = f"offset_{offset:.1%}_stop_{stop:.1%}"
results[key] = {
'offset': offset,
'stop': stop,
'total_profit': backtest_result['total_profit'],
'win_rate': backtest_result['wins'] / backtest_result['total_trades'],
'max_drawdown': backtest_result['max_drawdown_abs'],
'sharpe': backtest_result['sharpe']
}
# Find optimal parameters
best_params = max(results.keys(),
key=lambda x: results[x]['sharpe'])
return {
'results': results,
'best_parameters': best_params,
'best_performance': results[best_params]
}
Part 5: Practical Configuration Examples
5.1 Conservative Stop Loss Configuration
Suitable for: Beginners, low-risk preference
{
"stoploss": -0.06,
"trailing_stop": false,
"stoploss_on_exchange": true,
"stoploss_on_exchange_interval": 60,
"order_types": {
"stoploss": "market",
"stoploss_on_exchange": true,
"stoploss_on_exchange_interval": 60
}
}
Features:
- 6% fixed stop loss, relatively conservative
- Use exchange stop loss for high reliability
- No trailing stop loss, simple and direct
5.2 Aggressive Stop Loss Configuration
Suitable for: High-frequency trading, high-risk preference
{
"stoploss": -0.08,
"trailing_stop": true,
"trailing_stop_positive": 0.01,
"trailing_stop_positive_offset": 0.02,
"trailing_only_offset_is_reached": true,
"stoploss_on_exchange": false,
"order_types": {
"stoploss": "limit",
"stoploss_on_exchange": false
}
}
Features:
- Start 1% trailing stop loss after 2% profit
- Use local stop loss for complex logic implementation
- Stop loss limit order to control execution price
5.3 Intelligent Stop Loss Configuration
Suitable for: Experienced traders
class IntelligentStopLossStrategy(IStrategy):
use_custom_stoploss = True
stoploss = -0.15
# Configuration parameters
atr_multiplier = 2.0
trailing_start_profit = 0.03
trailing_distance = 0.02
max_stoploss = -0.20
min_stoploss = -0.02
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()
# 1. ATR dynamic stop loss
atr = last_candle.get('atr', current_rate * 0.02) # Default 2%
atr_stoploss = (atr * self.atr_multiplier) / current_rate
# 2. Trailing stop loss
if current_profit > self.trailing_start_profit:
trailing_stoploss = self.trailing_distance
else:
trailing_stoploss = self.stoploss * -1
# 3. Time stop loss
hold_time = current_time - trade.open_date
if hold_time > datetime.timedelta(hours=48):
time_stoploss = 0.05 if current_profit > 0 else 0.15
else:
time_stoploss = self.stoploss * -1
# Choose optimal stop loss
final_stoploss = min(atr_stoploss, trailing_stoploss, time_stoploss)
# Limit stop loss range
final_stoploss = max(final_stoploss, self.min_stoploss)
final_stoploss = min(final_stoploss, abs(self.max_stoploss))
return -final_stoploss
📝 Practical Tasks
Task 1: Stop Loss Strategy Testing
- Test different stop loss percentages (2%, 3%, 5%, 8%, 10%) in backtest
- Record win rate, return rate, maximum drawdown for each stop loss
- Choose the stop loss setting most suitable for your strategy
Task 2: Trailing Stop Loss Optimization
- Test different trailing parameter combinations
- Analyze the impact of trailing stop loss on return rate
- Find optimal trailing distance and trigger conditions
Task 3: Live Stop Loss Verification
- Test stop loss configuration with small capital in live trading
- Observe timeliness and accuracy of stop loss triggers
- Record actual slippage situations
- Adjust parameters based on live performance
📌 Key Points
Stop Loss Setting Principles
1. Protect Capital First
✅ Stop loss is a tool to protect capital
✅ Any stop loss is better than no stop loss
✅ Don't set stop loss too large due to fear of stops
2. Adapt to Strategy Characteristics
✅ Trend strategies need looser stop losses
✅ Range-bound strategies need tighter stop losses
✅ High-frequency strategies need fast stops
3. Consider Market Environment
✅ Loosen stops in high-volatility markets
✅ Tighten stops in low-volatility markets
✅ Adjust stops before major events
Common Stop Loss Mistakes
| Mistake | Consequence | Correct Approach |
|---|---|---|
| Stop loss set too large | Excessive losses | Set reasonably based on strategy |
| Stop loss set too small | Frequent stops | Consider normal volatility range |
| Moving stops after profit | May exit too early | Use trailing stop loss |
| Ignoring stop loss execution | Actual losses exceed expectations | Ensure reliable stop loss execution |
Stop Loss Optimization Checklist
□ Verify stop loss effectiveness through backtest
□ Test performance under different market conditions
□ Optimize stop loss parameters
□ Ensure reliable stop loss execution mechanism
□ Verify stop loss performance in live trading
□ Regularly review and adjust stop loss strategies
🎯 Next Lesson Preview
Lesson 24.3: Futures Trading Operations Detailed Guide
In the next lesson, we will learn:
- Binance futures trading API usage
- Leverage and margin management
- Futures order types and operations
- Capital management and risk control
After mastering spot trading stop loss techniques, we will enter the higher-risk futures trading domain.
Top comments (0)