NQ_Phantom_Scalper_Pro.pine
Copy
//@version=6
strategy("NQ Phantom Scalper Pro", overlay=true, default_qty_type=strategy.percent_of_equity, default_qty_value=10)
// === VWAP and Band Settings ===
anchor = input.string("Session", "Anchor Period", options=["Session", "Week", "Month", "Quarter", "Year"], group="VWAP")
src = input(hlc3, "Source", group="VWAP")
bandMult1 = input.float(1.0, "Band #1 Mult", minval=0.1, group="VWAP")
bandMult2 = input.float(2.0, "Band #2 Mult", minval=0.1, group="VWAP")
// === Volume Settings ===
volLookback = input.int(20, "Volume SMA Period", group="Volume")
volumeMultiplier = input.float(1.5, "Volume Spike Multiplier", group="Volume")
useVolumeFilter = input.bool(true, "Enable Volume Filter", group="Volume")
// === ATR Stop Loss Settings ===
atrLength = input.int(14, "ATR Length", group="Risk Management")
atrStopMult = input.float(1.0, "Stop Loss ATR Multiplier", group="Risk Management")
targetRatio = input.float(0.5, "Target Ratio (% to opposite band)", minval=0.1, maxval=1.0, group="Risk Management")
// === Time Filter ===
useTimeFilter = input.bool(true, "Enable Time Filter", group="Time Filter")
startHour = input.int(9, "Start Hour (12hr format)", minval=1, maxval=12, group="Time Filter")
startAMPM = input.string("AM", "Start AM/PM", options=["AM", "PM"], group="Time Filter")
endHour = input.int(4, "End Hour (12hr format)", minval=1, maxval=12, group="Time Filter")
endAMPM = input.string("PM", "End AM/PM", options=["AM", "PM"], group="Time Filter")
avoidLunch = input.bool(true, "Avoid Lunch Hours (12-2 PM)", group="Time Filter")
// === Trend Filter ===
useTrendFilter = input.bool(false, "Enable Trend Filter", group="Trend Filter")
trendLength = input.int(50, "Trend EMA Length", group="Trend Filter")
// === Dashboard Settings ===
showDashboard = input.bool(true, "Show Enhanced Dashboard", group="Dashboard")
dashboardPosition = input.string("Top Right", "Dashboard Position", options=["Top Left", "Top Right", "Bottom Left", "Bottom Right"], group="Dashboard")
dashboardSize = input.string("Normal", "Dashboard Size", options=["Small", "Normal", "Large"], group="Dashboard")
// === VWAP Anchor Logic ===
isNewPeriod = switch anchor
"Session" => timeframe.change("D")
"Week" => timeframe.change("W")
"Month" => timeframe.change("M")
"Quarter" => timeframe.change("3M")
"Year" => timeframe.change("12M")
=> false
// === VWAP + Band Calculations ===
[vwapVal, stdUp, _] = ta.vwap(src, isNewPeriod, 1)
stdev = stdUp - vwapVal
upper1 = vwapVal + stdev * bandMult1
lower1 = vwapVal - stdev * bandMult1
upper2 = vwapVal + stdev * bandMult2
lower2 = vwapVal - stdev * bandMult2
// === Volume Analysis ===
volSMA = ta.sma(volume, volLookback)
volSpike = volume > volSMA * volumeMultiplier
relativeVolume = volume / volSMA
// === ATR Calculation ===
atr = ta.atr(atrLength)
// === Time Filter ===
currentHour = hour(time, "America/New_York")
// Convert 12-hour format to 24-hour format
start24Hour = startAMPM == "AM" ? (startHour == 12 ? 0 : startHour) : (startHour == 12 ? 12 : startHour + 12)
end24Hour = endAMPM == "AM" ? (endHour == 12 ? 0 : endHour) : (endHour == 12 ? 12 : endHour + 12)
// Check if current time is within trading hours
timeInRange = currentHour >= start24Hour and currentHour <= end24Hour
// Check if it's lunch time (12 PM - 2 PM)
isLunchTime = avoidLunch and currentHour >= 12 and currentHour < 14
// Final time condition
timeOK = not useTimeFilter or (timeInRange and not isLunchTime)
// === Trend Filter ===
trendEMA = ta.ema(close, trendLength)
bullishTrend = close > trendEMA
bearishTrend = close < trendEMA
// === Performance Tracking Variables ===
var int totalTrades = 0
var int winTrades = 0
var int lossTrades = 0
var float dailyPnL = 0.0
var float maxDrawdown = 0.0
var float peakEquity = 0.0
var float totalPnL = 0.0
var int longTrades = 0
var int shortTrades = 0
var int longWins = 0
var int shortWins = 0
var float avgWin = 0.0
var float avgLoss = 0.0
var float totalWinAmount = 0.0
var float totalLossAmount = 0.0
var float largestWin = 0.0
var float largestLoss = 0.0
// Reset daily P&L at new day
if timeframe.change("D")
dailyPnL := 0.0
// Track performance metrics
if strategy.closedtrades > totalTrades
newTradeProfit = strategy.closedtrades.profit(strategy.closedtrades - 1)
newTradeSize = strategy.closedtrades.size(strategy.closedtrades - 1)
totalTrades := strategy.closedtrades
totalPnL += newTradeProfit
dailyPnL += newTradeProfit
// Track wins vs losses
if newTradeProfit > 0
winTrades += 1
totalWinAmount += newTradeProfit
largestWin := math.max(largestWin, newTradeProfit)
if newTradeSize > 0
longWins += 1
else
shortWins += 1
else if newTradeProfit < 0
lossTrades += 1
totalLossAmount += math.abs(newTradeProfit)
largestLoss := math.max(largestLoss, math.abs(newTradeProfit))
// Track long vs short
if newTradeSize > 0
longTrades += 1
else
shortTrades += 1
// Calculate average win/loss
avgWin := winTrades > 0 ? totalWinAmount / winTrades : 0
avgLoss := lossTrades > 0 ? totalLossAmount / lossTrades : 0
// Track drawdown
currentEquity = strategy.initial_capital + strategy.netprofit
peakEquity := math.max(peakEquity, currentEquity)
currentDrawdown = peakEquity > 0 ? (peakEquity - currentEquity) / peakEquity * 100 : 0
maxDrawdown := math.max(maxDrawdown, currentDrawdown)
// === Enhanced Entry Conditions ===
// Long conditions
longVWAPCondition = close <= lower1
longVolumeCondition = not useVolumeFilter or volSpike
longTrendCondition = not useTrendFilter or bullishTrend
longCondition = longVWAPCondition and longVolumeCondition and longTrendCondition and timeOK and strategy.opentrades == 0
// Short conditions
shortVWAPCondition = close >= upper1
shortVolumeCondition = not useVolumeFilter or volSpike
shortTrendCondition = not useTrendFilter or bearishTrend
shortCondition = shortVWAPCondition and shortVolumeCondition and shortTrendCondition and timeOK and strategy.opentrades == 0
// === Position Management ===
var float longEntryPrice = na
var float shortEntryPrice = na
if (longCondition)
longEntryPrice := close
longTarget = longEntryPrice + (upper2 - longEntryPrice) * targetRatio
longStop = longEntryPrice - atr * atrStopMult
strategy.entry("Long", strategy.long)
strategy.exit("TP/SL Long", from_entry="Long", limit=longTarget, stop=longStop)
if (shortCondition)
shortEntryPrice := close
shortTarget = shortEntryPrice - (shortEntryPrice - lower2) * targetRatio
shortStop = shortEntryPrice + atr * atrStopMult
strategy.entry("Short", strategy.short)
strategy.exit("TP/SL Short", from_entry="Short", limit=shortTarget, stop=shortStop)
// === VWAP Mean Reversion Exit (Optional) ===
// Close long if price reaches VWAP
if (strategy.position_size > 0 and close >= vwapVal)
strategy.close("Long", comment="VWAP Exit")
// Close short if price reaches VWAP
if (strategy.position_size < 0 and close <= vwapVal)
strategy.close("Short", comment="VWAP Exit")
// === Plots ===
plot(vwapVal, "VWAP", color=color.blue, linewidth=2)
plot(upper1, "Upper Band 1", color=color.green, linewidth=1)
plot(lower1, "Lower Band 1", color=color.green, linewidth=1)
plot(upper2, "Upper Band 2", color=color.red, linewidth=1)
plot(lower2, "Lower Band 2", color=color.red, linewidth=1)
// Trend EMA plot (if enabled)
plot(useTrendFilter ? trendEMA : na, "Trend EMA", color=color.orange, linewidth=1)
// Background color for time filter
lunchColor = isLunchTime ? color.new(color.yellow, 85) : na
afterHoursColor = not timeInRange ? color.new(color.gray, 90) : na
bgcolor(useTimeFilter ? (not na(lunchColor) ? lunchColor : afterHoursColor) : na, title="Time Filter")
// === Enhanced Dashboard ===
if barstate.islast and showDashboard
// Calculate metrics
winRate = totalTrades > 0 ? winTrades / totalTrades * 100 : 0
profitFactor = totalLossAmount > 0 ? totalWinAmount / totalLossAmount : 0
expectancy = totalTrades > 0 ? totalPnL / totalTrades : 0
longWinRate = longTrades > 0 ? longWins / longTrades * 100 : 0
shortWinRate = shortTrades > 0 ? shortWins / shortTrades * 100 : 0
// Dashboard position
tablePosition = switch dashboardPosition
"Top Left" => position.top_left
"Top Right" => position.top_right
"Bottom Left" => position.bottom_left
"Bottom Right" => position.bottom_right
=> position.top_right
// Dashboard size
tableSize = switch dashboardSize
"Small" => size.small
"Normal" => size.normal
"Large" => size.large
=> size.normal
var table dashboardTable = table.new(tablePosition, 3, 16, bgcolor=color.new(color.white, 10), border_width=2, border_color=color.gray)
// Header
table.cell(dashboardTable, 0, 0, "๐ NQ PHANTOM SCALPER PRO", text_color=color.white, bgcolor=color.new(color.blue, 20), text_size=tableSize)
table.cell(dashboardTable, 1, 0, "", bgcolor=color.new(color.blue, 20))
table.cell(dashboardTable, 2, 0, "", bgcolor=color.new(color.blue, 20))
table.merge_cells(dashboardTable, 0, 0, 2, 0)
// Market Info
table.cell(dashboardTable, 0, 1, "๐ฏ MARKET INFO", text_color=color.white, bgcolor=color.new(color.purple, 30), text_size=tableSize)
table.cell(dashboardTable, 1, 1, "", bgcolor=color.new(color.purple, 30))
table.cell(dashboardTable, 2, 1, "", bgcolor=color.new(color.purple, 30))
table.merge_cells(dashboardTable, 0, 1, 2, 1)
table.cell(dashboardTable, 0, 2, "VWAP", text_color=color.black, text_size=tableSize)
table.cell(dashboardTable, 1, 2, str.tostring(vwapVal, "#.##"), text_color=color.blue, text_size=tableSize)
table.cell(dashboardTable, 2, 2, close > vwapVal ? "๐" : "๐", text_size=tableSize)
table.cell(dashboardTable, 0, 3, "Current Price", text_color=color.black, text_size=tableSize)
table.cell(dashboardTable, 1, 3, str.tostring(close, "#.##"), text_color=color.black, text_size=tableSize)
table.cell(dashboardTable, 2, 3, "๐ฐ", text_size=tableSize)
table.cell(dashboardTable, 0, 4, "Rel. Volume", text_color=color.black, text_size=tableSize)
table.cell(dashboardTable, 1, 4, str.tostring(relativeVolume, "#.##") + "x", text_color=relativeVolume > volumeMultiplier ? color.green : color.orange, text_size=tableSize)
table.cell(dashboardTable, 2, 4, volSpike ? "๐ฅ" : "๐", text_size=tableSize)
table.cell(dashboardTable, 0, 5, "ATR", text_color=color.black, text_size=tableSize)
table.cell(dashboardTable, 1, 5, str.tostring(atr, "#.##"), text_color=color.black, text_size=tableSize)
table.cell(dashboardTable, 2, 5, "๐", text_size=tableSize)
// Performance Metrics
table.cell(dashboardTable, 0, 6, "๐ PERFORMANCE", text_color=color.white, bgcolor=color.new(color.green, 30), text_size=tableSize)
table.cell(dashboardTable, 1, 6, "", bgcolor=color.new(color.green, 30))
table.cell(dashboardTable, 2, 6, "", bgcolor=color.new(color.green, 30))
table.merge_cells(dashboardTable, 0, 6, 2, 6)
table.cell(dashboardTable, 0, 7, "Win Rate", text_color=color.black, text_size=tableSize)
table.cell(dashboardTable, 1, 7, str.tostring(winRate, "#.#") + "%", text_color=winRate >= 50 ? color.green : color.red, text_size=tableSize)
table.cell(dashboardTable, 2, 7, winRate >= 60 ? "๐ฏ" : winRate >= 50 ? "โ
" : "โ", text_size=tableSize)
table.cell(dashboardTable, 0, 8, "Total Trades", text_color=color.black, text_size=tableSize)
table.cell(dashboardTable, 1, 8, str.tostring(totalTrades), text_color=color.black, text_size=tableSize)
table.cell(dashboardTable, 2, 8, "๐ข", text_size=tableSize)
table.cell(dashboardTable, 0, 9, "Daily P&L", text_color=color.black, text_size=tableSize)
table.cell(dashboardTable, 1, 9, "$" + str.tostring(dailyPnL, "#.##"), text_color=dailyPnL > 0 ? color.green : dailyPnL < 0 ? color.red : color.gray, text_size=tableSize)
table.cell(dashboardTable, 2, 9, dailyPnL > 0 ? "๐" : dailyPnL < 0 ? "โค๏ธ" : "๐", text_size=tableSize)
table.cell(dashboardTable, 0, 10, "Total P&L", text_color=color.black, text_size=tableSize)
table.cell(dashboardTable, 1, 10, "$" + str.tostring(totalPnL, "#.##"), text_color=totalPnL > 0 ? color.green : totalPnL < 0 ? color.red : color.gray, text_size=tableSize)
table.cell(dashboardTable, 2, 10, totalPnL > 0 ? "๐" : totalPnL < 0 ? "๐ฅ" : "โ๏ธ", text_size=tableSize)
table.cell(dashboardTable, 0, 11, "Profit Factor", text_color=color.black, text_size=tableSize)
table.cell(dashboardTable, 1, 11, str.tostring(profitFactor, "#.##"), text_color=profitFactor > 1 ? color.green : color.red, text_size=tableSize)
table.cell(dashboardTable, 2, 11, profitFactor > 1.5 ? "โญ" : profitFactor > 1 ? "โ
" : "โ ๏ธ", text_size=tableSize)
table.cell(dashboardTable, 0, 12, "Max Drawdown", text_color=color.black, text_size=tableSize)
table.cell(dashboardTable, 1, 12, str.tostring(maxDrawdown, "#.#") + "%", text_color=maxDrawdown > 10 ? color.red : maxDrawdown > 5 ? color.orange : color.green, text_size=tableSize)
table.cell(dashboardTable, 2, 12, maxDrawdown > 15 ? "๐จ" : maxDrawdown > 10 ? "โ ๏ธ" : "โ
", text_size=tableSize)
// Trade Breakdown
table.cell(dashboardTable, 0, 13, "๐ TRADE BREAKDOWN", text_color=color.white, bgcolor=color.new(color.orange, 30), text_size=tableSize)
table.cell(dashboardTable, 1, 13, "", bgcolor=color.new(color.orange, 30))
table.cell(dashboardTable, 2, 13, "", bgcolor=color.new(color.orange, 30))
table.merge_cells(dashboardTable, 0, 13, 2, 13)
table.cell(dashboardTable, 0, 14, "Long Win Rate", text_color=color.black, text_size=tableSize)
table.cell(dashboardTable, 1, 14, str.tostring(longWinRate, "#.#") + "% (" + str.tostring(longTrades) + ")", text_color=longWinRate >= 50 ? color.green : color.red, text_size=tableSize)
table.cell(dashboardTable, 2, 14, "๐", text_size=tableSize)
table.cell(dashboardTable, 0, 15, "Short Win Rate", text_color=color.black, text_size=tableSize)
table.cell(dashboardTable, 1, 15, str.tostring(shortWinRate, "#.#") + "% (" + str.tostring(shortTrades) + ")", text_color=shortWinRate >= 50 ? color.green : color.red, text_size=tableSize)
table.cell(dashboardTable, 2, 15, "๐", text_size=tableSize)
Show all 296 lines