Adaptives Volatilitäts-Multiindikator-Trendfolge-Handelssystem

ATR SMA RSI DCA 烛台模式 趋势跟踪 波动率适应 多时间周期 止损 止盈
Erstellungsdatum: 2025-04-11 13:41:56 zuletzt geändert: 2025-04-11 13:41:56
Kopie: 3 Klicks: 378
2
konzentrieren Sie sich auf
319
Anhänger

Adaptives Volatilitäts-Multiindikator-Trendfolge-Handelssystem Adaptives Volatilitäts-Multiindikator-Trendfolge-Handelssystem

Überblick

Die Strategie basiert auf der dynamischen Anpassung der Moving Average-Parameter an die ATR (Average True Range) zur Anpassung an die Marktschwankungen, während die Integration von RSI-Überkauf-Überverkauf-Filtern, Plattformformformform, Identifizierung von Trends in mehreren Zeiträumen und schrittweise Positionserstellung (DCA) zu einem umfassenden Handelsrahmen. Die Strategie ist besonders geeignet für hohe Volatilität in Umgebungen wie Terminmärkten und bietet eine flexible Betriebsweise für Intra-Tag- und Wellenhandelsphasen.

Strategieprinzip

Die Kernprinzipien der Strategie basieren auf folgenden Schlüsselmodulen:

  1. Adaptive mobile GleichgewichtssystemeStrategie: Die Verwendung von schnellen und langsamen einfachen Moving Averages (SMA), deren Länge durch ATR dynamisch angepasst wird. In einem hohen Wellenumfeld verkürzt sich die Länge der Mittellinie, um schnell auf Marktveränderungen zu reagieren. In einem niedrigen Wellenumfeld verlängert sich die Länge der Mittellinie, um den Lärm zu reduzieren.

  2. RSI-Dynamik-FilterDie Funktion kann optional eingeschaltet oder ausgeschaltet werden und unterstützt benutzerdefinierte RSI-Parameter (z. B. Länge 14, Überkauf 60, Überverkauf 40).

  3. GestaltsausweisDas System ist in der Lage, starke bullish oder bearish Verschluckformen zu erkennen und zu verifizieren, in Kombination mit dem Umsatz und der Reichweite der Stärke. Um falsche Signale zu vermeiden, wird das System den Handel überspringen, wenn zwei entgegengesetzte Formen gleichzeitig auftreten.

  4. Bestätigung von mehrzeitlichen Trends: Optional Ausrichtung von Handelssignalen auf SMA-Trends in 15-Minuten-Zeiträumen, Hinzufügung einer Bestätigungs-Ebene und Verbesserung der Handelsqualität.

  5. DCA-MechanismenEs werden maximal eine vorgegebene Anzahl von Eintritten (z. B. 4 Eintritte) in der Richtung der Tendenz erlaubt, wobei die Eintrittsintervalle auf ATR-Multiplikatoren basieren. Diese Mechanismen helfen, die Durchschnittskosten in einem Trendmarkt zu optimieren.

  6. Hochrangiges Risikomanagement

    • Erster Stopp: basierend auf der ATR-Einstellung (normalerweise 2-3.5x) wird ein breiterer Fix-Stopp-Multiplikator (z. B. 1.3) auf den Einstiegspalten angewendet.
    • Verfolgung von Stop-Losses: Verlagerung und Multiplikation der ATR-Basis mit dynamischer Anpassung der Profit-Erhöhung (z. B. Multiplikation von 0,5 auf 0,3, wenn die Profit-Erhöhung die ATR überschreitet).
    • Stopp-Ziel: Setzen Sie den Einstiegspreis auf ein bestimmtes Vielfaches von ±ATR (z. B. 1,2).
    • Abkühlungszeit: Nach der Ausstiegspause ((0-5 Minuten)), um übermäßigen Handel zu verhindern.
    • Mindesthaltungsdauer: Sicherstellen, dass der Handel eine bestimmte Anzahl von Pfosten dauert (z. B. 2-10).
  7. Logik der TransaktionsdurchführungDas System priorisiert das bewegliche Mittelwert- oder Fallformsignal (je nach Benutzerwahl) und verwendet die Filter für Transaktionsmenge, Volatilität und Zeit. Um die Einstiegsqualität zu gewährleisten, wurden die Bedingungen für die Transaktionsspitzen erhöht (Transaktionsmenge >1,2).*Die SMA-Ausgabe 10

Strategische Vorteile

  1. MarktanpassungsfähigkeitDurch die dynamische Anpassung der Parameter der technischen Indikatoren durch ATR kann die Strategie automatisch an unterschiedliche Marktbedingungen angepasst werden und bleibt sowohl in hoch- als auch in niedrig-volatilem Umfeld wirksam.

  2. SignalqualitätsfilterungEs gibt mehrere Filtermechanismen (RSI, mehrere Zeitzyklustrends, Transaktionsvolumen und Volatilität), die falsche Signale reduzieren und die Qualität der Transaktionen verbessern.

  3. Flexible Zugangsmöglichkeiten: Unterstützung für die bevorzugte Verwendung von mobilen Mittellinien oder Fallformsignalen je nach Benutzerpräferenz und Optimierung der Einstiegspunkte in Richtung der Tendenz durch die DCA-Funktion.

  4. Dynamische RisikomanagementDer Trend wird von der Marktfluktuation und den dynamischen Handelsgewinnen angepasst, um den Trends genügend Spielraum zu geben, während das Kapital geschützt wird.

  5. Visualisierungs- und Debugging-ToolsStrategie bietet eine umfangreiche Grafiküberlagerung, eine Echtzeit-Arbeitstafel und eine Debugging-Tabelle, die Benutzern helfen, ihre Parameter zu optimieren und die Logik des Handels zu verstehen.

  6. Modulares DesignDer Benutzer kann verschiedene Funktionen (z. B. RSI-Filter, Fallformerkennung, mehrzeitige Trends usw.) nach seinen Vorlieben ein- und ausschalten.

  7. Feine EintrittskontrolleDie Spitzen-Filter sorgen dafür, dass die Börse nur bei bedeutenden Marktaktivitäten auftritt, während die Abkühlungsphase übermäßige Geschäfte verhindert.

Strategisches Risiko

  1. ParameterempfindlichkeitDie Strategie verwendet mehrere Parameter (z. B. Durchschnittslänge, ATR-Zyklus, RSI-Threshold usw.), deren Einstellungen einen signifikanten Einfluss auf die Leistung haben. Eine falsche Kombination von Parametern kann zu einer Überanpassung der historischen Daten führen.

*Die Lösung*Umfangreiche Parameteroptimierungs-Tests, aber keine Überoptimierungen; Walk-Forward-Tests und Off-Sample-Tests zur Validierung der Strategie-Stabilität.

  1. Risiken von MarktveränderungenIn Zeiten schneller Veränderungen der Marktmuster (z. B. von Trends zu Schwankungen) kann eine Strategie einen Verlust in Folge verursachen, bevor sie sich dem neuen Umfeld anpasst.

*Die Lösung*Erwägen Sie die Erweiterung der Marktsituationserkennungsmechanismen, um verschiedene Parameter in verschiedenen Marktumgebungen zu verwenden; Implementieren Sie allgemeine Risikobeschränkungen, z. B. die Aussetzung des Handels nach einem täglichen Maximalverlust oder nach einem fortlaufenden Verlust.

  1. Schlupfpunkte und LiquiditätsproblemeEs ist möglich, dass sich die Marktfrequenz erhöht und die Marktfluktuation erhöht.

*Die Lösung*Um den Markt zu schützen, sollten Sie sich auf die folgenden Faktoren konzentrieren: Eingliederung von realen Slippoints und Kommissionsschätzungen in die Rückmessung; Vermeidung von Handel in Zeiten mit geringer Liquidität; Erwägung der Verwendung von Limit-Listing statt Marktpreislisten.

  1. Komplexität der SystemeDie Mehrfachlogik und die Kombination von Bedingungen erhöhen die Komplexität der Strategie und können schwierig zu verstehen und zu pflegen sein.

*Die Lösung*Die Strategie beinhaltet: die Verwendung von Debugging-Tools, um die Leistung der einzelnen Komponenten genau zu überwachen; die Aufrechterhaltung guter Code-Kommentare; die Berücksichtigung der unabhängigen Wirksamkeit von Komponenten bei der Modularisierung.

  1. ÜberhändlerrisikenDie DCA-Mechanismen und die häufige Signalgenerierung können zu übermäßigen Transaktionen führen und die Transaktionskosten erhöhen.

*Die Lösung*Das Unternehmen hat die folgenden Ziele: angemessene Abkühlungsfristen und Mindesthaltungszeiten festzulegen; bei der Rückmessung die Transaktionskosten sorgfältig zu berücksichtigen; Regelmäßige Überprüfung und Optimierung der Aufnahmebedingungen.

Optimierungsrichtung

  1. Maschinelles Lernen verstärktDie Einführung von Adaptive Parameter Optimierung Algorithmen, wie Bayesian Optimierung oder genetische Algorithmen, um automatisch die beste Parameterkombination für verschiedene Marktumgebungen zu finden. Dies wird die Notwendigkeit der manuellen Optimierung reduzieren und die Anpassung der Strategie an Marktveränderungen verbessern.

  2. Klassifizierung der MarktumgebungEntwicklung eines System zur Klassifizierung von Marktzuständen (Trends, Erschütterungen, Hoch- und Niedrigschwankungen usw.) und Vorbereitung der optimalen Parameterkonfiguration für jeden Zustand. Diese Methode ermöglicht eine schnellere Anpassung des Strategieverhaltens bei Marktveränderungen und verringert die Anpassungsrückstände.

  3. Erweiterte PositionsverwaltungEinführung von komplexeren Positionsmanagement-Algorithmen, wie beispielsweise dynamische Positionsanpassungen basierend auf Kelly-Richtlinien oder Dynamikstärken. Dies kann die Kapitalnutzung optimieren, die Exposition bei starken Signalen erhöhen und das Risiko bei schwachen Signalen verringern.

  4. Integration der Alternativen: Test der Wirksamkeit anderer technischer Indikatoren, wie Bollinger Bands, MACD oder Ichimoku Cloud Charts, als Ergänzung oder Ersatz für bestehende Systeme. Unterschiedliche Indikatoren können unter bestimmten Marktbedingungen ein genaueres Signal liefern.

  5. Integration der EmotionsdatenErwägen Sie die Einbeziehung von Marktstimmungsindikatoren, wie z. B. dem VIX-Rate-Index oder Optionsmarktdaten, um potenzielle Marktveränderungen im Voraus zu erkennen. Diese externen Datenquellen können Informationen liefern, die mit herkömmlichen technischen Indikatoren nicht erfasst werden können.

  6. Multi-Asset-KonnektivitätsanalyseDie Entwicklung von Zusammenhängenanalysen über Assetklassen hinweg, die die Signale eines Marktes nutzen, um Handelsentscheidungen in einem anderen relevanten Markt zu bestätigen oder zu verstärken. Zum Beispiel die Verwendung von Warenpreisänderungen, um Trends in den relevanten Aktiensegmenten zu bestätigen.

  7. Optimierung der RechenleistungUmstrukturierung des Codes zur Erhöhung der Rechenleistung, insbesondere für Hochfrequenzstrategien. Dies beinhaltet die Optimierung der ATR-Berechnung, der Reihenfolge der Bedingungen und die Verringerung unnötiger Rechenüberschneidungen.

Zusammenfassen

Das Multi-Indikator-Trend-Tracking-Trading-System mit selbstadaptiver Volatilität stellt eine umfassende und flexible quantitative Handelsmethode dar, die effektiv auf verschiedene Marktumgebungen durch dynamische Parameteranpassungen und mehrschichtige Filtermechanismen reagiert. Die Kernvorteile der Strategie liegen in ihrer Anpassungsfähigkeit und dem integrierten Risikomanagement-Framework, was sie besonders für den hochvolatilen Futures-Markt geeignet macht.

Die Strategie integriert mehrere klassische technische Analyse-Tools (Moving Average, RSI, Fallform) mit modernen quantitativen Trading-Elementen (Adaptive Parameter, Multiple-Time-Cycle-Analyse, DCA), um ein ausgewogenes System zu bilden. Durch die genaue Kontrolle der Einstiegszeit, die Optimierung der Multiple-Entry-Strategie und die dynamische Anpassung der Stop-Loss-Ebene kann die Strategie die Markttrendchancen optimal nutzen, während sie das Kapital schützt.

Die Komplexität der Strategie bringt jedoch auch die Herausforderung der Parameter-Sensitivität und der Systempflege mit sich. Bevor die Strategie umgesetzt wird, sollten die Anleger ausreichend Rückmeldung und Vorwärtsprüfung durchführen und bereit sein, die Parameter an Marktveränderungen anzupassen. Zukünftige Optimierungsrichtungen umfassen die Einführung von automatischen Optimierungsparametern durch Machine-Learning-Technologien, die Aufnahme eines Markteinhaltungsklassifikationssystems und die Verbesserung der Positionsmanagement-Algorithmen, die die Robustheit und Anpassungsfähigkeit der Strategie weiter verbessern werden.

Insgesamt bietet die Strategie einen soliden, quantifizierten Handelsrahmen, der für erfahrene Händler geeignet ist, der auf ihre spezifischen Bedürfnisse und Risikopräferenzen zugeschnitten ist, um in den heutigen schnelllebigen Finanzmärkten einen konsistenten Handelsvorteil zu erlangen.

Strategiequellcode
/*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)