Strategy ยท Pine Script v6 ยท On the chart

NQ Phantom Scalper Pro

by rosijay17-cmd

A strategy that trades around an anchored VWAP with standard-deviation bands.

View on GitHub

GitHub stars1on the repository
Pine versionv6current
Lines of code296
Settings21inputs
LicenceGPL-3.0
Last update7 days ago22 Oct 2026

Add It to Your TradingView Chart

  1. 1Copy the scriptPress Copy script above, or the copy button on the code below.
  2. 2Open the Pine EditorOpen a TradingView chart and choose Pine Editor at the bottom of the screen.
  3. 3Paste over the templateCreate a new strategy, select all of the template text and paste. Press Save and give it a name.
  4. 4Add it to the chartPress Add to chart. The trades and results appear in the Strategy Tester tab; adjust the settings with the gear icon.

Source Code

296 lines of Pine Script v6 from NQ_Phantom_Scalper_Pro.pine, published under GPL-3.0. Keep the author's credit and licence lines when you reuse it.

NQ_Phantom_Scalper_Pro.pine
//@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)

Overview

The VWAP can reset each session, week, month, quarter or year, with two adjustable band multipliers. A volume spike filter, a time-of-day filter with an optional lunch-hour exclusion, and an optional trend EMA filter gate entries. Stops are set from an ATR multiple and the target is a chosen fraction of the distance to the opposite band. Position size is a percentage of equity. A dashboard table can be shown, and everything draws on the price chart.

Details

Published by

rosijay17-cmd on GitHub

Type

Strategy, Pine Script v6

Draws

On the price chart

Category

Mean reversion, Volume, Scalping

Markets

Indices

Timeframes

M1-M5

Risk Notes

No repainting, lookahead or stacked entries were found in its code or README. That says nothing about how well it works: test it first.

Settings

The inputs you can change from the gear icon on the chart. Defaults are the author's.

SettingTypeDefaultVariable
Anchor PeriodstringSessionanchor
Sourcesourcehlc3src
Band #1 Multfloat1.0bandMult1
Band #2 Multfloat2.0bandMult2
Volume SMA Periodint20volLookback
Volume Spike Multiplierfloat1.5volumeMultiplier
Enable Volume FilterbooltrueuseVolumeFilter
ATR Lengthint14atrLength
Stop Loss ATR Multiplierfloat1.0atrStopMult
Target Ratio (% to opposite band)float0.5targetRatio
Enable Time FilterbooltrueuseTimeFilter
Start Hour (12hr format)int9startHour
Show all 21 settings
SettingTypeDefaultVariable
Start AM/PMstringAMstartAMPM
End Hour (12hr format)int4endHour
End AM/PMstringPMendAMPM
Avoid Lunch Hours (12-2 PM)booltrueavoidLunch
Enable Trend FilterboolfalseuseTrendFilter
Trend EMA Lengthint50trendLength
Show Enhanced DashboardbooltrueshowDashboard
Dashboard PositionstringTop RightdashboardPosition
Dashboard SizestringNormaldashboardSize
Third-party code. ForexR did not write, test or endorse this script, and the summary above was generated automatically from its code and README. Indicators describe the past, and a strategy's backtest can look better than live trading, especially when a script repaints. Check it in the Strategy Tester and on a demo account before you rely on it.

Similar Pine Scripts

This strategy plots Bollinger Bands on the price chart using an EMA or SMA basis and a matching standard-deviation calculation. It enters long when price crosses back above the lower band and short when price crosses back below the upper band. An optional Intr

Strategy v4 Volatility & bandsMoving averages
Updated 2 years ago ยท GPL-3.0 GitHub repository of Bollinger Bands Strategy with Intraday Intensity Index

Ruckard Scalping 03

by ruckard
13 stars

This strategy trades both long and short on the price chart. It enters long after a five percent or larger drop over the last thirty minutes and short after a matching rise. Two dollar-cost-averaging adds increase size when price moves against the position. A

Strategy v4 ScalpingMean reversion
Updated 1 year ago ยท None stated GitHub repository of Ruckard Scalping 03
12 stars

This is a Pine Script strategy that executes a fixed historical backtest on BTC-USD. It places multiple manual trades using strategy.order at specific timestamps and prices, with corresponding close conditions based on time. Some trades are long and some are s

Strategy v4 Mean reversionScalping
Updated 5 years ago ยท None stated GitHub repository of Lazarus3 BTC Backtest

Enhanced DCA Strategy

by SynergOps
7 stars

The Enhanced DCA Strategy invests a fixed dollar amount at regular intervals (daily, weekly or monthly) into the asset after start date, deducting trading fees and tracking total invested, units acquired, current value, profit, ROI, Sharpe ratio, Sortino ratio

Strategy v6 ScalpingMean reversion Repaints
Updated 1 year ago ยท MPL-2.0 GitHub repository of Enhanced DCA Strategy
7 stars

Calculates volume profile levels over a lookback window to identify support, resistance, and Point of Control (POC) lines on the price chart. It executes trades based on price interaction with these low-volume zones, featuring customizable signal inversion and

Strategy v6 ScalpingVolume
Updated 1 year ago ยท None stated GitHub repository of Enhanced NQ1 Scalping Strategy

More strategys

Trade Your Charts With a Regulated Broker

Compare brokers that connect to TradingView, with spreads, minimum deposits and leverage side by side.

Compare brokers