
Strategi ini mengintegrasikan tiga mode entry yang berbeda: breakout entry, trap entry, dan reverse entry, dan melakukan perdagangan dengan mengidentifikasi gap fair value (FVG) dan breakout mode antara zona harga. Strategi ini berfokus pada periode volatilitas tinggi di jam pertama setelah pembukaan pasar saham AS (09:30-10:30 EST), melakukan perdagangan pada grafik 1 menit, dan mengadopsi tabel pengembalian risiko 2:1 yang ditetapkan untuk pengelolaan stop loss. Strategi ini ringkas, tidak memiliki indikator kompleks atau siklus waktu yang lebih tinggi, dan tidak memiliki bias untuk menyediakan kerangka kerja sistematisasi bagi pedagang intraday dalam satu hari pendek.
Prinsip inti dari strategi ini didasarkan pada pola perilaku harga setelah pembentukan kisaran awal di awal perdagangan, yang dioperasikan dalam tiga langkah:
Jarak penanda::
Mencari titik masuk (hanya satu jam setelah perdagangan dibuka): Strategi ini menawarkan tiga cara masuk yang berbeda:
Break Entry (dalam bahasa Inggris):
Trap Entry (Penerimaan Jejak):
Reversal Entry (bahasa Inggris: Reverse Entry):
Manajemen transaksi:
Kode strategi mengimplementasikan kerangka logis yang lengkap, termasuk deteksi otomatis interval perdagangan, identifikasi berbagai kondisi masuk, pengaturan level stop loss dan perhitungan ukuran posisi yang tepat. Sistem ini juga menyertakan filter waktu, memastikan perdagangan hanya dalam jangka waktu tertentu, dan dapat secara selektif mengaktifkan atau menonaktifkan berbagai strategi masuk.
Aturan yang Sederhana dan Jelas: Aturan strategi jelas dan intuitif, tanpa penilaian subjektif, mengurangi pengaruh emosi pada keputusan perdagangan. Logika kondisional dan pelacakan status dalam kode memastikan pelaksanaan aturan yang ketat.
Fleksibilitas dalam berbagai cara masuk: Menyediakan tiga strategi masuk yang berbeda (break, trap, dan reverse) yang memungkinkan trader untuk beradaptasi dengan lingkungan pasar yang berbeda.enableBreak、enableTrapDanenableReversalParameter memungkinkan fleksibilitas tersebut.
Fokus pada periode probabilitas tinggiStrategi: Hanya berdagang dalam satu jam pertama setelah buka, memanfaatkan volatilitas dan likuiditas yang lebih tinggi yang biasanya ada selama periode ini.inWindowKondisi memastikan transaksi hanya dilakukan antara pukul 9:30 dan 10:30.
Manajemen risiko yang ketat: Rasio pengembalian risiko tetap 2: 1 dan pengaturan stop loss berdasarkan tindakan harga tertentu, memberikan kontrol risiko yang jelas untuk setiap perdagangan.riskPctParameter ini memungkinkan pengguna untuk menyesuaikan persentase risiko untuk setiap transaksi sesuai dengan preferensi risiko mereka sendiri.
Tidak perlu indikator yang rumitStrategi ini tidak bergantung pada indikator teknis yang rumit, tetapi didasarkan pada perilaku dan struktur harga murni, mengurangi risiko over-fitting.
Penghindaran Musim: Kode ini menyertakan daftar hitam liburan ((15 Desember - 15 Januari), menghindari periode di mana pasar mungkin tidak stabil atau kurang likuiditas.
Manajemen posisi yang fleksibelSistem ini menyediakan dua jenis manajemen posisi berdasarkan persentase risiko atau jumlah kontrak tetap, yang disesuaikan dengan kebutuhan manajemen dana yang berbeda.
Risiko Penembusan PalsuUntuk mengurangi risiko ini, strategi ini mengintegrasikan modus trap dan reverse entry, namun tetap perlu dipantau dengan hati-hati.
Masalah lebar spasi: Jika K-Line dalam 5 menit pertama setelah dibuka terlalu lebar atau terlalu sempit, itu dapat mempengaruhi efektivitas strategi. Interval yang terlalu sempit dapat menyebabkan sinyal pemicu yang terlalu sering, dan interval yang terlalu lebar dapat menyebabkan titik berhenti yang terlalu jauh.
Biaya kesempatan dari keterbatasan waktuNamun, pembatasan ini juga merupakan bentuk disiplin yang mencegah perdagangan berlebihan.
Keterbatasan RR yang tetapMeskipun rasio risiko-pengembalian 2:1 memberikan konsistensi, rasio risiko-pengembalian yang lebih tinggi mungkin lebih cocok untuk pasar yang sedang tren.
Pasar yang tidak biasa selama liburanMeskipun strategi menghindari perdagangan antara 15 Desember dan 15 Januari, aktivitas pasar yang tidak biasa sebelum dan sesudah hari libur lainnya dapat mempengaruhi kinerja strategi.
Ketergantungan pada FVGStrategi ini bergantung pada model FVG dalam penembusan dan reversal entry, tetapi dalam kondisi pasar tertentu, FVG mungkin tidak mudah terbentuk atau dikenali.
Keterbatasan Satu Kerangka WaktuBergantung sepenuhnya pada grafik 1 menit dapat membuat strategi mengabaikan struktur pasar yang penting dalam kerangka waktu yang lebih besar.
Adaptasi lebar interval: Anda dapat mempertimbangkan untuk menyesuaikan lebar kisaran berdasarkan dinamika volatilitas pasar, misalnya menggunakan kisaran yang lebih luas pada hari-hari dengan volatilitas tinggi, menggunakan kisaran yang lebih sempit pada hari-hari dengan volatilitas rendah. Hal ini dapat dicapai dengan menghitung kisaran rata-rata real-time (ATR) atau indikator serupa.
Optimalkan jendela waktuJendela waktu perdagangan optimal untuk pasar yang berbeda dapat dipelajari, bukan tetap pada 9:30-10:30. Beberapa pasar mungkin menunjukkan pola penembusan interval yang lebih jelas pada waktu yang berbeda.
Pengaturan risiko-pengembalian dinamisAnda dapat menyesuaikan RRD sesuai dengan kondisi pasar dan dinamika fluktuasi, misalnya, meningkatkan target saat tren kuat, mengurangi target saat pasar beratur.
Mengintegrasikan indikator sentimen pasarAnda dapat mempertimbangkan untuk memasukkan indikator luas pasar atau indikator volatilitas sebagai filter untuk menghindari perdagangan dalam kondisi pasar yang tidak menguntungkan.
Konfirmasi multi-frame waktu: Meskipun transaksi eksekusi masih berada pada grafik 1 menit, kondisi konfirmasi pada kerangka waktu yang lebih tinggi dapat ditambahkan, seperti pemeriksaan konsistensi arah tren pada grafik 15 menit atau 1 jam.
Optimalkan definisi FVGDefinisi FVG saat ini relatif sederhana, dapat mempertimbangkan definisi zona tidak seimbang yang lebih kompleks atau lebih tepat, seperti mempertimbangkan kerangka dan bukan hanya garis bayangan.
Menambahkan konfirmasi volume transaksiTermasuk konfirmasi volume transaksi dalam persyaratan masuk mungkin meningkatkan kualitas sinyal, terutama untuk penembusan masuk.
Adaptasi untuk menangkal kerugianAdaptasi level stop loss berdasarkan dinamika pasar yang berfluktuasi dapat meningkatkan kemampuan strategi untuk beradaptasi dalam berbagai kondisi pasar.
Sistem perdagangan multi-strategi break-back-reversal adalah strategi perdagangan intraday yang terstruktur dengan aturan yang jelas, yang mencari peluang perdagangan dengan mengidentifikasi kisaran harga yang terbentuk di awal perdagangan dan pola penembusan, jebakan, atau reversal berikutnya. Keunggulan utama dari strategi ini adalah kesederhanaan dan fleksibilitas berbagai cara masuk, sementara batasan waktu yang ketat dan prinsip manajemen risiko membantu menjaga disiplin perdagangan.
Namun, strategi ini juga menghadapi risiko seperti false breakout, lebar interval yang tidak sesuai, dan ketergantungan pada model harga tertentu. Strategi dapat ditingkatkan lebih lanjut dengan cara meningkatkan stabilitas dan adaptasi strategi dengan cara mengoptimalkan metode pengaturan interval, menyesuaikan jendela waktu, secara dinamis mengatur perbandingan risiko-pengembalian, dan mengintegrasikan analisis multi-frame waktu.
Pada akhirnya, strategi ini memberikan kerangka kerja yang sistematis untuk pedagang garis pendek, terutama bagi investor yang mencari perdagangan yang efisien pada jam buka setiap hari. Seperti semua strategi perdagangan, pengembalian yang memadai dan manajemen risiko yang tepat harus dilakukan sebelum diterapkan.
/*backtest
start: 2025-07-22 00:00:00
end: 2025-08-21 00:00:00
period: 1m
basePeriod: 1m
exchanges: [{"eid":"Binance","currency":"ETH_USDT","balance":500000}]
*/
//@version=5
strategy("Three-Step 9:30 Range Scalping (Backtest)", overlay=true, calc_on_every_tick=false, process_orders_on_close=true,
initial_capital=100000, default_qty_type=strategy.percent_of_equity, default_qty_value=100, pyramiding=0)
// -------------------- Inputs
enableBreak = input.bool(true, "Enable Break Entry")
enableTrap = input.bool(false, "Enable Trap Entry")
enableReversal = input.bool(true, "Enable Reversal Entry")
rr = input.float(2.0, "Take-Profit R Multiple", step=0.25, minval=0.25)
oneTradePerDay = input.bool(false, "One Trade Per Day")
showRange = input.bool(true, "Show 9:30 5m Range")
// Risk management
riskPct = input.float(1.0, "Risk % of Equity per Trade", step=0.1, minval=0.1, maxval=100.0)
sizeMode = input.string("Risk %", "Position Sizing Mode", options=["Risk %", "Fixed contracts"])
fixedContracts = input.int(1, "Fixed Contracts", minval=1)
// Optional: warn if not on 1-minute chart (execution timeframe per PRD)
onOneMinute = timeframe.isminutes and timeframe.multiplier == 1
// -------------------- Time helpers (chart is assumed New York time)
newDay = ta.change(time("D")) != 0
// Trade the first hour only: 9:30:00 to 10:29:59
inWindow = (hour == 9 and minute >= 30) or (hour == 10 and minute <= 29)
// Holiday blackout window: Do not trade Dec 15 – Jan 15
inBlackout = (month == 12 and dayofmonth >= 15) or (month == 1 and dayofmonth <= 15)
// -------------------- First 5-min range (use the actual 9:30 5m candle via security())
var float rangeHi = na
var float rangeLo = na
var bool haveRange = false
// -------------------- State for entries
var bool breakUpFound = false
var bool breakDownFound = false
var float initBreakUpLow = na // for Break/Trap long SL
var float initBreakDownHigh = na // for Break/Trap short SL
var bool trapUpRetestedInside = false
var bool trapDownRetestedInside = false
var bool tradedToday = false
// Reset daily state at midnight (chart timezone)
if newDay
rangeHi := na
rangeLo := na
haveRange := false
breakUpFound := false
breakDownFound := false
initBreakUpLow := na
initBreakDownHigh := na
trapUpRetestedInside := false
trapDownRetestedInside := false
tradedToday := false
// Pull the 5-minute bar that STARTS at 9:30 (value available on its close at 9:35)
sess0930Hi = request.security(syminfo.tickerid, "5", (hour == 9 and minute == 30) ? high : na, barmerge.gaps_off, barmerge.lookahead_off)
sess0930Lo = request.security(syminfo.tickerid, "5", (hour == 9 and minute == 30) ? low : na, barmerge.gaps_off, barmerge.lookahead_off)
// Lock the range when the 9:30 5m candle closes (value appears non-na exactly then)
if not haveRange and not na(sess0930Hi) and not na(sess0930Lo)
rangeHi := sess0930Hi
rangeLo := sess0930Lo
haveRange := true
// reset session-specific flags at start of trading window
breakUpFound := false
breakDownFound := false
initBreakUpLow := na
initBreakDownHigh := na
trapUpRetestedInside := false
trapDownRetestedInside := false
tradedToday := false
// -------------------- Visuals
plot(showRange and haveRange ? rangeHi : na, "Range High", color=color.new(color.teal, 0), style=plot.style_linebr, linewidth=2)
plot(showRange and haveRange ? rangeLo : na, "Range Low", color=color.new(color.orange, 0), style=plot.style_linebr, linewidth=2)
plotchar(not onOneMinute, title="Use 1-minute chart", char="⚠", location=location.top, color=color.new(color.red, 0), size=size.tiny)
plotchar(inBlackout, title="Holiday blackout (Dec 15–Jan 15)", char="⛔", location=location.top, color=color.new(color.red, 0), size=size.tiny)
// -------------------- Convenience conditions
closeAbove = haveRange and close > rangeHi
closeBelow = haveRange and close < rangeLo
closeInside = haveRange and close <= rangeHi and close >= rangeLo
// Track first body-close outside the range in each direction (initial break-close)
if haveRange and inWindow and not tradedToday
if not breakUpFound and closeAbove
breakUpFound := true
initBreakUpLow := low
trapUpRetestedInside := false
if not breakDownFound and closeBelow
breakDownFound := true
initBreakDownHigh := high
trapDownRetestedInside := false
// Trap retest flags (retest back inside after first break)
if haveRange and inWindow and not tradedToday
if breakUpFound and not trapUpRetestedInside and closeInside
trapUpRetestedInside := true
if breakDownFound and not trapDownRetestedInside and closeInside
trapDownRetestedInside := true
// -------------------- FVG detectors (three-candle imbalance)
// Simple wick-gap definition, preserved through the third candle
// Bullish: gap exists if Candle C low > Candle A high AND Candle B low > Candle A high
// Bearish: gap exists if Candle C high < Candle A low AND Candle B high < Candle A low
bullFVG = not na(high[2]) and (low[1] > high[2]) and (low > high[2])
bearFVG = not na(low[2]) and (high[1] < low[2]) and (high < low[2])
// -------------------- Entry gating
allowEntry = haveRange and inWindow and not inBlackout and strategy.position_size == 0 and (not oneTradePerDay or not tradedToday)
// Calculate contracts based on selected sizing mode
calcOrderQty(entryPrice, stopPrice) =>
qty = 0
if sizeMode == "Fixed contracts"
qty := fixedContracts
else
riskCash = strategy.equity * riskPct / 100.0
riskPerContract = math.abs(entryPrice - stopPrice) * syminfo.pointvalue
qty := riskPerContract > 0 ? math.floor(riskCash / riskPerContract) : 0
qty
// -------------------- BREAK Entries (needs FVG and ANY of the 3 bars closes outside)
if enableBreak and allowEntry
// Long BREAK
breakLongOk = bullFVG and (close > rangeHi or close[1] > rangeHi or close[2] > rangeHi)
if breakLongOk
// Stop at the FIRST candle that closed outside among the 3 FVG candles
float stopL = na
stopL := close[2] > rangeHi ? low[2] : stopL
stopL := na(stopL) and close[1] > rangeHi ? low[1] : stopL
stopL := na(stopL) and close > rangeHi ? low : stopL
entryL = close
if entryL > stopL
tpL = entryL + rr * (entryL - stopL)
qtyL = calcOrderQty(entryL, stopL)
if qtyL > 0
strategy.entry("LONG_BREAK", strategy.long, qty=qtyL)
strategy.exit("LONG_BREAK_TP/SL", from_entry="LONG_BREAK", stop=stopL, limit=tpL)
tradedToday := oneTradePerDay ? true : tradedToday
// Short BREAK
breakShortOk = bearFVG and (close < rangeLo or close[1] < rangeLo or close[2] < rangeLo)
if breakShortOk
// Stop at the FIRST candle that closed outside among the 3 FVG candles
float stopS = na
stopS := close[2] < rangeLo ? high[2] : stopS
stopS := na(stopS) and close[1] < rangeLo ? high[1] : stopS
stopS := na(stopS) and close < rangeLo ? high : stopS
entryS = close
if entryS < stopS
tpS = entryS - rr * (stopS - entryS)
qtyS = calcOrderQty(entryS, stopS)
if qtyS > 0
strategy.entry("SHORT_BREAK", strategy.short, qty=qtyS)
strategy.exit("SHORT_BREAK_TP/SL", from_entry="SHORT_BREAK", stop=stopS, limit=tpS)
tradedToday := oneTradePerDay ? true : tradedToday
// -------------------- TRAP Entries (Break → Retest inside → Reclose outside; FVG not required)
if enableTrap and allowEntry
// Long TRAP
if breakUpFound and trapUpRetestedInside and closeAbove
stopL = na(initBreakUpLow) ? low : initBreakUpLow
entryL = close
if entryL > stopL
tpL = entryL + rr * (entryL - stopL)
qtyL = calcOrderQty(entryL, stopL)
if qtyL > 0
strategy.entry("LONG_TRAP", strategy.long, qty=qtyL)
strategy.exit("LONG_TRAP_TP/SL", from_entry="LONG_TRAP", stop=stopL, limit=tpL)
tradedToday := oneTradePerDay ? true : tradedToday
// Short TRAP
if breakDownFound and trapDownRetestedInside and closeBelow
stopS = na(initBreakDownHigh) ? high : initBreakDownHigh
entryS = close
if entryS < stopS
tpS = entryS - rr * (stopS - entryS)
qtyS = calcOrderQty(entryS, stopS)
if qtyS > 0
strategy.entry("SHORT_TRAP", strategy.short, qty=qtyS)
strategy.exit("SHORT_TRAP_TP/SL", from_entry="SHORT_TRAP", stop=stopS, limit=tpS)
tradedToday := oneTradePerDay ? true : tradedToday
// -------------------- REVERSAL Entries (Failed break + opposite FVG back into range)
if enableReversal and allowEntry
// After bearish break, bullish FVG back into range → LONG
if breakDownFound and bullFVG and closeInside
stopL = low[2] // first candle of the FVG
entryL = close
if entryL > stopL
tpL = entryL + rr * (entryL - stopL)
qtyL = calcOrderQty(entryL, stopL)
if qtyL > 0
strategy.entry("LONG_REV", strategy.long, qty=qtyL)
strategy.exit("LONG_REV_TP/SL", from_entry="LONG_REV", stop=stopL, limit=tpL)
tradedToday := oneTradePerDay ? true : tradedToday
// After bullish break, bearish FVG back into range → SHORT
if breakUpFound and bearFVG and closeInside
stopS = high[2] // first candle of the FVG
entryS = close
if entryS < stopS
tpS = entryS - rr * (stopS - entryS)
qtyS = calcOrderQty(entryS, stopS)
if qtyS > 0
strategy.entry("SHORT_REV", strategy.short, qty=qtyS)
strategy.exit("SHORT_REV_TP/SL", from_entry="SHORT_REV", stop=stopS, limit=tpS)
tradedToday := oneTradePerDay ? true : tradedToday
// -------------------- Markers
plotshape(enableBreak and (bullFVG and (close > rangeHi or close[1] > rangeHi or close[2] > rangeHi)) and allowEntry, title="Break Long", style=shape.triangleup, color=color.new(color.teal, 0), size=size.tiny, location=location.belowbar, text="Break")
plotshape(enableBreak and (bearFVG and (close < rangeLo or close[1] < rangeLo or close[2] < rangeLo)) and allowEntry, title="Break Short", style=shape.triangledown, color=color.new(color.orange, 0), size=size.tiny, location=location.abovebar, text="Break")
plotshape(enableTrap and breakUpFound and trapUpRetestedInside and closeAbove and allowEntry, title="Trap Long", style=shape.circle, color=color.new(color.teal, 0), size=size.tiny, location=location.belowbar, text="Trap")
plotshape(enableTrap and breakDownFound and trapDownRetestedInside and closeBelow and allowEntry, title="Trap Short", style=shape.circle, color=color.new(color.orange, 0), size=size.tiny, location=location.abovebar, text="Trap")
plotshape(enableReversal and breakDownFound and bullFVG and closeInside and allowEntry, title="Reversal Long", style=shape.diamond, color=color.new(color.teal, 0), size=size.tiny, location=location.belowbar, text="Rev")
plotshape(enableReversal and breakUpFound and bearFVG and closeInside and allowEntry, title="Reversal Short", style=shape.diamond, color=color.new(color.orange, 0), size=size.tiny, location=location.abovebar, text="Rev")