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

412 lines
10 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.
# 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
```python
# 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
```python
# 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
```python
# 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
```python
# 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
```python
# 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
```python
# 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)
```python
# 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
```python
# 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
```python
# 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
```python
# 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
```python
# 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:
```python
# 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
```python
# 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).