Files
XauBot/docs/arsitektur-ai/09-Entry-Trade.md
T
GifariKemalandClaude Opus 4.6 757b499033 docs: sync architecture docs with v5 major issues fix
5 major issues reflected in documentation:

1. Confidence calibration (03-SMC, 00-ARSITEKTUR):
   - Base 55% + 10% each → base 40% + weighted scoring
   - Structure +15%, BOS/CHoCH +12%, FVG +8%, OB +10%, Trend +10%

2. ATR-based pullback filter (09-Entry, 00-ARSITEKTUR):
   - Hardcoded $2/$1.5 → bounce 15% ATR, consolidation 10% ATR

3. Smarter time-based exit (10-Exit, 05-Risk, 00-ARSITEKTUR):
   - 4h: check profit growth, not just profit<$5
   - 6h: extend to 8h if profit>$10 and growing + ML agrees

4. Slippage validation (09-Entry, 23-Main, 00-ARSITEKTUR):
   - Check actual vs expected price, log if >0.15%

5. Partial fill handling (09-Entry, 23-Main, 00-ARSITEKTUR):
   - Check filled volume, use actual values for tracking

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-06 10:06:43 +07:00

10 KiB
Raw Blame History

Entry Trade — Proses Masuk Posisi

File utama: main_live.py File pendukung: src/smc_polars.py, src/ml_model.py, src/smart_risk_manager.py, src/session_filter.py


Apa Itu Entry Trade?

Entry Trade adalah keseluruhan proses dari mendeteksi peluang hingga mengirim order ke broker. Bot menggunakan 10+ filter yang harus SEMUA lolos sebelum satu trade dieksekusi.

Analogi: Entry Trade seperti proses boarding pesawat — harus punya tiket (signal), passport valid (confirmation), lulus security check (risk), tepat waktu (session), dan gate terbuka (position limit).


Checklist Entry (Semua Harus PASS)

 1. [SESSION]     Session filter izinkan trading?
 2. [RISK MODE]   Trading mode bukan STOPPED?
 3. [SMC SIGNAL]  Ada signal dari SMC Analyzer?
 4. [ML CONFIRM]  XGBoost confidence >= 50%?
 5. [ML AGREE]    ML tidak strongly disagree (>65% berlawanan)?
 6. [QUALITY]     Market quality bukan AVOID/CRISIS?
 7. [CONFIRM]     Signal konsisten 2 bar berturut?
 8. [PULLBACK]    Bukan sedang pullback/retrace?
 9. [COOLDOWN]    Sudah 5 menit sejak trade terakhir?
10. [POS LIMIT]   Posisi terbuka < 2?
11. [LOT SIZE]    Lot > 0 setelah semua adjustment?

SEMUA PASS -> Execute Trade
SATU GAGAL -> Skip, tunggu loop berikutnya

Step-by-Step Flow

Step 1: Session Filter

# main_live.py Lines 472-483
session_ok, session_reason, session_multiplier = self.session_filter.can_trade()

if not session_ok:
    return  # Skip — bukan waktu trading

# Simpan multiplier untuk lot sizing nanti
self._current_session_multiplier = session_multiplier

Bisa block: Weekend, Friday >23:00, danger zone (00:00-06:00), low volatility session.


Step 2: Risk Mode Check

# main_live.py Lines 537-542
risk_rec = self.smart_risk.get_trading_recommendation()

if not risk_rec["can_trade"]:
    return  # STOPPED mode — daily/total limit tercapai

Bisa block: Mode STOPPED (daily loss >= $250, total loss >= $500).


Step 3: SMC Signal Generation

# main_live.py Lines 498-499
smc_signal = self.smc.generate_signal(df)

if smc_signal is None:
    return  # Tidak ada setup SMC yang valid

SMC membutuhkan:

  • Market structure (bullish/bearish) ATAU BOS/CHoCH
  • DAN (FVG ATAU Order Block)
  • Minimum 2:1 risk/reward

Output: Entry price, SL, TP, confidence (55-85%), reason.


Step 4: ML Confidence Check

# main_live.py Lines 419-425
ml_prediction = self.ml_model.predict(df, feature_cols)

# Lines 664-669
if ml_prediction.confidence < 0.50:
    return  # ML terlalu tidak yakin

Step 5: ML Agreement Check

# main_live.py Lines 676-684
# Jika SMC bilang BUY tapi ML bilang SELL dengan confidence > 65%:
if smc_signal.signal_type == "BUY":
    if ml_prediction.signal == "SELL" and ml_prediction.confidence > 0.65:
        return  # ML strongly disagrees — VETO

if smc_signal.signal_type == "SELL":
    if ml_prediction.signal == "BUY" and ml_prediction.confidence > 0.65:
        return  # ML strongly disagrees — VETO

Step 6: Dynamic Market Quality

# main_live.py Lines 618-657
# Analisis kualitas pasar berdasarkan:
# - Session (London/NY = tinggi, Sydney = rendah)
# - Regime (low vol = bagus, crisis = block)
# - Volatility (medium = ideal)
# - Trend strength
# - SMC confluence
# - ML signal alignment

quality_score = analyze_market_quality(...)
# EXCELLENT (80+), GOOD (60+), MODERATE (40+), POOR (20+), AVOID (<20), CRISIS

if quality == "AVOID" or quality == "CRISIS":
    return  # Pasar tidak layak untuk trading

Step 7: Signal Confirmation (2 Bar Berturut)

# main_live.py Lines 686-709
signal_key = f"{smc_signal.signal_type}_{smc_signal.entry_price:.0f}"

if signal_key in self._signal_persistence:
    self._signal_persistence[signal_key] += 1
else:
    self._signal_persistence[signal_key] = 1

if self._signal_persistence[signal_key] < 2:
    return  # Belum dikonfirmasi — tunggu 1 loop lagi

# Signal sudah muncul 2x berturut -> CONFIRMED

Tujuan: Mencegah whipsaw — signal yang hanya muncul 1 detik kemungkinan noise.


Step 8: Pullback Filter

# main_live.py Lines 742-871
can_enter, pullback_reason = self._check_pullback_filter(df, signal.signal_type)

if not can_enter:
    return  # Sedang pullback, tunggu momentum selaras

v5: Threshold sekarang ATR-based (bukan hardcoded)

ATR diambil dari data (default $12 untuk XAUUSD)
bounce_threshold      = ATR × 0.15    # ~$1.80 (sebelumnya: $2.00 fixed)
consolidation_threshold = ATR × 0.10  # ~$1.20 (sebelumnya: $1.50 fixed)

Kenapa ATR-based?
  - Threshold menyesuaikan volatilitas pasar saat ini
  - Saat volatilitas tinggi (ATR=$20): bounce=$3, consolidation=$2
  - Saat volatilitas rendah (ATR=$8): bounce=$1.2, consolidation=$0.8
  - Lebih akurat daripada threshold tetap

Untuk signal BUY, block jika:

  • Harga turun > bounce_threshold (15% ATR) dalam 3 candle terakhir
  • MACD bearish + harga turun
  • Harga jauh di bawah EMA9 + terus turun

Untuk signal SELL, block jika:

  • Harga naik > bounce_threshold (15% ATR) dalam 3 candle terakhir
  • MACD bullish + harga naik
  • Harga jauh di atas EMA9 + terus naik

Komponen yang dicek:

1. Short-term Momentum (3 candle terakhir)
   -> Arah pergerakan harga terkini
   -> Block jika bounce > 15% ATR (v5: dinamis)

2. MACD Histogram
   -> Rising = bullish momentum
   -> Falling = bearish momentum

3. Harga vs EMA9
   -> Di atas = bullish bias
   -> Di bawah = bearish bias

4. RSI Extreme
   -> RSI > 80 = overbought (block BUY)
   -> RSI < 20 = oversold (block SELL)

5. Consolidation Check
   -> Jika movement < 10% ATR = consolidation → ALLOW
   -> v5: dinamis, bukan fixed $1.5

Step 9: Trade Cooldown

# main_live.py Lines 520-524
trade_cooldown = 300  # 5 menit

if last_trade_time:
    elapsed = (now - last_trade_time).total_seconds()
    if elapsed < trade_cooldown:
        return  # Tunggu cooldown selesai

Tujuan: Mencegah overtrading — minimal 5 menit antar trade.


Step 10: Position Limit

# main_live.py Lines 588-592
can_open, limit_reason = self.smart_risk.can_open_position()

if not can_open:
    return  # Sudah 2 posisi terbuka (max)

Step 11: Lot Size Calculation

# main_live.py Lines 544-560
safe_lot = self.smart_risk.calculate_lot_size(
    entry_price=signal.entry_price,
    confidence=signal.confidence,        # SMC confidence
    regime=regime_name,                  # HMM regime
    ml_confidence=ml_prediction.confidence,  # ML confidence
)

# Apply session multiplier
safe_lot = max(0.01, safe_lot * session_multiplier)

if safe_lot <= 0:
    return  # Lot 0 = tidak boleh trade

Eksekusi Order

Setelah semua 11 filter lolos:

# main_live.py Lines 985-1008
# Step A: Ambil harga real-time
tick = mt5.get_tick(symbol)
current_price = tick.ask if BUY else tick.bid

# Step B: Validasi broker SL (min 10 pips)
broker_sl = signal.stop_loss
if jarak_terlalu_dekat:
    broker_sl = paksa_lebih_lebar

# Step C: Kirim order
result = mt5.send_order(
    symbol="XAUUSD",
    order_type="BUY" / "SELL",
    volume=0.01 - 0.02,          # Lot dari risk calculation
    sl=broker_sl,                # ATR-based SL (v3)
    tp=signal.take_profit,       # SMC TP (ATR-capped)
    magic=123456,                # ID bot
    comment="AI Safe v3",
)

# Step D: Fallback jika broker reject SL
if gagal dan error 10016:
    result = mt5.send_order(sl=0, ...)  # Tanpa broker SL

# Step E: Slippage Validation (v5 BARU)
if result.success:
    actual_price = result.price
    slippage = abs(actual_price - signal.entry_price)
    max_slippage = signal.entry_price * 0.0015  # 0.15% dari harga

    if slippage > max_slippage:
        log WARNING "HIGH SLIPPAGE"  # Catat slippage tinggi
    # Gunakan harga AKTUAL untuk tracking, bukan harga expected

# Step F: Partial Fill Check (v5 BARU)
    filled_volume = result.volume
    if filled_volume < requested_volume:
        log WARNING "PARTIAL FILL"
        # Update lot_size ke volume yang sebenarnya terisi
        position.lot_size = filled_volume

# Step G: Register posisi (gunakan nilai AKTUAL)
    smart_risk.register_position(
        ticket=result.order_id,
        entry_price=actual_price,     # v5: harga aktual (bukan expected)
        lot_size=filled_volume,       # v5: volume aktual (bukan requested)
        direction=signal.signal_type,
    )

Slippage & Partial Fill (v5 Detail)

SLIPPAGE VALIDATION:
  expected_price = signal.entry_price
  actual_price   = result.price (dari broker)
  slippage       = |actual - expected|
  max_acceptable = 0.15% dari harga (~$4 untuk XAUUSD @$2650)

  Jika slippage > max_acceptable:
    -> LOG WARNING (untuk monitoring & analisis)
    -> Tetap pakai harga aktual untuk position tracking

PARTIAL FILL HANDLING:
  requested_volume = lot dari risk calculation
  filled_volume    = result.volume (dari broker)

  Jika filled < requested:
    -> LOG WARNING dengan fill ratio (%)
    -> Update position.lot_size ke filled_volume
    -> Risk calculation tetap akurat (berdasarkan volume sebenarnya)

Post-Entry

# Step H: Log trade detail
trade_logger.log_trade_open(
    signal, ml_prediction, regime, market_quality, ...
)

# Step G: Kirim notifikasi Telegram
await telegram.send_trade_open(trade_info)

# Step H: Update cooldown timer
last_trade_time = now

Diagram Flow Lengkap

Loop setiap 1 detik
    |
    v
Fetch 200 bar M15 -> Feature Eng -> SMC -> HMM -> XGBoost
    |
    v
[1] Session OK? ----NO----> Skip
    |YES
[2] Risk OK? -------NO----> Skip (STOPPED)
    |YES
[3] SMC Signal? ----NO----> Skip (tidak ada setup)
    |YES
[4] ML >= 50%? -----NO----> Skip (terlalu uncertain)
    |YES
[5] ML Agree? ------NO----> Skip (ML veto)
    |YES
[6] Quality OK? ----NO----> Skip (AVOID/CRISIS)
    |YES
[7] Confirmed 2x? --NO----> Skip (tunggu konfirmasi)
    |YES
[8] No Pullback? ---NO----> Skip (retrace)
    |YES
[9] Cooldown OK? ---NO----> Skip (< 5 menit)
    |YES
[10] Pos < 2? ------NO----> Skip (full)
    |YES
[11] Lot > 0? ------NO----> Skip
    |YES
    v
EXECUTE TRADE -> Register -> Log -> Telegram

Statistik Filter

Dalam kondisi normal, dari ratusan loop per jam:

  • ~95% diblokir oleh "tidak ada SMC signal" (pasar sideways)
  • ~3% diblokir oleh ML disagreement atau low confidence
  • ~1% diblokir oleh pullback filter atau session
  • <1% lolos semua filter dan menghasilkan trade

Rata-rata: 3-8 trade per hari (sangat selektif).