Files
XauBot/docs/WEAKNESS_ANALYSIS.md
T
GifariKemal 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

7.2 KiB

Analisis Kelemahan Sistem Trading Bot

Tanggal Analisis: 6 Februari 2026


1. STOP LOSS - KELEMAHAN KRITIS

1.1 Tidak Ada Broker Stop Loss

File: main_live.py line 876

result = self.mt5.send_order(
    sl=0,  # MASALAH: Tidak ada SL di broker!
    tp=signal.take_profit,
)

Risiko:

  • Gap weekend = loss unlimited
  • Flash crash = posisi tidak terproteksi
  • Disconnect internet = loss tidak terkontrol

Solusi:

# Hitung emergency SL berdasarkan ATR
atr = df["atr"].tail(1).item()
emergency_sl = entry_price - (3.0 * atr) if direction == "BUY" else entry_price + (3.0 * atr)

result = self.mt5.send_order(
    sl=emergency_sl,  # BROKER-LEVEL PROTECTION
    tp=signal.take_profit,
)

1.2 Smart Hold Terlalu Agresif

File: smart_risk_manager.py line 460-486

# Tahan loss $15 selama 3 jam menunggu golden time
if loss_percent_of_max < 30 and hours_to_golden <= 3 and momentum > -50:
    return False, None, f"SMART HOLD..."

Risiko:

  • Loss $15 bisa jadi $30 dalam 3 jam
  • Momentum -50 masih terlalu lemah sebagai threshold

Solusi:

  • Kurangi max hold time ke 1 jam
  • Naikkan momentum threshold ke -30
  • Exit jika loss > 40% max (bukan 50%)

1.3 SL Berbasis Swing Terlalu Dekat

File: smc_polars.py line 639-640

sl = last_swing_low if last_swing_low and last_swing_low < entry else entry * 0.995
# Entry 2000, fallback SL = 1990 (hanya 10 pips!)

Risiko:

  • Volatilitas normal XAUUSD = 10-20 pips
  • SL 10 pips = kena stop oleh noise

Solusi:

# Minimum SL = 1.5 * ATR
atr = df["atr"].tail(1).item()
min_sl_distance = 1.5 * atr

if direction == "BUY":
    swing_sl = last_swing_low
    atr_sl = entry - min_sl_distance
    sl = min(swing_sl, atr_sl) if swing_sl else atr_sl

2. TAKE PROFIT - KELEMAHAN

2.1 TP Fixed 2:1 RR

File: smc_polars.py line 643-644

risk = entry - sl
tp = entry + (risk * 2)

Masalah:

  • Tidak cek apakah TP di zona resistance
  • TP bisa 100+ pips, tidak realistis

Solusi:

# TP berdasarkan ATR dan struktur market
atr = df["atr"].tail(1).item()
max_tp_distance = 4.0 * atr  # Maximum 4 ATR

# Cek resistance terdekat
nearest_resistance = find_nearest_resistance(df, entry)

# TP = minimum dari RR target atau resistance
rr_tp = entry + (risk * 2)
tp = min(rr_tp, entry + max_tp_distance)
if nearest_resistance and nearest_resistance < tp:
    tp = nearest_resistance * 0.995  # Sedikit di bawah resistance

2.2 Tidak Ada Partial Take Profit

Solusi:

# Partial TP levels
tp_25 = entry + (risk * 0.5)   # 25% posisi di 0.5 RR
tp_50 = entry + (risk * 1.0)   # 25% posisi di 1.0 RR
tp_75 = entry + (risk * 1.5)   # 25% posisi di 1.5 RR
tp_100 = entry + (risk * 2.0)  # 25% posisi di 2.0 RR

3. ENTRY TRADE - KELEMAHAN

3.1 ML Threshold 50% = Coin Flip

File: main_live.py line 723

ml_min_threshold = 0.50

Masalah:

  • 50% confidence = tidak lebih baik dari random
  • Seharusnya dinamis per session

Solusi:

# Dynamic threshold berdasarkan session
if session == "Sydney":
    ml_min_threshold = 0.60  # Low liquidity = butuh confidence tinggi
elif session == "London-NY Overlap":
    ml_min_threshold = 0.50  # High quality = threshold lebih rendah OK
else:
    ml_min_threshold = 0.55  # Default

3.2 Signal Key Reset Terus

File: main_live.py line 733

signal_key = f"{smc_signal.signal_type}_{int(smc_signal.entry_price):.0f}"
# Entry price berubah setiap candle = signal key selalu baru!

Solusi:

# Gunakan zone-based key, bukan exact price
zone_size = 5  # $5 zone
zone = int(smc_signal.entry_price / zone_size) * zone_size
signal_key = f"{smc_signal.signal_type}_{zone}"

3.3 Pullback Filter Fixed $2

File: main_live.py line 673

if momentum_direction == "UP" and short_momentum > 2:  # Fixed $2

Solusi:

# ATR-based threshold
atr = df["atr"].tail(1).item()
pullback_threshold = 0.5 * atr  # 50% of ATR

if momentum_direction == "UP" and short_momentum > pullback_threshold:
    return False, "SELL blocked: Price bouncing"

4. EXIT TRADE - KELEMAHAN

4.1 ML Reversal Butuh 75% Confidence

File: smart_risk_manager.py line 441

if ml_confidence >= 0.75 and ml_is_reversal:
    return True, ExitReason.TREND_REVERSAL

Masalah:

  • Terlalu tinggi, sering sudah telat
  • Harga sudah bergerak jauh saat ML 75%

Solusi:

# Lower threshold dengan tambahan konfirmasi
if ml_confidence >= 0.65 and ml_is_reversal:
    if momentum_score < -30:  # Momentum juga negatif
        return True, ExitReason.TREND_REVERSAL

4.2 Tidak Ada Time-Based Exit

Solusi:

# Exit jika trade stuck terlalu lama
trade_duration = (datetime.now() - entry_time).total_seconds() / 3600  # hours

if trade_duration > 4 and abs(current_profit) < 5:  # 4 jam tanpa progress
    return True, ExitReason.TIMEOUT, "Trade stuck > 4 hours"

if trade_duration > 6:  # Maximum 6 jam
    return True, ExitReason.TIMEOUT, "Maximum duration reached"

4.3 Tidak Ada Breakeven Protection

Solusi:

# Move to breakeven setelah profit tertentu
if current_profit >= 15:  # $15 profit
    if not breakeven_set:
        move_sl_to_breakeven(ticket)
        breakeven_set = True

5. BACKTEST vs LIVE - PERBEDAAN

5.1 Exit Timing Berbeda

Aspek Backtest Live
Check interval Per bar (15 min) Per detik
ML reversal check Setiap 5 bar Setiap loop
Smart Hold Tidak ada Ada

Solusi:

  • Sinkronkan logic di backtest_live_sync.py
  • Tambah Smart Hold logic ke backtest
  • Gunakan bar-close sebagai trigger

5.2 Slippage Tidak Dihitung

# Tambah slippage simulation
SLIPPAGE_PIPS = 0.5  # 0.5 pip slippage

def simulate_entry(entry_price, direction):
    if direction == "BUY":
        return entry_price + SLIPPAGE_PIPS * 0.1
    else:
        return entry_price - SLIPPAGE_PIPS * 0.1

6. PRIORITAS PERBAIKAN

# Item Risiko Effort Prioritas
1 Broker SL KRITIS Low P0
2 ATR-based SL TINGGI Medium P1
3 Faster reversal exit TINGGI Low P1
4 Time-based exit SEDANG Low P2
5 Dynamic ML threshold SEDANG Low P2
6 Partial TP SEDANG Medium P3
7 Breakeven logic SEDANG Low P3
8 Backtest sync SEDANG High P3

7. SKENARIO TERBURUK

Skenario 1: Weekend Gap

  • Jumat: Posisi BUY di 2000, profit $10
  • Weekend: Berita ekonomi buruk
  • Senin: Market buka di 1950 (-50 pips = -$50)
  • Tanpa broker SL = loss unlimited

Skenario 2: Flash Crash

  • Posisi aktif, harga normal
  • Flash crash -2% dalam 1 menit
  • Bot detect, tapi close gagal (broker overload)
  • Tanpa broker SL = loss unlimited

Skenario 3: Connection Lost

  • Posisi aktif dengan profit $20
  • Internet mati 2 jam
  • Market reversal -$60
  • Tanpa broker SL = loss unlimited

8. IMPLEMENTASI SEGERA

File yang perlu diubah:

  1. main_live.py - Tambah broker SL
  2. smc_polars.py - ATR-based SL
  3. smart_risk_manager.py - Faster exit, time-based exit
  4. backtest_live_sync.py - Sinkronkan dengan live