
Multi-level Price Structure Identification and Fair Value Gap Quantification Trading System adalah strategi perdagangan otomatis yang didasarkan pada perilaku harga yang menggabungkan dua konsep perdagangan kunci: Character of Change (CHoCH, Change of Character) dan Fair Value Gap (FVG, Fair Value Gap). Strategi ini menangkap peluang perdagangan probabilitas tinggi dengan mengidentifikasi titik perubahan struktur pasar dan area ketidakseimbangan, masuk ke pasar saat harga kembali ke Fair Value Gap, dan melakukan kontrol masuk dan keluar yang tepat.
Sistem perdagangan kuantitatif ini didasarkan pada prinsip-prinsip inti berikut:
Identifikasi struktur hargaPivot Points: Mengidentifikasi titik-titik tinggi dan rendah di pasar yang merupakan bagian penting dari struktur pasar. Sistem ini menggunakan parameter panjang gelombang (default 5 siklus) untuk menentukan titik-titik penting.
Deteksi karakteristik perubahan:
Pengidentifikasian FVG (Fair Value Gap):
Logika input:
Mekanisme manajemen risiko:
Setelah analisis kode yang mendalam, strategi ini memiliki keuntungan yang signifikan sebagai berikut:
Analisis pasar terstrukturStrategi ini didasarkan pada prinsip perubahan struktur harga dan ketidakseimbangan pasar, bukan sekedar crossover indikator, yang membuatnya memiliki keunggulan unik dalam mengidentifikasi titik-titik perubahan pasar.
Waktu masuk yang tepatDengan menunggu pembentukan FVG setelah CHoCH, strategi ini dapat masuk pada tingkat harga yang menguntungkan, menghindari mengejar tinggi dan rendah, dan meningkatkan kualitas masuk.
Adaptasi Manajemen RisikoStrategi: Mengatur posisi stop loss secara otomatis berdasarkan struktur pasar yang sebenarnya, bukan menggunakan poin tetap. Metode ini lebih sesuai dengan sifat pasar yang sebenarnya berfluktuasi.
Elemen transaksi visualStrategi menyediakan fitur visualisasi yang komprehensif, termasuk label CHoCH, kotak FVG, titik ayunan dan garis perdagangan, yang memungkinkan pedagang untuk memahami struktur pasar dan logika strategi secara langsung.
Manajemen posisi yang fleksibel: Mengatur ukuran posisi secara otomatis melalui persentase risiko, melindungi dana akun dan secara otomatis menyesuaikan ambang risiko berdasarkan volatilitas.
Desain Optimasi Kinerja: Kode berisi mekanisme untuk membersihkan kotak FVG lama, memastikan bahwa kinerja sistem tidak turun saat berjalan lama.
Pemantauan Kinerja KomprehensifStrategi menyediakan tabel kinerja real-time, termasuk indikator kunci seperti status strategi, tingkat kemenangan, dan faktor keuntungan, yang membantu pedagang menilai kinerja strategi.
Meskipun strategi ini dirancang dengan baik, ada beberapa risiko dan keterbatasan potensial:
Risiko Penembusan PalsuUntuk mengurangi risiko ini, pertimbangkan untuk menambahkan mekanisme konfirmasi, seperti menunggu garis K untuk mengkonfirmasi penembusan.
Risiko celah: Dalam pasar yang berfluktuasi tinggi atau perdagangan semalam, harga mungkin melompat melebihi posisi stop loss, menyebabkan kerugian aktual melebihi ekspektasi. Disarankan untuk menggunakan jaminan stop loss order (jika memungkinkan) atau mengurangi ukuran posisi.
Parameter SensitivitasKinerja strategi sangat bergantung pada pengaturan parameter seperti panjang berayun, jarak CHoCH minimal, dan ukuran FVG. Kombinasi parameter yang berbeda mungkin diperlukan untuk pasar dan kerangka waktu yang berbeda, dan optimasi umpan balik yang komprehensif disarankan.
Ketergantungan lingkungan pasarStrategi ini lebih baik dilakukan di pasar tren, dan dapat menghasilkan sinyal kesalahan yang sering terjadi di pasar yang bergeser. Pertimbangkan untuk menambahkan filter tren atau mekanisme identifikasi status pasar.
Kompleksitas komputasi: Strategi menggunakan beberapa array dan pemeriksaan kondisional, yang dapat menyebabkan masalah kinerja pada perangkat yang lebih rendah konfigurasi. Meskipun kode telah menyertakan mekanisme pembersihan, tetapi operasi jangka panjang masih perlu memperhatikan konsumsi sumber daya.
Manajemen penarikan kurang baikStrategi saat ini tidak mempertimbangkan perubahan skala posisi yang dinamis dalam kondisi pasar yang berbeda, yang dapat menyebabkan penarikan yang lebih besar dalam kondisi yang tidak menguntungkan.
Berdasarkan analisis kode, kami mengusulkan optimasi sebagai berikut:
Konfirmasi multi-frame waktu: Memperkenalkan analisis struktur pasar pada kerangka waktu yang lebih tinggi, hanya berdagang di arah tren utama. Sebagai contoh, filter tren garis matahari dapat ditambahkan, hanya melakukan perdagangan jika arah tren garis matahari konsisten.
Optimalisasi parameter dinamis: Sistem parameter yang memungkinkan penyesuaian otomatis berdasarkan volatilitas pasar, misalnya dengan meningkatkan ukuran FVG minimum dan persyaratan jarak Choch selama fluktuasi tinggi dan mengurangi parameter ini selama fluktuasi rendah.
Pengoptimalan masuk:
Peningkatan manajemen risiko:
Adaptasi kondisi pasar:
Pembelajaran Mesin: Menggunakan algoritma pembelajaran mesin untuk menganalisis pola CHoCH dan FVG historis, mengidentifikasi karakteristik pola dengan tingkat keberhasilan yang lebih tinggi, dan menyesuaikan berat keputusan masuk sesuai.
Filter waktu transaksiMenambahkan filter waktu perdagangan, menghindari pengumuman berita besar dan periode fluktuasi tinggi saat pasar terbuka / ditutup, dan fokus pada waktu perdagangan yang lebih likuid.
Multi-Level Price Structure Identification and Fair Value Gap Quantification Trading System adalah solusi trading yang lengkap yang menggabungkan teori perilaku harga yang canggih. Ini melindungi modal trading dengan mengidentifikasi perubahan struktur pasar (CHoCH) dan area ketidakseimbangan harga (FVG) pada tingkat harga yang ideal dan menggunakan metode manajemen risiko yang sistematis.
Keuntungan terbesar dari strategi ini adalah bahwa metode analisisnya didasarkan pada struktur pasar yang sebenarnya, dan bukan mengandalkan indikator yang tertinggal, yang memungkinkannya untuk mengidentifikasi titik-titik perubahan pasar lebih awal. Selain itu, fungsi visualisasi yang baik dan sistem pemantauan kinerja memungkinkan pedagang untuk secara intuitif memahami logika strategi dan menilai efektivitasnya.
Meskipun ada risiko seperti terobosan palsu dan sensitivitas parameter, stabilitas dan kinerja strategi dapat ditingkatkan secara signifikan melalui arah optimasi yang diusulkan, terutama konfirmasi multi-frame waktu, penyesuaian parameter dinamis, dan peningkatan fungsi manajemen risiko.
Strategi ini memberikan kerangka kerja yang solid bagi investor yang ingin melakukan perdagangan dengan metode sistematis, yang menyerap esensi dari perdagangan perilaku harga tradisional dan memanfaatkan keunggulan objektivitas dan disiplin dari sistem kuantitatif. Strategi ini memiliki potensi untuk mencapai kinerja perdagangan yang stabil di berbagai lingkungan pasar melalui optimasi parameter yang berkelanjutan dan penyesuaian untuk adaptasi pasar.
/*backtest
start: 2024-06-03 00:00:00
end: 2025-06-02 00:00:00
period: 2h
basePeriod: 2h
exchanges: [{"eid":"Futures_Binance","currency":"ETH_USDT"}]
*/
//@version=5
strategy("ICT CHoCH & FVG Strategy - NQ1!", overlay=true, pyramiding=0, calc_on_every_tick=false, calc_on_order_fills=false, max_boxes_count=500, max_lines_count=100, max_labels_count=100)
// ============================================================================
// INPUT PARAMETERS
// ============================================================================
// Strategy Settings
riskRewardRatio = input.float(2.0, title="Risk:Reward Ratio", minval=0.5, maxval=10.0, group="Strategy Settings")
fixedTarget = input.int(40, title="Fixed Target (Ticks)", minval=5, maxval=200, group="Strategy Settings")
useRRTarget = input.bool(true, title="Use Risk:Reward Target", tooltip="If false, uses fixed target", group="Strategy Settings")
riskPercent = input.float(2.0, title="Risk % of Account", minval=0.1, maxval=10.0, group="Strategy Settings")
useAutoSize = input.bool(false, title="Auto Size Positions", tooltip="Size based on risk % and stop distance", group="Strategy Settings")
// Visual Settings
showCHoCH = input.bool(true, title="Show CHoCH Labels", group="Visual Settings")
showFVG = input.bool(true, title="Show FVG Boxes", group="Visual Settings")
showSwings = input.bool(true, title="Show Swing Points", group="Visual Settings")
showTradeLines = input.bool(true, title="Show Entry/SL/TP Lines", group="Visual Settings")
// CHoCH Detection Settings
swingLength = input.int(5, title="Swing Detection Length", minval=2, maxval=20, group="CHoCH Settings")
minCHoCHDistance = input.int(10, title="Min CHoCH Distance (bars)", minval=5, maxval=50, group="CHoCH Settings")
// FVG Settings
minFVGSize = input.float(2.0, title="Min FVG Size (ticks)", minval=0.25, maxval=10.0, group="FVG Settings")
maxFVGAge = input.int(50, title="Max FVG Age (bars)", minval=10, maxval=200, group="FVG Settings")
// ============================================================================
// VARIABLES AND ARRAYS
// ============================================================================
// Swing point detection
var float lastSwingHigh = na
var float lastSwingLow = na
var int lastSwingHighBar = na
var int lastSwingLowBar = na
// CHoCH tracking
var bool bullishCHoCH = false
var bool bearishCHoCH = false
var float chochLevel = na
var int chochBar = na
var bool waitingForFVG = false
// FVG tracking
var array<box> bullishFVGs = array.new<box>()
var array<box> bearishFVGs = array.new<box>()
var float activeFVGTop = na
var float activeFVGBottom = na
var bool lookingForEntry = false
// Trade management
var float stopLossLevel = na
var float takeProfitLevel = na
var bool inPosition = false
// ============================================================================
// HELPER FUNCTIONS
// ============================================================================
// Convert ticks to price for NQ
ticksToPrice(ticks) => ticks * 0.25
// Calculate position size based on risk
calcPositionSize(stopDistance) =>
if useAutoSize and strategy.equity > 0
accountValue = strategy.equity
riskAmount = accountValue * (riskPercent / 100)
stopDistancePrice = stopDistance * syminfo.mintick
math.max(1, math.floor(riskAmount / stopDistancePrice))
else
1
// ============================================================================
// SWING POINT DETECTION
// ============================================================================
// Detect swing highs and lows
swingHigh = ta.pivothigh(high, swingLength, swingLength)
swingLow = ta.pivotlow(low, swingLength, swingLength)
// Update swing points
if not na(swingHigh)
lastSwingHigh := swingHigh
lastSwingHighBar := bar_index - swingLength
if showSwings
label.new(bar_index - swingLength, swingHigh, "SH", style=label.style_triangledown, color=color.red, size=size.tiny)
if not na(swingLow)
lastSwingLow := swingLow
lastSwingLowBar := bar_index - swingLength
if showSwings
label.new(bar_index - swingLength, swingLow, "SL", style=label.style_triangleup, color=color.green, size=size.tiny)
// ============================================================================
// CHoCH DETECTION
// ============================================================================
// Check for bullish CHoCH (break above prior swing high after making lower low)
bullishCHoCHCondition = not na(lastSwingHigh) and not na(lastSwingLow) and
high > lastSwingHigh and
lastSwingLow < lastSwingHigh and
bar_index - lastSwingHighBar > minCHoCHDistance and
strategy.position_size == 0
// Check for bearish CHoCH (break below prior swing low after making higher high)
bearishCHoCHCondition = not na(lastSwingHigh) and not na(lastSwingLow) and
low < lastSwingLow and
lastSwingHigh > lastSwingLow and
bar_index - lastSwingLowBar > minCHoCHDistance and
strategy.position_size == 0
// Process CHoCH signals
if bullishCHoCHCondition and not bullishCHoCH
bullishCHoCH := true
bearishCHoCH := false
chochLevel := lastSwingHigh
chochBar := bar_index
waitingForFVG := true
lookingForEntry := false
if bearishCHoCHCondition and not bearishCHoCH
bearishCHoCH := true
bullishCHoCH := false
chochLevel := lastSwingLow
chochBar := bar_index
waitingForFVG := true
lookingForEntry := false
// ============================================================================
// FVG DETECTION
// ============================================================================
// Check for FVG formation (3-candle pattern)
if bar_index >= 2
// Bullish FVG: low[0] > high[2]
bullishFVG = low[0] > high[2] and (low[0] - high[2]) >= ticksToPrice(minFVGSize)
// Bearish FVG: high[0] < low[2]
bearishFVG = high[0] < low[2] and (low[2] - high[0]) >= ticksToPrice(minFVGSize)
// Process bullish FVG after bullish CHoCH
if bullishFVG and bullishCHoCH and waitingForFVG and bar_index > chochBar
fvgTop = low[0]
fvgBottom = high[2]
// Set active FVG for entry
activeFVGTop := fvgTop
activeFVGBottom := fvgBottom
waitingForFVG := false
lookingForEntry := true
// Process bearish FVG after bearish CHoCH
if bearishFVG and bearishCHoCH and waitingForFVG and bar_index > chochBar
fvgTop = low[2]
fvgBottom = high[0]
// Set active FVG for entry
activeFVGTop := fvgTop
activeFVGBottom := fvgBottom
waitingForFVG := false
lookingForEntry := true
// ============================================================================
// ENTRY LOGIC
// ============================================================================
// Long entry: price touches bullish FVG after bullish CHoCH
longCondition = lookingForEntry and bullishCHoCH and
not na(activeFVGTop) and not na(activeFVGBottom) and
low <= activeFVGTop and high >= activeFVGBottom and
strategy.position_size == 0
// Short entry: price touches bearish FVG after bearish CHoCH
shortCondition = lookingForEntry and bearishCHoCH and not na(activeFVGTop) and not na(activeFVGBottom) and low <= activeFVGTop and high >= activeFVGBottom and strategy.position_size == 0
// Process long entries
if longCondition
var float entryPrice = na
var float stopLoss = na
var float takeProfit = na
entryPrice := math.avg(activeFVGTop, activeFVGBottom)
stopLoss := lastSwingLow
stopDistance = entryPrice - stopLoss
if useRRTarget
takeProfit := entryPrice + (stopDistance * riskRewardRatio)
else
takeProfit := entryPrice + ticksToPrice(fixedTarget)
// Calculate position size
qty = calcPositionSize(stopDistance / syminfo.mintick)
// Enter trade
strategy.entry("Long", strategy.long, qty=qty)
strategy.exit("Long Exit", "Long", stop=stopLoss, limit=takeProfit)
// Update tracking
stopLossLevel := stopLoss
takeProfitLevel := takeProfit
inPosition := true
lookingForEntry := false
// Reset CHoCH state
bullishCHoCH := false
activeFVGTop := na
activeFVGBottom := na
// Process short entries
if shortCondition
var float entryPrice = na
var float stopLoss = na
var float takeProfit = na
entryPrice := math.avg(activeFVGTop, activeFVGBottom)
stopLoss := lastSwingHigh
stopDistance = stopLoss - entryPrice
if useRRTarget
takeProfit := entryPrice - (stopDistance * riskRewardRatio)
else
takeProfit := entryPrice - ticksToPrice(fixedTarget)
// Calculate position size
qty = calcPositionSize(stopDistance / syminfo.mintick)
// Enter trade
strategy.entry("Short", strategy.short, qty=qty)
strategy.exit("Short Exit", "Short", stop=stopLoss, limit=takeProfit)
// Update tracking
stopLossLevel := stopLoss
takeProfitLevel := takeProfit
inPosition := true
lookingForEntry := false
// Reset CHoCH state
bearishCHoCH := false
activeFVGTop := na
activeFVGBottom := na
// ============================================================================
// POSITION MANAGEMENT
// ============================================================================
// Reset position state when trade is closed
if inPosition and strategy.position_size == 0
inPosition := false
stopLossLevel := na
takeProfitLevel := na
// ============================================================================
// VISUAL SIGNALS
// ============================================================================
// Plot entry signals
plotshape(longCondition, title="Long Entry", location=location.belowbar, color=color.green,
style=shape.triangleup, size=size.normal)
plotshape(shortCondition, title="Short Entry", location=location.abovebar, color=color.red,
style=shape.triangledown, size=size.normal)
// Plot active stop loss and take profit levels
plot(inPosition ? stopLossLevel : na, title="Stop Loss", color=color.red, linewidth=2, style=plot.style_linebr)
plot(inPosition ? takeProfitLevel : na, title="Take Profit", color=color.green, linewidth=2, style=plot.style_linebr)
// ============================================================================
// CLEANUP
// ============================================================================
// Clean up old FVG boxes (helps with performance)
if bar_index % 100 == 0
while array.size(bullishFVGs) > 20
box.delete(array.shift(bullishFVGs))
while array.size(bearishFVGs) > 20
box.delete(array.shift(bearishFVGs))
// ============================================================================
// ALERTS
// ============================================================================
// Alert conditions
alertcondition(longCondition, title="Long Entry Signal", message="ICT Strategy: Long entry at FVG - SL: {{strategy.position_avg_price}}")
alertcondition(shortCondition, title="Short Entry Signal", message="ICT Strategy: Short entry at FVG - SL: {{strategy.position_avg_price}}")