Indicators··7 min read

Measured Move Projector

2 references, link-verified · inline [n] markersEditor of record: Shane CantyStandards review editorial standard · audit log

The measured move projects price extension targets based on the distance of a completed swing (the move from a reference point to a swing extreme). When a swing high or low is confirmed, the indicator measures the displacement to that swing and projects the same distance forward from the swing level, producing potential extension targets. This tool is useful for traders who operate within swing-based frameworks and want to establish objective price objectives without relying on subjective fib levels or round numbers.

//@version=6
indicator("Measured Move Projector", overlay=true, max_lines_count=500, max_labels_count=500)

// Inputs
lookback = input(5, "Swing Lookback Bars", minval=1)
use_swing_high = input(true, "Use Swing High Moves")
use_swing_low = input(true, "Use Swing Low Moves")
line_color_high = input(color.new(color.green, 80), "Swing High Projection Color")
line_color_low = input(color.new(color.red, 80), "Swing Low Projection Color")
line_width = input(1, "Line Width", minval=1, maxval=5)
show_labels = input(true, "Show Distance Labels")
max_lines_display = input(20, "Max Lines to Display", minval=1, maxval=100)

// Function to detect a swing high
f_is_swing_high() =>
    high[lookback] > high[lookback-1] and high[lookback] > high[lookback+1]

// Function to detect a swing low
f_is_swing_low() =>
    low[lookback] < low[lookback-1] and low[lookback] < low[lookback+1]

// Function to find last reference point (where the swing started from)
f_find_reference(swing_bar_index, is_high) =>
    ref_price = close[0]
    for i = swing_bar_index + 1 to bar_index - 1
        if is_high and low[i] < ref_price
            ref_price := low[i]
        if not is_high and high[i] > ref_price
            ref_price := high[i]
    ref_price

// Track last swing and its properties
var array<line> active_lines = array.new<line>()
var array<label> active_labels = array.new<label>()

// On each bar, check for new swing completion
bar_idx = bar_index

// Detect swing high completion (2 bars ago is confirmed as swing high)
if bar_index > lookback + 1
    if use_swing_high and high[lookback] > high[lookback-1] and high[lookback] > high[lookback+1]
        swing_high_price = high[lookback]
        swing_bar = bar_index - lookback
        
        // Find lowest point between swing reference and swing high
        ref_low = swing_high_price
        for i = lookback + 1 to bar_index - swing_bar - 1
            if low[i] < ref_low
                ref_low := low[i]
        
        move_distance = swing_high_price - ref_low
        target_price = swing_high_price + move_distance
        
        // Draw projection line
        x1 = swing_bar
        x2 = bar_index
        line proj = line.new(x1, swing_high_price, x2, target_price, closed=false, 
                             color=line_color_high, width=line_width)
        array.push(active_lines, proj)
        
        // Add label with distance
        if show_labels
            label lbl = label.new(x2, target_price, str.format("MM+: {0:.2f}", move_distance),
                                  color=line_color_high, textcolor=color.white, style=label.style_label_lower)
            array.push(active_labels, lbl)
    
    // Detect swing low completion
    if use_swing_low and low[lookback] < low[lookback-1] and low[lookback] < low[lookback+1]
        swing_low_price = low[lookback]
        swing_bar = bar_index - lookback
        
        // Find highest point between swing reference and swing low
        ref_high = swing_low_price
        for i = lookback + 1 to bar_index - swing_bar - 1
            if high[i] > ref_high
                ref_high := high[i]
        
        move_distance = ref_high - swing_low_price
        target_price = swing_low_price - move_distance
        
        // Draw projection line
        x1 = swing_bar
        x2 = bar_index
        line proj = line.new(x1, swing_low_price, x2, target_price, closed=false,
                             color=line_color_low, width=line_width)
        array.push(active_lines, proj)
        
        // Add label with distance
        if show_labels
            label lbl = label.new(x2, target_price, str.format("MM-: {0:.2f}", move_distance),
                                  color=color.new(line_color_low, 0), textcolor=color.white, style=label.style_label_upper)
            array.push(active_labels, lbl)

// Remove oldest lines and labels when max display is exceeded
while array.size(active_lines) > max_lines_display
    line old_line = array.shift(active_lines)
    line.delete(old_line)

while array.size(active_labels) > max_lines_display
    label old_label = array.shift(active_labels)
    label.delete(old_label)

How the code works

The indicator operates on a fixed lookback period. Each bar, it checks whether the bar lookback bars ago qualifies as a swing high (higher than its neighbors) or swing low (lower than its neighbors). When a swing is detected, the script searches backward through the recent history to find the reference point: the lowest low between the swing high and its preceding reference, or the highest high between the swing low and its preceding reference.

The measured move distance is simply the absolute price difference between the swing extreme and the reference point. A projection line is then drawn from the swing bar to the current bar, starting at the swing price and extending to a target price derived by adding (for swing highs) or subtracting (for swing lows) the measured distance from the swing level itself. Labels display the calculated move distance alongside each projection.

The indicator maintains arrays of lines and labels, removing the oldest projections once the display limit is exceeded, preventing chart clutter while preserving recent signals.

Reading it on a chart

Green projection lines indicate measured move targets extending above a swing high. Red projection lines extend below swing lows. Each line runs from the swing bar to the right edge, showing where price might reach if the measured distance repeats. A label shows the distance in price units. Traders observe whether price respects these targets: rejection at the target suggests potential reversal, while a break above (or below, for upside projections) suggests continuation. The lookback parameter tunes sensitivity: lower values detect more frequent swings, while higher values filter for larger, more significant moves.

Limitations

The measured move assumes that past displacement predicts future displacement with equal probability, an assumption unsupported by market theory or empirical evidence. Swings identified by a fixed lookback period are arbitrary: a 5-bar lookback and a 10-bar lookback will identify different swings from the same chart, leading to different projections. The indicator repaints: a bar that does not appear to be a swing may later be retroactively identified as a swing once subsequent bars arrive, causing projections to appear and disappear. The measure ignores volatility, momentum, volume, and order-book structure; two identical measured moves in different market environments may have vastly different outcomes. Projections assume the prior move's structure repeats exactly, which rarely occurs; market microstructure, news, and participation change continuously. The tool offers no guidance on position sizing, risk management, or trade timing; it provides only a price level with no probability estimate.


Key definitions

Swing high: A bar whose close is higher than the closes of the bars immediately to its left and right within a specified lookback window.

Swing low: A bar whose close is lower than the closes of the bars immediately to its left and right within a specified lookback window.

Measured move: A price target derived by calculating the distance of a prior price movement and projecting that same distance forward from a key price level (usually a swing extreme).

Reference point: The price level from which a swing distance is measured, typically the low preceding a swing high or the high preceding a swing low.

Projection: A line or level extending into future bars, representing an anticipated price objective based on prior price action.

Repainting: A condition where a plotted value changes on a historical bar after new bars arrive, causing apparent signals to form and disappear retrospectively.


References

  1. Miner, Robert C., "High Probability Trading", Wiley (2008)., Foundational work on swing trading and measured move concepts.

  2. CME Group, "Technical Analysis of Futures Markets", CME Education Center., Primary source on standard price action terminology and swing identification.

  3. Kirkpatrick, Charles D. And Dahlquist, Julie R., "Technical Analysis: The Complete Resource for Financial Market Technicians", FT Press (2011)., full reference on measured move and price projection mechanics.

  4. Wikipedia, "Support and Resistance", https://en.wikipedia.org/wiki/Support_and_resistance, Overview of swing extremes and price levels.

  5. TradingView Documentation, "Pine Script Reference Manual", https://www.tradingview.com/pine-script-docs/, Technical specification for indicator development.


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-10-18. Educational research on historical data, not financial advice.

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. Found an error? Email support@prop-ledger.org and the paper is corrected or withdrawn.