Pine Script NQ Futures Strategy for Prop Firms
NQ and MNQ move fast enough to hit a profit target without overtrading — and fast enough to end an evaluation just as quickly if the script isn't built around that volatility. Here's how to run one that survives it.
NQ vs. MNQ: which one to run on an evaluation
The full-size NQ contract moves $20 × price per point; the micro MNQ moves $2 × price — a tenth of the size for identical price action. For an evaluation, MNQ is almost always the right call: same signal, same entry and exit logic, a fraction of the dollar risk.
| Contract | Tick value | Per-point move | Typical daily range |
|---|---|---|---|
| NQ | $5.00 | $20 × price | 200–400 pts |
| MNQ | $0.50 | $2 × price | 200–400 pts |
On a 50k Apex evaluation with a $2,500 trail, a 100-point adverse move on 1 MNQ costs about $200 — manageable. The same 100 points on 1 NQ costs roughly $2,000, most of the trail on a single trade.
Why NQ is harder than ES on an evaluation
ES moves slower and more predictably. NQ is tech-heavy and reacts violently to macro events — Fed commentary, earnings surprises, and CPI prints can push it well over a hundred points in seconds. On a trailing-drawdown account, that's account-ending territory if the position is on the wrong side.
- Wider average true range: NQ's ATR on a 5-minute chart typically runs 8–15 points — a stop needs to account for that without becoming too wide for sound position sizing
- Gap risk: NQ gaps harder at the open than ES; any overnight exposure on an evaluation account is a real liability
- Session sensitivity: NQ front-runs the cash open by 15–30 minutes — the pre-market window often produces the day's best move, but it's also the most dangerous to fade
Script rules that matter specifically for NQ
1. A hard session filter
NQ after noon ET tends toward low-volume chop. A script trading all day will accumulate afternoon losers that eat into the trail. Restricting to the first 90 minutes of RTH (9:30–11:00 AM ET), with an optional look at the power hour (3:00–3:30 PM), keeps activity in the highest-quality window.
2. An ATR-based stop, not a fixed tick count
Because NQ's volatility swings day to day, a fixed 20-tick stop gets clipped constantly on high-volatility days.
ta.atr(14) multiplied by a factor (typically 0.5–1.0) keeps risk proportional to the day's actual
range instead.
3. A news blackout
Hard-code a blackout window around major releases — at minimum 8:30 AM ET (CPI, NFP, jobless claims) and 2:00 PM ET (FOMC). The alert fires into TradersPost, which flattens any open position before the print and holds off re-entry for roughly 15 minutes.
4. A max daily loss kill switch
Track a running daily loss counter. Once realized-plus-unrealized loss on the day reaches around 40% of the trailing drawdown limit, the strategy stops opening new positions for the rest of the session — non-negotiable on NQ, where a single bad morning trend can otherwise take the whole trail with it.
Sizing MNQ contracts to the evaluation
A workable formula: take roughly a third of the trailing drawdown as a maximum single-day loss budget, divide by the average losing trade in dollars, and that's a rough per-trade contract ceiling.
Worked example on a 50k Apex evaluation ($2,500 trail):
- Daily loss budget: roughly $833
- Average losing trade on 1 MNQ with a 30-tick stop: about $15
- That budget covers well over 50 losing trades in theory — but that's a ceiling, not a target
- In practice: start with 1–3 MNQ contracts, prove the strategy over 5 sessions, then scale from there
VWAP reclaim: the cleanest NQ setup for evaluations
The most reliable NQ eval setup is a VWAP reclaim: price dips below VWAP in the first 30 minutes, then closes
back above it with volume confirmation. In Pine Script that's close[1] < vwap[1],
close > vwap, and barstate.isconfirmed. The long entry fires on the next bar's open,
with a stop below the reclaim candle's low and a target around 1.5–2x the risk. See our
full VWAP strategy guide for the complete build.
Complete MNQ strategy — Pine Script
An original VWAP-reclaim-plus-kill-switch strategy for a 1- or 3-minute MNQ chart, configured for a 50k Apex evaluation ($2,500 trail, kill switch at $1,000).
//@version=5
strategy("MNQ Prop Firm — VWAP Reclaim", overlay = true,
default_qty_type = strategy.fixed, default_qty_value = 1)
// ── inputs ───────────────────────────────────────────────────────────
dailyLossLimit = input.float(1000.0, "Daily Loss Limit ($)")
atrMult = input.float(0.75, "ATR Stop Multiplier")
rrRatio = input.float(1.5, "Reward:Risk Ratio")
// ── session: RTH only, 9:30–11:00 ET ────────────────────────────────
inSession = not na(time("1", "0930-1100:23456", "America/New_York"))
// ── news blackout: 8:25–9:00 and 13:55–14:30 ET ─────────────────────
newsBlackout = not na(time("1", "0825-0900:23456", "America/New_York")) or
not na(time("1", "1355-1430:23456", "America/New_York"))
// ── daily loss kill switch ───────────────────────────────────────────
isNewSession = ta.change(time("D")) != 0
var float dayOpenEq = na
dayOpenEq := isNewSession ? strategy.equity : dayOpenEq
halted = math.min(0.0, strategy.equity - nz(dayOpenEq, strategy.equity)) <= -dailyLossLimit
// ── VWAP reclaim signal ──────────────────────────────────────────────
vwapVal = ta.vwap(hlc3)
atrVal = ta.atr(14)
volFilter = volume > ta.sma(volume, 20)
longSig = close[1] < vwapVal[1] and close > vwapVal and barstate.isconfirmed and volFilter
shortSig = close[1] > vwapVal[1] and close < vwapVal and barstate.isconfirmed and volFilter
canTrade = inSession and not halted and not newsBlackout and strategy.position_size == 0
if longSig and canTrade
stopDist = atrMult * atrVal
strategy.entry("L", strategy.long)
strategy.exit("L-x", "L", profit = stopDist * rrRatio / syminfo.mintick,
loss = stopDist / syminfo.mintick)
if shortSig and canTrade
stopDist = atrMult * atrVal
strategy.entry("S", strategy.short)
strategy.exit("S-x", "S", profit = stopDist * rrRatio / syminfo.mintick,
loss = stopDist / syminfo.mintick)
// ── EOD flatten ──────────────────────────────────────────────────────
eodFlat = not na(time("1", "1529-1531:23456", "America/New_York"))
fridayFlat = dayofweek == dayofweek.friday and not na(time("1", "1459-1501:6", "America/New_York"))
if (eodFlat or fridayFlat) and strategy.position_size != 0
strategy.close_all("EOD") Backtesting NQ strategies against evaluation rules
Add these constraints to any TradingView backtest before trusting the result:
- Track a rolling equity peak and flag any bar where drawdown from that peak exceeds the eval limit
- Count distinct trading days — bars where at least one trade fired — to confirm the strategy clears minimums
- Apply the session filter to the backtest itself, not just live trading
A strategy that looks strong on a full-session backtest can still fail an evaluation because it churns through the afternoon chop. Filter to RTH and the intended session window before evaluating any result.