- 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>
8.4 KiB
Entry Trade — Proses Masuk Posisi
File utama:
main_live.pyFile 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
Untuk signal BUY, block jika:
- Harga turun > $2 dalam 3 candle terakhir
- MACD bearish + harga turun
- Harga jauh di bawah EMA9 + terus turun
Untuk signal SELL, block jika:
- Harga naik > $2 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
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)
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: Register posisi untuk monitoring
if result.success:
smart_risk.register_position(
ticket=result.order_id,
entry_price=signal.entry_price,
lot_size=position.lot_size,
direction=signal.signal_type,
)
Post-Entry
# Step F: 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).