
SMC, FVG, BOS, OB, EMA
Phân tích kỹ thuật truyền thống đã bị lỗi thời. Chiến lược SMC này sao chép trực tiếp mô hình suy nghĩ của nhà giao dịch tổ chức: tìm kiếm điểm săn lùng thanh khoản, xác định khối đơn đặt hàng, bắt giữ sự phá vỡ cấu trúc thị trường. Dữ liệu phản hồi cho thấy sử dụng chu kỳ 15 phút trên cặp BTC / EUR, kết hợp với bộ lọc xu hướng EMA200 1 giờ, lợi nhuận điều chỉnh rủi ro rõ ràng tốt hơn chiến lược chỉ số truyền thống.
Điều quan trọng là cơ chế xác nhận đa dạng: lỗ hổng giá trị công bằng ((FVG) + phá vỡ cấu trúc thị trường ((BOS) + săn lùng thanh khoản + Fibonacci 50% giảm giá / khu vực thưởng. Đây không phải là một đống chỉ số kỹ thuật, mà là một giải thích chính xác về cấu trúc vi mô của thị trường.
Quản lý rủi ro trực tiếp hiệu quả thô sơ: mỗi giao dịch cố định chịu rủi ro 2 euro, bất kể thị trường biến động lớn như thế nào. Khoảng cách dừng lỗ được tính tự động, đảm bảo rủi ro không đổi. Tỷ lệ lỗ hổng bị khóa ở mức 1:3, có nghĩa là tỷ lệ thắng thua là 33,4% để đạt được cân bằng lỗ hổng, bất kỳ tỷ lệ thắng nào cao hơn con số này là lợi nhuận ròng.
Vị trí tối thiểu là 0.00001 BTC, vị trí tối đa là 0.01 BTC, hoàn toàn phù hợp với quy mô vốn bán lẻ. Không chịu rủi ro không cần thiết vì vị trí quá lớn và không bỏ lỡ cơ hội vì vị trí quá nhỏ. Cách quản lý tiền này ổn định hơn so với mô hình rủi ro phần trăm truyền thống.
Tín hiệu SMC đơn thuần dễ bị lỗi trong thị trường biến động. Chiến lược này thêm EMA200 1 giờ làm bộ lọc xu hướng: chỉ thực hiện tín hiệu đa đầu khi giá 15 phút nằm trên EMA200 1 giờ, ngược lại thực hiện tín hiệu trống.
Thiết kế này trực tiếp thu hẹp khả năng áp dụng của chiến lược từ “toàn bộ thị trường” đến “thị trường xu hướng”, mặc dù giảm tần suất giao dịch, nhưng cải thiện đáng kể chất lượng tín hiệu. Trong thời gian biên soạn ngang, chiến lược sẽ tự động dừng giao dịch, tránh tiêu hao tiền trong biến động không hiệu quả.
Các khối lệnh không phải là hỗ trợ cho kháng cự, mà là khu vực giá mà các quỹ lớn của tổ chức đã từng hoạt động. Chiến lược xác định khối lệnh có hiệu lực bằng các điều kiện sau:
Bảng đặt hàng đa đầu: Đường K trước là đường âm + Có FVG lên + Giá phá vỡ mức thấp trước khi dao động + Có tính thanh khoản bên dưới + Giá hiện tại nằm trong khu vực giảm giá dưới 50% Fibonacci.
Các khối đơn đặt hàng trống: Đường K phía trước là đường nắng + Có FVG xuống + Giá giảm trước điểm biến động cao + Có tính thanh khoản lên + Giá hiện tại nằm trong khu vực phí bảo hiểm Fibonacci trên 50%.
Mỗi điều kiện có logic của nó: âm / dương biểu thị áp lực định hướng, FVG biểu thị sự mất cân bằng về tính thanh khoản, BOS xác nhận sự thay đổi cấu trúc, tham gia của cơ quan chứng nhận săn lùng tính thanh khoản, khu vực giảm giá / thưởng cung cấp thời gian nhập cảnh tốt nhất.
90% các lệnh dừng bán lẻ trên thị trường được đặt ở các mức kháng cự hỗ trợ rõ ràng. Các quỹ tổ chức sẽ cố tình đẩy giá chạm vào các khu vực này, kích hoạt hoạt động ngược sau một số lượng lớn lệnh dừng. Chiến lược nhận diện hành vi săn lùng thanh khoản này bằng chênh lệch giá 0,1%.
Khi mức giá thấp nhất trong 7 chu kỳ thấp hơn 0,1% so với mức thấp hiện tại, xác nhận có tính thanh khoản bên dưới. Thiết kế này tránh được sự phán đoán sai lầm quá nhạy cảm, đồng thời đảm bảo không bị bỏ qua việc săn lùng tính thanh khoản thực sự.
Chiến lược sử dụng độ dài dao động 4 chu kỳ để xác nhận điểm cao thấp, có nghĩa là cần phải đợi 4 đường K để xác nhận một điểm dao động. Sự chậm trễ này là một cái giá cần thiết: quá ngắn xác nhận sẽ tạo ra một số lượng lớn các điểm dao động giả, quá dài xác nhận sẽ mất hiệu lực.
4 chu kỳ tương đương với thời gian xác nhận 1 giờ trên biểu đồ 15 phút, đảm bảo hiệu quả của điểm dao động và không bị chậm trễ quá mức so với thay đổi thị trường. Thuần số này được tối ưu hóa sau nhiều lần đo đạc, là điểm cân bằng tốt nhất cho hiệu quả và độ chính xác.
Lịch sử phản hồi không đại diện cho lợi nhuận trong tương lai, bất kỳ chiến lược nào cũng có khả năng thua lỗ liên tục. Chiến lược SMC hoạt động tốt trong thị trường xu hướng mạnh, nhưng chất lượng tín hiệu sẽ giảm trong thị trường chấn động.
Chiến lược đòi hỏi những phẩm chất tâm lý nghiêm ngặt: phải chấp nhận thua lỗ 2 euro một lần, phải thực hiện một cách dứt khoát khi có tín hiệu, phải kiên nhẫn khi không có tín hiệu. Bất kỳ hành động cảm xúc nào cũng sẽ phá hủy lợi thế thống kê của chiến lược.
Cố gắng thực hiện giao dịch mô phỏng ít nhất 3 tháng trước khi thực hiện giao dịch thực để đảm bảo hiểu đầy đủ về logic và đặc điểm rủi ro của chiến lược. Hãy nhớ rằng: cấu trúc thị trường thay đổi và không có chiến lược nào có hiệu quả mãi mãi.
/*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