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)