Trend Strength Index: correlation-based trend consistency
The Trend Strength Index measures the linear relationship between closing price and bar index. A value near +1 describes a steadily rising line; a value near -1 describes a steadily falling line. It summarizes the selected history, without estimating the probability of the next price move.
Trend Strength Index = Pearson r(close, bar index, N)
Synthetic check: the same five prices give r = 1.00 in ascending order and r = 0.30 after the specified shuffle below. Order matters; the set of prices alone is insufficient.
Looking for the momentum oscillator with double smoothing? That is the True Strength Index. Both use the abbreviation TSI, but they are different indicators.
What TradingView's Trend Strength Index calculates
TradingView documents a correlation of closing prices with bar index, plus Length and bullish/bearish color inputs. This page uses that public definition and a Pine Script v6 example. It does not reproduce a private script or infer an indicator's release history from the Pine language version. TradingView's indicator reference.
Write the last N observations in chronological order. Let t be the bar position and p the closing price. Compute both means, subtract each mean from its observations, then use the following centered sums. The sample or population normalization cancels when covariance is divided by both standard deviations.
t̄ = Σt / N; p̄ = Σp / N
S_tt = Σ(t − t̄)²
S_pp = Σ(p − p̄)²
S_tp = Σ(t − t̄)(p − p̄)
r = S_tp / √(S_tt × S_pp)
This is the Pearson formula described by NIST. With positive variance in both series, r is between -1 and +1. An exact +1 or -1 requires a straight-line relationship, not merely a sequence of higher or lower closes. With N = 2, any two unequal prices produce an absolute correlation of 1, so that setting offers no gradation of consistency.
Replacing absolute bar indices with 0 through N − 1 leaves r unchanged: subtracting a constant does not change deviations from the mean. Bar index measures successive chart bars, not elapsed seconds. A weekend or overnight break does not insert extra time points. Correlation with timestamps can therefore give a different answer when time gaps are unequal.
Adding a constant to every price or multiplying every price by a positive constant also leaves r unchanged. A tiny straight-line drift and a large straight-line advance can both score +1. Price scale, return magnitude, volume and tradable opportunity are separate measurements.
Same prices, different order: a reproducible calculation
These are invented five-bar samples in arbitrary price units, not market data or a backtest. All rows use t = [0, 1, 2, 3, 4], t̄ = 2 and S_tt = 10. Prices are listed oldest to newest. Sorted, Reversed and Shuffled contain exactly the same five values.
| Sample | Prices in chronological order | S_tp | S_pp | Expected r |
|---|---|---|---|---|
| Sorted | 100, 101, 102, 103, 104 | 10 | 10 | +1.000000 |
| Reversed | 104, 103, 102, 101, 100 | -10 | 10 | -1.000000 |
| Shuffled | 102, 100, 104, 101, 103 | 3 | 10 | +0.300000 |
| U-shaped | 104, 101, 100, 101, 104 | 0 | 14 | 0.000000 |
| Single jump | 100, 100, 100, 100, 110 | 20 | 80 | +0.707107 |
| Constant | 100, 100, 100, 100, 100 | 0 | 0 | Undefined (na) |
| Missing | 100, 101, na, 103, 104 | Not computed | Not computed | na (strict policy) |
Work through the shuffle
For [102, 100, 104, 101, 103], the mean price is 102. Its deviations are [0, -2, 2, -1, 1], and time deviations are [-2, -1, 0, 1, 2]. Their products are [0, 2, 0, -1, 2], which sum to 3. Price squared deviations sum to 10, so r = 3 / √(10 × 10) = 0.30. Sorting this same set makes the deviations match time and changes r to 1.00.
Sorting is a diagnostic demonstration only. Never sort observed closes before calculating a trading indicator: doing so manufactures a trend that was absent from the chronological series. One chosen permutation is also not a randomization test or a distribution of possible shuffled results.
Counterexamples to common interpretations
The U-shaped sample has zero correlation despite a deterministic curved pattern. The Single jump sample has r = 20 / √800 = 0.707107 even though four closes are identical and only the last one jumps. A reading above 0.5 therefore cannot establish that prices rose consistently on each bar. The constant sample has zero price variance and an undefined denominator; its result is not zero.
For initialization at N = 5, [100], [100, 101], [100, 101, 102] and [100, 101, 102, 103] all return na under the script's full-window policy. The fifth observation, 104, produces +1. With [100, 101, na, 103, 104, 105, 106, 107], valid output first resumes at the eighth observation, when the window is [103, 104, 105, 106, 107].
Pine Script v6 with chart data and synthetic test modes
Paste the complete indicator into TradingView Pine Editor and add it to a chart. Chart close uses the adjustable Chart length, starting at 14. The other modes use exactly five samples and repeat the table's sequences. The script retains the purple line, reference levels and directional gradient fills, with editable fill colors.
//@version=6
indicator("Trend Strength Index: correlation and fixtures", overlay = false, precision = 6)
lengthInput = input.int(14, "Chart length", minval = 2, maxval = 500)
mode = input.string("Chart close", "Data", options = ["Chart close", "Sorted", "Reversed", "Shuffled", "U-shaped", "Single jump", "Constant", "Missing"])
bullColor = input.color(color.rgb(8, 153, 129), "Bullish color")
bearColor = input.color(color.rgb(242, 54, 69), "Bearish color")
// Fixtures repeat every five bars. Compare at step 4: the oldest-to-newest
// window then matches the five observations printed in the guide.
int step = bar_index % 5
var array<float> shuffled = array.from(102.0, 100.0, 104.0, 101.0, 103.0)
var array<float> curved = array.from(104.0, 101.0, 100.0, 101.0, 104.0)
float sample = switch mode
"Sorted" => 100.0 + step
"Reversed" => 104.0 - step
"Shuffled" => array.get(shuffled, step)
"U-shaped" => array.get(curved, step)
"Single jump" => step == 4 ? 110.0 : 100.0
"Constant" => 100.0
"Missing" => step == 2 ? na : 100.0 + step
=> close
int length = mode == "Chart close" ? lengthInput : 5
// Explicit policy: require a full, contiguous, non-missing window.
// Missing values are never replaced by zero or carried forward.
bool complete = bar_index >= length - 1
for offset = 0 to length - 1
if na(sample[offset])
complete := false
float priceHigh = ta.highest(sample, length)
float priceLow = ta.lowest(sample, length)
float rawCorrelation = ta.correlation(sample, bar_index, length)
float trendStrength = complete and priceHigh > priceLow ? rawCorrelation : na
trendPlot = plot(trendStrength, "Trend Strength Index", color = color.purple, style = plot.style_linebr)
zeroPlot = plot(0, "Fill reference", display = display.none)
hline(1, "Positive limit", color = bullColor)
hline(0, "Zero", color = color.gray)
hline(-1, "Negative limit", color = bearColor)
fill(trendPlot, zeroPlot, 1, 0, top_color = bullColor, bottom_color = color.new(bullColor, 100), fillgaps = false)
fill(trendPlot, zeroPlot, 0, -1, top_color = color.new(bearColor, 100), bottom_color = bearColor, fillgaps = false)
plot(sample, "Input sample", display = display.data_window)
plot(mode == "Chart close" ? na : step, "Fixture step (compare at 4)", display = display.data_window)
crossUp = ta.crossover(trendStrength, 0)
crossDown = ta.crossunder(trendStrength, 0)
alertcondition(mode == "Chart close" and crossUp and barstate.isconfirmed, "Positive correlation cross", "Trend Strength Index crossed above zero on a closed bar.")
alertcondition(mode == "Chart close" and crossDown and barstate.isconfirmed, "Negative correlation cross", "Trend Strength Index crossed below zero on a closed bar.")- Select Sorted in the Data input. Open the Data Window and inspect a bar where Fixture step equals 4. Expect +1.000000.
- On that same bar, select Shuffled. Expect +0.300000. Check Reversed, U-shaped and Single jump against the table.
- Select Constant or Missing. The Trend Strength Index output should be na; a missing or undefined value must not become a zero cross.
- Return Data to Chart close before interpreting market data. Match the length, symbol, session, chart type and closed bar with the TradingView indicator.
At other fixture steps, the rolling window rotates across repetitions and is no longer the table's chronological sample. At the start of the available dataset, the first four fixture bars have no output. The repeat pattern deliberately makes the same fixture available throughout a long chart; it does not simulate a market.
The calculation calls ta.correlation on every bar. The explicit completeness check then rejects any window containing na, and the high/low check rejects constant prices. This strict missing-data policy is part of this example; do not assume every built-in or third-party script makes the same choice. It avoids silently using older observations or filling missing prices with zero.
Alerts are available only in Chart close mode. They require a zero cross and barstate.isconfirmed, so they become true at the close of the chart bar. Create the alert in TradingView and select Once Per Bar Close. The line itself remains live during an open bar. TradingView's bar-state documentation explains this confirmation boundary. There are no orders or strategy performance calculations in this indicator.

Read correlation without turning thresholds into probabilities
| Observation | What the formula establishes | What remains unproven |
|---|---|---|
| Positive r | Positive slope of the fitted price-versus-bar line. | The next return, the size of the move, or every bar closing higher. |
| Negative r | Negative slope of the fitted line. | A profitable short or an imminent further decline. |
| r near zero | Weak linear association in this window. | Randomness, absence of a curved pattern, or an uneventful market. |
| Cross above zero | The rolling linear association changed sign. | The start of a lasting trend or an entry with positive expected return. |
| Absolute r near one | Price lies close to a rising or falling straight line. | An overbought/oversold state, exhaustion, or a guaranteed reversal. |
A threshold such as +0.5 or a dead zone from -0.2 to +0.2 is a rule chosen by an analyst. Neither is automatically a statistical significance boundary. A claim of significance needs a null model, a sample size and defensible assumptions about dependence. Price levels can be serially dependent, and adjacent rolling windows share most of their observations. Treating each reading as an independent test would ignore that structure.
For these five-point examples only, a fitted ordinary least-squares line with an intercept has R² = r². The shuffled row's R² is 0.09. That describes its in-sample linear fit; it is not a 9% win rate or probability of trend continuation. No trading outcome follows from this identity.
Choose a window and test a complete trading rule
Length counts chart bars. Fourteen five-minute bars and fourteen daily bars each supply fourteen observations but cover different periods. Shorter windows give a new observation a larger role; longer windows retain more of the prior path. A longer window need not change every zero cross later, and there is no fixed number of false signals removed by changing length.
Compare 7, 14 and 28 only as example research settings, holding source data and timeframe fixed. Record how the line changes around turns, isolated jumps and quiet drift. When an old extreme leaves the window, correlation can move sharply even if the latest price barely changes. Gaps are valid price observations, but a single gap may dominate a short-window fit, as the Single jump sample shows.
If testing a rule such as a confirmed zero cross with a moving average filter, specify entry timing, exit, size, costs and slippage before measuring results. Compare it with the same rule without the filter, then evaluate an untouched time period. Record turnover and drawdown as well as returns. Adding RSI, ADX or a moving average does not create independent evidence automatically; these indicators also use related price history.
| Indicator | Input and calculation | Pine implementation |
|---|---|---|
| Trend Strength Index | Closing price levels versus successive bar positions; Pearson correlation. | ta.correlation(close, bar_index, length), with explicit validity checks here. |
| True Strength Index | Double-smoothed signed price changes divided by double-smoothed absolute changes. | ta.tsi(source, shortLength, longLength); display scaling depends on the script. |
| ADX | Smoothed directional movement strength; direction is read separately from +DI and -DI. | A distinct calculation; its numeric thresholds cannot be copied to a correlation scale. |
See the True Strength Index guide for the smoothing calculation, or ADX for directional movement. The official True Strength Index reference also distinguishes its inputs from price-time correlation.
Turn the explicit formula into a Pineify coding request
Pineify's Pine Script AI Coding Agent can draft and edit a script from written requirements and offers syntax checking. Give it the formula, the handling of incomplete windows, and the expected synthetic results so you can review the generated calculation. A successful syntax check does not prove the math or a trading edge.
Create a Pine v6 Trend Strength Index using Pearson correlation of close with bar index. Expose length, starting at 14. Require N consecutive non-missing samples and return na for a constant-price window. Preserve the five-bar Sorted and Shuffled fixture modes; their results at step 4 must be 1.00 and 0.30. Alert on confirmed chart-bar zero crosses only. Do not substitute True Strength Index.
Compare the generated output with the table and with matching closed bars in TradingView. Define a complete strategy separately if you want to evaluate trades. This workflow produces code for review; it does not automate profitable trading or verify a statistical claim merely by compiling.
Build a correlation indicator with PineifyTrend Strength Index questions
Sources and related indicator guides
Official references checked October 18, 2026. All five-bar examples are synthetic calculations.
- TradingView: Trend Strength Index definition and inputs
- NIST Dataplot: Pearson correlation formula
- TradingView: True Strength Index calculation
- TradingView Pine Script v6 reference: ta.correlation
- TradingView Pine Script: confirmed bar states
- TradingView: Directional Movement and ADX
Continue with RSI, MACD, or the TradingView indicator collection.
Educational information, not investment advice. The examples verify arithmetic and edge cases, not strategy performance. Historical correlation and indicator thresholds cannot guarantee future returns.