Strategi Perdagangan Arbitrase Osilator Stokastik Kerangka Waktu Ganda

STOCH KDJ MA RSI VWMA SMA EMA WMA
Tanggal Pembuatan: 2025-06-18 13:47:35 Akhirnya memodifikasi: 2025-06-18 13:47:35
menyalin: 0 Jumlah klik: 318
2
fokus pada
319
Pengikut

Strategi Perdagangan Arbitrase Osilator Stokastik Kerangka Waktu Ganda Strategi Perdagangan Arbitrase Osilator Stokastik Kerangka Waktu Ganda

Ringkasan

Strategi perdagangan arbitrage adalah sistem perdagangan frekuensi tinggi harian yang didasarkan pada indikator oscillator stochastic, yang menggunakan dua parameter yang berbeda untuk menghasilkan dan mengkonfirmasi sinyal perdagangan dalam jangka waktu 15 detik. Logika utamanya adalah untuk mengidentifikasi titik masuk potensial melalui persimpangan antara% K dan% D dari indikator acak utama, sambil merujuk nilai% D dari indikator acak sekunder sebagai filter status pasar, menggabungkan rata-rata bergerak dan kondisi penyaringan waktu pasar, untuk membangun sistem perdagangan dengan mekanisme konfirmasi bertingkat.

Prinsip Strategi

Strategi ini menggunakan dua sistem indikator seismik acak, masing-masing disebut indikator utama dan indikator referensi:

  1. Pengaturan indikator seismik acak utama:

    • Rangka waktu: 15 detik
    • Panjang K: 12
    • K-line smoothness: 12
    • D Panjang garis: 12
  2. Pengaturan indikator seismik acak:

    • Rangka waktu: 15 detik
    • Panjang K: 12
    • K Line Smoothness: 15
    • Panjang D: 30

Logika input dirancang dengan baik, dan validasi sinyal dilakukan pada beberapa tingkatan:

  • Syarat masuk:

    • Indikator utama %K melewati %D, dan
    • Reference %D ≥ 50 atau < 20, atau
    • Indikator utama %K mendekati indikator referensi %D (variabel dalam 0,15)
    • Harga berada di atas rata-rata bergerak (jika MA filter diaktifkan)
    • Waktu perdagangan harus berada pada jam pasar normal (9:30 AM - 4:00 PM ET)
  • Syarat untuk masuk dengan kepala kosong:

    • Indikator utama% K melewati% D, dan
    • berada dalam kisaran toleransi% D dari indikator referensi, atau memenuhi kondisi tertentu
    • Harga di bawah rata-rata bergerak
    • Waktu perdagangan harus di jam pasar normal

Logika keluar berdasarkan kombinasi waktu dan sinyal teknis:

  • Waktu untuk keluar:
    • Pada pukul 3:30 sore waktu timur (sebelum berakhirnya waktu pasar reguler)
  • Pengunduran diri teknis:
    • Posisi multihead: saat indikator utama% K di bawah indikator referensi% D
    • Posisi kosong: saat indikator utama% K memakai indikator referensi% D dan indikator referensi% D> 20

Strategi ini juga mengintegrasikan fitur pengenalan bentuk:

  • Lebih tinggi bentuk titik rendah: saat ini nilai% K di atas titik lebih tinggi dari nilai% K di atas titik sebelumnya ((pandangan berlanjut bentuk)
  • Lebih rendah bentuk titik tinggi: saat ini nilai K% di bawah titik tembus lebih rendah dari nilai K% di bawah titik tembus sebelumnya ((membutuhkan bentuk terus turun)

Keunggulan Strategis

  1. Mekanisme konfirmasi multi-lapisan: Mengkonfirmasi satu sama lain melalui dua indikator getaran acak yang berbeda, mengurangi sinyal palsu yang dihasilkan oleh satu indikator, meningkatkan keandalan sinyal.

  2. Aturan masuk dan keluar yang tepatStrategi ini mendefinisikan persyaratan masuk dan keluar yang jelas, menghilangkan subjektivitas dalam keputusan perdagangan, dan memungkinkan perdagangan yang sepenuhnya sistematis.

  3. Kemampuan untuk mengenali bentukIni adalah kemampuan untuk mengidentifikasi bentuk “higher low” dan “lower high” di pasar, dan menangkap peluang untuk melanjutkan tren, yang tidak dapat dicapai oleh banyak strategi sederhana.

  4. Filter waktuDengan membatasi waktu perdagangan pada jam pasar biasa, menghindari periode likuiditas rendah dan berfluktuasi tinggi sebelum buka dan tutup, mengurangi slippage dan biaya.

  5. Filter rata-rata bergerakOpsi penyaringan rata-rata bergerak menambahkan lapisan konfirmasi tren untuk memastikan arah perdagangan sesuai dengan tren keseluruhan.

  6. Perbedaan harga dan parameter perbedaan kapasitasStrategi ini memperkenalkan berbagai parameter untuk mengontrol amplitudo perubahan harga dan kisaran perbedaan indikator, yang secara efektif menyaring sinyal noise yang dihasilkan oleh fluktuasi kecil.

  7. Konversi Logika DinamisSistem ini dapat menyesuaikan kondisi transisi dari multihead ke headless dan dari headless ke multiheadless berdasarkan kondisi pasar yang dinamis, dan lebih mudah beradaptasi.

  8. Sistem Peringatan KomprehensifStrategi ini terintegrasi dengan kondisi peringatan yang kaya untuk memonitor dan melakukan transaksi secara real time.

Risiko Strategis

  1. Risiko perdagangan frekuensi tinggi dalam jangka waktu singkatStrategi: Menggunakan 15 detik waktu frame dapat menghasilkan terlalu banyak sinyal, menyebabkan perdagangan yang sering, meningkatkan biaya transaksi, dan dapat menghasilkan sejumlah besar sinyal palsu dalam situasi pasar yang berfluktuasi besar.

  2. Kurangnya pengendalian kerugian: Tidak ada penghentian kerugian yang jelas dalam kode, risiko kerugian yang lebih besar dapat terjadi jika tren tiba-tiba berbalik. Kurangnya kontrol risiko adalah salah satu kelemahan utama strategi.

  3. Parameter SensitivitasBeberapa parameter yang tepat digunakan dalam strategi (misalnya, batas diferensial 0,15 dan batas diferensial 0,1%) mungkin terlalu sensitif terhadap kondisi pasar yang berbeda dan perlu disesuaikan secara teratur.

  4. Biaya kesempatan dari keterbatasan waktuPerdagangan hanya pada jam pasar biasa dapat melewatkan beberapa peluang penting sebelum dan sesudah perdagangan, terutama ketika pasar bereaksi setelah berita besar.

  5. Ketergantungan pada likuiditasStrategi frekuensi tinggi mungkin mengalami masalah slippage di pasar yang kurang likuid, dan harga yang sebenarnya dieksekusi mungkin berbeda secara signifikan dari harga saat sinyal dihasilkan.

  6. Penundaan indikator teknisIndikator pergerakan acak sendiri memiliki keterlambatan, terutama dalam pasar yang berbalik dengan cepat, dan mungkin tidak dapat menangkap titik-titik pergeseran tepat waktu.

  7. Risiko overadaptasiPerbaikan parameter strategi dapat menyebabkan penyesuaian yang berlebihan terhadap data historis, yang dapat menyebabkan kinerja yang buruk dalam situasi pasar di masa depan.

Arah optimasi strategi

  1. Meningkatkan mekanisme penghentian kerugianOptimalisasi yang paling penting adalah menerapkan sistem stop loss cerdas, yang dapat mempertimbangkan strategi stop loss berdasarkan ATR, atau menggunakan tingkat teknologi sebagai titik stop loss untuk membatasi kerugian maksimum pada satu transaksi.

  2. Memperkenalkan manajemen posisiSkala transaksi disesuaikan secara dinamis berdasarkan volatilitas pasar dan toleransi risiko akun, menggunakan konfigurasi posisi yang berbeda pada intensitas sinyal yang berbeda untuk mengoptimalkan tingkat pemanfaatan dana dan rasio keuntungan risiko.

  3. Menambahkan konfirmasi pengirimanUntuk mengintegrasikan indikator lalu lintas ke dalam sistem, sinyal masuk yang penting harus memiliki dukungan lalu lintas yang cukup untuk menyaring sinyal yang tidak dapat diandalkan dalam lingkungan lalu lintas rendah.

  4. Integrasi multi-indikatorPertimbangan: Menggabungkan indikator momentum dan tren lainnya seperti RSI, MACD, atau Bollinger Bands, untuk membangun perspektif pasar yang lebih komprehensif dan meningkatkan stabilitas sistem.

  5. Pengoptimalan kerangka waktu: menguji berbagai kerangka waktu dasar, seperti 1 menit atau 5 menit, yang mungkin mengurangi kebisingan sambil mempertahankan peluang perdagangan yang cukup, untuk menemukan titik keseimbangan kualitas dan kuantitas sinyal yang optimal.

  6. Menambahkan pelacakan statistik retrospektif: Mendapatkan indikator kinerja pelacakan yang lebih komprehensif, seperti pengembalian maksimum, rasio Sharpe, tingkat kemenangan, rasio kerugian, dll, untuk menilai kinerja strategi dengan lebih ilmiah.

  7. Parameter adaptasi: mengubah parameter tetap menjadi parameter adaptif berdasarkan perubahan dinamika volatilitas pasar, sehingga strategi dapat beradaptasi dengan berbagai kondisi pasar.

  8. Meningkatkan filter lingkungan pasar: Menambahkan VIX (Indeks Volatilitas) atau indikator serupa sebagai kondisi penyaring lingkungan pasar, menyesuaikan parameter strategi atau menghentikan perdagangan dalam lingkungan yang sangat berfluktuasi.

Meringkaskan

Strategi ini adalah sistem perdagangan frekuensi tinggi jangka pendek yang dirancang dengan baik, yang meningkatkan keandalan sinyal perdagangan melalui mekanisme konfirmasi berlapis seperti indikator getaran acak ganda, penyaringan rata-rata bergerak, dan penyaringan waktu. Strategi ini mengidentifikasi titik balik overbought dan oversold jangka pendek dan bentuk kelanjutan tren dalam waktu pasar reguler, sesuai untuk pasar yang memiliki likuiditas yang cukup dan volatilitas moderat.

Meskipun struktur desain strategi yang sempurna, masih ada kekurangan mekanisme manajemen risiko kunci seperti risiko yang melekat pada perdagangan frekuensi tinggi dan kurangnya stop loss. Untuk meningkatkan stabilitas strategi dan profitabilitas jangka panjang, disarankan untuk menambahkan langkah-langkah optimasi seperti mekanisme stop loss, sistem manajemen posisi, konfirmasi volume transaksi dan integrasi multi-indikator. Selain itu, mengubah parameter tetap menjadi parameter adaptif dan menambahkan pelacakan statistik pengembalian yang komprehensif akan membantu strategi untuk mempertahankan kinerja yang stabil dalam berbagai lingkungan pasar.

Dengan pemahaman yang mendalam dan pengoptimalan yang berkelanjutan dari para pedagang tentang strategi ini, sistem perdagangan ini berpotensi menjadi komponen yang efektif dalam kotak alat perdagangan intraday, terutama cocok untuk digunakan oleh para pedagang yang memiliki pemahaman yang mendalam tentang indikator teknis dan dapat memantau pasar secara tepat waktu.

Kode Sumber Strategi
/*backtest
start: 2025-01-01 00:00:00
end: 2025-06-17 00:00:00
period: 4h
basePeriod: 4h
exchanges: [{"eid":"Binance","currency":"ETH_USDT"}]
*/

//@version=6
strategy("Dual TF Stochastic Strategy", overlay=false)

// Input parameters with updated defaults
primaryLen = input.int(12, "Primary Stoch K Length", minval=1)  // Changed from 14 to 12
primarySmooth = input.int(12, "Primary Stoch K Smoothing", minval=1)  // Changed from 3 to 12
primaryDLen = input.int(12, "Primary Stoch D Length", minval=1)  // Changed from 3 to 12
primaryRes = input.timeframe("15S", "Primary Timeframe")  // Changed from "" to "15S"

refLen = input.int(12, "Reference Stoch K Length", minval=1)  // Changed from 14 to 12
refSmooth = input.int(15, "Reference Stoch K Smoothing", minval=1)  // Changed from 3 to 15
refDLen = input.int(30, "Reference Stoch D Length", minval=1)  // Changed from 3 to 30
refRes = input.timeframe("15S", "Reference Timeframe")  // Changed from "D" to "15S"

tolerance = input.float(0.1, "Ref D Tolerance %", minval=0.1, maxval=10.0, step=0.1)  // Changed from 1.0 to 0.1
maxPriceDiff = input.float(0.1, "Maximum Price % Difference", minval=0.1, maxval=5.0, step=0.1)  // Changed from 1.0 to 0.1
closeKThreshold = input.float(0.7, "Close %K Tolerance %", minval=0.1, maxval=10.0, step=0.1)  // Changed from 5.0 to 0.7
minPriceDiffShort = input.float(0.1, "Min Price % Diff for Close %K Short", minval=0.1, maxval=5.0, step=0.1)  // Changed from 0.5 to 0.1
showLabels = input.bool(true, "Show Crossover/Crossunder Labels")

// Time Filters (America/New_York timezone, UTC-4)
is_premarket = hour(time, "America/New_York") < 9
is_postmarket = hour(time, "America/New_York") >= 16
is_regular_hours = hour(time, "America/New_York") >= 9 and hour(time, "America/New_York") < 16
is_exit_time = hour(time, "America/New_York") >= 15 and minute(time, "America/New_York") >= 30  // 3:30 PM ET

// Moving Average Settings
useMAFilter = input.bool(true, "Use Moving Average Filter")
maLength = input.int(200, "Moving Average Length", minval=1)
maType = input.string("SMA", "Moving Average Type", options=["SMA", "EMA", "WMA", "VWMA"])
maTimeframe = input.timeframe("", "Moving Average Timeframe")

// Stochastic Calculations
primaryHighest = ta.highest(high, primaryLen)
primaryLowest = ta.lowest(low, primaryLen)
primaryK_raw = 100 * (close - primaryLowest) / (primaryHighest - primaryLowest)
primaryK = ta.sma(primaryK_raw, primarySmooth)
primaryD = ta.sma(primaryK, primaryDLen)
[primaryK_tf, primaryD_tf] = request.security(syminfo.tickerid, primaryRes, [primaryK, primaryD])

refHighest = ta.highest(high, refLen)
refLowest = ta.lowest(low, refLen)
refK_raw = 100 * (close - refLowest) / (refHighest - refLowest)
refK = ta.sma(refK_raw, refSmooth)
refD = ta.sma(refK, refDLen)
[refK_tf, refD_tf] = request.security(syminfo.tickerid, refRes, [refK, refD])

// Calculate Moving Average
var float ma = na
if useMAFilter
    if maType == "SMA"
        ma := request.security(syminfo.tickerid, maTimeframe, ta.sma(close, maLength))
    else if maType == "EMA"
        ma := request.security(syminfo.tickerid, maTimeframe, ta.ema(close, maLength))
    else if maType == "WMA"
        ma := request.security(syminfo.tickerid, maTimeframe, ta.wma(close, maLength))
    else if maType == "VWMA"
        ma := request.security(syminfo.tickerid, maTimeframe, ta.vwma(close, maLength))

// Price relative to MA
priceAboveMA = not useMAFilter or close > ma
priceBelowMA = not useMAFilter or close < ma

// Crossover Detection and Tracking
crossOver = ta.crossover(primaryK_tf, primaryD_tf)
crossUnder = ta.crossunder(primaryK_tf, primaryD_tf)

// Separate tracking for crossover and crossunder %K and price
var float lastCrossOverK = na
var float lastCrossOverPrice = na
var float currentCrossOverK = na
var float currentCrossOverPrice = na

var float lastCrossUnderK = na
var float lastCrossUnderPrice = na
var float currentCrossUnderK = na
var float currentCrossUnderPrice = na

// Update crossover tracking variables
if crossOver
    lastCrossOverK := nz(currentCrossOverK, primaryK_tf[1])
    lastCrossOverPrice := nz(currentCrossOverPrice, close[1])
    currentCrossOverK := primaryK_tf
    currentCrossOverPrice := close

// Update crossunder tracking variables
if crossUnder
    lastCrossUnderK := nz(currentCrossUnderK, primaryK_tf[1])
    lastCrossUnderPrice := nz(currentCrossUnderPrice, close[1])
    currentCrossUnderK := primaryK_tf
    currentCrossUnderPrice := close

// Calculate differences separately
crossOverPriceDiffPercent = math.abs((currentCrossOverPrice - lastCrossOverPrice) / lastCrossOverPrice * 100)
crossOverKDiffPercent = math.abs((currentCrossOverK - lastCrossOverK) / lastCrossOverK * 100)
crossUnderPriceDiffPercent = math.abs((currentCrossUnderPrice - lastCrossUnderPrice) / lastCrossUnderPrice * 100)
crossUnderKDiffPercent = math.abs((currentCrossUnderK - lastCrossUnderK) / lastCrossUnderK * 100)

isKCloseCrossUnder = crossUnderKDiffPercent <= closeKThreshold and not na(lastCrossUnderK)

// New condition for long entry based on %K and refD_tf difference
kAndRefDDiffClose = crossOver and math.abs(currentCrossOverK - refD_tf) <= 0.15

// Labels for crossover and crossunder (optional)
if showLabels
    if crossOver
        diffKandRefD = math.abs(currentCrossOverK - refD_tf)
        label.new(bar_index, 50, "CrossOver\nDiff K-RefD: " + str.tostring(diffKandRefD, "#.###"), color=color.green, textcolor=color.black, style=label.style_label_up)
    if crossUnder
        diffKandRefD = math.abs(currentCrossUnderK - refD_tf)
        label.new(bar_index, 50, "CrossUnder\nDiff K-RefD: " + str.tostring(diffKandRefD, "#.###"), color=color.red, textcolor=color.black, style=label.style_label_down)

// Entry Conditions
longKCondition = crossOver and (na(lastCrossOverK) or currentCrossOverK > lastCrossOverK)
shortKCondition = crossUnder and (crossUnderPriceDiffPercent <= maxPriceDiff)
closeKShortCondition = crossUnder and isKCloseCrossUnder and (crossUnderPriceDiffPercent > minPriceDiffShort)
crossUnderBetween50and45 = crossUnder and currentCrossUnderK <= 50 and currentCrossUnderK > 45

// Long to Short if crossunder %K > 80 OR < 60
longToShortCondition = crossUnder and (currentCrossUnderK > 80 or currentCrossUnderK < 60) and strategy.position_size > 0 and is_regular_hours

upperLimit = refD_tf * (1 + tolerance/100)
lowerLimit = refD_tf * (1 - tolerance/100)
withinToleranceLong = primaryK_tf >= lowerLimit and primaryK_tf <= upperLimit
withinToleranceShort = primaryK_tf >= lowerLimit and primaryK_tf <= upperLimit

// Final Entry Conditions with MA filter
longCondition = ((longKCondition and (refD_tf >= 50 or refD_tf < 20)) or kAndRefDDiffClose) and is_regular_hours and not is_exit_time and priceAboveMA
shortCondition = (shortKCondition or (crossUnder and withinToleranceShort and (crossUnderPriceDiffPercent <= maxPriceDiff)) or closeKShortCondition or longToShortCondition or crossUnderBetween50and45) and is_regular_hours and not is_exit_time and priceBelowMA

// Short-to-Long Transition Condition with MA filter
shortToLongCondition = crossOver and currentCrossOverK < 25 and strategy.position_size < 0 and is_regular_hours and not is_exit_time and priceAboveMA

// Tracking for %K crossing under refD_tf
var float lastPrimaryKCrossUnderRefD = na
var float currentPrimaryKCrossUnderRefD = na
var bool isPrimaryKCrossUnderRefD = false

// Check if primary %K crosses under reference %D
isPrimaryKCrossUnderRefD := ta.crossunder(primaryK_tf, refD_tf)

// Update tracking for %K crossing under refD
if isPrimaryKCrossUnderRefD
    lastPrimaryKCrossUnderRefD := currentPrimaryKCrossUnderRefD
    currentPrimaryKCrossUnderRefD := primaryK_tf

// Exit Conditions
if is_exit_time
    strategy.close("Long")
    strategy.close("Short")
else if isPrimaryKCrossUnderRefD and not na(lastPrimaryKCrossUnderRefD) and currentPrimaryKCrossUnderRefD < lastPrimaryKCrossUnderRefD
    strategy.close("Long")
else if (ta.crossunder(primaryK_tf, primaryD_tf) and primaryK_tf < refD_tf and refD_tf < 60)
    strategy.close("Long")

if (ta.crossover(primaryK_tf, primaryD_tf) and primaryK_tf > refD_tf and refD_tf > 20) and not is_exit_time
    strategy.close("Short")

// Track if crossunder happens above 85
var bool crossUnderAbove85 = false

// Detect crossunder above 85
if crossUnder and currentCrossUnderK > 85
    crossUnderAbove85 := true

// Reset condition if %K crosses over %D
if ta.crossover(primaryK_tf, primaryD_tf)
    crossUnderAbove85 := false

// Track previous crossover/crossunder values for Higher Low/Lower High detection
var float prevCrossOverK = na
var float prevCrossUnderK = na

// Update previous values on new crossovers/crossunders
if crossOver
    prevCrossOverK := currentCrossOverK
if crossUnder
    prevCrossUnderK := currentCrossUnderK

// Higher Low and Lower High conditions
higherLowCondition = crossOver and not na(prevCrossOverK) and currentCrossOverK > prevCrossOverK
lowerHighCondition = crossUnder and not na(prevCrossUnderK) and currentCrossUnderK < prevCrossUnderK

// Strategy Entries and Transitions
if longCondition
    strategy.entry("Long", strategy.long)

if shortCondition
    if strategy.position_size > 0  // If in a long position, close it first
        strategy.close("Long")
    strategy.entry("Short", strategy.short)

if shortToLongCondition
    strategy.close("Short")
    if ((longKCondition and (refD_tf >= 50 or refD_tf < 20)) or kAndRefDDiffClose)  // Check full longCondition minus time (already checked)
        strategy.entry("Long", strategy.long)

// Add label for Short to Long Transition
if shortToLongCondition
    label.new(bar_index, na, "T", color=color.green, textcolor=color.white, style=label.style_label_up)

// Add label for Long to Short Transition
if longToShortCondition
    label.new(bar_index, na, "T", color=color.red, textcolor=color.white, style=label.style_label_down)

// Plotting
plot(primaryK_tf, "Primary %K", color=color.white, linewidth=1)
plot(primaryD_tf, "Primary %D", color=color.orange, linewidth=1)
plot(refK_tf, "Reference %K", color=color.navy, linewidth=1)
plot(refD_tf, "Reference %D", color=color.rgb(33, 233, 243), linewidth=2)

// Plot current and last %K only for crossUnder when isKCloseCrossUnder is true and currentCrossUnderK < lastCrossUnderK
plot(crossUnder and isKCloseCrossUnder and currentCrossUnderK < lastCrossUnderK ? currentCrossUnderK : na, "Current CrossUnder %K (Close)", color=color.green, style=plot.style_cross, linewidth=2)
plot(crossUnder and isKCloseCrossUnder and currentCrossUnderK < lastCrossUnderK ? lastCrossUnderK : na, "Last CrossUnder %K (Close)", color=color.red, style=plot.style_cross, linewidth=2)

h0 = hline(85, "Upper Band", color=color.rgb(242, 187, 21))
hline(50, "Middle Band", color=#eaff04)
h1 = hline(20, "Lower Band", color=color.rgb(242, 187, 21))
h2 = hline(40, "Lower Band", color=#787B86)
h3 = hline(60, "Lower Band", color=#787B86)
h = hline(0, "Lower Band", color=#787B86)
h5 = hline(100, "Lower Band", color=#787B86)
fill(h0, h1, color=color.rgb(33, 150, 243, 90), title="Background")
fill(h, h1, color=#1be2781d, title="Background")
fill(h0, h5, color=#e21b742d, title="Background")

// Plot the MA if enabled
plot(useMAFilter ? ma : na, "Moving Average", color=color.yellow, linewidth=2)

// Add plot for visualization (optional)
plot(isPrimaryKCrossUnderRefD ? primaryK_tf : na, "Primary %K CrossUnder RefD", color=color.purple, style=plot.style_cross, linewidth=2)
plot(isPrimaryKCrossUnderRefD and not na(lastPrimaryKCrossUnderRefD) ? lastPrimaryKCrossUnderRefD : na, "Last Primary %K CrossUnder RefD", color=color.fuchsia, style=plot.style_cross, linewidth=2)

// Add new alert conditions
alertcondition(higherLowCondition, title="Stoch Higher Low", message="Stoch Higher Low Pattern Detected")
alertcondition(lowerHighCondition, title="Stoch Lower High", message="Stoch Lower High Pattern Detected")

// Plot markers for Higher Low and Lower High patterns
plot(higherLowCondition ? currentCrossOverK : na, "Higher Low", color=color.green, style=plot.style_cross, linewidth=2)
plot(lowerHighCondition ? currentCrossUnderK : na, "Lower High", color=color.red, style=plot.style_cross, linewidth=2)

// Alert conditions
alertcondition(crossOver, title="Stochastic %K Crossed Over %D", message="Stochastic %K crossed over %D")
alertcondition(crossUnder, title="Stochastic %K Crossed Under %D", message="Stochastic %K crossed under %D")
alertcondition(crossOver and primaryK_tf > 50, title="Stochastic %K Crossed Over %D Above 50", message="Stochastic %K crossed over %D above 50")
alertcondition(crossOver and primaryK_tf > refD_tf, title="Stochastic %K Crossed Over %D Above Reference %D", message="Stochastic %K crossed over %D above Reference %D")
alertcondition(longCondition, title="Long Entry Signal", message="Long entry signal triggered")
alertcondition(shortCondition, title="Short Entry Signal", message="Short entry signal triggered")
alertcondition(shortToLongCondition, title="Short to Long Transition", message="Short to Long transition triggered")
alertcondition(longToShortCondition, title="Long to Short Transition", message="Long to Short transition triggered")
alertcondition(isPrimaryKCrossUnderRefD, title="Primary %K Crossed Under Reference %D", message="Primary %K crossed under Reference %D")
alertcondition(crossOver and primaryK_tf > refD_tf, title="Bullish Crossover Above Ref %D", message="Bull: Dual Stoch")
alertcondition(crossUnder and primaryK_tf < refD_tf, title="Bearish Crossunder Below Ref %D", message="Bear: Dual Stoch")