
SMC, FVG, BOS, OB, EMA
Analisis teknis tradisional sudah ketinggalan zaman. Strategi SMC ini secara langsung menyalin pola pikir pedagang institusional: mencari titik-titik penangkapan likuiditas, mengidentifikasi blok pesanan, dan menangkap kerusakan struktur pasar. Data retrospektif menunjukkan bahwa dengan menggunakan siklus 15 menit pada pasangan BTC / EUR, dengan penyaringan tren EMA200 selama 1 jam, pengembalian yang disesuaikan dengan risiko jauh lebih baik daripada strategi indikator tradisional.
Kuncinya adalah mekanisme multiple confirmation: Fair Value Gap ((FVG) + Market Structure Disruption ((BOS) + Liquidity Hunt + Fibonacci 50% Discount/Premium Area. Ini bukan tumpukan indikator teknis, tetapi interpretasi yang akurat dari struktur mikro pasar.
Pengelolaan risiko secara langsung dan kasar efektif: setiap transaksi tetap menanggung risiko 2 euro, tidak peduli seberapa besar fluktuasi pasar. Stop loss distance dihitung secara otomatis, memastikan risiko konstan. Rasio untung-rugi terkunci pada 1: 3, yang berarti kemenangan 33.4% hanya dapat mencapai keseimbangan untung-rugi, dan kemenangan apa pun di atas angka ini adalah keuntungan bersih.
Posisi minimum 0.00001 BTC, posisi maksimum 0.01 BTC, sepenuhnya sesuai dengan ukuran modal ritel. Tidak akan menanggung risiko yang tidak perlu karena posisi terlalu besar, atau kehilangan peluang karena posisi terlalu kecil.
Sinyal SMC yang sederhana mudah tersesat dalam pasar yang bergoyang. Strategi ini menambahkan EMA200 1 jam sebagai filter tren: sinyal multihead hanya dijalankan ketika harga 15 menit berada 1 jam di atas EMA200, sebaliknya, sinyal kosong dijalankan.
Desain ini secara langsung mempersempit kelayakan strategi dari “semua pasar” ke “pasar tren”, meskipun mengurangi frekuensi perdagangan, namun meningkatkan kualitas sinyal secara signifikan. Selama penyusunan horizontal, strategi akan secara otomatis menghentikan perdagangan, menghindari pengonsumsi dana dalam fluktuasi yang tidak efektif.
Blok pesanan bukan untuk mendukung resistensi, tetapi untuk area harga di mana dana besar institusional pernah aktif. Strategi untuk mengidentifikasi blok pesanan yang efektif adalah:
Blok multi-order: K-line terdepan adalah negatif + Ada FVG ke atas + Harga menembus titik terendah sebelum berayun + Ada likuiditas ke bawah + Harga saat ini berada di zona diskon di bawah 50% Fibonacci.
Blok pesanan kosong: K garis depan adalah garis matahari + Ada FVG ke bawah + Harga turun di atas titik tinggi sebelum periode ayunan + Ada likuiditas ke atas + Harga saat ini berada di zona premium lebih dari 50% Fibonacci.
Masing-masing kondisi memiliki logikanya sendiri: sinis/sanis menunjukkan tekanan arah, FVG menunjukkan ketidakseimbangan likuiditas, BOS mengkonfirmasi perubahan struktur, keterlibatan lembaga sertifikasi perburuan likuiditas, dan area diskon/premium memberikan waktu masuk yang optimal.
90% dari stop loss ritel di pasar diatur pada resistensi dukungan yang jelas. Dana institusional secara sengaja mendorong harga untuk menyentuh area-area ini, memicu reversal setelah banyak stop loss. Strategi untuk mengidentifikasi tindakan pengintai likuiditas ini adalah dengan selisih harga 0,1%.
Ketika harga terendah dalam 7 periode lebih dari 0,1% di bawah titik terendah saat ini, dipastikan ada likuiditas di bawah. Desain ini menghindari kesalahan penilaian yang terlalu sensitif, sekaligus memastikan bahwa penangkapan likuiditas yang sebenarnya tidak akan terlewatkan.
Strategi menggunakan 4 siklus panjang berayun untuk mengkonfirmasi titik tinggi dan rendah, yang berarti perlu menunggu 4 garis K untuk mengkonfirmasi satu titik berayun. Keterlambatan ini adalah biaya yang diperlukan: terlalu pendek periode konfirmasi akan menghasilkan banyak titik berayun palsu, terlalu lama periode konfirmasi akan kehilangan validitas.
4 siklus dalam grafik 15 menit sama dengan 1 jam waktu konfirmasi, yang menjamin efektivitas titik berayun dan tidak terlalu terbelakang dari perubahan pasar. Parameter ini telah banyak dioptimalkan dengan pengetesan ulang, dan merupakan titik keseimbangan terbaik untuk efisiensi dan akurasi.
Retrospeksi historis tidak mewakili keuntungan di masa depan, dan setiap strategi memiliki kemungkinan kerugian berturut-turut. Strategi SMC berkinerja baik di pasar tren yang kuat, tetapi kualitas sinyal menurun di pasar yang bergoyang. Bahkan dengan filter tren, tidak mungkin untuk sepenuhnya menghindari terobosan palsu dan kebisingan pasar.
Strategi membutuhkan kualitas psikologis yang ketat: harus menerima kerugian 2 euro per putaran, harus melaksanakan dengan tegas ketika sinyal muncul, harus bersabar ketika tidak ada sinyal. Operasi emosional apa pun akan merusak keunggulan statistik strategi.
Disarankan untuk melakukan simulasi perdagangan setidaknya 3 bulan sebelum perdagangan nyata, untuk memastikan pemahaman penuh tentang logika strategi dan karakteristik risiko. Ingat: Struktur pasar berubah, dan tidak ada strategi yang akan bekerja selamanya.
/*backtest
start: 2024-12-04 00:00:00
end: 2025-12-02 08:00:00
period: 1d
basePeriod: 1d
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/
//@version=6
strategy(title="Stratégie SMC V18.2 (BTC/EUR FINAL R3 - Tendance)", shorttitle="SMC-BTC-FINAL-Tendance", overlay=true,
currency=currency.EUR, // <--- CHANGÉ EN EUR
initial_capital=1000, // Capital initial de 1000 euros pour coller à votre compte démo
pyramiding=0,
default_qty_type=strategy.cash,
default_qty_value=1)
// --- PARAMÈTRES ADAPTÉS POUR BTC (M15) ---
i_max_lot_size = input.float(0.01, title="Lot Max (Quantité Max BTC)", minval=0.00001, step=0.001)
i_min_lot_size = input.float(0.00001, title="Lot Min Réel (Exigence Broker)", minval=0.00001, step=0.00001)
i_swing_length = input.int(4, title="Long. Swing (BOS) pour BTC", minval=2) // ADAPTÉ M15
i_ob_opacity = input.int(80, title="Opacité OB", minval=0, maxval=100)
i_liq_tolerance = input.float(0.1, title="Tolérance Liq. (%) pour BTC", minval=0.01, step=0.01)
i_liq_search = input.int(7, title="Long. Recherche Liq.", minval=5) // ADAPTÉ M15
// --- PARAMÈTRES DE FILTRE DE TENDANCE (H1/EMA 200 PAR DÉFAUT) ---
i_tf_tendance = input.string("60", title="Timeframe Tendance (ex: 60 pour H1)", options=["30", "60", "120", "240"]) // ADAPTÉ H1
i_ema_length = input.int(200, title="Longueur EMA Tendance", minval=1)
// --- GESTION DU RISQUE DÉDIÉE ---
float risk_amount = 2.0 // Risque de 2.00 EUROS par transaction
float min_sl_distance = 0.0001
// --- VARIABLES SMC ---
var float obHigh = na
var float obLow = na
var bool obIsBullish = false
var box currentBox = na
var float last_swing_low = na
var float last_swing_high = na
var label active_label = na
var bool signal_entry_long = false
var bool signal_entry_short = false
var float entry_sl_level = na
var float entry_tp_level = na
var float entry_qty_to_risk = na
var bool signal_persistant_long = false
var bool signal_persistant_short = false
// --- FONCTION DE FILTRE DE TENDANCE (EMA sur TF supérieur) ---
f_get_ema_hl() =>
request.security(syminfo.tickerid, i_tf_tendance, ta.ema(close, i_ema_length))
ema_tendance = f_get_ema_hl()
// PLOT de l'EMA pour la visualisation (Titre corrigé)
plot(ema_tendance, color=color.new(color.white, 20), title="EMA Tendance (Filtre)", linewidth=2)
// --- RÉINITIALISATION ---
if not na(active_label)
label.delete(active_label)
active_label := na
signal_entry_long := false
signal_entry_short := false
entry_qty_to_risk := na
// Mise à jour des Swings Highs/Lows
sh_confirmed = ta.barssince(high == ta.highest(i_swing_length * 2 + 1)) == i_swing_length
sl_confirmed = ta.barssince(low == ta.lowest(i_swing_length * 2 + 1)) == i_swing_length
// Initialisation des swings
if na(last_swing_high)
last_swing_high := ta.highest(200)
if na(last_swing_low)
last_swing_low := ta.lowest(200)
if sh_confirmed
last_swing_high := high[i_swing_length]
if sl_confirmed
last_swing_low := low[i_swing_length]
float fib_0_5_level = not na(last_swing_high) and not na(last_swing_low) ? (last_swing_high + last_swing_low) / 2 : na
// PLOT DE DÉBOGAGE: Visualisation des derniers swings
plot(last_swing_high, color=color.new(color.fuchsia, 50), style=plot.style_line, linewidth=2, title="Last Swing High")
plot(last_swing_low, color=color.new(color.lime, 50), style=plot.style_line, linewidth=2, title="Last Swing Low")
// --- FONCTIONS DE DÉTECTION (unchanged) ---
fvg_bullish() => high[1] < low[3]
fvg_bearish() => low[1] > high[3]
f_has_liquidity(direction) =>
result = false
price_to_search = direction ? low : high
search_price = direction ? ta.lowest(i_liq_search) : ta.highest(i_liq_search)
tolerance = close * i_liq_tolerance / 100
if direction
result := search_price < price_to_search - tolerance
else
result := search_price > price_to_search + tolerance
result
// --- LOGIQUE DE DÉCLENCHEMENT DE L'ORDRE BLOCK (unchanged) ---
is_bullish_ob() =>
isBearCandle = close[1] < open[1]
hasFVG = fvg_bullish()
isBOS = not na(last_swing_low) and close > last_swing_low
hasLiquiditySupport = f_has_liquidity(true)
isDiscount = not na(fib_0_5_level) and close < fib_0_5_level
isBearCandle and hasFVG and isBOS and hasLiquiditySupport and isDiscount
is_bearish_ob() =>
isBullCandle = close[1] > open[1]
hasFVG = fvg_bearish()
isBOS = not na(last_swing_high) and close < last_swing_high
hasLiquiditySupport = f_has_liquidity(false)
isPremium = not na(fib_0_5_level) and close > fib_0_5_level
isBullCandle and hasFVG and isBOS and hasLiquiditySupport and isPremium
// --- CRÉATION / MISE À JOUR DE L'OB ACTIF (unchanged) ---
if na(obHigh) or strategy.position_size == 0
if is_bullish_ob() or is_bearish_ob()
obIsBullish := is_bullish_ob()
obHigh := high[1]
obLow := low[1]
// --- GESTION DE LA MITIGATION ET VALIDATION ---
if not na(obHigh)
float mitigation_buffer = 0.00005 * close
isTouched = obIsBullish ? low <= obHigh + mitigation_buffer : high >= obLow - mitigation_buffer
isInvalidatedBull = obIsBullish and close < obLow
isInvalidatedBear = not obIsBullish and close > obHigh
// L'OB est touché ET nous ne sommes pas déjà en position
if isTouched and strategy.position_size == 0
// --- CALCULS ET SIGNAL ---
var float sl_level = obIsBullish ? obLow : obHigh
var float rr_distance_usd = math.abs(close - sl_level)
float safe_rr_distance = math.max(rr_distance_usd, min_sl_distance)
float desired_risk_amount = risk_amount
float calculated_qty = desired_risk_amount / safe_rr_distance
// LOGIQUE POUR GÉRER LOT MAX/MIN
float minimum_lot_for_market = i_min_lot_size
entry_qty_to_risk := math.max(calculated_qty, minimum_lot_for_market)
entry_qty_to_risk := math.min(entry_qty_to_risk, i_max_lot_size)
entry_sl_level := sl_level
// TP FIXE : R:R 1:3
entry_tp_level := obIsBullish ? close + safe_rr_distance * 3 : close - safe_rr_distance * 3
// VÉRIFICATION DU LOT MINIMUM
if entry_qty_to_risk >= minimum_lot_for_market
if obIsBullish
signal_entry_long := true
else
signal_entry_short := true
// --- EXÉCUTION DE LA STRATÉGIE ---
// Persistance du signal
if signal_entry_long and strategy.position_size == 0
signal_persistant_long := true
if signal_entry_short and strategy.position_size == 0
signal_persistant_short := true
// EXÉCUTION AVEC FILTRE DE TENDANCE
if strategy.position_size == 0
// EXÉCUTION LONG
if signal_persistant_long and not na(entry_qty_to_risk)
// FILTRE LONG : Prix M15 au-dessus de l'EMA de tendance H1
if close > ema_tendance
strategy.entry("LongEntry", strategy.long, qty=entry_qty_to_risk, comment="OB Long Actif")
strategy.exit("ExitLong", from_entry="LongEntry", stop=entry_sl_level, limit=entry_tp_level)
signal_persistant_long := false
// EXÉCUTION SHORT
if signal_persistant_short and not na(entry_qty_to_risk)
// FILTRE SHORT : Prix M15 en dessous de l'EMA de tendance H1
if close < ema_tendance
strategy.entry("ShortEntry", strategy.short, qty=entry_qty_to_risk, comment="OB Short Actif")
strategy.exit("ExitShort", from_entry="ShortEntry", stop=entry_sl_level, limit=entry_tp_level)
signal_persistant_short := false
// S'assurer que le signal actif est effacé après l'entrée/sortie
if strategy.position_size != 0
signal_persistant_long := false
signal_persistant_short := false