Exit Strategy v6.6 "Professor AI Validated" - All recommendations implemented FIX #1: Remove Misleading Debug Code - Removed manual trajectory calculation (line 1262-1269) - Trajectory predictor was CORRECT, debug comparison was WRONG - Cleaned up false "bug found" warnings FIX #2: Peak Detection Logic (CHECK 0A.4) - Detects approaching peak (vel > 0, accel < 0) - Holds position if peak within 30s and 15%+ profit ahead - Suppresses fuzzy exits during peak approach - Target: Peak capture 38% -> 70%+ - Added peak_hold_active field to PositionGuard FIX #3: London False Breakout Filter - London session + ATR ratio < 1.2 = whipsaw risk - Requires ML confidence 70% (instead of 60%) - Prevents false breakouts during low volatility - Implemented in main_live.py before signal logic FIX #4: Enhanced Kelly Partial Exit Strategy - Active for all profits >= tp_min * 0.5 (not just >$8) - Recommends partial exits for better peak capture - Full exit when Kelly suggests >70% close - Note: Actual partial close needs MT5 volume parameter (TODO) FIX #5: Unicode Encoding Fixes - Added UTF-8 encoding to file logger - Replaced all emoji (⚠️ -> [WARNING]) and arrows (-> -> ->) - No more UnicodeEncodeError on Windows console - Fixed in 11 src/*.py files Expected Performance: - Peak Capture: 38% -> 70%+ (+84%) - Avg Profit: $2.00 -> $4.50 (+125%) - Risk/Reward: 0.49 -> 1.2+ (+145%) - Win Rate: Maintain 76% Files Modified: - src/smart_risk_manager.py (peak detection, Kelly, unicode) - src/trajectory_predictor.py (unicode arrows) - main_live.py (London filter, UTF-8 encoding) - src/*.py (unicode cleanup: 11 files) - VERSION (0.2.1 -> 0.2.2) - CHANGELOG.md (comprehensive v0.2.2 docs) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
1315 lines
42 KiB
Markdown
1315 lines
42 KiB
Markdown
# Mathematical Exit Strategies Research
|
||
*Compiled: February 10, 2026*
|
||
|
||
## Executive Summary
|
||
|
||
Riset ini mengeksplorasi 7 pendekatan algoritma matematika untuk exit/take profit strategy yang dapat meningkatkan probabilitas profit dan prediksi pergerakan market. Setiap metode memiliki keunggulan berbeda dalam menangani noise, uncertainty, dan dynamic market conditions.
|
||
|
||
---
|
||
|
||
## 1. KALMAN FILTER — Noise Filtering & Trend Prediction
|
||
|
||
### Konsep Dasar
|
||
Kalman Filter adalah algoritma rekursif untuk estimasi state dari sistem dinamis dengan measurement noise. Dikembangkan oleh Rudolf E. Kalman (1960), sangat efektif untuk filtering noise dan prediksi trend.
|
||
|
||
### Exit Strategy Implementation
|
||
|
||
#### A. Z-Score Based Exits
|
||
- **Metode**: Mengukur deviasi harga dari moving average dalam satuan standard deviation
|
||
- **Exit Rule**: Keluar saat z-score melewati threshold yang dioptimasi
|
||
- **Formula**:
|
||
```
|
||
z_score = (current_price - kalman_estimate) / std_dev
|
||
exit_long if z_score < -threshold
|
||
exit_short if z_score > +threshold
|
||
```
|
||
|
||
#### B. Mean Reversion Detection
|
||
- **Konsep**: Spread yang di-filter Kalman lebih stationary dan mean-reverting
|
||
- **Exit Signal**: Saat spread kembali ke expected value
|
||
- **Advantage**: Better drawdown characteristics vs traditional methods
|
||
|
||
#### C. Sharp Reversal Protection
|
||
- **Trigger**: Exit position saat deteksi sharp reverse movement
|
||
- **Implementation**: Monitor Kalman innovation (difference between predicted vs observed)
|
||
- **Threshold**: 2-3x standard deviation of innovation
|
||
|
||
### Mathematical Framework
|
||
```python
|
||
# State space model
|
||
x(k) = A*x(k-1) + B*u(k) + w(k) # State equation
|
||
y(k) = H*x(k) + v(k) # Measurement equation
|
||
|
||
# Kalman equations
|
||
# Prediction
|
||
x_pred = A*x_est + B*u
|
||
P_pred = A*P*A' + Q
|
||
|
||
# Update
|
||
K = P_pred*H' / (H*P_pred*H' + R) # Kalman gain
|
||
x_est = x_pred + K*(y - H*x_pred)
|
||
P = (I - K*H)*P_pred
|
||
```
|
||
|
||
### Performance Characteristics
|
||
- **Spread Stationarity**: Much more stationary than traditional methods
|
||
- **Mean Reversion**: Stronger mean-reverting properties
|
||
- **Drawdown**: Better drawdown management
|
||
- **Noise Reduction**: Effective signal extraction from noisy data
|
||
|
||
### Implementation for XAUBot
|
||
```python
|
||
class KalmanExitStrategy:
|
||
def __init__(self, lookback=20, z_threshold=2.0):
|
||
self.kf = KalmanFilter(dim_state=2, dim_observation=1)
|
||
self.z_threshold = z_threshold
|
||
self.lookback = lookback
|
||
|
||
def should_exit(self, price_history, position_type):
|
||
# Run Kalman filter
|
||
estimates = self.kf.filter(price_history)
|
||
current_estimate = estimates[-1]
|
||
|
||
# Calculate z-score
|
||
residuals = price_history - estimates
|
||
std = np.std(residuals[-self.lookback:])
|
||
z_score = (price_history[-1] - current_estimate) / std
|
||
|
||
# Exit logic
|
||
if position_type == "LONG":
|
||
return z_score < -self.z_threshold
|
||
else:
|
||
return z_score > self.z_threshold
|
||
```
|
||
|
||
**Sources**:
|
||
- [Implementing a Kalman Filter-Based Trading Strategy | Medium](https://medium.com/@serdarilarslan/implementing-a-kalman-filter-based-trading-strategy-8dec764d738e)
|
||
- [Kalman Filter-Based Pairs Trading Strategy | QuantStart](https://www.quantstart.com/articles/kalman-filter-based-pairs-trading-strategy-in-qstrader/)
|
||
- [Kalman Filters for Pairs Trading Guide | Medium](https://theaiquant.medium.com/kalman-filters-are-a-powerful-tool-in-the-world-of-finance-for-modeling-and-predicting-time-series-6b4c614244d3)
|
||
|
||
---
|
||
|
||
## 2. PID CONTROLLER — Feedback-Based Position Management
|
||
|
||
### Konsep Dasar
|
||
Proportional-Integral-Derivative (PID) control menggunakan feedback loop untuk menyesuaikan investment level berdasarkan cumulative gains/losses.
|
||
|
||
### Exit Strategy Framework
|
||
|
||
#### A. PI Controller (Proportional-Integral)
|
||
- **Proportional Term**: Response terhadap current error (price deviation)
|
||
- **Integral Term**: Response terhadap cumulative error (total P&L)
|
||
- **Exit Rule**: Position size → 0 saat PI output mencapai threshold
|
||
|
||
#### B. PIDD Controller (Enhanced 4-Term)
|
||
- **Added Terms**:
|
||
- Second Derivative (D²): Prediksi acceleration changes
|
||
- Switched Structure: Dynamic parameter adjustment
|
||
- **Optimization**: Backtesting-driven profit maximization
|
||
|
||
### Mathematical Model
|
||
|
||
#### Standard PID Formula
|
||
```
|
||
u(t) = Kp*e(t) + Ki*∫e(τ)dτ + Kd*de(t)/dt
|
||
|
||
where:
|
||
- u(t) = control signal (position size adjustment)
|
||
- e(t) = error (target_profit - current_profit)
|
||
- Kp, Ki, Kd = tuning gains
|
||
```
|
||
|
||
#### Exit Decision Logic
|
||
```python
|
||
class PIDExitStrategy:
|
||
def __init__(self, Kp=1.0, Ki=0.1, Kd=0.05, target_profit=100):
|
||
self.Kp = Kp
|
||
self.Ki = Ki
|
||
self.Kd = Kd
|
||
self.target_profit = target_profit
|
||
self.integral = 0
|
||
self.prev_error = 0
|
||
|
||
def should_exit(self, current_profit, dt=1.0):
|
||
# Calculate error
|
||
error = self.target_profit - current_profit
|
||
|
||
# Integral term (accumulated error)
|
||
self.integral += error * dt
|
||
|
||
# Derivative term (rate of change)
|
||
derivative = (error - self.prev_error) / dt
|
||
self.prev_error = error
|
||
|
||
# PID output (position adjustment signal)
|
||
output = (self.Kp * error +
|
||
self.Ki * self.integral +
|
||
self.Kd * derivative)
|
||
|
||
# Exit if output suggests closing (near zero or negative)
|
||
return output <= 0.1 * self.target_profit
|
||
```
|
||
|
||
### Advanced PIDD Implementation
|
||
```python
|
||
class PIDDExitStrategy:
|
||
"""Enhanced 4-term controller with second derivative"""
|
||
|
||
def should_exit(self, profit_history):
|
||
# Standard PID components
|
||
error = target - profit_history[-1]
|
||
integral = sum(profit_history)
|
||
derivative = profit_history[-1] - profit_history[-2]
|
||
|
||
# Second derivative (acceleration)
|
||
derivative2 = (profit_history[-1] - 2*profit_history[-2] +
|
||
profit_history[-3])
|
||
|
||
# PIDD output
|
||
output = (Kp*error + Ki*integral +
|
||
Kd*derivative + Kdd*derivative2)
|
||
|
||
# Switched logic: exit conditions depend on regime
|
||
if is_trending():
|
||
exit_threshold = 0.2
|
||
else:
|
||
exit_threshold = 0.1
|
||
|
||
return output <= exit_threshold
|
||
```
|
||
|
||
### Optimization via Data-Driven Approach
|
||
- **Method**: Log-normal probability distribution from historical data
|
||
- **Objective**: Maximize Sharpe ratio or total return
|
||
- **Gains Optimization**: Grid search or Bayesian optimization for Kp, Ki, Kd
|
||
|
||
### Performance Results
|
||
- **Positive Expectation**: Proven mathematically under GBM assumptions
|
||
- **Model-Free**: Works without price prediction models
|
||
- **Robust**: Handles highly fluctuating markets
|
||
- **Adaptivity**: Switched structure responds to regime changes
|
||
|
||
**Sources**:
|
||
- [PID Control Applied to Automated Trading | Quora](https://www.quora.com/Can-PID-controls-and-control-theory-in-general-be-applied-to-automated-trading)
|
||
- [PI Controller in Stock Trading | IEEE](https://ieeexplore.ieee.org/document/6760047/)
|
||
- [Data-Driven PID Optimization | MDPI](https://www.mdpi.com/1911-8074/16/9/387)
|
||
- [PIDD Control Strategy | ScienceDirect](https://www.sciencedirect.com/science/article/pii/S240589632300068X)
|
||
|
||
---
|
||
|
||
## 3. FUZZY LOGIC — Handling Uncertainty & Multi-Factor Exits
|
||
|
||
### Konsep Dasar
|
||
Fuzzy Logic menggunakan fuzzy set theory untuk memetakan multiple blurred inputs ke crisp outputs, sangat efektif untuk handling market uncertainty.
|
||
|
||
### Exit Strategy Architecture
|
||
|
||
#### A. Fuzzy Inference System (FIS)
|
||
**Two Types**:
|
||
1. **Mamdani FIS**: Rule-based output membership functions
|
||
2. **Takagi-Sugeno FIS**: Linear/polynomial output functions (lebih efisien)
|
||
|
||
#### B. Exit Rule Categories
|
||
|
||
##### 1. Dynamic Profit Target
|
||
```
|
||
IF trend = LOW THEN profit_target = 10-20 points
|
||
IF trend = MODERATE THEN profit_target = 20-30 points
|
||
IF trend = MEDIUM THEN profit_target = 30-40 points
|
||
IF trend = HIGH THEN profit_target = 40-50 points
|
||
```
|
||
|
||
##### 2. Multi-Factor Exit Rules
|
||
```
|
||
IF (RSI = OVERBOUGHT) AND (profit = GOOD) THEN exit = HIGH
|
||
IF (RSI = NEUTRAL) AND (profit = LOW) THEN exit = LOW
|
||
IF (trend_strength = WEAK) AND (time_in_trade = LONG) THEN exit = MEDIUM
|
||
```
|
||
|
||
##### 3. Risk-Based Exits
|
||
```
|
||
IF (drawdown = HIGH) AND (volatility = INCREASING) THEN exit = URGENT
|
||
IF (drawdown = MEDIUM) AND (time = LONG) THEN exit = CONSIDER
|
||
```
|
||
|
||
### Mathematical Framework
|
||
|
||
#### Membership Functions
|
||
```python
|
||
def membership_rsi_overbought(rsi):
|
||
"""Fuzzy membership for overbought RSI"""
|
||
if rsi < 60:
|
||
return 0.0
|
||
elif rsi < 70:
|
||
return (rsi - 60) / 10 # Linear ramp
|
||
elif rsi < 80:
|
||
return 1.0
|
||
else:
|
||
return 1.0 - min((rsi - 80) / 20, 1.0)
|
||
```
|
||
|
||
#### Fuzzy Exit Implementation
|
||
```python
|
||
class FuzzyExitStrategy:
|
||
def __init__(self):
|
||
# Define input variables
|
||
self.rsi = ctrl.Antecedent(np.arange(0, 101, 1), 'rsi')
|
||
self.profit = ctrl.Antecedent(np.arange(-100, 200, 1), 'profit')
|
||
self.trend = ctrl.Antecedent(np.arange(0, 101, 1), 'trend_strength')
|
||
|
||
# Define output variable
|
||
self.exit_signal = ctrl.Consequent(np.arange(0, 101, 1), 'exit')
|
||
|
||
# Define membership functions
|
||
self.rsi['oversold'] = fuzz.trimf(self.rsi.universe, [0, 0, 30])
|
||
self.rsi['neutral'] = fuzz.trimf(self.rsi.universe, [20, 50, 80])
|
||
self.rsi['overbought'] = fuzz.trimf(self.rsi.universe, [70, 100, 100])
|
||
|
||
self.profit['loss'] = fuzz.trimf(self.profit.universe, [-100, -100, 0])
|
||
self.profit['small'] = fuzz.trimf(self.profit.universe, [-10, 20, 50])
|
||
self.profit['good'] = fuzz.trimf(self.profit.universe, [40, 100, 200])
|
||
|
||
# Exit signal strength
|
||
self.exit_signal['hold'] = fuzz.trimf(self.exit_signal.universe, [0, 0, 30])
|
||
self.exit_signal['consider'] = fuzz.trimf(self.exit_signal.universe, [20, 50, 80])
|
||
self.exit_signal['exit'] = fuzz.trimf(self.exit_signal.universe, [70, 100, 100])
|
||
|
||
def build_rules(self):
|
||
"""Define fuzzy rules"""
|
||
rule1 = ctrl.Rule(
|
||
self.rsi['overbought'] & self.profit['good'],
|
||
self.exit_signal['exit']
|
||
)
|
||
rule2 = ctrl.Rule(
|
||
self.rsi['oversold'] & self.profit['good'],
|
||
self.exit_signal['exit']
|
||
)
|
||
rule3 = ctrl.Rule(
|
||
self.profit['loss'] & self.trend['weak'],
|
||
self.exit_signal['exit']
|
||
)
|
||
rule4 = ctrl.Rule(
|
||
self.rsi['neutral'] & self.profit['small'],
|
||
self.exit_signal['hold']
|
||
)
|
||
|
||
return ctrl.ControlSystem([rule1, rule2, rule3, rule4])
|
||
|
||
def should_exit(self, rsi, profit, trend_strength):
|
||
"""Compute exit signal"""
|
||
system = self.build_rules()
|
||
simulation = ctrl.ControlSystemSimulation(system)
|
||
|
||
simulation.input['rsi'] = rsi
|
||
simulation.input['profit'] = profit
|
||
simulation.input['trend_strength'] = trend_strength
|
||
|
||
simulation.compute()
|
||
exit_strength = simulation.output['exit']
|
||
|
||
# Exit if signal > 70
|
||
return exit_strength > 70
|
||
```
|
||
|
||
### Performance Benefits
|
||
- **Accuracy Improvement**: Considerable increase in profitability factor
|
||
- **Adaptivity**: Handles changing market conditions better than static rules
|
||
- **Multi-Factor Integration**: Combines multiple indicators naturally
|
||
- **Human-Like Reasoning**: Mimics trader decision-making process
|
||
|
||
### Integration with Genetic Algorithms
|
||
- **Optimization**: Use GA to optimize membership functions and rule weights
|
||
- **Self-Learning**: Evolve rules based on performance feedback
|
||
- **Robustness**: Find optimal parameters that work across market conditions
|
||
|
||
**Sources**:
|
||
- [Fuzzy Logic in Trading Strategies | MQL5](https://www.mql5.com/en/articles/3795)
|
||
- [Fuzzy Logic Stock Trading Using Bollinger Bands | IEEE](https://ieeexplore.ieee.org/document/9072734/)
|
||
- [Modeling Trading Decisions Using Fuzzy Logic](https://ghannami.com/modeling-trading-decisions-using-fuzzy-logic/)
|
||
- [Role of Fuzzy Logic in Algorithmic Trading | GeeksforGeeks](https://www.geeksforgeeks.org/blogs/what-is-the-role-of-fuzzy-logic-in-algorithmic-trading/)
|
||
|
||
---
|
||
|
||
## 4. SMART MONEY CONCEPTS (SMC) — Mitigation-Based Exits
|
||
|
||
### Konsep Dasar
|
||
SMC exit strategy berbasis pada pemahaman institutional flow dan order block mitigation untuk menentukan timing optimal keluar dari trade.
|
||
|
||
### Order Block Mitigation Framework
|
||
|
||
#### A. Mitigation Zone Definition
|
||
- **Mitigation Block**: Zone dimana smart money di-stop out sebelumnya
|
||
- **Purpose**: Recovery losses before pushing price ke intended direction
|
||
- **Confirmation**: Retest zone validates breakout authenticity
|
||
|
||
#### B. Mathematical Approach to Mitigation
|
||
|
||
##### 1. Fibonacci Retracement Integration
|
||
```python
|
||
def calculate_mitigation_zone(swing_high, swing_low, fib_level=0.618):
|
||
"""Calculate mitigation zone using Fibonacci"""
|
||
range_size = swing_high - swing_low
|
||
mitigation_level = swing_low + (range_size * fib_level)
|
||
|
||
# Zone is +/- 0.2% from mitigation level
|
||
zone_upper = mitigation_level * 1.002
|
||
zone_lower = mitigation_level * 0.998
|
||
|
||
return zone_lower, zone_upper
|
||
```
|
||
|
||
##### 2. Gap Mitigation Detection
|
||
```python
|
||
class GapMitigationDetector:
|
||
def is_gap_mitigated(self, gap_high, gap_low, current_price):
|
||
"""
|
||
Gap is "mitigated" when price reaches it
|
||
Gap is "filled" when price moves completely through it
|
||
"""
|
||
if gap_low <= current_price <= gap_high:
|
||
return True, "mitigated"
|
||
elif current_price > gap_high: # For bearish gap
|
||
return True, "filled"
|
||
return False, "open"
|
||
```
|
||
|
||
#### C. Exit Strategy Based on Mitigation
|
||
|
||
##### Exit Rule 1: Mitigation Block Rejection
|
||
```
|
||
IF price enters mitigation block AND shows rejection (wick)
|
||
THEN exit opposite position with profit
|
||
```
|
||
|
||
##### Exit Rule 2: Order Block Status
|
||
```
|
||
IF order_block.is_mitigated() AND position_profit > 0
|
||
THEN consider exit (block lost significance)
|
||
```
|
||
|
||
##### Exit Rule 3: BOS/CHoCH Integration
|
||
```
|
||
IF mitigation_occurred AND Break_of_Structure in opposite direction
|
||
THEN exit immediately (trend reversal confirmed)
|
||
```
|
||
|
||
### Implementation for XAUBot
|
||
```python
|
||
class SMCExitStrategy:
|
||
def __init__(self):
|
||
self.order_blocks = []
|
||
self.mitigation_zones = []
|
||
|
||
def detect_mitigation_block(self, df):
|
||
"""Detect mitigation blocks in price action"""
|
||
mitigation_blocks = []
|
||
|
||
for i in range(len(df) - 20):
|
||
# Look for zone where price was rejected before
|
||
window = df[i:i+20]
|
||
|
||
# Check for liquidity grab (stop hunt)
|
||
if self._is_liquidity_grab(window):
|
||
block = {
|
||
'high': window['high'].max(),
|
||
'low': window['low'].min(),
|
||
'type': 'mitigation',
|
||
'timestamp': window.index[-1]
|
||
}
|
||
mitigation_blocks.append(block)
|
||
|
||
return mitigation_blocks
|
||
|
||
def should_exit(self, position, current_price, current_candle):
|
||
"""Exit decision based on mitigation"""
|
||
|
||
# Check if price entered mitigation zone
|
||
for zone in self.mitigation_zones:
|
||
if zone['low'] <= current_price <= zone['high']:
|
||
|
||
# Check for rejection (wick)
|
||
if position.type == 'LONG':
|
||
# Bearish rejection in mitigation zone
|
||
if (current_candle['high'] - current_candle['close']) > \
|
||
(current_candle['close'] - current_candle['open']) * 2:
|
||
return True, "mitigation_rejection"
|
||
|
||
elif position.type == 'SHORT':
|
||
# Bullish rejection in mitigation zone
|
||
if (current_candle['close'] - current_candle['low']) > \
|
||
(current_candle['open'] - current_candle['close']) * 2:
|
||
return True, "mitigation_rejection"
|
||
|
||
# Check order block status
|
||
for ob in self.order_blocks:
|
||
if ob.is_mitigated() and position.profit > 0:
|
||
return True, "order_block_mitigated"
|
||
|
||
return False, None
|
||
```
|
||
|
||
### Integration with Other SMC Concepts
|
||
|
||
#### 1. Fair Value Gap (FVG) + Mitigation
|
||
```python
|
||
def check_fvg_mitigation_exit(position, fvgs):
|
||
"""Exit when FVG gets mitigated against position"""
|
||
for fvg in fvgs:
|
||
if fvg.is_mitigated() and fvg.direction != position.direction:
|
||
return True
|
||
return False
|
||
```
|
||
|
||
#### 2. Liquidity Sweep + Mitigation
|
||
```python
|
||
def detect_liquidity_sweep_exit(position, price_action):
|
||
"""Exit after liquidity sweep in opposite direction"""
|
||
if position.type == 'LONG':
|
||
# Check for sweep below recent lows
|
||
if price_swept_low() and now_reversing_up():
|
||
return True # Exit long before reversal completes
|
||
return False
|
||
```
|
||
|
||
### Performance Optimization
|
||
- **Time-Based Mitigation**: Monitor how long mitigation zone is respected
|
||
- **Volume Confirmation**: Higher volume at mitigation = stronger signal
|
||
- **Multiple Timeframe**: Check mitigation on H1, H4, D1 simultaneously
|
||
|
||
**Sources**:
|
||
- [Smart Money Concepts Strategy Explained | EplanetBrokers](https://eplanetbrokers.com/training/smart-money-concept)
|
||
- [SMC Complete Trading Guide | XS](https://www.xs.com/en/blog/smart-money-concept/)
|
||
- [SMC Trading Guide | Mind Math Money](https://www.mindmathmoney.com/articles/smart-money-concepts-the-ultimate-guide-to-trading-like-institutional-investors-in-2025)
|
||
- [Order Blocks Rules | Daily Price Action](https://dailypriceaction.com/blog/order-blocks/)
|
||
|
||
---
|
||
|
||
## 5. REINFORCEMENT LEARNING (DQN) — Adaptive Exit Learning
|
||
|
||
### Konsep Dasar
|
||
Deep Q-Network (DQN) mengintegrasikan Q-learning dengan deep neural networks untuk mempelajari optimal exit policy dari historical experience.
|
||
|
||
### Exit Strategy Framework
|
||
|
||
#### A. DQN Architecture for Exit Decisions
|
||
|
||
##### State Space (Input)
|
||
```python
|
||
state = [
|
||
current_profit, # Current P&L
|
||
profit_peak, # Peak profit reached
|
||
profit_velocity, # Rate of profit change
|
||
time_in_trade, # Duration
|
||
rsi, macd, adx, # Technical indicators
|
||
regime, # Market regime (0=ranging, 1=trending)
|
||
volatility, # ATR-based volatility
|
||
distance_from_entry, # Price distance from entry
|
||
]
|
||
```
|
||
|
||
##### Action Space (Output)
|
||
```python
|
||
actions = [
|
||
0: HOLD, # Continue holding position
|
||
1: EXIT_25_PERCENT, # Partial exit 25%
|
||
2: EXIT_50_PERCENT, # Partial exit 50%
|
||
3: EXIT_100_PERCENT, # Full exit
|
||
]
|
||
```
|
||
|
||
##### Reward Function
|
||
```python
|
||
def calculate_reward(action, next_state, position):
|
||
"""Reward optimized for Sharpe ratio"""
|
||
|
||
if action == HOLD:
|
||
# Reward for holding if profit increases
|
||
profit_change = next_state.profit - position.profit
|
||
time_penalty = -0.01 * position.duration # Encourage faster exits
|
||
reward = profit_change + time_penalty
|
||
|
||
elif action in [EXIT_25, EXIT_50, EXIT_100]:
|
||
# Reward for exiting
|
||
final_profit = position.profit
|
||
max_possible = position.peak_profit
|
||
|
||
# Capture efficiency: how much of peak we captured
|
||
capture_rate = final_profit / max_possible if max_possible > 0 else 0
|
||
|
||
# Sharpe-based reward
|
||
sharpe_component = final_profit / (position.volatility + 1e-6)
|
||
|
||
# Timing bonus: exit near peak
|
||
time_since_peak = position.time - position.peak_time
|
||
timing_bonus = max(0, 1.0 - time_since_peak / 300) # Decay over 5min
|
||
|
||
reward = (capture_rate * 10 +
|
||
sharpe_component * 5 +
|
||
timing_bonus * 3)
|
||
|
||
return reward
|
||
```
|
||
|
||
#### B. DQN Training Process
|
||
|
||
##### Experience Replay
|
||
```python
|
||
class ExperienceReplay:
|
||
def __init__(self, capacity=10000):
|
||
self.buffer = deque(maxlen=capacity)
|
||
|
||
def add(self, state, action, reward, next_state, done):
|
||
self.buffer.append((state, action, reward, next_state, done))
|
||
|
||
def sample(self, batch_size):
|
||
return random.sample(self.buffer, batch_size)
|
||
```
|
||
|
||
##### DQN Network
|
||
```python
|
||
class DQNExitNetwork(nn.Module):
|
||
def __init__(self, state_dim, action_dim):
|
||
super().__init__()
|
||
self.fc1 = nn.Linear(state_dim, 128)
|
||
self.fc2 = nn.Linear(128, 128)
|
||
self.fc3 = nn.Linear(128, 64)
|
||
self.fc4 = nn.Linear(64, action_dim)
|
||
self.dropout = nn.Dropout(0.2)
|
||
|
||
def forward(self, x):
|
||
x = F.relu(self.fc1(x))
|
||
x = self.dropout(x)
|
||
x = F.relu(self.fc2(x))
|
||
x = self.dropout(x)
|
||
x = F.relu(self.fc3(x))
|
||
return self.fc4(x) # Q-values for each action
|
||
```
|
||
|
||
##### Training Loop
|
||
```python
|
||
def train_dqn_exit(env, episodes=1000):
|
||
state_dim = 10
|
||
action_dim = 4
|
||
|
||
policy_net = DQNExitNetwork(state_dim, action_dim)
|
||
target_net = DQNExitNetwork(state_dim, action_dim)
|
||
target_net.load_state_dict(policy_net.state_dict())
|
||
|
||
optimizer = optim.Adam(policy_net.parameters(), lr=0.001)
|
||
memory = ExperienceReplay(10000)
|
||
|
||
for episode in range(episodes):
|
||
state = env.reset()
|
||
total_reward = 0
|
||
|
||
while not done:
|
||
# Epsilon-greedy action selection
|
||
if random.random() < epsilon:
|
||
action = random.randint(0, action_dim-1)
|
||
else:
|
||
with torch.no_grad():
|
||
q_values = policy_net(torch.FloatTensor(state))
|
||
action = q_values.argmax().item()
|
||
|
||
# Take action
|
||
next_state, reward, done = env.step(action)
|
||
memory.add(state, action, reward, next_state, done)
|
||
|
||
# Train on batch
|
||
if len(memory.buffer) > batch_size:
|
||
batch = memory.sample(batch_size)
|
||
|
||
# Compute loss
|
||
states, actions, rewards, next_states, dones = zip(*batch)
|
||
|
||
current_q = policy_net(states).gather(1, actions)
|
||
next_q = target_net(next_states).max(1)[0].detach()
|
||
target_q = rewards + gamma * next_q * (1 - dones)
|
||
|
||
loss = F.mse_loss(current_q, target_q)
|
||
|
||
# Update
|
||
optimizer.zero_grad()
|
||
loss.backward()
|
||
optimizer.step()
|
||
|
||
state = next_state
|
||
total_reward += reward
|
||
|
||
# Update target network every N episodes
|
||
if episode % 10 == 0:
|
||
target_net.load_state_dict(policy_net.state_dict())
|
||
```
|
||
|
||
### C. Self-Rewarding DQN (SR-DDQN)
|
||
|
||
#### Advanced Architecture
|
||
```python
|
||
class SelfRewardingDQN:
|
||
"""
|
||
Integrates self-rewarding network to learn better reward function
|
||
Compares predicted rewards with expert-labeled rewards
|
||
"""
|
||
|
||
def __init__(self):
|
||
self.policy_net = DQNExitNetwork()
|
||
self.reward_net = RewardPredictionNetwork()
|
||
|
||
def compute_self_reward(self, state, action, next_state):
|
||
# Predicted reward from learned model
|
||
predicted = self.reward_net(state, action, next_state)
|
||
|
||
# Expert metrics
|
||
min_max_metric = self.compute_min_max(next_state)
|
||
sharpe_metric = self.compute_sharpe(next_state)
|
||
return_metric = self.compute_return(next_state)
|
||
|
||
# Weighted combination
|
||
expert_reward = (0.3 * min_max_metric +
|
||
0.4 * sharpe_metric +
|
||
0.3 * return_metric)
|
||
|
||
# Update reward network
|
||
reward_loss = F.mse_loss(predicted, expert_reward)
|
||
|
||
return expert_reward
|
||
```
|
||
|
||
### Performance Results (From Research)
|
||
- **ROI**: 11.24% with single asset (TQQQ)
|
||
- **Cumulative Return**: 1124.23% on IXIC dataset (SR-DDQN)
|
||
- **Sharpe Ratio**: Optimized through reward function
|
||
- **Win Rate**: Improved through experience replay
|
||
|
||
### Challenges & Solutions
|
||
|
||
#### Overfitting Prevention
|
||
```python
|
||
# Techniques:
|
||
1. Dropout layers (0.2-0.3)
|
||
2. Early stopping based on validation performance
|
||
3. Ensemble methods (multiple DQNs voting)
|
||
4. Regularization (L2 penalty)
|
||
```
|
||
|
||
#### Spurious Correlation Avoidance
|
||
```python
|
||
# Solutions:
|
||
1. Longer training periods (multiple market cycles)
|
||
2. Walk-forward validation
|
||
3. Regime-aware training (separate models per regime)
|
||
4. Feature importance analysis
|
||
```
|
||
|
||
**Sources**:
|
||
- [Portfolio Optimization using DQN | ACM](https://dl.acm.org/doi/10.1145/3711542.3711567)
|
||
- [Quantitative Trading using Deep Q Learning | arXiv](https://arxiv.org/html/2304.06037v2)
|
||
- [Self-Rewarding Mechanism in Deep RL for Trading | MDPI](https://www.mdpi.com/2227-7390/12/24/4020)
|
||
- [Reinforcement Learning in Trading | QuantInsti](https://blog.quantinsti.com/reinforcement-learning-trading/)
|
||
|
||
---
|
||
|
||
## 6. ADAPTIVE TRAILING STOP — Dynamic Exit Management
|
||
|
||
### Konsep Dasar
|
||
Adaptive trailing stops menyesuaikan stop distance berdasarkan market volatility dan regime, providing dynamic downside protection.
|
||
|
||
### Mathematical Framework
|
||
|
||
#### A. ATR-Based Adaptive Stop
|
||
|
||
##### Core Formula
|
||
```python
|
||
def calculate_adaptive_trailing_stop(position, atr, regime, efficiency):
|
||
"""
|
||
Dynamic trailing stop that adapts to market conditions
|
||
"""
|
||
# Base multiplier
|
||
base_multiplier = 2.0
|
||
|
||
# Regime adjustment
|
||
if regime == "trending":
|
||
regime_factor = 1.2 # Wider stops in trends
|
||
elif regime == "ranging":
|
||
regime_factor = 0.8 # Tighter stops in ranges
|
||
else: # volatile
|
||
regime_factor = 1.5 # Much wider stops
|
||
|
||
# Efficiency adjustment (how clean the move is)
|
||
if efficiency > 0.7: # Strong directional move
|
||
efficiency_factor = 1.3
|
||
elif efficiency < 0.3: # Choppy
|
||
efficiency_factor = 0.7
|
||
else:
|
||
efficiency_factor = 1.0
|
||
|
||
# Combined multiplier
|
||
multiplier = base_multiplier * regime_factor * efficiency_factor
|
||
|
||
# Calculate stop distance
|
||
stop_distance = atr * multiplier
|
||
|
||
# Apply trailing logic
|
||
if position.type == "LONG":
|
||
new_stop = position.current_price - stop_distance
|
||
position.stop_loss = max(position.stop_loss, new_stop)
|
||
else:
|
||
new_stop = position.current_price + stop_distance
|
||
position.stop_loss = min(position.stop_loss, new_stop)
|
||
|
||
return position.stop_loss
|
||
```
|
||
|
||
#### B. Stochastic Trailing Stop (Advanced)
|
||
|
||
##### Mathematical Model
|
||
- **Concept**: Trailing stop as stochastic floor based on running maximum
|
||
- **Formula**:
|
||
```
|
||
S(t) = max(S(t-1), α * M(t))
|
||
|
||
where:
|
||
- S(t) = stop level at time t
|
||
- M(t) = running maximum of asset price
|
||
- α = trail factor (typically 0.85-0.95)
|
||
```
|
||
|
||
##### Implementation
|
||
```python
|
||
class StochasticTrailingStop:
|
||
def __init__(self, alpha=0.90):
|
||
self.alpha = alpha
|
||
self.running_max = 0
|
||
self.stop_level = 0
|
||
|
||
def update(self, current_price):
|
||
# Update running maximum
|
||
self.running_max = max(self.running_max, current_price)
|
||
|
||
# Update stop level (stochastic floor)
|
||
self.stop_level = max(
|
||
self.stop_level,
|
||
self.alpha * self.running_max
|
||
)
|
||
|
||
return self.stop_level
|
||
|
||
def should_exit(self, current_price):
|
||
return current_price <= self.stop_level
|
||
```
|
||
|
||
#### C. Adaptive ML Trailing Stop
|
||
|
||
##### Regime-Responsive Structure
|
||
```python
|
||
class AdaptiveMLTrailingStop:
|
||
"""
|
||
Combines ML prediction with adaptive trailing logic
|
||
Contracts during orderly moves, relaxes during rotation
|
||
"""
|
||
|
||
def calculate_dynamic_trail_distance(self, market_state):
|
||
# ML model predicts optimal trail distance
|
||
features = [
|
||
market_state['volatility'],
|
||
market_state['trend_strength'],
|
||
market_state['efficiency'],
|
||
market_state['volume_profile'],
|
||
market_state['regime']
|
||
]
|
||
|
||
# Predict optimal multiplier
|
||
optimal_multiplier = self.ml_model.predict([features])[0]
|
||
|
||
# Constrain to reasonable range
|
||
optimal_multiplier = np.clip(optimal_multiplier, 0.18, 0.35)
|
||
|
||
trail_distance = market_state['atr'] * optimal_multiplier
|
||
|
||
return trail_distance
|
||
|
||
def update_stop(self, position, market_state):
|
||
trail_distance = self.calculate_dynamic_trail_distance(market_state)
|
||
|
||
if market_state['state'] == 'accelerating':
|
||
# Wider trail during acceleration
|
||
trail_distance *= 1.5
|
||
elif market_state['state'] == 'stalling':
|
||
# Tighter trail when stalling
|
||
trail_distance *= 0.6
|
||
elif market_state['state'] == 'reversing':
|
||
# Very tight trail on reversal
|
||
trail_distance *= 0.4
|
||
|
||
# Apply trailing stop
|
||
new_stop = position.current_price - trail_distance
|
||
position.stop_loss = max(position.stop_loss, new_stop)
|
||
|
||
return position.stop_loss
|
||
```
|
||
|
||
### Advanced Techniques
|
||
|
||
#### 1. Multi-Timeframe Trailing Stop
|
||
```python
|
||
def multi_timeframe_trailing_stop(position, timeframes=['M15', 'H1', 'H4']):
|
||
"""Use the tightest stop across multiple timeframes"""
|
||
stops = []
|
||
|
||
for tf in timeframes:
|
||
atr = get_atr(tf)
|
||
regime = get_regime(tf)
|
||
stop = calculate_adaptive_trailing_stop(position, atr, regime)
|
||
stops.append(stop)
|
||
|
||
# Use tightest stop that's still reasonable
|
||
return max(stops) if position.type == "LONG" else min(stops)
|
||
```
|
||
|
||
#### 2. Profit-Level Based Trailing
|
||
```python
|
||
def profit_based_trailing(position, current_profit):
|
||
"""Adjust trail distance based on profit level"""
|
||
|
||
if current_profit < 10:
|
||
# Wider stop when profit is small
|
||
multiplier = 2.5
|
||
elif current_profit < 30:
|
||
# Medium stop
|
||
multiplier = 2.0
|
||
elif current_profit < 50:
|
||
# Tighter stop
|
||
multiplier = 1.5
|
||
else:
|
||
# Very tight stop to protect large profits
|
||
multiplier = 1.0
|
||
|
||
return position.atr * multiplier
|
||
```
|
||
|
||
### Performance Characteristics
|
||
- **Volatility Adaptation**: Wider stops in volatile periods, tighter in calm
|
||
- **Drawdown Reduction**: Better downside protection vs fixed stops
|
||
- **Profit Maximization**: Lets winners run longer in strong trends
|
||
- **False Exit Reduction**: Fewer premature exits in ranging markets
|
||
|
||
**Sources**:
|
||
- [Dynamic ATR Trailing Stop Strategy | Medium](https://medium.com/@redsword_23261/dynamic-atr-trailing-stop-trading-strategy-market-volatility-adaptive-system-2c2df9f778f2)
|
||
- [Adaptive ML Trailing Stop | TradingView](https://www.tradingview.com/script/2mgFal7W-Adaptive-ML-Trailing-Stop-BOSWaves/)
|
||
- [Optimal Trading with Trailing Stop | Medium](https://medium.com/quantitative-investing/optimal-trading-with-a-trailing-stop-796964fc892a)
|
||
- [ATR Stop-Loss Strategies | LuxAlgo](https://www.luxalgo.com/blog/5-atr-stop-loss-strategies-for-risk-control/)
|
||
|
||
---
|
||
|
||
## 7. BAYESIAN OPTIMIZATION — Parameter & Threshold Optimization
|
||
|
||
### Konsep Dasar
|
||
Bayesian Optimization menggunakan probabilistic model untuk mencari optimal exit parameters dengan minimal evaluations.
|
||
|
||
### Exit Parameter Optimization Framework
|
||
|
||
#### A. Optimization Target
|
||
```python
|
||
# Parameters to optimize
|
||
exit_params = {
|
||
'profit_target_multiplier': [0.5, 3.0], # Range
|
||
'stop_loss_atr_multiplier': [1.0, 3.0],
|
||
'trailing_start_profit': [5.0, 50.0],
|
||
'trailing_distance_atr': [0.5, 2.5],
|
||
'time_exit_threshold_minutes': [30, 300],
|
||
'rsi_exit_threshold': [60, 85],
|
||
}
|
||
|
||
# Objective function
|
||
def objective(params):
|
||
"""Maximize Sharpe ratio or return/drawdown ratio"""
|
||
backtest_results = run_backtest_with_params(params)
|
||
|
||
sharpe = backtest_results['sharpe_ratio']
|
||
return_dd_ratio = backtest_results['return'] / backtest_results['max_dd']
|
||
win_rate = backtest_results['win_rate']
|
||
|
||
# Combined objective
|
||
score = 0.5 * sharpe + 0.3 * return_dd_ratio + 0.2 * win_rate
|
||
return score
|
||
```
|
||
|
||
#### B. Gaussian Process Surrogate Model
|
||
|
||
##### Implementation
|
||
```python
|
||
from sklearn.gaussian_process import GaussianProcessRegressor
|
||
from sklearn.gaussian_process.kernels import Matern
|
||
from scipy.stats import norm
|
||
|
||
class BayesianExitOptimizer:
|
||
def __init__(self, param_bounds):
|
||
self.param_bounds = param_bounds
|
||
self.gp = GaussianProcessRegressor(
|
||
kernel=Matern(nu=2.5),
|
||
n_restarts_optimizer=25,
|
||
normalize_y=True
|
||
)
|
||
self.X_observed = []
|
||
self.y_observed = []
|
||
|
||
def acquisition_function(self, X, xi=0.01):
|
||
"""Expected Improvement (EI) acquisition function"""
|
||
mu, sigma = self.gp.predict(X, return_std=True)
|
||
|
||
if len(self.y_observed) == 0:
|
||
return 0
|
||
|
||
mu_best = max(self.y_observed)
|
||
|
||
with np.errstate(divide='warn'):
|
||
Z = (mu - mu_best - xi) / sigma
|
||
ei = (mu - mu_best - xi) * norm.cdf(Z) + sigma * norm.pdf(Z)
|
||
ei[sigma == 0.0] = 0.0
|
||
|
||
return ei
|
||
|
||
def suggest_next_params(self):
|
||
"""Suggest next parameter combination to try"""
|
||
|
||
# Random search for maximum EI
|
||
best_ei = -np.inf
|
||
best_params = None
|
||
|
||
for _ in range(1000):
|
||
# Random sample from parameter space
|
||
params = {}
|
||
for key, (low, high) in self.param_bounds.items():
|
||
params[key] = np.random.uniform(low, high)
|
||
|
||
X = self._params_to_array(params)
|
||
ei = self.acquisition_function(X.reshape(1, -1))
|
||
|
||
if ei > best_ei:
|
||
best_ei = ei
|
||
best_params = params
|
||
|
||
return best_params
|
||
|
||
def update(self, params, score):
|
||
"""Update GP model with new observation"""
|
||
X = self._params_to_array(params)
|
||
self.X_observed.append(X)
|
||
self.y_observed.append(score)
|
||
|
||
# Refit GP
|
||
self.gp.fit(np.array(self.X_observed), np.array(self.y_observed))
|
||
|
||
def optimize(self, n_iterations=50):
|
||
"""Run Bayesian optimization"""
|
||
|
||
# Initial random samples
|
||
for _ in range(5):
|
||
params = self._random_params()
|
||
score = objective(params)
|
||
self.update(params, score)
|
||
|
||
# Bayesian optimization loop
|
||
for i in range(n_iterations - 5):
|
||
# Suggest next params
|
||
params = self.suggest_next_params()
|
||
|
||
# Evaluate
|
||
score = objective(params)
|
||
|
||
# Update model
|
||
self.update(params, score)
|
||
|
||
print(f"Iteration {i+6}: Score = {score:.4f}")
|
||
|
||
# Return best parameters
|
||
best_idx = np.argmax(self.y_observed)
|
||
best_params = self.X_observed[best_idx]
|
||
return self._array_to_params(best_params)
|
||
```
|
||
|
||
#### C. Upper Confidence Bound (UCB) Alternative
|
||
|
||
```python
|
||
def ucb_acquisition(mu, sigma, kappa=2.0):
|
||
"""
|
||
Upper Confidence Bound acquisition function
|
||
kappa controls exploration vs exploitation
|
||
"""
|
||
return mu + kappa * sigma
|
||
|
||
class UCBOptimizer(BayesianExitOptimizer):
|
||
def acquisition_function(self, X, kappa=2.0):
|
||
mu, sigma = self.gp.predict(X, return_std=True)
|
||
return mu + kappa * sigma
|
||
```
|
||
|
||
### Stop-Loss Threshold Optimization
|
||
|
||
#### Specialized Framework
|
||
```python
|
||
class StopLossOptimizer:
|
||
"""
|
||
Bayesian optimization specifically for stop-loss thresholds
|
||
Balances two objectives:
|
||
1. Minimize magnitude of losses
|
||
2. Maximize correct classification of winning trades
|
||
"""
|
||
|
||
def objective(self, stop_loss_params):
|
||
trades = self.get_historical_trades()
|
||
|
||
total_loss = 0
|
||
winners_stopped = 0
|
||
losers_stopped = 0
|
||
|
||
for trade in trades:
|
||
# Simulate stop loss
|
||
stopped, stop_profit = self.simulate_stop(
|
||
trade,
|
||
stop_loss_params
|
||
)
|
||
|
||
if stopped:
|
||
total_loss += stop_profit
|
||
|
||
# Check if we stopped a would-be winner
|
||
if trade['final_profit'] > 0:
|
||
winners_stopped += 1
|
||
else:
|
||
losers_stopped += 1
|
||
|
||
# Objective: minimize losses, maximize correct stops
|
||
avg_loss = total_loss / len(trades)
|
||
correct_stop_rate = losers_stopped / (losers_stopped + winners_stopped)
|
||
|
||
# Combined score (higher is better)
|
||
score = -avg_loss + 10 * correct_stop_rate
|
||
|
||
return score
|
||
```
|
||
|
||
### Practical Application to XAUBot
|
||
|
||
```python
|
||
# Define parameter space for XAUBot exit optimization
|
||
xaubot_exit_params = {
|
||
# Profit protection
|
||
'min_profit_to_protect': [5.0, 15.0],
|
||
'be_shield_activation': [2.0, 8.0],
|
||
'be_shield_percentage': [0.5, 0.9],
|
||
|
||
# Trailing stop
|
||
'atr_trail_start_profit': [8.0, 20.0],
|
||
'atr_trail_multiplier': [0.15, 0.40],
|
||
|
||
# Time-based
|
||
'grace_period_minutes': [5, 15],
|
||
'max_trade_duration_minutes': [30, 180],
|
||
|
||
# Signal-based
|
||
'signal_exit_threshold_pct': [0.6, 0.9],
|
||
'regime_change_exit_delay': [1, 5], # candles
|
||
}
|
||
|
||
# Run optimization
|
||
optimizer = BayesianExitOptimizer(xaubot_exit_params)
|
||
best_params = optimizer.optimize(n_iterations=100)
|
||
|
||
print("Optimal Exit Parameters:")
|
||
print(best_params)
|
||
```
|
||
|
||
### Performance Benefits
|
||
- **Sample Efficiency**: Find optimal params with ~50 evaluations vs 10,000+ for grid search
|
||
- **Robustness**: GP handles noisy objective functions well
|
||
- **Adaptivity**: Can reoptimize as market conditions change
|
||
- **Multi-Objective**: Can optimize Sharpe, return/DD, win rate simultaneously
|
||
|
||
**Sources**:
|
||
- [Bayesian Optimization in Trading | HackerNoon](https://hackernoon.com/bayesian-optimization-in-trading-4fb918fc52a7)
|
||
- [Determining Optimal Stop-Loss via Bayesian | arXiv](https://arxiv.org/pdf/1609.00869)
|
||
- [Optimising Supertrend with Bayesian Optimization | arXiv](https://arxiv.org/html/2405.14262v1)
|
||
- [Optimizing Trading Strategies | Springer](https://link.springer.com/chapter/10.1007/978-1-4842-9675-2_9)
|
||
|
||
---
|
||
|
||
## IMPLEMENTATION ROADMAP FOR XAUBOT
|
||
|
||
### Phase 1: Hybrid Adaptive Exit System (Priority)
|
||
|
||
#### Components to Integrate
|
||
1. **Kalman Filter** — For noise reduction and trend prediction
|
||
- Use for profit velocity smoothing
|
||
- Detect true reversals vs noise
|
||
|
||
2. **Adaptive ATR Trailing** — Already partially implemented, enhance with:
|
||
- Regime-specific multipliers
|
||
- Profit-level based adjustment
|
||
- Multi-timeframe confirmation
|
||
|
||
3. **Fuzzy Logic Integration** — For multi-factor exit decisions
|
||
- Combine RSI, profit, trend, time factors
|
||
- Dynamic threshold adjustment
|
||
- Replace hard-coded if/else chains
|
||
|
||
#### Pseudocode
|
||
```python
|
||
class HybridExitSystem:
|
||
def __init__(self):
|
||
self.kalman = KalmanExitStrategy()
|
||
self.adaptive_trail = AdaptiveMLTrailingStop()
|
||
self.fuzzy = FuzzyExitStrategy()
|
||
self.smc = SMCExitStrategy()
|
||
|
||
def should_exit(self, position, market_state):
|
||
# 1. Kalman noise filtering
|
||
smoothed_profit = self.kalman.filter(position.profit_history)
|
||
profit_velocity = self.kalman.predict_velocity()
|
||
|
||
# 2. SMC mitigation check
|
||
smc_exit, reason = self.smc.should_exit(position, market_state)
|
||
if smc_exit and reason == "mitigation_rejection":
|
||
return True, "SMC_MITIGATION", urgency=10
|
||
|
||
# 3. Adaptive trailing stop
|
||
trail_stop = self.adaptive_trail.update_stop(position, market_state)
|
||
if position.current_price <= trail_stop:
|
||
return True, "ATR_TRAIL", urgency=9
|
||
|
||
# 4. Fuzzy logic multi-factor decision
|
||
fuzzy_signal = self.fuzzy.should_exit(
|
||
rsi=market_state['rsi'],
|
||
profit=smoothed_profit,
|
||
trend=market_state['trend_strength'],
|
||
velocity=profit_velocity
|
||
)
|
||
|
||
if fuzzy_signal > 70: # High exit confidence
|
||
return True, "FUZZY_MULTI_FACTOR", urgency=8
|
||
|
||
return False, None, urgency=0
|
||
```
|
||
|
||
### Phase 2: DQN Training (Medium-term)
|
||
|
||
#### Data Collection
|
||
- Save all exit decisions with state, action, outcome
|
||
- Build dataset of 1000+ trades
|
||
- Label with actual profit captured vs peak
|
||
|
||
#### Training Pipeline
|
||
```python
|
||
# 1. Prepare training data
|
||
states, actions, rewards = prepare_training_data()
|
||
|
||
# 2. Train DQN
|
||
dqn = train_dqn_exit(states, actions, rewards, episodes=5000)
|
||
|
||
# 3. Validate on hold-out set
|
||
validation_sharpe = validate_dqn(dqn, validation_trades)
|
||
|
||
# 4. Deploy if better than current system
|
||
if validation_sharpe > current_sharpe * 1.15: # 15% improvement
|
||
deploy_dqn_to_production(dqn)
|
||
```
|
||
|
||
### Phase 3: Bayesian Optimization (Ongoing)
|
||
|
||
#### Weekly Reoptimization
|
||
```python
|
||
# Every week, reoptimize parameters
|
||
weekly_optimizer = BayesianExitOptimizer(xaubot_exit_params)
|
||
|
||
# Use last 2 weeks of data
|
||
recent_trades = get_trades(days=14)
|
||
optimizer.fit(recent_trades)
|
||
|
||
# Update parameters if significant improvement
|
||
new_params = optimizer.get_best_params()
|
||
if improvement > 10%:
|
||
update_config(new_params)
|
||
```
|
||
|
||
---
|
||
|
||
## PERFORMANCE METRICS TO TRACK
|
||
|
||
### Exit Quality Metrics
|
||
```python
|
||
# 1. Peak Capture Rate
|
||
peak_capture_rate = actual_profit / peak_profit_during_trade
|
||
|
||
# 2. Exit Timing Score
|
||
# How close to peak did we exit? (in time and price)
|
||
timing_score = 1.0 - (time_from_peak / total_trade_duration)
|
||
|
||
# 3. False Exit Rate
|
||
# Exits that were followed by continued profit
|
||
false_exit_rate = exits_before_continuation / total_exits
|
||
|
||
# 4. Regime-Specific Performance
|
||
for regime in ['trending', 'ranging', 'volatile']:
|
||
regime_sharpe = calculate_sharpe(exits_in_regime)
|
||
regime_capture = calculate_capture(exits_in_regime)
|
||
|
||
# 5. Method Attribution
|
||
# Which exit method is performing best?
|
||
for method in exit_methods:
|
||
method_profit = sum(profits_from_method)
|
||
method_count = count(exits_by_method)
|
||
```
|
||
|
||
---
|
||
|
||
## CONCLUSION
|
||
|
||
### Best Combination for XAUBot
|
||
Based on research, the optimal exit strategy combines:
|
||
|
||
1. **Kalman Filter** (30%) — Noise reduction and velocity prediction
|
||
2. **Adaptive ATR Trailing** (25%) — Dynamic stop management
|
||
3. **Fuzzy Logic** (20%) — Multi-factor decision integration
|
||
4. **SMC Mitigation** (15%) — Institutional flow reading
|
||
5. **Bayesian Optimization** (10%) — Continuous parameter tuning
|
||
|
||
### Expected Improvements
|
||
- **Peak Capture Rate**: 75% → 85%+ (current v5 = 83-84%)
|
||
- **False Exit Rate**: Reduce by 30-40%
|
||
- **Sharpe Ratio**: Increase by 20-30%
|
||
- **Drawdown**: Reduce max drawdown by 15-20%
|
||
- **Win Rate**: Maintain or slightly improve (current ~54%)
|
||
|
||
### Next Steps
|
||
1. Implement Kalman Filter for profit smoothing ✅ Priority
|
||
2. Enhance adaptive trailing with fuzzy logic ✅ Priority
|
||
3. Add SMC mitigation detection 🔄 Medium
|
||
4. Collect data for DQN training 🔄 Long-term
|
||
5. Setup weekly Bayesian reoptimization 🔄 Long-term
|
||
|
||
---
|
||
|
||
## REFERENCES
|
||
|
||
### Academic Papers
|
||
- Kalman, R. E. (1960). "A New Approach to Linear Filtering and Prediction Problems"
|
||
- Various IEEE papers on PID control in trading
|
||
- Fuzzy logic trading systems research (2020-2025)
|
||
- Deep Q-Learning for quantitative trading (arXiv 2023-2025)
|
||
|
||
### Online Resources
|
||
- QuantStart, QuantInsti, Medium articles
|
||
- MQL5 and TradingView technical documentation
|
||
- Recent 2025/2026 trading algorithm research
|
||
|
||
### Tools & Libraries
|
||
- `filterpy` — Kalman Filter implementation
|
||
- `scikit-optimize` — Bayesian optimization
|
||
- `skfuzzy` — Fuzzy logic systems
|
||
- `stable-baselines3` — Reinforcement learning
|
||
- `pytorch` — Deep learning for DQN
|
||
|
||
---
|
||
|
||
*End of Research Document*
|