Strategi Dagangan Arbitraj Stochastic Oscillator Rangka Masa Dwi

STOCH KDJ MA RSI VWMA SMA EMA WMA
Tarikh penciptaan: 2025-06-18 13:47:35 Akhirnya diubah suai: 2025-06-18 13:47:35
Salin: 0 Bilangan klik: 318
2
fokus pada
319
Pengikut

Strategi Dagangan Arbitraj Stochastic Oscillator Rangka Masa Dwi Strategi Dagangan Arbitraj Stochastic Oscillator Rangka Masa Dwi

Gambaran keseluruhan

Strategi perdagangan lelang indikator goyang acak bingkai dua adalah sistem perdagangan frekuensi tinggi dalam hari berdasarkan indikator goyang acak (Stochastic Oscillator), yang terasnya menggunakan dua parameter goyang acak yang berbeza untuk menghasilkan dan mengesahkan isyarat perdagangan dalam jangka masa 15 saat. Logik utama adalah untuk mengenal pasti titik masuk yang berpotensi melalui persimpangan garis% K dan garis% D pada indikator acak utama, sambil merujuk kepada nilai% D pada indikator acak kecil sebagai penapis keadaan pasaran, menggabungkan purata bergerak dan keadaan penapisan masa pasaran, untuk membina sistem perdagangan dengan mekanisme pengesahan bertingkat.

Prinsip Strategi

Strategi ini menggunakan dua sistem penunjuk goyah rawak, masing-masing dikenali sebagai penunjuk utama dan penunjuk rujukan:

  1. Tetapan indikator gegaran secara rawak:

    • Jangka masa: 15 saat
    • Panjang K: 12
    • K garis halus: 12
    • Panjang D: 12
  2. Untuk tetapan penunjuk gegaran rawak:

    • Jangka masa: 15 saat
    • Panjang K: 12
    • K-Glassy: 15
    • Panjang D: 30

Logik masuk direka dengan baik, dan kebolehgunaan isyarat disahkan dalam pelbagai peringkat:

  • Syarat kemasukan:

    • Indeks utama %K melalui %D, dan
    • Indeks rujukan %D ≥ 50 atau < 20, atau
    • Indeks utama %K berhampiran dengan indeks rujukan %D ((kesenjangan dalam 0.15)
    • Harga terletak di atas purata bergerak (jika penapis MA diaktifkan)
    • Waktu dagangan mestilah pada waktu pasaran biasa (9:30 AM - 4:00 PM ET)
  • Syarat kemasukan:

    • Indeks utama% K melalui% D, dan
    • terletak dalam jarak kapasiti rujukan% D, atau memenuhi syarat tertentu
    • Harga di bawah purata bergerak
    • Waktu dagangan mestilah pada waktu pasaran biasa

Logik keluar berdasarkan gabungan masa dan isyarat teknikal:

  • Masa untuk keluar:
    • Pada pukul 3:30 petang (waktu timur) (sebelum waktu pasaran biasa berakhir)
  • Pengunduran diri teknikal:
    • Kedudukan berbilang kepala: apabila petunjuk utama% K di bawah petunjuk rujukan% D
    • Kedudukan kosong: apabila penunjuk utama %K memakai penunjuk rujukan %D dan penunjuk rujukan %D> 20

Strategi ini juga menyertakan pengenalan bentuk:

  • Bentuk titik rendah yang lebih tinggi: nilai% K pada titik pengalihan semasa lebih tinggi daripada nilai% K pada titik pengalihan sebelumnya ((bentuk lanjutan bullish)
  • Bentuk puncak yang lebih rendah: nilai% K pada titik penembusan bawah semasa lebih rendah daripada nilai% K pada titik penembusan sebelumnya (bentuk berterusan penurunan)

Kelebihan Strategik

  1. Mekanisme pengesahan pelbagai peringkatDengan dua penunjuk gegaran rawak yang berbeza, saling mengesahkan, mengurangkan isyarat palsu yang dihasilkan oleh penunjuk tunggal, meningkatkan kebolehpercayaan isyarat.

  2. Peraturan kemasukan dan keluar yang tepatStrategi ini mentakrifkan syarat masuk dan keluar yang jelas, menghilangkan subjektiviti dalam keputusan perdagangan, dan mencapai perdagangan yang sepenuhnya sistematik.

  3. Kemampuan untuk mengenali bentukKeupayaan untuk mengenal pasti bentuk “lebih rendah” dan “lebih tinggi” dalam pasaran, menangkap peluang untuk meneruskan trend, yang tidak dapat dicapai oleh banyak strategi mudah.

  4. Penapis masaDengan mengehadkan masa dagangan pada waktu pasaran biasa, mengelakkan pergerakan yang tinggi pada masa turun naik dan turun naik sebelum buka dan tutup, mengurangkan titik tergelincir dan kos.

  5. Penapis purata bergerakFungsi penapis purata bergerak pilihan menambah lapisan pengesahan trend untuk memastikan arah perdagangan selaras dengan trend keseluruhan.

  6. Perbezaan harga dan parameter kapasitiStrategi memperkenalkan pelbagai parameter untuk mengawal kelajuan perubahan harga dan julat perbezaan penunjuk, dengan berkesan menapis isyarat bising yang dihasilkan oleh turun naik kecil.

  7. Peralihan logik dinamikSistem ini dapat menyesuaikan diri dengan keadaan pasaran yang dinamik dari multicore ke multicore dan dari multicore ke multicore.

  8. Sistem amaran penuhStrategi ini mengintegrasikan banyak keadaan amaran untuk pemantauan dan pelaksanaan transaksi dalam masa nyata.

Risiko Strategik

  1. Risiko perdagangan frekuensi tinggi dalam jangka masa yang singkatKaedah: Penggunaan jangka masa 15 saat mungkin menghasilkan terlalu banyak isyarat, menyebabkan perdagangan yang kerap, meningkatkan kos perdagangan, dan mungkin menghasilkan banyak isyarat palsu dalam keadaan pasaran yang tidak menentu.

  2. Kekurangan mekanisme kawalan kerugianTidak ada penghentian kerugian yang jelas dalam kod, risiko kerugian yang lebih besar mungkin berlaku jika trend tiba-tiba berbalik. Kekurangan kawalan risiko adalah salah satu kelemahan utama strategi.

  3. Kepekaan ParameterBeberapa parameter tepat yang digunakan dalam strategi (seperti had perbezaan 0.15, had perbezaan harga 0.1%, dan lain-lain) mungkin terlalu sensitif terhadap keadaan pasaran yang berbeza dan memerlukan penyesuaian yang kerap.

  4. Kos peluang yang terhad kepada masaBerdagang hanya pada waktu pasaran biasa mungkin terlepas peluang penting sebelum dan selepas tutup, terutamanya apabila pasaran bereaksi selepas siaran berita penting.

  5. Ketergantungan kepada kecairanStrategi frekuensi tinggi mungkin menghadapi masalah slippage di pasaran yang kurang cair, dan harga pelaksanaan sebenar mungkin berbeza dengan harga semasa isyarat dihasilkan.

  6. Penundaan bagi penunjuk teknikalIndeks goyah rawak mempunyai kemunduran, terutamanya dalam pasaran yang berubah dengan cepat, dan mungkin tidak dapat menangkap titik perubahan tepat pada masanya.

  7. Risiko terlalu serasi: Pengesuaian parameter strategi yang halus boleh menyebabkan penyesuaian yang berlebihan terhadap data sejarah dan tidak berfungsi dengan baik dalam keadaan pasaran masa depan.

Arah pengoptimuman strategi

  1. Meningkatkan mekanisme kawalan kerugianTitik pengoptimuman yang paling penting adalah untuk melaksanakan sistem berhenti pintar, anda boleh mempertimbangkan untuk menghentikan strategi berdasarkan ATR, atau menggunakan tahap teknologi sebagai titik berhenti untuk mengehadkan kerugian maksimum dalam satu perdagangan.

  2. Memperkenalkan pengurusan kedudukan: Mengubah saiz dagangan secara dinamik berdasarkan turun naik pasaran dan toleransi risiko akaun, menggunakan konfigurasi kedudukan yang berbeza di bawah intensiti isyarat yang berbeza untuk mengoptimumkan penggunaan dana dan nisbah keuntungan risiko.

  3. Tambah pengesahan jumlahUntuk mengintegrasikan penunjuk lalu lintas ke dalam sistem, isyarat masuk penting mesti mempunyai sokongan lalu lintas yang mencukupi untuk menyaring isyarat yang tidak boleh dipercayai dalam persekitaran lalu lintas rendah.

  4. Perpaduan pelbagai indikatorPertimbangan: Menggabungkan RSI, MACD, atau Bollinger Bands dengan penunjuk lain dan trend, untuk membina perspektif pasaran yang lebih menyeluruh dan meningkatkan kestabilan sistem.

  5. Pengoptimuman jangka masaUjian jangka masa asas yang berbeza, seperti 1 minit atau 5 minit, mungkin akan mengurangkan kebisingan sambil mengekalkan peluang dagangan yang mencukupi untuk mencari keseimbangan terbaik antara kualiti dan kuantiti isyarat.

  6. Menambah pengesanan statistik: Mencapai penunjuk prestasi pengulangan yang lebih komprehensif, seperti penarikan balik maksimum, nisbah Sharpe, kemenangan, dan kadar kerugian, untuk menilai prestasi strategi dengan lebih saintifik.

  7. Parameter penyesuaian: mengubah parameter tetap menjadi parameter penyesuaian berdasarkan perubahan dinamik turun naik pasaran, membolehkan strategi menyesuaikan diri dengan keadaan pasaran yang berbeza.

  8. Menambah penapisan persekitaran pasaranMenambahkan VIX (Indeks Volatilitas) atau penunjuk serupa sebagai syarat penapisan keadaan pasaran, menyesuaikan parameter strategi atau menangguhkan perdagangan dalam keadaan bergelombang tinggi.

ringkaskan

Strategi perdagangan lelang indikator goyang acak bingkai dua masa adalah sistem perdagangan frekuensi tinggi jangka pendek yang dirancang dengan baik, meningkatkan kebolehpercayaan isyarat perdagangan melalui mekanisme pengesahan berlapis seperti indikator goyang acak ganda, penapisan purata bergerak dan penapisan masa. Strategi ini, dalam tempoh pasaran biasa, mengenal pasti titik peralihan overbought dan oversold jangka pendek dan bentuk kesinambungan trend, sesuai untuk pasaran yang mempunyai kebolehliruan yang mencukupi dan turun naik yang sederhana.

Walaupun struktur reka bentuk strategi yang sempurna, masih terdapat kekurangan mekanisme pengurusan risiko utama seperti risiko yang melekat pada perdagangan frekuensi tinggi dan kekurangan stop loss. Untuk meningkatkan kestabilan strategi dan keuntungan jangka panjang, disarankan untuk menambah langkah-langkah pengoptimuman seperti mekanisme stop loss, sistem pengurusan kedudukan, pengesahan jumlah transaksi dan penggabungan pelbagai indikator.

Dengan pemahaman yang mendalam dan pengoptimuman berterusan terhadap strategi ini, sistem perdagangan ini berpotensi untuk menjadi komponen yang berkesan dalam kotak alat perdagangan dalam sehari, terutamanya untuk digunakan oleh peniaga yang mempunyai pemahaman yang mendalam mengenai petunjuk teknikal dan dapat memantau pasaran pada masa yang tepat.

Kod 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")