TradingView indicator calculations

Linear regression slope indicator: units and normalization

A linear regression slope indicator measures the change in a fitted price line per chart bar over a rolling window. Its raw unit is price units per bar, so a value of 2 is not automatically 2%. Divide by a stated positive price reference for a percentage slope, or by ATR for a volatility-relative slope. The fitted endpoint is a price; a residual measures distance from that line. These three outputs answer different questions.

See the decision guide

Calculate the rolling least-squares slope

For N observations, number bars x = 0 through N − 1 from oldest to newest, and let y be the selected price source. Least squares chooses a and b to minimize the sum of squared errors from yhat = a + bx. Require N ≥ 2 and a complete valid window. Repeat the fit when the window advances; b describes the observations in that window rather than a forecast.

  • For consecutive x values, the denominator is N(N² − 1)/12. At N = 1 it is zero, so a slope cannot be estimated.
  • Reversing x so that zero means the newest bar reverses the sign. Match the indexing convention before comparing a manual loop with a built-in calculation.
  • On a 15-minute chart, one step means one 15-minute bar. On a daily chart it means one daily bar. Session gaps and non-time-based charts prevent a bar count from being a universal elapsed-time measure.
QuantityCalculationUnit
Slope bΣ[(x − mean(x))(y − mean(y))] / Σ[(x − mean(x))²]Price units per bar
Intercept amean(y) − b × mean(x)Price units
Newest fitted endpointa + b × (N − 1)Price units
Newest residualNewest price − newest fitted endpointPrice units

Work through a five-bar example

Use hypothetical closes 100, 102, 101, 105 and 107, ordered oldest to newest. The mean price is 103 and mean x is 2. The cross-product sum is 17 and the squared-x sum is 10, giving b = 1.7 price units per bar and a = 99.6. These values are arithmetic fixtures, not observed returns.

  • The fitted line rises by 1.7 × 4 = 6.8 across four intervals. The actual first-to-last price change is 7. A least-squares slope uses all five prices, not just the endpoints.
  • Using the current source price 107 as denominator gives 100 × 1.7 / 107 = 1.588785% per bar. Using the window mean 103 would give 1.650485%; those are different definitions.
  • Assume the separately calculated ATR is 2.5 price units. Then b / ATR = 0.68 ATR units per bar. ATR cannot be recovered from these five closes alone because it needs high, low and previous-close information.
  • Append a close of 106 and roll to 102, 101, 105, 107, 106. The new slope is 1.4 and endpoint is 107.0. The endpoint changed by 0.6, demonstrating why a change in rolling endpoints is not the current slope of 1.4.
xCloseFitted price 99.6 + 1.7xResidual
010099.6+0.4
1102101.3+0.7
2101103.0-2.0
3105104.7+0.3
4107106.4+0.6

Choose a denominator that matches the comparison

Normalization changes the interpretation of the output. For positive denominators, all three versions retain the sign of b, but their magnitudes and thresholds differ. The percent calculation here uses current source price. It is not compounded return, the observed one-bar return, or regression on logarithmic prices.

  • Multiplying all OHLC prices by 10 multiplies raw b and ATR by 10. Percent slope and ATR slope remain unchanged under that consistent rescaling.
  • If b stays at 1.7 while ATR increases from 2.5 to 5, ATR slope halves from 0.68 to 0.34. A falling normalized value can therefore reflect a rising denominator without a slower fitted price trend.
  • Default ATR smoothing on TradingView is RMA. The script below uses that convention with a separate ATR length; changing smoothing changes normalized slope.
  • Normalization does not make a 20-bar hourly window equivalent to a 20-bar daily window. It also does not remove sensitivity to jumps, outliers or an old observation leaving the window.
OutputUseful interpretationConstraint
Raw bSpeed in the quoted price units of the instrumentA 1-point slope on a 10-price asset differs from 1 point on a 1,000-price asset.
100 × b / current priceSpeed relative to the current price levelRequires a positive denominator here; changing the reference changes the result.
b / ATRSpeed relative to recent trading rangeRequires positive ATR and a stated ATR length and smoothing.

Separate the fitted line, slope and residual oscillator

The phrase linear regression oscillator does not identify one universal calculation. Inspect the formula and script author. An oscillator may plot slope around zero, distance from the fitted endpoint, or a standardized residual. A zero crossing has a different meaning for each.

  • For a separate counterexample, prices 100, 102, 104, 106, 103 give a positive slope of 1.0 but a newest residual of -2.0. Price below the fitted line can coexist with an upward fitted trend.
  • A regression channel adds bounds around the fitted line. Its width is not the slope, and a residual divided by a residual standard deviation is not b / ATR.
  • Zero slope does not prove low volatility: large alternating moves can cancel in the fit. A positive slope does not establish a profitable entry or a statistically reliable forecast.
OutputFive-bar exampleWhat zero means
Rolling endpoint / LSMA106.4A fitted price of zero, not a trend-neutral reading
Slope oscillator+1.7 per barA flat fitted line over the selected window
Endpoint residual oscillator+0.6Current price equals the fitted endpoint

Use the same fitted window in Pine Script v6

The two ta.linreg calls below evaluate adjacent x positions of the same current fit. Their difference is b. A history reference on the endpoint would instead access the previous window. Select one unit for the pane and inspect the other quantities in the TradingView Data Window. The code uses chart-timeframe data and plots provisional values on an open bar; its alert conditions wait for that bar to close.

  • No slope is emitted until N valid consecutive source observations exist. Missing source values invalidate the window. ATR may need additional history before its normalized output is available.
  • A flat positive-price series gives raw and percent slopes of zero. If ATR is zero, ATR slope is unavailable rather than an artificial zero. A nonpositive source disables percent slope while raw slope can still be defined.
  • Set the alert frequency to Once Per Bar Close. If you later add higher-timeframe inputs, chart-bar confirmation alone does not confirm those inputs.
Educational indicator with explicit units and confirmed chart-bar zero-cross alerts. No order execution or higher-timeframe requests.pine
//@version=6
indicator("Regression slope: explicit units", overlay=false, precision=6)
source = input.source(close, "Source")
length = input.int(20, "Regression bars", minval=2, maxval=500)
atrLength = input.int(14, "ATR bars", minval=1)
units = input.string("Percent per bar", "Pane units", options=["Price per bar", "Percent per bar", "ATR per bar"])

endpoint = ta.linreg(source, length, 0)
adjacentFit = ta.linreg(source, length, 1)
missingCount = math.sum(na(source) ? 1.0 : 0.0, length)
ready = bar_index >= length - 1 and missingCount == 0
slope = ready ? endpoint - adjacentFit : na
atrValue = ta.atr(atrLength)
percentSlope = source > 0 ? 100.0 * slope / source : na
atrSlope = atrValue > 0 ? slope / atrValue : na
selected = units == "Price per bar" ? slope : units == "Percent per bar" ? percentSlope : atrSlope

plot(selected, "Selected slope", color=color.blue, linewidth=2)
hline(0, "Zero", color=color.gray)
plot(slope, "Price units per bar", display=display.data_window)
plot(percentSlope, "Percent per bar", display=display.data_window)
plot(atrSlope, "ATR units per bar", display=display.data_window)
plot(ready ? endpoint : na, "Fitted endpoint", display=display.data_window)
plot(ready ? source - endpoint : na, "Endpoint residual", display=display.data_window)

crossUp = ta.crossover(selected, 0)
crossDown = ta.crossunder(selected, 0)
alertcondition(barstate.isconfirmed and crossUp, "Slope crossed above zero", "Selected regression slope crossed above zero at chart-bar close.")
alertcondition(barstate.isconfirmed and crossDown, "Slope crossed below zero", "Selected regression slope crossed below zero at chart-bar close.")

Check the numbers before building a trading rule

On standard candles, fix the symbol, session, source, timeframe and lengths. Compare completed-bar Data Window values with a spreadsheet least-squares calculation using the same observations. First check raw b, then the chosen denominator. A syntax check cannot prove numerical parity, signal quality or profitability.

  • Use N = 5 with the hypothetical fixtures above in a separate calculation; do not expect an arbitrary market chart to contain those prices.
  • Test rising, falling, constant and missing-data windows, plus zero ATR. Verify that a changing open-bar plot produces no alert until a confirmed cross remains at close.
  • If you want a customized implementation, give the Pine Script AI Coding Agent the source, oldest-to-newest indexing, denominator, missing-data policy and confirmation rule. Review its generated code and repeat the numerical comparison before creating alerts.
  • Any strategy still needs separately defined entries, exits, position size, execution timing and trading costs. A slope threshold alone leaves those decisions unspecified.
Where Pineify fits

Pine Script AI Coding Agent

Draft a Pine indicator from an explicit regression specification, then inspect its code and compare values with your calculation before adding alerts.

Build a slope indicator

Frequently asked questions

Educational information, not investment advice. Prices and ATR values are hypothetical calculation examples. Regression slope describes a historical fit and does not guarantee future returns.

Sources and verification

Published by Pineify. Pineify is an independent product and is not affiliated with TradingView. Sources support the technical explanations; examples do not establish trading performance.