Measured Move Projector
A measured move projects the magnitude of a completed price swing forward to estimate potential support, resistance, or target levels. This indicator identifies the most recent completed swing (either up or down), measures its vertical distance, and extends that same distance forward from the swing endpoint, helping traders anticipate where price may travel if the momentum pattern repeats.
Swing traders, breakout traders, and mean-reversion practitioners use measured moves to set target profit levels or to gauge the expected scale of continuation moves.
//@version=6
indicator("Measured Move Projector", overlay=true, max_bars_back=500)
// ─── Inputs ───
swingLookback = input.int(5, "Swing Lookback Bars", minval=2, maxval=50)
projectionBars = input.int(20, "Bars to Project Forward", minval=1, maxval=100)
showUpMoves = input.bool(true, "Project Upswings")
showDownMoves = input.bool(true, "Project Downswings")
lineWidth = input.int(2, "Line Width", minval=1, maxval=4)
lineStyleUp = input.string("Solid", "Upswing Line Style", options=["Solid", "Dashed", "Dotted"])
lineStyleDown = input.string("Dashed", "Downswing Line Style", options=["Solid", "Dashed", "Dotted"])
// ─── Helper: Convert line style string to chart.line_style ───
f_lineStyle(styleStr) =>
styleStr == "Solid" ? chart.line_style_solid :
styleStr == "Dashed" ? chart.line_style_dashed :
chart.line_style_dotted
// ─── Detect Local Highs and Lows ───
isLocalHigh = high[swingLookback] > ta.highest(high, 2 * swingLookback + 1)[swingLookback]
isLocalLow = low[swingLookback] < ta.lowest(low, 2 * swingLookback + 1)[swingLookback]
// ─── Identify Last Completed Swing ───
barsSinceLastSwing = 0
swingType = 0 // 1 = up, -1 = down, 0 = none
swingStart = 0.0
swingEnd = 0.0
swingMag = 0.0
if isLocalHigh
swingType := 1
barsSinceLastSwing := 0
swingStart := low[swingLookback]
swingEnd := high[swingLookback]
swingMag := swingEnd - swingStart
else if isLocalLow
swingType := -1
barsSinceLastSwing := 0
swingStart := high[swingLookback]
swingEnd := low[swingLookback]
swingMag := swingStart - swingEnd
else
swingType := nz(swingType[1])
barsSinceLastSwing := nz(barsSinceLastSwing[1]) + 1
swingStart := nz(swingStart[1])
swingEnd := nz(swingEnd[1])
swingMag := nz(swingMag[1])
// ─── Calculate Projection ───
currentBar = bar_index
barsSinceSwingEnd = currentBar - (currentBar[swingLookback])
isInProjectionWindow = barsSinceLastSwing >= swingLookback and
barsSinceLastSwing <= swingLookback + projectionBars
// Upswing measured move: project upward from high
projectionUp = swingType == 1 and showUpMoves and isInProjectionWindow
projectionTarget_up = swingEnd + swingMag
// Downswing measured move: project downward from low
projectionDown = swingType == -1 and showDownMoves and isInProjectionWindow
projectionTarget_down = swingEnd - swingMag
// ─── Plot Projections ───
if projectionUp
targetLine_up = chart.linefill(
chart.point.new(currentBar - swingLookback, swingEnd),
chart.point.new(currentBar - swingLookback + projectionBars, projectionTarget_up),
color.new(color.green, 20))
chart.plot(swingEnd, "Swing High", color.green, 1, char='H')
plot(projectionTarget_up, "Measured Move Target (Up)", color.green, lineWidth,
f_lineStyle(lineStyleUp))
if projectionDown
targetLine_down = chart.linefill(
chart.point.new(currentBar - swingLookback, swingEnd),
chart.point.new(currentBar - swingLookback + projectionBars, projectionTarget_down),
color.new(color.red, 20))
chart.plot(swingEnd, "Swing Low", color.red, 1, char='L')
plot(projectionTarget_down, "Measured Move Target (Down)", color.red, lineWidth,
f_lineStyle(lineStyleDown))
// ─── Plot Current Swing Level ───
plot(swingEnd, "Current Swing End",
swingType == 1 ? color.new(color.green, 50) : color.new(color.red, 50),
1, plot.style_line)
How the code works
The indicator begins by detecting local highs and lows using a lookback window. A local high forms when the bar at position swingLookback bars back is higher than all bars within a symmetric window around it; a local low is the inverse. This objective definition avoids ambiguity.
Once a local high or low is confirmed, the code stores three values: the swing type (up or down), the entry price of the swing, and the exit price. The swing magnitude is the absolute vertical distance between these two prices.
The projection then advances forward in time. The code tracks how many bars have elapsed since the swing completed and checks whether the current bar falls within the "projection window", a forward-looking range specified by the user (default 20 bars). Within that window, it calculates the target level by taking the swing endpoint and adding (for upswings) or subtracting (for downswings) the swing magnitude.
The plot displays this target as a horizontal line or extended projection, colored green for upswing projections and red for downswing projections. The line style (solid, dashed, dotted) is user-selectable per direction. A light fill area connects the swing endpoint to the target level for visual clarity.
Reading it on a chart
When a measured move projects, a horizontal line or extended band appears showing the expected target level. For an upswing, the target sits above the swing high at a distance equal to the swing's magnitude. For a downswing, it sits below the swing low by the same amount.
Traders look for price approaching or crossing these projected levels, which often act as:
- Resistance on upswing projections: price may pause or reverse near the target.
- Support on downswing projections: price may bounce or consolidate at the target.
- Breakout confirmation: a clean close beyond the target suggests the swing pattern has extended beyond the "measured" expectation.
- Risk/reward setup: the target level defines one boundary of a risk-reward calculation when combined with entry or stop placement.
The indicator allows separate styling for upswings and downswings, and the projection window is adjustable so traders can focus on near-term projections (5-10 bars) or longer-term ones (50+ bars). Disabling one direction focuses the chart on, for example, only downswing projections if the trader is looking for short opportunities.
Limitations
Measured moves assume past magnitude will repeat in the next swing, an assumption often violated by momentum changes, volatility regimes, news events, or support/resistance at different price levels. The indicator projects rigidly and does not account for market structure, trend strength, or volume conviction; a target hit with weak volume may fail to hold, or price may stop short of the target if a stronger technical level intervenes.
Swing detection depends on the lookback parameter. Too small a value identifies choppy local extremes and produces frequent, tight projections; too large a value misses smaller, more tradeable swings. A single "best" setting does not exist, the indicator is sensitive to parameter choice and will require recalibration as timeframe, instrument, or market regime changes.
The measured move is a proportional projection, not a probabilistic or statistically weighted one. It carries no information about likelihood, and it should not be used as a sole entry or exit criterion. Traders typically combine measured moves with other signals, such as order flow, volatility extremes, trend confirmation, or key support/resistance levels, before committing capital.
Finally, historical performance of measured move targets on any given instrument is not guaranteed to be predictive. Markets evolve, liquidity patterns shift, and an indicator that worked well in backtesting may underperform in live conditions if the swing pattern formation changes.
Key definitions
Swing: A local extreme (high or low) in price over a specified period, used as the anchor point for projections.
Measured Move: A technical projection that assumes the magnitude of a completed swing will repeat in the subsequent move, extending the same vertical distance forward.
Projection Window: The forward-looking time period (number of bars) during which a measured move target is active and displayed on the chart.
Local High/Low: A price extreme where a bar's high or low is more extreme than all other bars within a symmetric lookback window.
Magnitude: The vertical distance in price units between the start and end points of a swing.
References
- CME Group, "Futures Education: Technical Analysis Basics," CME Education, https://www.cmegroup.com/education.html
- Bulkowski, Thomas N., "Encyclopedia of Chart Patterns," Wiley, 2005. (Defines swing projections and measured moves in technical analysis.)
- Investopedia, "Measured Move: Definition and Uses," Investopedia, https://www.investopedia.com/terms/m/measured-move.asp
- TradingView, "Pine Script v6 Documentation," TradingView Wiki, https://www.tradingview.com/pine-script-reference/
Educational research on historical data only. Not investment advice, not a signal, and never a performance promise. Past results do not predict future performance. Every reference is link-verified before publication and every paper is re-audited weekly against the library's editorial standard.
Last reviewed by the PropLedger research pipeline: 2026-09-13. Educational research on historical data, not financial advice.
Keep reading
Volatility Regime Bands from Percentile-Ranked ATR
Free open-source Pine Script indicator: volatility regime bands from percentile-ranked ATR. Full code and a plain-English walkthrough.
Spread Tracker: Related Futures Contracts
Free open-source Pine Script indicator: spread tracker between two related futures contracts. Full code and a plain-English walkthrough.
Seasonality Heat Strip
Free open-source Pine Script indicator: seasonality heat strip: month-of-year average returns. Full code and a plain-English walkthrough.