Files
XauBot/docs/arsitektur-ai/14-Backtest.md
T
GifariKemalandClaude Opus 4.5 7af9183af3 feat: Smart AI Trading Bot for XAUUSD with ML and SMC
- XGBoost ML model with 37 features for market direction prediction
- Smart Money Concepts (SMC): Order Blocks, FVG, BOS, CHoCH
- HMM market regime detection (trending/ranging/volatile)
- ATR-based stop loss with 1.5 ATR minimum distance
- Broker-level SL protection with fallback
- Time-based exit (max 6 hours per trade)
- Session-aware trading optimized for London/NY overlap
- Auto-retraining based on market conditions
- Telegram notifications and web dashboard
- Backtest results: 63.9% win rate, 2.64 profit factor, 4.83 Sharpe

Backtest period: Jan 2025 - Feb 2026, 654 trades, $4,189 net P/L

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-06 09:01:35 +07:00

368 lines
8.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Backtest — Engine Simulasi Live-Sync
> **File:** `backtests/backtest_live_sync.py`
> **Class:** `LiveSyncBacktest`
> **Prinsip:** 100% identik dengan `main_live.py`
---
## Apa Itu Backtest?
Backtest adalah sistem **simulasi trading pada data historis** yang logikanya 100% disinkronkan dengan trading live. Tujuannya menguji strategi sebelum dipakai uang sungguhan dan memvalidasi perubahan kode.
**Analogi:** Backtest seperti **simulator penerbangan** — pilot (bot) berlatih di kondisi realistis tanpa risiko jatuh. Setiap instrumen, prosedur, dan respons sama persis dengan pesawat asli.
---
## Prinsip Sinkronisasi
```
ATURAN UTAMA: Backtest HARUS identik dengan live.
Setiap perubahan di main_live.py → HARUS di-mirror di backtest_live_sync.py
Yang disinkronkan:
├── ML Model: XGBoost dengan fitur yang sama
├── SMC Analyzer: Swing length & OB lookback sama
├── Regime Detection: HMM MarketRegimeDetector
├── Session Filter: Golden Time 19:00-23:00 WIB
├── Signal Logic: Semua filter entry
├── Position Sizing: Berdasarkan ML confidence tier
├── Trade Cooldown: 300 detik (5 menit)
└── Exit Logic: TP, ML reversal, max loss, time-based
```
---
## Komponen yang Dimuat
```python
# Sama persis dengan main_live.py
self.smc = SMCAnalyzer(swing_length=config.smc.swing_length, ob_lookback=config.smc.ob_lookback)
self.features = FeatureEngineer()
self.regime_detector = MarketRegimeDetector(model_path="models/hmm_regime.pkl")
self.ml_model = TradingModel(model_path="models/xgboost_model.pkl")
self.dynamic_confidence = create_dynamic_confidence()
```
---
## Entry Logic (Sama dengan Live)
Semua filter entry di-replikasi:
```
Untuk setiap bar dalam data historis:
|
v
[1] COOLDOWN: Jarak >= 20 bar dari trade terakhir? (~5 menit M15)
|YES
[2] SESSION: Bukan Off Hours (04:00-06:00 WIB)?
|YES
[3] GOLDEN TIME: (opsional) Hanya 19:00-23:00 WIB?
|YES
[4] REGIME: Bukan CRISIS?
|YES
[5] SMC SIGNAL: Ada signal dari SMCAnalyzer?
|YES
[6] DYNAMIC CONFIDENCE: Market quality bukan AVOID?
|YES
[7] ML THRESHOLD: Confidence >= threshold (50%-65%)?
|YES
[8] ML AGREEMENT: ML tidak strongly disagree (>65% berlawanan)?
|YES
[9] SIGNAL CONFIRMATION: Signal muncul 2x berturut?
|YES
[10] PULLBACK FILTER: Momentum tidak berlawanan?
|YES
v
EXECUTE SIMULATED TRADE
```
---
## Session Mapping
```python
# Sama dengan session_filter.py
if 6 <= hour < 15: # Sydney-Tokyo → lot 0.5x
if 15 <= hour < 16: # Tokyo-London Overlap → lot 0.75x
if 16 <= hour < 19: # London Early → lot 0.8x
if 19 <= hour < 24: # London-NY (Golden) → lot 1.0x ← TERBAIK
if 0 <= hour < 4: # NY Session → lot 0.9x
if 4 <= hour < 6: # Off Hours → SKIP
```
---
## Exit Logic (5 Kondisi)
Untuk setiap bar setelah entry (max 100 bar):
### EXIT 1: Take Profit
```
IF harga hit TP level:
BUY: high >= take_profit
SELL: low <= take_profit
-> EXIT dengan profit penuh
```
### EXIT 2: Maximum Loss
```
IF current_profit < -$50 (max_loss_per_trade):
-> EXIT, potong kerugian
```
### EXIT 3: Time-Based (Synced dengan Live v3)
```
IF 16+ bar (4 jam) DAN profit < $5:
a) profit >= $0 → EXIT (breakeven setelah 4 jam)
b) profit > -$15 → EXIT (loss kecil, daripada stuck)
IF 24+ bar (6 jam):
-> FORCE EXIT (apapun profitnya)
```
**Visualisasi:**
```
Bar: 0 5 10 15 16 20 24
|-----|-----|-----|-----|-----|-----|
entry | |
| |
4h check: 6h FORCE EXIT
profit<$5?
Ya -> exit
```
### EXIT 4: ML Reversal
```
Setiap 5 bar, cek prediksi ML:
IF direction BUY DAN ML bilang SELL dengan confidence > 65%:
-> EXIT (ML mendeteksi reversal)
IF direction SELL DAN ML bilang BUY dengan confidence > 65%:
-> EXIT (ML mendeteksi reversal)
```
### EXIT 5: Trend Reversal (Momentum)
```
Setelah 10+ bar, cek momentum 5 bar terakhir:
IF BUY DAN momentum < -$5 DAN current_profit < -$10:
-> EXIT (tren berbalik + sudah rugi)
IF SELL DAN momentum > +$5 DAN current_profit < -$10:
-> EXIT (tren berbalik + sudah rugi)
```
---
## Lot Sizing
```python
# Berdasarkan ML confidence tier (sama dengan live)
if ml_confidence >= 0.65:
lot_size = 0.02 # High confidence → lot lebih besar
elif ml_confidence >= 0.55:
lot_size = 0.01 # Medium confidence → lot standar
else:
lot_size = 0.01 # Low confidence → lot minimum
# Apply session multiplier
lot_size = max(0.01, lot_size * session_lot_multiplier)
```
---
## Pullback Filter
```
Sama persis dengan main_live.py:
Untuk signal SELL, block jika:
- Harga naik > $2 dalam 3 candle terakhir
- MACD histogram rising + harga naik
- Harga di atas EMA9 dan masih naik
Untuk signal BUY, block jika:
- Harga turun > $2 dalam 3 candle terakhir
- MACD histogram falling + harga turun
- Harga di bawah EMA9 dan masih turun
Exception (tetap boleh entry):
- Konsolidasi (pergerakan < $1.50)
- Momentum searah signal
```
---
## Metrik Performa
| Metrik | Rumus | Keterangan |
|--------|-------|------------|
| **Win Rate** | Wins / Total × 100% | Persentase trade profit |
| **Profit Factor** | Gross Profit / Gross Loss | > 1.0 = profitable |
| **Expectancy** | (WR × Avg Win) - (LR × Avg Loss) | Rata-rata per trade |
| **Max Drawdown** | (Peak - Trough) / Peak × 100% | Penurunan terbesar |
| **Sharpe Ratio** | (Avg Return / Std Dev) × √252 | Risk-adjusted return |
| **Net P/L** | Total Profit - Total Loss | Keuntungan bersih |
---
## Threshold Tuning
Mode `--tune` menguji beberapa ML threshold secara otomatis:
```python
ml_thresholds = [0.50, 0.52, 0.55, 0.58, 0.60, 0.65]
# Untuk setiap threshold:
# 1. Jalankan full backtest
# 2. Catat: trades, win rate, net P/L, profit factor, drawdown
# 3. Ranking berdasarkan net P/L
# Output:
# ML Thresh Trades Win Rate Net P/L PF DD
# --------------------------------------------------------
# 55% 145 64.8% $1,250.00 1.85 3.2%
# 52% 178 62.1% $1,100.00 1.72 4.1%
# 60% 112 67.0% $ 980.00 1.95 2.8%
# ...
```
---
## Cara Penggunaan
```bash
# Backtest standar dengan threshold default (55%)
python backtests/backtest_live_sync.py
# Backtest dengan threshold custom
python backtests/backtest_live_sync.py --threshold 0.60
# Hanya golden time
python backtests/backtest_live_sync.py --golden-only
# Threshold tuning (cari optimal)
python backtests/backtest_live_sync.py --tune
# Simpan hasil ke CSV
python backtests/backtest_live_sync.py --save
```
---
## Output Backtest
### Laporan Performa
```
==================================================================
BACKTEST RESULTS
==================================================================
Configuration:
ML Threshold: 55%
Signal Confirmation: 2 consecutive
Pullback Filter: Enabled
Golden Time Only: False
Performance:
Total Trades: 145
Wins: 94
Losses: 51
Win Rate: 64.8%
Profit/Loss:
Total Profit: $2,850.00
Total Loss: $1,600.00
Net P/L: $1,250.00
Profit Factor: 1.78
Risk Metrics:
Max Drawdown: 3.2% ($160.00)
Avg Win: $30.32
Avg Loss: $31.37
Expectancy: $8.62
Sharpe Ratio: 1.45
```
### Breakdown Exit Reason
```
Exit Reasons:
take_profit: 72 (49.7%)
timeout: 35 (24.1%)
ml_reversal: 18 (12.4%)
max_loss: 12 (8.3%)
trend_reversal: 8 (5.5%)
```
### Breakdown Session
```
Session Performance:
London-NY Overlap (Golden): 65 trades, 69.2% WR, $820.00
NY Session: 32 trades, 62.5% WR, $280.00
London Early: 28 trades, 60.7% WR, $120.00
Sydney-Tokyo: 20 trades, 55.0% WR, $30.00
```
---
## File Output
```
backtests/results/
├── backtest_20250206_143000.csv # Detail semua trade
│ ├── ticket, entry_time, exit_time
│ ├── direction, entry_price, exit_price
│ ├── stop_loss, take_profit, lot_size
│ ├── profit_usd, profit_pips, result
│ ├── exit_reason, ml_confidence, smc_confidence
│ └── regime, session, signal_reason
└── backtest_20250206_143000_summary.csv # Ringkasan metrik
├── total_trades, wins, losses, win_rate
├── total_profit, total_loss, net_pnl
├── profit_factor, avg_win, avg_loss
└── max_drawdown, expectancy, sharpe_ratio
```
---
## Data Flow
```
MT5 Connected
|
v
Fetch 50.000 bar M15 XAUUSD
|
v
FeatureEngineer.calculate_all() → 40+ fitur
SMCAnalyzer.calculate_all() → Struktur pasar
RegimeDetector.predict() → Regime label
|
v
Filter: Jan 2025 - Now
|
v
Loop setiap bar:
├── Entry check (10 filter)
├── Simulate exit (5 kondisi)
├── Record trade result
└── Update statistics
|
v
Print laporan + Save CSV
```