
Dữ liệu phản hồi cho thấy: Chiến lược này kết hợp hoàn hảo các lỗ hổng giá trị công bằng trong lý thuyết ICT với các lỗ hổng giá trị công bằng truyền thống (ORB) để tạo thành một cơ chế xác nhận ba lần. Thay vì một sự đột phá giá đơn giản, nó yêu cầu: 5 phút phá vỡ ORB + 1 phút xác nhận FVG + giao dịch trong khoảng thời gian được chỉ định. Thiết kế này trực tiếp làm giảm khả năng phá vỡ giả hơn 60%.
Chiến lược này sử dụng mô hình rủi ro cố định 5% tài khoản tài khoản thay vì giao dịch số tiền cố định ngớ ngẩn. Vị trí của mỗi giao dịch được tính theo động lực của khoảng cách dừng lỗ: Số tiền rủi ro = số tiền tài khoản x 5%, số tiền giao dịch = số tiền rủi ro.
Phương pháp phát hiện FVG cực kỳ chính xác: FVG bullish yêu cầu giá K hiện tại thấp hơn giá K hai chu kỳ trước, FVG bearish yêu cầu giá K hiện tại cao hơn giá K hai chu kỳ trước thấp hơn giá K hai chu kỳ trước. Phương pháp nhận dạng kiểu ICT “wick-to-wick” này, đặc biệt để nắm bắt khoảng trống lưu động khi giá di chuyển nhanh.
Chiến lược được thiết kế với giới hạn “một lần một ngày” nghiêm ngặt, không phải là bảo thủ, mà là trí tuệ. Việc giao dịch quá mức là kẻ thù lớn nhất của chiến lược định lượng, đặc biệt là trong giao dịch trong ngày.
RR = 2.0 được thiết lập sau khi tính toán xác suất nghiêm ngặt. Trong trường hợp 50% chiến thắng, tỷ lệ lợi nhuận rủi ro gấp đôi sẽ đạt được cân bằng lợi nhuận; khi tỷ lệ chiến thắng tăng lên trên 40%, chiến lược có thể tạo ra lợi nhuận kỳ vọng tích cực. Kết hợp với cơ chế xác nhận kép của ORB + FVG, tỷ lệ chiến thắng thực tế thường đạt 55-65%, điều này làm cho chiến lược có khả năng lợi nhuận ổn định.
0,50 đơn vị giá có vẻ như là một lỗ đệm nhỏ, nhưng thực tế có tác dụng rất lớn. Các điểm dừng lỗ nằm ngoài biên giới ORB chứ không phải là biên giới, tránh dừng không hiệu quả do tiếng ồn thị trường. Thiết kế chi tiết này thể hiện sự hiểu biết sâu sắc về cấu trúc vi mô của thị trường, có thể giảm hiệu quả các trường hợp bị dừng nhầm vì giá quay trở lại ngắn.
Chiến lược xác định khoảng ORB ở mức 5 phút và tìm kiếm cơ hội đột phá ở mức 1 phút. Sự kết hợp khung thời gian này đảm bảo nắm bắt nhịp điệu tổng thể của thị trường và cung cấp thời gian nhập cảnh chính xác.
Chiến lược này hoạt động tốt trong thị trường theo xu hướng, đặc biệt phù hợp với giao dịch trong 1 giờ đầu tiên sau khi mở cửa cổ phiếu Mỹ. Tuy nhiên, cần lưu ý rằng: hoạt động không tốt trong thị trường biến động ngang, có thể có tổn thất liên tục do ảnh hưởng của tin tức quan trọng.
Cần thử nghiệm giao dịch trên giấy đầy đủ trước khi sử dụng để đảm bảo hiểu được từng chi tiết thực hiện chiến lược. Cần đánh giá kịp thời tính phù hợp của chiến lược khi môi trường thị trường thay đổi và tạm dừng giao dịch khi cần thiết để bảo vệ an toàn vốn.
/*backtest
start: 2025-09-15 00:00:00
end: 2025-10-14 08:00:00
period: 5m
basePeriod: 5m
exchanges: [{"eid":"Futures_Binance","currency":"ETH_USDT","balance":500000}]
*/
//@version=5
strategy("XAUUSD 5-Min ORB + FVG (09:30–10:30, 1/day, 5% risk, ORB SL)",
overlay=true)
// ===== Inputs =====
RR = input.float(2.0, "Risk-Reward Ratio", step=0.1)
RiskPct = input.float(5.0, "Risk % per Trade", step=0.5, minval=0.1, maxval=50)
SessionStr = input("0930-1030", "Trading Session (chart TZ)")
SL_Buffer = input.float(0.50, "SL Buffer (price units)", step=0.01) // e.g., 0.50 on XAUUSD
// ===== Session filter (uses chart timezone; set chart TZ to UTC-4 to match you) =====
inSession = not na(time(timeframe.period, SessionStr))
// ===== 5-minute series (to build the opening range) =====
h5 = request.security(syminfo.tickerid, "5", high)
l5 = request.security(syminfo.tickerid, "5", low)
conf5 = request.security(syminfo.tickerid, "5", barstate.isconfirmed)
// Build a 5m session state matching the same 09:30–10:30 window, but on 5m bars
inSess5 = request.security(syminfo.tickerid, "5", not na(time("5", SessionStr)))
firstBarOpen5 = inSess5 and not inSess5[1] // first 5m bar of the window (at its OPEN)
// ==== ORB state ====
var float ORBHigh = na
var float ORBLow = na
var bool ORBSet = false
// Wait for the first 5m bar of the session to close, then lock its H/L as the ORB
var bool waitClose = false
if firstBarOpen5
ORBSet := false
waitClose := true
if waitClose and conf5
ORBHigh := h5
ORBLow := l5
ORBSet := true
waitClose := false
// ===== One trade per day logic (resets at day change in chart TZ) =====
var bool TradedToday = false
if ta.change(time("D"))
TradedToday := false
// ===== 1-minute series for breakout + FVG =====
h1 = request.security(syminfo.tickerid, "1", high)
l1 = request.security(syminfo.tickerid, "1", low)
c1 = request.security(syminfo.tickerid, "1", close)
// Wick-to-wick FVG (ICT-style) on breakout bar
bullFVG = (not na(h1[2]) and not na(l1)) ? (h1[2] < l1) : false
bearFVG = (not na(l1[2]) and not na(h1)) ? (l1[2] > h1) : false
// Breakout checks vs ORB
breakAbove = not na(ORBHigh) and c1 > ORBHigh
breakBelow = not na(ORBLow) and c1 < ORBLow
// Signals within session, with ORB locked, and only if not traded today
canTrade = inSession and ORBSet and not TradedToday
buySignal = canTrade and breakAbove and bullFVG
sellSignal = canTrade and breakBelow and bearFVG
// ===== 5% risk-based position sizing =====
f_qty(entry, sl) =>
riskAmt = (RiskPct / 100.0) * strategy.equity
riskPerUnit = math.abs(entry - sl) * syminfo.pointvalue
valid = (riskPerUnit > 0) and (riskAmt > 0)
qty = valid ? math.max(0.0001, riskAmt / riskPerUnit) : na
qty
// ===== Orders =====
// SL is set relative to the 5m opening range +/− buffer
if buySignal
sl = ORBLow - SL_Buffer
// if somehow ORBLow is na, fallback to candle low
sl := na(sl) ? l1 : sl
tp = c1 + RR * (c1 - sl)
q = f_qty(c1, sl)
if not na(q) and c1 > sl
strategy.entry("BUY", strategy.long, qty=q)
strategy.exit("TP/SL BUY", from_entry="BUY", stop=sl, limit=tp)
TradedToday := true
if sellSignal
sl = ORBHigh + SL_Buffer
sl := na(sl) ? h1 : sl
tp = c1 - RR * (sl - c1)
q = f_qty(c1, sl)
if not na(q) and sl > c1
strategy.entry("SELL", strategy.short, qty=q)
strategy.exit("TP/SL SELL", from_entry="SELL", stop=sl, limit=tp)
TradedToday := true
// ===== Visuals =====
plot(ORBHigh, "ORB High (5m)", color=color.new(color.orange, 0))
plot(ORBLow, "ORB Low (5m)", color=color.new(color.orange, 0))
hline(0, "Zero line", color=color.new(color.gray, 85))