
Hệ thống giao dịch theo dõi xu hướng đa chỉ số tự thích ứng là một chiến lược giao dịch định lượng được thiết kế cho thị trường biến động cao, kết hợp các chỉ số kỹ thuật được điều chỉnh động với cơ chế quản lý rủi ro tiên tiến. Cốt lõi của chiến lược này là điều chỉnh động các tham số đường trung bình di động thông qua ATR (trung bình sóng thực) để tự thích ứng với biến động thị trường, đồng thời tích hợp các tính năng như RSI, siêu bán, siêu bán, phân tích, nhận dạng xu hướng theo nhiều chu kỳ thời gian và xác nhận vị trí dần dần (DCA), tạo thành một khung giao dịch toàn diện.
Các nguyên tắc cốt lõi của chiến lược được xây dựng dựa trên các mô-đun quan trọng sau:
Hệ thống tự điều chỉnh chuyển độngChiến lược sử dụng đường trung bình di chuyển đơn giản nhanh và chậm ((SMA), chiều dài của nó được điều chỉnh động thông qua ATR. Trong môi trường có sóng cao, chiều dài đường trung bình sẽ được rút ngắn để phản ứng nhanh với sự thay đổi của thị trường; trong môi trường có sóng thấp, chiều dài đường trung bình được kéo dài để giảm tiếng ồn. Tín hiệu dài được tạo ra khi đi qua đường trung bình chậm trên đường trung bình nhanh và nhận được xác nhận giá; tín hiệu ngắn ngược lại.
RSI động lực lọc: Xác nhận tín hiệu nhập cảnh thông qua RSI (chỉ số tương đối mạnh) để đảm bảo hướng giao dịch phù hợp với động lực thị trường. Chức năng này có thể bật hoặc tắt tùy chọn và hỗ trợ các tham số RSI tùy chỉnh (như chiều dài 14, quá mua 60, quá bán 40).
Nhận dạng hình dạng thất bại: Hệ thống có thể nhận diện các hình thức đà tăng mạnh hoặc đà giảm mạnh, và kết hợp khối lượng giao dịch và cường độ phạm vi để xác minh. Để tránh tín hiệu giả, hệ thống sẽ bỏ qua giao dịch khi hai hình thức ngược lại xuất hiện cùng một lúc.
Xác nhận xu hướng đa chu kỳLựa chọn các tín hiệu giao dịch phù hợp với xu hướng SMA trong chu kỳ 15 phút, thêm một lớp cơ chế xác nhận, nâng cao chất lượng giao dịch.
Cơ chế DCA: Cho phép nhiều lần nhập vào hướng xu hướng, hỗ trợ tối đa số lượng nhập trước (ví dụ như 4 lần), khoảng thời gian nhập được thiết lập dựa trên ATR nhân. Cơ chế này giúp tối ưu hóa chi phí trung bình trong thị trường xu hướng tiếp tục.
Quản lý rủi ro cấp cao:
Logic thực hiện giao dịch: Hệ thống ưu tiên tín hiệu hình dạng trung bình di chuyển hoặc hình dạng sụp đổ ((theo sự lựa chọn của người dùng) và áp dụng bộ lọc khối lượng giao dịch, biến động và thời gian. Để đảm bảo chất lượng nhập cảnh, điều kiện đỉnh lượng giao dịch cũng được tăng lên ((thị trường giao dịch> 1.2*10 SMA).
Thị trường thích ứngThông qua ATR động điều chỉnh các tham số chỉ số kỹ thuật, chiến lược có thể tự động thích ứng với các điều kiện thị trường khác nhau, duy trì hiệu quả trong môi trường biến động cao và thấp.
Chọn chất lượng tín hiệuCác cơ chế lọc đa tầng ((RSI, xu hướng nhiều chu kỳ, khối lượng giao dịch và biến động) có hiệu quả trong việc giảm tín hiệu giả và cải thiện chất lượng giao dịch.
Cơ chế nhập học linh hoạt: Hỗ trợ ưu tiên sử dụng tín hiệu hình dạng đường trung bình di động hoặc hình dạng sụp đổ theo sở thích của người dùng và tối ưu hóa điểm vào theo hướng xu hướng thông qua chức năng DCA.
Quản lý rủi ro động: Điểm dừng và theo dõi dừng điều chỉnh theo biến động thị trường và lợi nhuận giao dịch, để cho xu hướng phát triển đủ không gian trong khi bảo vệ vốn.
Công cụ trực quan và khởi độngChiến lược cung cấp lớp phủ biểu đồ phong phú, bảng điều khiển thời gian thực và bảng điều khiển để giúp người dùng tối ưu hóa các tham số và hiểu logic giao dịch.
Thiết kế mô-đun: Người dùng có thể bật hoặc tắt các chức năng tùy theo sở thích của họ (như bộ lọc RSI, nhận dạng hình dạng sụp đổ, xu hướng nhiều chu kỳ thời gian, v.v.), tùy chỉnh cao.
Kiểm soát nhập cảnh tinh tếBộ lọc khối lượng giao dịch cao nhất đảm bảo chỉ tham gia vào các hoạt động thị trường đáng kể, trong khi cơ chế thời gian nguội ngăn chặn giao dịch quá mức.
Giải pháp: thực hiện thử nghiệm tối ưu hóa tham số rộng rãi, nhưng tránh tối ưu hóa quá mức; sử dụng thử nghiệm đi bộ (walk-forward testing) và thử nghiệm ngoài mẫu để xác minh sự ổn định của chiến lược.
Giải pháp: Xem xét thêm cơ chế nhận dạng trạng thái thị trường, sử dụng các tập hợp tham số khác nhau trong các môi trường thị trường khác nhau; thực hiện các giới hạn rủi ro tổng thể, chẳng hạn như tạm dừng giao dịch sau khi mất lỗ tối đa mỗi ngày hoặc thua lỗ liên tục.
*Giải pháp*Lưu ý: Thêm điểm trượt thực tế và ước tính hoa hồng vào phản hồi; Tránh giao dịch trong thời gian có tính thanh khoản thấp; Xem xét việc sử dụng bảng giá giới hạn thay vì bảng giá thị trường.
*Giải pháp*Sử dụng các công cụ debug cung cấp bởi chính sách để giám sát chặt chẽ hiệu suất của các thành phần; Giữ các chú thích mã tốt; Xem xét hiệu quả độc lập của các thành phần thử nghiệm mô-đun.
Giải pháp: thiết lập thời gian nguội thích hợp và thời gian nắm giữ tối thiểu; xem xét nghiêm ngặt chi phí giao dịch trong đánh giá lại; thường xuyên xem xét và tối ưu hóa tiêu chuẩn nhập cảnh.
Tăng cường học máyTiến hành các thuật toán tối ưu hóa tham số tự thích ứng, chẳng hạn như Bayesian Optimization hoặc thuật toán di truyền, tự động tìm ra sự kết hợp tham số tốt nhất cho các môi trường thị trường khác nhau. Điều này sẽ giảm nhu cầu tối ưu hóa bằng tay và cải thiện khả năng thích ứng của chiến lược với sự thay đổi của thị trường.
Phân loại môi trường thị trườngPhát triển hệ thống phân loại tình trạng thị trường (( xu hướng, chấn động, biến động cao, biến động thấp, v.v.) và cấu hình tham số tối ưu cho từng tình trạng. Phương pháp này có thể điều chỉnh hành vi chiến lược nhanh hơn khi thị trường chuyển đổi và giảm sự chậm trễ thích ứng.
Tăng cường quản lý vị tríGhi chú: Tiến hành các thuật toán quản lý vị thế phức tạp hơn, chẳng hạn như điều chỉnh vị thế động dựa trên quy tắc Kelly hoặc cường độ động. Điều này có thể tối ưu hóa việc sử dụng vốn, tăng tiếp xúc khi có tín hiệu mạnh và giảm rủi ro khi có tín hiệu yếu.
Thống nhất các chỉ số thay thế: Kiểm tra tính hiệu quả của các chỉ số kỹ thuật khác, chẳng hạn như Bollinger Bands, MACD hoặc Ichimoku Cloud Graph, để bổ sung hoặc thay thế cho hệ thống hiện có. Các chỉ số khác nhau có thể cung cấp tín hiệu chính xác hơn trong điều kiện thị trường cụ thể.
Kết hợp dữ liệu cảm xúcXem xét việc đưa vào các chỉ số tâm trạng thị trường, chẳng hạn như chỉ số biến động VIX hoặc dữ liệu thị trường quyền chọn, để xác định trước sự chuyển đổi tiềm năng của thị trường. Những nguồn dữ liệu bên ngoài này có thể cung cấp thông tin mà các chỉ số kỹ thuật truyền thống không thể nắm bắt được.
Phân tích liên kết đa tài sản: Phát triển phân tích liên quan giữa các loại tài sản, sử dụng tín hiệu của một thị trường để xác nhận hoặc tăng cường quyết định giao dịch của một thị trường liên quan khác. Ví dụ: sử dụng biến động giá hàng hóa để xác nhận xu hướng của các ngành chứng khoán liên quan.
Tối ưu hóa hiệu quả tính toán: Tái cấu trúc mã để tăng hiệu quả tính toán, đặc biệt là đối với các chiến lược tần số cao. Điều này bao gồm tối ưu hóa tính toán ATR, thứ tự đánh giá điều kiện và giảm tính toán lặp đi lặp lại không cần thiết.
Hệ thống giao dịch theo dõi xu hướng đa chỉ số với tỷ lệ biến động tự điều chỉnh đại diện cho một phương pháp giao dịch định lượng toàn diện và linh hoạt, đáp ứng hiệu quả với các môi trường thị trường khác nhau thông qua điều chỉnh tham số động và cơ chế lọc nhiều lớp. Ưu điểm cốt lõi của chiến lược là khả năng tự điều chỉnh và khung quản lý rủi ro tổng hợp, đặc biệt phù hợp với thị trường tương lai có tính biến động cao.
Chiến lược này tích hợp một số công cụ phân tích kỹ thuật cổ điển ((Moving Average, RSI, Bollinger Bands)) cùng với các yếu tố giao dịch định lượng hiện đại ((Custom Parameters, Multi-Time Cycle Analysis, DCA), tạo thành một hệ thống cân bằng. Bằng cách kiểm soát chính xác thời gian nhập cảnh, tối ưu hóa chiến lược nhập cảnh nhiều lần và động điều chỉnh mức dừng lỗ, chiến lược này có thể tận dụng tối đa các cơ hội xu hướng thị trường trong khi bảo vệ vốn.
Tuy nhiên, sự phức tạp của chiến lược cũng mang lại những thách thức về tính nhạy cảm của tham số và bảo trì hệ thống. Trước khi thực hiện chiến lược, nhà đầu tư nên thực hiện đầy đủ phản hồi và thử nghiệm về phía trước và sẵn sàng điều chỉnh tham số theo sự thay đổi của thị trường.
Nhìn chung, chiến lược này cung cấp một khung giao dịch định lượng vững chắc, phù hợp với các nhà giao dịch có kinh nghiệm, được tùy chỉnh theo nhu cầu và sở thích rủi ro cụ thể, tìm kiếm lợi thế giao dịch nhất quán trong thị trường tài chính thay đổi nhanh chóng ngày nay.
/*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)