Aliran Berbilang Penunjuk Kemeruapan Adaptif Mengikuti Sistem Dagangan

ATR SMA RSI DCA 烛台模式 趋势跟踪 波动率适应 多时间周期 止损 止盈
Tarikh penciptaan: 2025-04-11 13:41:56 Akhirnya diubah suai: 2025-04-11 13:41:56
Salin: 3 Bilangan klik: 378
2
fokus pada
319
Pengikut

Aliran Berbilang Penunjuk Kemeruapan Adaptif Mengikuti Sistem Dagangan Aliran Berbilang Penunjuk Kemeruapan Adaptif Mengikuti Sistem Dagangan

Gambaran keseluruhan

Sistem perdagangan trend pengesanan pelbagai indikator yang menyesuaikan diri adalah strategi perdagangan kuantitatif yang direka untuk pasaran yang bergelombang tinggi, menggabungkan petunjuk teknikal yang disesuaikan secara dinamik dengan mekanisme pengurusan risiko yang maju. Inti strategi ini adalah untuk menyesuaikan parameter garis purata bergerak secara dinamik melalui ATR (rata-rata gelombang sebenar) untuk menyesuaikan diri dengan turun naik pasaran, sambil mengintegrasikan RSI, penapis overbought dan oversold, penanda dan penanda bentuk, pengenalan trend pelbagai tempoh masa, pengesahan dan penempatan beransur-ansur (DCA), dan lain-lain untuk membentuk kerangka perdagangan yang komprehensif.

Prinsip Strategi

Prinsip-prinsip utama strategi ini adalah berdasarkan beberapa modul utama:

  1. Sistem linear bergerak yang beradaptasiStrategi: menggunakan garis purata bergerak sederhana cepat dan lambat ((SMA), panjangnya disesuaikan secara dinamik melalui ATR. Dalam persekitaran yang bergelombang tinggi, panjang garis purata akan dipersingkat untuk bertindak balas dengan cepat terhadap perubahan pasaran; dalam persekitaran yang bergelombang rendah, panjang garis purata akan diperpanjang untuk mengurangkan bunyi.

  2. RSI penapis dinamik: Memeriksa isyarat masuk melalui RSI (indikator kekuatan relatif lemah) untuk memastikan arah dagangan selaras dengan pergerakan pasaran. Fungsi ini boleh dihidupkan atau dimatikan secara pilihan, dan menyokong parameter RSI yang disesuaikan (seperti panjang 14, overbuying 60, overselling 40).

  3. Pengiktirafan bentuk runtuhSistem ini dapat mengenal pasti bentuk bullish atau bearish yang kuat, dan menggabungkan intensiti perdagangan dan julat untuk mengesahkan. Untuk mengelakkan isyarat palsu, sistem akan melangkau perdagangan apabila dua bentuk yang bertentangan muncul pada masa yang sama.

  4. Pengesahan trend jangka masa ganda: secara pilihan menyelaraskan isyarat dagangan dengan trend SMA pada kitaran masa 15 minit, menambah satu lapisan mekanisme pengesahan, meningkatkan kualiti dagangan.

  5. Mekanisme DCA: membenarkan banyak kemasukan di arah trend, maksimum menyokong jumlah kemasukan yang telah ditetapkan (seperti 4 kali), selang kemasukan ditetapkan berdasarkan kelipatan ATR.

  6. Pengurusan risiko peringkat tinggi

    • Hentikan awal: Berdasarkan tetapan ATR (biasanya 2-3.5 kali ganda), gunakan pengganda hentikan tetap yang lebih luas (seperti 1.3) pada tiang permulaan.
    • Tracking Stop Loss: Menggunakan penyesuaian dan penggandaan asas ATR, menyesuaikan secara dinamik dengan keuntungan yang meningkat (contohnya, apabila keuntungan melebihi ATR, penggandaan turun dari 0.5 hingga 0.3)
    • Matlamat penangguhan: ditetapkan pada kelipatan tertentu harga masuk ± ATR (seperti 1.2).
    • Tempoh sejuk: Tempoh berehat selepas keluar ((0-5 minit), untuk mengelakkan perdagangan berlebihan.
    • Tempoh minimum memegang: memastikan perdagangan berterusan dalam jumlah tiang tertentu (seperti 2-10)
  7. Logik pelaksanaan transaksiSistem memberi keutamaan kepada isyarat bentuk bergerak rata-rata atau jatuh ((sesuai dengan pilihan pengguna), dan menggunakan penapis kuantiti, turun naik dan masa. Untuk memastikan kualiti kemasukan, syarat puncak kuantiti pertukaran juga ditingkatkan ((kualiti> 1.2*10 SMA).

Kelebihan Strategik

  1. Kebolehan beradaptasiDengan ATR secara dinamik menyesuaikan parameter penunjuk teknikal, strategi dapat menyesuaikan diri secara automatik dengan keadaan pasaran yang berbeza dan kekal berkesan dalam persekitaran yang bergelombang tinggi dan rendah.

  2. Penapisan kualiti isyaratMekanisme penapisan bertingkat ((RSI, trend pelbagai kitaran masa, jumlah transaksi dan turun naik) berkesan mengurangkan isyarat palsu dan meningkatkan kualiti perdagangan.

  3. Mekanisme kemasukan yang fleksibelSokongan untuk memprioritaskan penggunaan isyarat bermobile linear atau bergelombang mengikut keutamaan pengguna, dan mengoptimumkan titik masuk ke arah trend melalui fungsi DCA.

  4. Pengurusan risiko dinamik: Stop loss dan tracking stop loss disesuaikan dengan turun naik pasaran dan dinamika keuntungan perdagangan, memberikan ruang yang cukup untuk perkembangan trend sambil melindungi modal.

  5. Visual dan alat debugStrategi menyediakan lapisan grafik yang kaya, papan pemuka dan jadual penyesuaian dalam masa nyata untuk membantu pengguna mengoptimumkan parameter dan memahami logik perdagangan.

  6. Reka bentuk modular: Pengguna boleh menghidupkan atau mematikan pelbagai fungsi mengikut keutamaan (seperti penapis RSI, pengenalan bentuk kejatuhan, trend pelbagai kitaran masa, dan sebagainya), sangat disesuaikan.

  7. Kawalan kemasukan halusPenapis puncak perdagangan memastikan hanya masuk semasa aktiviti pasaran yang ketara, sementara mekanisme tempoh sejuk mencegah perdagangan berlebihan.

Risiko Strategik

  1. Kepekaan ParameterStrategi menggunakan beberapa parameter (seperti panjang garisan purata, kitaran ATR, nilai RSI, dan lain-lain) yang mempunyai kesan ketara terhadap prestasi, kombinasi parameter yang tidak betul boleh menyebabkan data sejarah yang terlalu sesuai.

Penyelesaian: menjalankan ujian pengoptimuman parameter yang luas, tetapi mengelakkan pengoptimuman berlebihan; menggunakan ujian berjalan maju (walk-forward testing) dan ujian luar sampel untuk mengesahkan kehandalan strategi.

  1. Risiko perubahan pasaranDalam keadaan pasaran berubah dengan cepat (seperti dari trend ke goyah), strategi mungkin menghasilkan kerugian berturut-turut sebelum menyesuaikan diri dengan keadaan baru.

*Penyelesaian*Pertimbangan untuk menambah mekanisme pengenalan keadaan pasaran, menggunakan set parameter yang berbeza dalam persekitaran pasaran yang berbeza; melaksanakan had risiko keseluruhan, seperti penghentian dagangan selepas kerugian maksimum harian atau kerugian berturut-turut.

  1. Titik geser dan masalah kecairanPeluang perdagangan yang tinggi dan pasaran yang bergelombang mungkin menghadapi risiko peningkatan slippage dan penurunan kecairan.

*Penyelesaian*Menambahkan titik tergelincir sebenar dan anggaran komisen dalam penilaian semula; mengelakkan dagangan pada masa-masa likuiditi rendah; pertimbangkan untuk menggunakan senarai harga terhad dan bukan senarai harga pasaran.

  1. Kerumitan sistemPerpaduan pelbagai lapisan logik dan syarat menambah kerumitan strategi yang mungkin sukar difahami dan dipelihara.

*Penyelesaian*Menggunakan alat debug yang disediakan oleh strategi untuk memantau prestasi setiap komponen dengan teliti; mengekalkan kod yang baik; pertimbangkan kesan bebas setiap komponen dalam ujian modul.

  1. Risiko perdagangan berlebihanMekanisme DCA dan penjanaan isyarat yang kerap boleh menyebabkan perdagangan berlebihan dan meningkatkan kos transaksi.

Penyelesaian: menetapkan tempoh penyejukan dan tempoh penyimpanan minimum yang sesuai; mempertimbangkan kos urus niaga dengan ketat dalam penilaian semula; semakan dan mengoptimumkan kriteria kemasukan secara berkala.

Arah pengoptimuman

  1. Pembelajaran MesinMemperkenalkan algoritma pengoptimuman parameter yang bersesuaian, seperti pengoptimuman Bayesian atau algoritma genetik, untuk mencari kombinasi parameter yang terbaik secara automatik untuk keadaan pasaran yang berbeza. Ini akan mengurangkan keperluan untuk pengoptimuman manual dan meningkatkan kemampuan strategi untuk menyesuaikan diri dengan perubahan pasaran.

  2. Klasifikasi persekitaran pasaranMengembangkan sistem klasifikasi keadaan pasaran ((kecenderungan, gegaran, turun naik, turun naik, dan lain-lain) dan menyediakan konfigurasi parameter terbaik untuk setiap keadaan. Kaedah ini dapat menyesuaikan tingkah laku strategi dengan lebih cepat semasa peralihan pasaran dan mengurangkan kelewatan penyesuaian.

  3. Pengurusan kedudukan yang lebih baikPemasangan algoritma pengurusan kedudukan yang lebih kompleks, seperti penyesuaian kedudukan dinamik berdasarkan kod Kelly atau kekuatan momentum. Ini dapat mengoptimumkan penggunaan dana, meningkatkan pendedahan pada isyarat kuat, dan mengurangkan risiko pada isyarat lemah.

  4. Penggabungan penunjuk alternatif: menguji keberkesanan petunjuk teknikal lain, seperti Bollinger Bands, MACD atau Ichimoku Cloud Graph, sebagai pelengkap atau pengganti sistem sedia ada. Indikator yang berbeza mungkin memberikan isyarat yang lebih tepat dalam keadaan pasaran tertentu.

  5. Integrasi data emosiPertimbangkan untuk memasukkan indikator sentimen pasaran, seperti indeks turun naik VIX atau data pasaran pilihan, untuk mengenal pasti perubahan pasaran yang berpotensi lebih awal. Sumber data luaran ini dapat memberikan maklumat yang tidak dapat ditangkap oleh penunjuk teknikal tradisional.

  6. Analisis hubungan pelbagai aset: Mengembangkan analisis hubungan antara kelas aset, menggunakan isyarat dari satu pasaran untuk mengesahkan atau menguatkan keputusan perdagangan di pasaran lain yang berkaitan. Sebagai contoh, menggunakan perubahan harga komoditi untuk mengesahkan trend dalam sektor saham yang berkaitan.

  7. Mengoptimumkan kecekapan pengiraanMengubah semula kod untuk meningkatkan kecekapan pengiraan, terutamanya untuk strategi frekuensi tinggi. Ini termasuk mengoptimumkan pengiraan ATR, urutan penilaian syarat dan mengurangkan pengiraan berulang yang tidak perlu.

ringkaskan

Sistem perdagangan trend pemantauan pelbagai indikator dengan kadar turun naik yang menyesuaikan diri mewakili kaedah perdagangan kuantitatif yang komprehensif dan fleksibel yang bertindak balas dengan berkesan terhadap keadaan pasaran yang berbeza melalui penyesuaian parameter dinamik dan mekanisme penapisan berlapis. Kelebihan utama strategi ini adalah kerangka pengurusan risiko yang menyesuaikan diri dan komprehensif, menjadikannya sangat sesuai untuk pasaran niaga hadapan yang bergelombang.

Strategi ini mengintegrasikan pelbagai alat analisis teknikal klasik ((Moving Average, RSI, Bollinger Bands)) sambil menambah elemen perdagangan kuantitatif moden ((Adaptive Parameters, Multi-Time Cycle Analysis, DCA), membentuk sistem yang seimbang. Dengan mengawal masa masuk dengan teliti, mengoptimumkan strategi masuk beberapa kali dan secara dinamik menyesuaikan tahap penangguhan, strategi ini dapat memanfaatkan peluang tren pasaran dengan baik sambil melindungi modal.

Walau bagaimanapun, kerumitan strategi juga membawa cabaran sensitiviti parameter dan penyelenggaraan sistem. Sebelum melaksanakan strategi, pelabur harus melakukan pengesanan dan pengujian ke hadapan yang mencukupi, dan bersedia untuk menyesuaikan parameter mengikut perubahan pasaran. Arah pengoptimuman masa depan termasuk pengenalan parameter pengoptimuman automatik teknologi pembelajaran mesin, penambahan sistem klasifikasi persekitaran pasaran, dan penambahbaikan algoritma pengurusan kedudukan.

Secara keseluruhannya, strategi ini menyediakan kerangka perdagangan kuantitatif yang kukuh, sesuai untuk peniaga berpengalaman yang disesuaikan dengan keperluan dan keutamaan risiko tertentu, mencari kelebihan perdagangan yang konsisten dalam pasaran kewangan yang berubah-ubah hari ini.

Kod sumber strategi
/*backtest
start: 2024-04-11 00:00:00
end: 2025-04-10 00:00:00
period: 1h
basePeriod: 1h
exchanges: [{"eid":"Futures_Binance","currency":"ETH_USDT"}]
*/

//@version=6
strategy('Dskyz Adaptive Futures Elite (DAFE) - Updated', 
         overlay=true, 
         default_qty_type=strategy.fixed, 
         initial_capital=1000000, 
         commission_value=0, 
         slippage=1, 
         pyramiding=10)

// === INPUTS ===

// Moving Average Settings
fastLength       = input.int(9, '[MA] Fast MA Length', minval=1)
slowLength       = input.int(19, '[MA] Slow MA Length', minval=1)

// RSI Settings
useRSI           = input.bool(false, '[RSI Settings] Use RSI Filter')
rsiLength        = input.int(14, 'RSI Length', minval=1)
rsiOverbought    = input.int(60, 'RSI Overbought', minval=50, maxval=100)
rsiOversold      = input.int(40, 'RSI Oversold', minval=0, maxval=50)
rsiLookback      = input.int(1, 'RSI Lookback', minval=1)

// Pattern Settings
usePatterns      = input.bool(true, '[Pattern Settings] Use Candlestick Patterns')
patternLookback  = input.int(19, 'Pattern Lookback Bars', minval=1)

// Filter Settings
useTrendFilter   = input.bool(true, '[Filter Settings] Use 15m Trend Filter')
minVolume        = input.int(10, 'Minimum Volume', minval=1)
volatilityThreshold = input.float(1.0, 'Volatility Threshold (%)', minval=0.1, step=0.1) / 100
tradingStartHour = input.int(9, 'Trading Start Hour (24h)', minval=0, maxval=23)
tradingEndHour   = input.int(16, 'Trading End Hour (24h)', minval=0, maxval=23)

// DCA Settings
useDCA           = input.bool(false, '[DCA Settings] Use DCA')
maxTotalEntries  = input.int(4, 'Max Total Entries per Direction', minval=1)
dcaMultiplier    = input.float(1.0, 'DCA ATR Multiplier', minval=0.1, step=0.1)

// Signal Settings
signalPriority   = input.string('MA', '[Signal Settings] Signal Priority', options=['Pattern', 'MA'])
minBarsBetweenSignals = input.int(5, 'Min Bars Between Signals', minval=1)
plotMode         = input.string('Potential Signals', 'Plot Mode', options=['Potential Signals', 'Actual Entries'])

// Exit Settings
trailOffset      = input.float(0.5, '[Exit Settings] Trailing Stop Offset ATR Multiplier', minval=0.01, step=0.01)
trailPointsMult  = input.float(0.5, 'Trailing Stop Points ATR Multiplier', minval=0.01, step=0.01)
profitTargetATRMult = input.float(1.2, 'Profit Target ATR Multiplier', minval=0.1, step=0.1)  // Profit target factor
fixedStopMultiplier  = input.float(1.3, 'Fixed Stop Multiplier', minval=0.5, step=0.1)    // Fixed stop multiplier

// General Settings
debugLogging     = input.bool(true, '[General Settings] Enable Debug Logging')
fixedQuantity    = input.int(2, 'Trade Quantity', minval=1)
cooldownMinutes  = input.int(0, 'Cooldown Minutes', minval=0)

// ATR Settings – Use Dynamic ATR or fixed value
useDynamicATR    = input.bool(true, title="Use Dynamic ATR")
userATRPeriod    = input.int(7, title="ATR Period (if not using dynamic)", minval=1)
defaultATR       = timeframe.isminutes and timeframe.multiplier <= 2 ? 5 :
                   timeframe.isminutes and timeframe.multiplier <= 5 ? 7 : 10
atrPeriod        = useDynamicATR ? defaultATR : userATRPeriod

// === TRADE TRACKING VARIABLES ===
var int lastSignalBar   = 0
var int lastSignalType  = 0         // 1 for long, -1 for short
var int entryBarIndex   = 0
var bool inLongTrade    = false
var bool inShortTrade   = false

// DCA Tracking Variables
var int longEntryCount  = 0
var int shortEntryCount = 0
var float longInitialEntryPrice = na
var float shortInitialEntryPrice = na
var float longEntryATR  = na
var float shortEntryATR = na
var float long_stop_price = na
var float short_stop_price = na

// Signal Plotting Variables
var int lastLongPlotBar = 0
var int lastShortPlotBar = 0

// === CALCULATIONS ===

// Volume and Time Filters
volumeOk    = volume >= minVolume
currentHour = hour(time)
timeWindow  = currentHour >= tradingStartHour and currentHour <= tradingEndHour

// Additional Entry Filter: Volume Spike Condition
volumeSpike = volume > 1.2 * ta.sma(volume, 10)

// ATR & Volatility Calculations
atr         = ta.atr(atrPeriod)
volatility  = nz(atr / close, 0)
volatilityOk= volatility <= volatilityThreshold

// Adaptive MA Lengths
fastLengthAdaptive = math.round(fastLength / (1 + volatility))
slowLengthAdaptive = math.round(slowLength / (1 + volatility))
fastLengthSafe     = math.max(1, not na(atr) ? fastLengthAdaptive : fastLength)
slowLengthSafe     = math.max(1, not na(atr) ? slowLengthAdaptive : slowLength)
fastMA             = ta.sma(close, fastLengthSafe)
slowMA             = ta.sma(close, slowLengthSafe)

// RSI Calculation
rsi               = ta.rsi(close, rsiLength)
rsiCrossover      = ta.crossover(rsi, rsiOversold)
rsiCrossunder     = ta.crossunder(rsi, rsiOverbought)
rsiLongOk         = not useRSI or (rsiCrossover and rsi[rsiLookback] < 70)
rsiShortOk        = not useRSI or (rsiCrossunder and rsi[rsiLookback] > 30)

// 15m Trend Filter
[fastMA15m, slowMA15m] = request.security(syminfo.tickerid, '15', [ta.sma(close, fastLength), ta.sma(close, slowLength)])
trend15m = fastMA15m > slowMA15m ? 1 : fastMA15m < slowMA15m ? -1 : 0

// Candlestick Patterns
isBullishEngulfing() =>
    close[1] < open[1] and close > open and open < close[1] and close > open[1] and (close - open) > (open[1] - close[1]) * 0.8

isBearishEngulfing() =>
    close[1] > open[1] and close < open and open > close[1] and close < open[1] and (open - close) > (close[1] - open[1]) * 0.8

// Pattern Strength Calculation
patternStrength(isBull) =>
    bull = isBull ? 1 : 0
    bear = isBull ? 0 : 1
    volumeStrength = volume > ta.sma(volume, 10) ? 1 : 0
    rangeStrength  = (high - low) > ta.sma(high - low, 10) ? 1 : 0
    strength = bull * (volumeStrength + rangeStrength) - bear * (volumeStrength + rangeStrength)
    strength

bullStrength = patternStrength(true)
bearStrength = patternStrength(false)

// Detect Patterns
bullishEngulfingOccurred = ta.barssince(isBullishEngulfing()) <= patternLookback and bullStrength >= 1
bearishEngulfingOccurred = ta.barssince(isBearishEngulfing()) <= patternLookback and bearStrength <= -1
patternConflict          = bullishEngulfingOccurred and bearishEngulfingOccurred

// MA Conditions with Trend & RSI Filters
maAbove      = close > fastMA and fastMA > slowMA and close > close[1]
maBelow      = close < fastMA and fastMA < slowMA and close < close[1]
trendLongOk  = not useTrendFilter or trend15m >= 0
trendShortOk = not useTrendFilter or trend15m <= 0

// Signal Priority Logic
bullPattern  = usePatterns and bullishEngulfingOccurred
bearPattern  = usePatterns and bearishEngulfingOccurred
bullMA       = maAbove and trendLongOk and rsiLongOk
bearMA       = maBelow and trendShortOk and rsiShortOk

longCondition  = false
shortCondition = false

if signalPriority == 'Pattern'
    longCondition  := bullPattern or (not bearPattern and bullMA)
    shortCondition := bearPattern or (not bullPattern and bearMA)
else
    longCondition  := bullMA or (not bearMA and bullPattern)
    shortCondition := bearMA or (not bullMA and bearPattern)

// Apply Filters and require volume spike for quality entries
longCondition  := longCondition and volumeOk and volumeSpike and timeWindow and volatilityOk and not patternConflict
shortCondition := shortCondition and volumeOk and volumeSpike and timeWindow and volatilityOk and not patternConflict

// Update Trade Status
if strategy.position_size > 0
    inLongTrade := true
    inShortTrade := false
else if strategy.position_size < 0
    inShortTrade := true
    inLongTrade := false
else
    inLongTrade := false
    inShortTrade := false

// Entry Checks
canTrade      = strategy.position_size == 0
validQuantity = fixedQuantity > 0
quantity      = fixedQuantity

// Prevent Multiple Alerts Per Bar
var bool alertSent = false
if barstate.isnew
    alertSent := false

// Cooldown Logic
var float lastExitTime = na
if strategy.position_size == 0 and strategy.position_size[1] != 0
    lastExitTime := time
canEnter = na(lastExitTime) or ((time - lastExitTime) / 60000 >= cooldownMinutes)

// === ENTRY LOGIC ===
if canTrade and validQuantity and not alertSent and canEnter and barstate.isconfirmed
    if longCondition and not shortCondition and (lastSignalBar != bar_index or lastSignalType != 1)
        strategy.entry('Long', strategy.long, qty=quantity)
        longInitialEntryPrice := close
        longEntryATR         := atr
        longEntryCount       := 1
        alert('Enter Long', alert.freq_once_per_bar)
        alertSent            := true
        lastSignalBar        := bar_index
        lastSignalType       := 1
        entryBarIndex        := bar_index

    else if shortCondition and not longCondition and (lastSignalBar != bar_index or lastSignalType != -1)
        strategy.entry('Short', strategy.short, qty=quantity)
        shortInitialEntryPrice := close
        shortEntryATR          := atr
        shortEntryCount        := 1
        alert('Enter Short', alert.freq_once_per_bar)
        alertSent             := true
        lastSignalBar         := bar_index
        lastSignalType        := -1
        entryBarIndex         := bar_index


// === DCA LOGIC (IF ENABLED) ===
if useDCA
    if strategy.position_size > 0 and longEntryCount < maxTotalEntries and bullMA and rsi < 70
        nextDCALevel = longInitialEntryPrice - longEntryCount * longEntryATR * dcaMultiplier
        if close <= nextDCALevel
            strategy.entry('Long DCA ' + str.tostring(longEntryCount), strategy.long, qty=quantity)
            longEntryCount := longEntryCount + 1
    if strategy.position_size < 0 and shortEntryCount < maxTotalEntries and bearMA and rsi > 30
        nextDCALevel = shortInitialEntryPrice + shortEntryATR * shortEntryCount * dcaMultiplier
        if close >= nextDCALevel
            strategy.entry('Short DCA ' + str.tostring(shortEntryCount), strategy.short, qty=quantity)
            shortEntryCount := shortEntryCount + 1

// === RESET DCA VARIABLES ON EXIT ===
if strategy.position_size == 0 and strategy.position_size[1] != 0
    longEntryCount := 0
    shortEntryCount := 0
    longInitialEntryPrice := na
    shortInitialEntryPrice := na
    longEntryATR := na
    shortEntryATR := na

// === FIXED STOP-LOSS CALCULATION (WIDER INITIAL STOP) ===
long_stop_price  := strategy.position_avg_price - atr * fixedStopMultiplier
short_stop_price := strategy.position_avg_price + atr * fixedStopMultiplier

// === ADJUST TRAILING POINTS BASED ON PROFIT ===
profitLong  = strategy.position_size > 0 ? close - strategy.position_avg_price : 0
profitShort = strategy.position_size < 0 ? strategy.position_avg_price - close : 0
trailPointsMultAdjusted       = profitLong > atr ? 0.3 : profitLong > atr * 0.66 ? 0.4 : trailPointsMult      // For long positions
trailPointsMultAdjustedShort  = profitShort > atr ? 0.3 : profitShort > atr * 0.66 ? 0.4 : trailPointsMult   // For short positions
trailPointsLong  = atr * trailPointsMultAdjusted
trailPointsShort = atr * trailPointsMultAdjustedShort

// === EXIT LOGIC ===
// On the entry bar, always use the fixed stop; thereafter, use a combination of fixed stop, trailing stop, and a profit target.
// Profit Target: For longs, exit at avg_entry + atr * profitTargetATRMult; for shorts, exit at avg_entry - atr * profitTargetATRMult.
if strategy.position_size > 0
    if bar_index == entryBarIndex
        if debugLogging
            log.info("Long exit on entry bar: fixed stop applied. Price=" + str.tostring(close))
        strategy.exit('Long Exit', 'Long', stop=long_stop_price)
    else
        if debugLogging
            log.info("Long Trade: profit=" + str.tostring(profitLong) + ", ATR=" + str.tostring(atr))
        strategy.exit('Long Exit', 'Long', 
             stop=long_stop_price, 
             limit = strategy.position_avg_price + atr * profitTargetATRMult,
             trail_points=trailPointsLong, 
             trail_offset=atr * trailOffset)
            
if strategy.position_size < 0
    if bar_index == entryBarIndex
        if debugLogging
            log.info("Short exit on entry bar: fixed stop applied. Price=" + str.tostring(close))
        strategy.exit('Short Exit', 'Short', stop=short_stop_price)
    else
        if debugLogging
            log.info("Short Trade: profit=" + str.tostring(profitShort) + ", ATR=" + str.tostring(atr))
        strategy.exit('Short Exit', 'Short', 
             stop=short_stop_price, 
             limit = strategy.position_avg_price - atr * profitTargetATRMult,
             trail_points=trailPointsShort, 
             trail_offset=atr * trailOffset)

// === FORCE CLOSE ON LAST BAR (OPTIONAL) ===
if barstate.islast
    if strategy.position_size > 0
        strategy.close('Long', comment='Forced Exit')
    if strategy.position_size < 0
        strategy.close('Short', comment='Forced Exit')

// === SIGNAL PLOTTING LOGIC ===
plotLongSignal  = longCondition and canTrade and (bar_index - lastLongPlotBar >= minBarsBetweenSignals or lastLongPlotBar == 0)
plotShortSignal = shortCondition and canTrade and (bar_index - lastShortPlotBar >= minBarsBetweenSignals or lastShortPlotBar == 0)

if plotLongSignal
    lastLongPlotBar := bar_index
if plotShortSignal
    lastShortPlotBar := bar_index

// Define plotting conditions based on plotMode
plotLongShape  = plotMode == 'Potential Signals' ? plotLongSignal : strategy.position_size > 0 and strategy.position_size[1] <= 0
plotShortShape = plotMode == 'Potential Signals' ? plotShortSignal : strategy.position_size < 0 and strategy.position_size[1] >= 0

// === VISUALIZATION ===
plot(fastMA, color=color.blue, linewidth=2, title='Fast MA')
plot(slowMA, color=color.red, linewidth=2, title='Slow MA')

var float longSL  = na
var float shortSL = na
if strategy.position_size > 0
    longSL := math.max(longSL, high - trailPointsLong)
else
    longSL := na
plot(longSL, color=color.green, style=plot.style_stepline, title='Long SL')

if strategy.position_size < 0
    shortSL := math.min(shortSL, low + trailPointsShort)
else
    shortSL := na
plot(shortSL, color=color.red, style=plot.style_stepline, title='Short SL')

bgcolor(timeWindow ? color.new(color.blue, 95) : na, title="Trading Hours Highlight")
if plotLongShape
    label.new(bar_index, low, "Buy", yloc=yloc.belowbar, color=color.green, textcolor=color.white, style=label.style_label_up)
if plotShortShape
    label.new(bar_index, high, "Sell", yloc=yloc.abovebar, color=color.red, textcolor=color.white, style=label.style_label_down)

// === DEBUG TABLE ===
var table debugTable = table.new(position.top_right, 3, 10, bgcolor=color.rgb(0, 0, 0, 80), border_color=color.white, border_width=1)
if barstate.islast
    table.cell(debugTable, 0, 0, 'Signal', text_color=color.rgb(168, 168, 168), bgcolor=color.rgb(50, 50, 50))
    table.cell(debugTable, 1, 0, 'Status', text_color=color.rgb(168, 168, 168), bgcolor=color.rgb(50, 50, 50))
    table.cell(debugTable, 2, 0, 'Priority', text_color=color.rgb(168, 168, 168), bgcolor=color.rgb(50, 50, 50))

    table.cell(debugTable, 0, 1, 'MA Long', text_color=color.blue)
    table.cell(debugTable, 1, 1, bullMA ? 'Yes' : 'No', text_color=bullMA ? color.green : color.red)
    table.cell(debugTable, 2, 1, signalPriority == 'MA' ? 'High' : 'Low', text_color=color.white)

    table.cell(debugTable, 0, 2, 'MA Short', text_color=color.blue)
    table.cell(debugTable, 1, 2, bearMA ? 'Yes' : 'No', text_color=bearMA ? color.green : color.red)
    table.cell(debugTable, 2, 2, signalPriority == 'MA' ? 'High' : 'Low', text_color=color.white)

    table.cell(debugTable, 0, 3, 'Bull Pattern', text_color=color.blue)
    table.cell(debugTable, 1, 3, bullPattern ? 'Yes' : 'No', text_color=bullPattern ? color.green : color.red)
    table.cell(debugTable, 2, 3, signalPriority == 'Pattern' ? 'High' : 'Low', text_color=color.white)

    table.cell(debugTable, 0, 4, 'Bear Pattern', text_color=color.blue)
    table.cell(debugTable, 1, 4, bearPattern ? 'Yes' : 'No', text_color=bearPattern ? color.green : color.red)
    table.cell(debugTable, 2, 4, signalPriority == 'Pattern' ? 'High' : 'Low', text_color=color.white)

    table.cell(debugTable, 0, 5, 'Filters', text_color=color.rgb(168, 168, 168), bgcolor=color.rgb(50, 50, 50))
    table.cell(debugTable, 1, 5, 'Status', text_color=color.rgb(168, 168, 168), bgcolor=color.rgb(50, 50, 50))
    table.cell(debugTable, 2, 5, '', text_color=color.white, bgcolor=color.rgb(50, 50, 50))

    table.cell(debugTable, 0, 6, 'Time Window', text_color=color.blue)
    table.cell(debugTable, 1, 6, timeWindow ? 'OK' : 'Closed', text_color=timeWindow ? color.green : color.red)
    table.cell(debugTable, 2, 6, str.tostring(currentHour) + 'h', text_color=color.white)

    table.cell(debugTable, 0, 7, 'Volume', text_color=color.blue)
    table.cell(debugTable, 1, 7, volumeOk ? 'OK' : 'Low', text_color=volumeOk ? color.green : color.red)
    table.cell(debugTable, 2, 7, str.tostring(volume, '#'), text_color=color.white)

    table.cell(debugTable, 0, 8, 'Volatility', text_color=color.blue)
    table.cell(debugTable, 1, 8, volatilityOk ? 'OK' : 'High', text_color=volatilityOk ? color.green : color.red)
    table.cell(debugTable, 2, 8, str.tostring(volatility * 100, '#.##') + '%', text_color=color.white)

    table.cell(debugTable, 0, 9, 'Signals', text_color=color.blue)
    table.cell(debugTable, 1, 9, longCondition and not shortCondition ? 'LONG' : shortCondition and not longCondition ? 'SHORT' : longCondition and shortCondition ? 'CONFLICT' : 'NONE', text_color=longCondition and not shortCondition ? color.green : shortCondition and not longCondition ? color.red : color.yellow)
    table.cell(debugTable, 2, 9, canEnter ? alertSent ? 'Sent' : 'Ready' : 'Cooldown', text_color=canEnter ? alertSent ? color.yellow : color.green : color.gray)

// === PERFORMANCE DASHBOARD ===
var table dashboard = table.new(position.bottom_left, 3, 3, bgcolor=color.rgb(0, 0, 0, 80), border_color=color.white, border_width=1)
if barstate.islast
    table.cell(dashboard, 0, 0, 'Position', text_color=color.rgb(168, 168, 168), bgcolor=color.rgb(50, 50, 50))
    table.cell(dashboard, 1, 0, 'P/L', text_color=color.rgb(168, 168, 168), bgcolor=color.rgb(50, 50, 50))
    table.cell(dashboard, 2, 0, 'Statistics', text_color=color.rgb(168, 168, 168), bgcolor=color.rgb(50, 50, 50))

    table.cell(dashboard, 0, 1, strategy.position_size > 0 ? 'Long' : strategy.position_size < 0 ? 'Short' : 'Flat', text_color=strategy.position_size > 0 ? color.green : strategy.position_size < 0 ? color.red : color.blue)
    table.cell(dashboard, 1, 1, str.tostring(strategy.netprofit, '#.##'), text_color=strategy.netprofit >= 0 ? color.green : color.red)
    table.cell(dashboard, 2, 1, 'Win Rate', text_color=color.white)

    table.cell(dashboard, 0, 2, strategy.position_size != 0 ? 'Bars: ' + str.tostring(bar_index - entryBarIndex) : '', text_color=color.white)
    table.cell(dashboard, 1, 2, strategy.position_size != 0 ? 'Cooldown: ' + str.tostring(cooldownMinutes) + 'm' : '', text_color=color.white)
    table.cell(dashboard, 2, 2, strategy.closedtrades > 0 ? str.tostring(strategy.wintrades / strategy.closedtrades * 100, '#.##') + '%' : 'N/A', text_color=color.white)

// === CHART TITLE ===
var table titleTable = table.new(position.bottom_right, 1, 1, bgcolor=color.rgb(0, 0, 0, 80), border_color=color.rgb(0, 50, 137), border_width=1)
table.cell(titleTable, 0, 0, "Dskyz - DAFE Trading Systems", text_color=color.rgb(159, 127, 255, 80), text_size=size.large)