Page 1 of 2

Weighted Moving Average (WMA) Explained + Custom Pine Script for ScalpersHey everyone, When trading lower timeframes, e

Posted: Fri Sep 04, 2026 10:36 am
by PTStockScalper
Hey everyone,

When trading lower timeframes, every tick matters and indicator lag is the enemy of a sharp entry. While many traders default to the Simple Moving Average (SMA) or Exponential Moving Average (EMA), the Weighted Moving Average (WMA) often gets overlooked—despite being arguably better suited for fast-paced price action.

Here is a breakdown of why it works well for scalping, along with a clean, color-coded Pine Script you can drop straight into TradingView.

What is the WMA?

Unlike an SMA that treats all data points in the lookback period equally, the WMA applies a linearly decreasing weight to older data. If you are looking at a 10-period WMA, the most recent closing price has a weight of 10, the previous period a weight of 9, and so on.

Why it matters for scalping:

Because it heavily prioritizes recent data, the WMA hugs price action much closer than an SMA. It is also inherently smoother than an EMA, meaning it responds rapidly to recent momentum shifts without overshooting quite as wildly during sudden volume spikes. This translates to faster crossover signals and earlier visual cues for exits.

The Pine Script (v5)

Here is a lightweight script for a responsive WMA. I've added a color-coded slope feature (green for rising, red for falling) so you can read the trend direction out of the corner of your eye without having to squint at the slope angle.

Re: Weighted Moving Average (WMA) Explained + Custom Pine Script for ScalpersHey everyone, When trading lower timeframe

Posted: Fri Sep 04, 2026 10:37 am
by PTStockScalper

Code: Select all

//@version=5
indicator("Color-Coded WMA for Scalping", overlay=true, timeframe="")

// --- Inputs ---
wma_length = input.int(14, title="WMA Length", minval=1)
src = input.source(close, title="Source")

// --- Calculation ---
wma_val = ta.wma(src, wma_length)

// --- Color Logic ---
// Green if sloping up, Red if sloping down, Gray if flat
wma_color = wma_val > wma_val[1] ? color.new(#26a69a, 0) : 
            wma_val < wma_val[1] ? color.new(#ef5350, 0) : 
            color.new(color.gray, 0)

// --- Plotting ---
plot(wma_val, title="WMA", color=wma_color, linewidth=2)

Re: Weighted Moving Average (WMA) Explained + Custom Pine Script for ScalpersHey everyone, When trading lower timeframe

Posted: Fri Sep 04, 2026 10:37 am
by PTStockScalper
How to Trade With It

Dynamic Trend Filter: Apply a higher period (e.g., 50 or 100) on your 1m or 5m chart. The color coding makes it a strict directional filter—only look for long entries when the line is green, and shorts when it is red.

Fast Crossovers: Pair a fast WMA (like a 7-period) with a slower one (21-period). Because WMAs shed lag faster than standard moving averages, your crossover entries will frequently trigger a candle or two earlier than they would with an EMA setup.

Are any of you currently running WMAs in your active sessions, or do you stick strictly to EMAs? Let me know below. If there is interest, I can update the script to include crossover alerts or Multi-Timeframe (MTF) support.

Happy trading!

Re: Weighted Moving Average (WMA) Explained + Custom Pine Script for ScalpersHey everyone, When trading lower timeframe

Posted: Fri Sep 04, 2026 10:38 am
by PTStockScalper
Here is the updated version of the script, tailored for you. I have added the secondary slow WMA, visual markers for the chart, and the alertcondition() functions so traders can easily hook it up to their TradingView alerts or automated webhooks.

You can frame this in your post as an evolution of the basic indicator into a fully actionable strategy signal.

The Updated Pine Script (v5)

Code: Select all

//@version=5
indicator("Dual WMA Crossover + Alerts", overlay=true, timeframe="")

// --- Inputs ---
fast_length = input.int(7, title="Fast WMA Length", minval=1)
slow_length = input.int(21, title="Slow WMA Length", minval=1)
src = input.source(close, title="Source")

// --- Calculations ---
fast_wma = ta.wma(src, fast_length)
slow_wma = ta.wma(src, slow_length)

// --- Crossover Logic ---
bull_cross = ta.crossover(fast_wma, slow_wma)
bear_cross = ta.crossunder(fast_wma, slow_wma)

// --- Color Logic (Fast WMA Slope) ---
// Keeps the momentum color-coding on the fast line
fast_color = fast_wma > fast_wma[1] ? color.new(#26a69a, 0) : 
             fast_wma < fast_wma[1] ? color.new(#ef5350, 0) : 
             color.new(color.gray, 0)

// --- Plotting ---
plot(fast_wma, title="Fast WMA", color=fast_color, linewidth=2)
plot(slow_wma, title="Slow WMA", color=color.new(color.white, 50), linewidth=2)

// --- Visual Markers ---
plotshape(bull_cross, title="Bullish Cross Marker", style=shape.triangleup, location=location.belowbar, color=color.new(#26a69a, 0), size=size.small)
plotshape(bear_cross, title="Bearish Cross Marker", style=shape.triangledown, location=location.abovebar, color=color.new(#ef5350, 0), size=size.small)

// --- Alerts ---
alertcondition(bull_cross, title="Bullish WMA Crossover", message="LONG ALERT: Fast WMA crossed ABOVE Slow WMA.")
alertcondition(bear_cross, title="Bearish WMA Crossover", message="SHORT ALERT: Fast WMA crossed BELOW Slow WMA.")

Re: Weighted Moving Average (WMA) Explained + Custom Pine Script for ScalpersHey everyone, When trading lower timeframe

Posted: Fri Sep 04, 2026 10:39 am
by PTStockScalper
Additions what i can highlight:

Visual confirmation: The script plots up/down triangles directly on the candle where the crossover prints, making backtesting visually intuitive.

Cleaner charts: The slow WMA is plotted in a semi-transparent white, keeping the visual focus on the color-coded fast WMA to read immediate momentum.

Alert setup: Remind your users that once the script is on their chart, they just need to hit Alt + A (or click the alert icon), select this script as the condition, and choose either the Bullish or Bearish alert trigger.

Re: Weighted Moving Average (WMA) Explained + Custom Pine Script for ScalpersHey everyone, When trading lower timeframe

Posted: Fri Sep 04, 2026 10:44 am
by PTStockScalper
Adding a volume condition is one of the most effective ways to filter out low-liquidity whipsaws. For scalpers, a crossover that happens on low volume is often just algorithmic noise or a minor retail drift—you want to see institutional participation backing the move.

Here is the updated script. I added a toggle so your forum users can turn the volume filter on or off via the settings menu, and a variable to define the volume moving average length (defaulted to 20).

The Volume-Filtered Pine Script (v5)

Code: Select all

//@version=5
indicator("Dual WMA Crossover + Alerts & Volume Filter", overlay=true, timeframe="")

// --- WMA Inputs ---
fast_length = input.int(7, title="Fast WMA Length", minval=1)
slow_length = input.int(21, title="Slow WMA Length", minval=1)
src = input.source(close, title="Source")

// --- Volume Filter Inputs ---
use_vol_filter = input.bool(true, title="Enable Volume Filter")
vol_length = input.int(20, title="Volume MA Length", minval=1)

// --- Calculations ---
fast_wma = ta.wma(src, fast_length)
slow_wma = ta.wma(src, slow_length)
vol_ma = ta.sma(volume, vol_length)

// --- Logic & Conditions ---
// 1. Identify the crossovers
bull_cross = ta.crossover(fast_wma, slow_wma)
bear_cross = ta.crossunder(fast_wma, slow_wma)

// 2. Check if current volume is above the Volume SMA
vol_valid = not use_vol_filter or (volume > vol_ma)

// 3. Combine crossover and volume conditions
long_signal = bull_cross and vol_valid
short_signal = bear_cross and vol_valid

// --- Color Logic (Fast WMA Slope) ---
fast_color = fast_wma > fast_wma[1] ? color.new(#26a69a, 0) : 
             fast_wma < fast_wma[1] ? color.new(#ef5350, 0) : 
             color.new(color.gray, 0)

// --- Plotting ---
plot(fast_wma, title="Fast WMA", color=fast_color, linewidth=2)
plot(slow_wma, title="Slow WMA", color=color.new(color.white, 50), linewidth=2)

// --- Visual Markers ---
plotshape(long_signal, title="Bullish Signal", style=shape.triangleup, location=location.belowbar, color=color.new(#26a69a, 0), size=size.small)
plotshape(short_signal, title="Bearish Signal", style=shape.triangledown, location=location.abovebar, color=color.new(#ef5350, 0), size=size.small)

// --- Alerts ---
alertcondition(long_signal, title="Bullish WMA Crossover (Vol Confirmed)", message="LONG ALERT: Fast WMA crossed ABOVE Slow WMA with High Volume.")
alertcondition(short_signal, title="Bearish WMA Crossover (Vol Confirmed)", message="SHORT ALERT: Fast WMA crossed BELOW Slow WMA with High Volume.")

Re: Weighted Moving Average (WMA) Explained + Custom Pine Script for ScalpersHey everyone, When trading lower timeframe

Posted: Fri Sep 04, 2026 10:45 am
by PTStockScalper
What Changed in the Code

vol_ma = ta.sma(volume, vol_length): Calculates the Simple Moving Average of the volume.

use_vol_filter Toggle: The logic not use_vol_filter or (volume > vol_ma) ensures that if a user unchecks the box in settings, the script defaults back to taking all crossovers regardless of volume.

Signal Requirement: The visual triangle markers and the alertcondition() functions now rely on long_signal and short_signal instead of the raw crossover variables. If a crossover happens but the volume is below the 20-period SMA, the script completely ignores it.

Re: Weighted Moving Average (WMA) Explained + Custom Pine Script for ScalpersHey everyone, When trading lower timeframe

Posted: Fri Sep 04, 2026 10:47 am
by PTStockScalper
Adding an ATR (Average True Range) trailing stop turns this from a simple signal indicator into a complete trade management system. In fast-moving forex and metals markets, static pip-based stops often get hunted out by sudden spread widening or volatility spikes. An ATR stop adapts dynamically to the current market speed.

Here is the updated script, formatted as an excellent follow-up post for your community. I used Pine Script’s group function to keep the settings menu organized, and implemented a "ratcheting" logic so the stop only moves in the direction of profit.

The Complete Strategy Script (v5)

Code: Select all

//@version=5
indicator("WMA Scalping System: Signals, Vol + ATR Stop", overlay=true, timeframe="")

// --- Moving Average Inputs ---
fast_length = input.int(7, title="Fast WMA", minval=1, group="Moving Averages")
slow_length = input.int(21, title="Slow WMA", minval=1, group="Moving Averages")
src = input.source(close, title="Source", group="Moving Averages")

// --- Volume Filter Inputs ---
use_vol_filter = input.bool(true, title="Enable Volume Filter", group="Volume Filter")
vol_length = input.int(20, title="Volume MA Length", minval=1, group="Volume Filter")

// --- ATR Stop Inputs ---
atr_length = input.int(14, title="ATR Length", minval=1, group="ATR Trailing Stop")
atr_mult = input.float(1.5, title="ATR Multiplier", step=0.1, group="ATR Trailing Stop")

// --- Core Calculations ---
fast_wma = ta.wma(src, fast_length)
slow_wma = ta.wma(src, slow_length)
vol_ma = ta.sma(volume, vol_length)
atr_val = ta.atr(atr_length)

// --- Signal Logic ---
bull_cross = ta.crossover(fast_wma, slow_wma)
bear_cross = ta.crossunder(fast_wma, slow_wma)
vol_valid = not use_vol_filter or (volume > vol_ma)

long_signal = bull_cross and vol_valid
short_signal = bear_cross and vol_valid

// --- ATR Trailing Stop Logic ---
// We use 'var' so the variables remember their value from the previous candle
var float trail_stop = na
var int pos_dir = 0 // 1 for Long, -1 for Short

if long_signal
    pos_dir := 1
    trail_stop := close - (atr_val * atr_mult)
else if short_signal
    pos_dir := -1
    trail_stop := close + (atr_val * atr_mult)
else if pos_dir == 1
    // Ratchet UP for longs: never let the stop decrease
    prev_stop = na(trail_stop[1]) ? close - (atr_val * atr_mult) : trail_stop[1]
    trail_stop := math.max(prev_stop, close - (atr_val * atr_mult))
else if pos_dir == -1
    // Ratchet DOWN for shorts: never let the stop increase
    prev_stop = na(trail_stop[1]) ? close + (atr_val * atr_mult) : trail_stop[1]
    trail_stop := math.min(prev_stop, close + (atr_val * atr_mult))

// --- Plotting Averages ---
fast_color = fast_wma > fast_wma[1] ? color.new(#26a69a, 0) : fast_wma < fast_wma[1] ? color.new(#ef5350, 0) : color.new(color.gray, 0)
plot(fast_wma, title="Fast WMA", color=fast_color, linewidth=2)
plot(slow_wma, title="Slow WMA", color=color.new(color.white, 50), linewidth=2)

// --- Plotting ATR Stop ---
stop_color = pos_dir == 1 ? color.new(#26a69a, 30) : pos_dir == -1 ? color.new(#ef5350, 30) : na
plot(trail_stop, title="ATR Trailing Stop", color=stop_color, style=plot.style_cross, linewidth=1)

// --- Visual Markers ---
plotshape(long_signal, title="Long Signal", style=shape.triangleup, location=location.belowbar, color=color.new(#26a69a, 0), size=size.small)
plotshape(short_signal, title="Short Signal", style=shape.triangledown, location=location.abovebar, color=color.new(#ef5350, 0), size=size.small)

// --- Alerts ---
alertcondition(long_signal, title="Long Entry Triggered", message="LONG ALERT: WMA Cross with Volume Confirmed")
alertcondition(short_signal, title="Short Entry Triggered", message="SHORT ALERT: WMA Cross with Volume Confirmed")

Re: Weighted Moving Average (WMA) Explained + Custom Pine Script for ScalpersHey everyone, When trading lower timeframe

Posted: Fri Sep 04, 2026 10:48 am
by PTStockScalper
Key Technical Concepts to Highlight for You:

The var Keyword: Pine Script recalculates variables from scratch on every single candle. By using var float trail_stop = na, we force the script to "remember" the stop loss value from the previous candle, which is essential for trailing stops.

The Ratchet Effect: The math.max() and math.min() functions ensure the stop loss only moves in the direction of profit. If you are in a long position and a sudden bearish candle drops the ATR calculation, the stop line will hold its ground instead of moving down with the price.

Scalping Tweak: I set the default atr_mult to 1.5 instead of the traditional 3.0 swing-trading multiplier. Lower timeframe scalpers need to cut losers faster, but they can adjust this easily in the newly organized input menu.

Re: Weighted Moving Average (WMA) Explained + Custom Pine Script for ScalpersHey everyone, When trading lower timeframe

Posted: Fri Sep 04, 2026 10:49 am
by PTStockScalper
In low-timeframe scalping environments, indicator latency directly degrades execution accuracy. While Standard and Exponential Moving Averages (SMA/EMA) are ubiquitous, their calculation methods often introduce unacceptable lag during high-frequency momentum shifts.

The Weighted Moving Average (WMA) mitigates this by applying a linearly decreasing weight to historical data, mathematically prioritizing recent price action. The underlying calculation ensures a tighter fit to the current market price without the severe overshooting characteristic of an EMA during sudden volume spikes.

To construct a complete, algorithmic-grade trading system, I have developed a Pine Script (v5) implementation that pairs a dual WMA crossover with a baseline volume filter and a volatility-adjusted trailing stop.

System Architecture & Logic

Directional Bias (Dual WMA): Utilizes a fast and slow WMA to identify momentum shifts. The fast WMA features dynamic color-coding based on its slope to provide immediate visual feedback on micro-trend direction.

Liquidity Filter (Volume SMA): Crossovers executed in low-liquidity environments frequently result in algorithmic whipsaws. This script requires the execution candle's volume to exceed a baseline Simple Moving Average (SMA), ensuring institutional participation is driving the move.

Risk Management (Ratcheting ATR Stop): Static, pip-based stops are inefficient in fluctuating volatility regimes. This script incorporates an Average True Range (ATR) trailing stop. Utilizing stateful variables in Pine Script, the logic acts as a ratchet—the stop-loss only adjusts in the direction of profitability and holds firm against adverse price spikes.