◆ New — Strategy Validator, Code Fixer & Prop Compliance Checker are live. Try one free →
Home / Indicators / Correlation Coefficient
Statistics indicator

Correlation Coefficient

A rolling Pearson correlation between two symbols, scored from -1 to +1 over a chosen lookback window.

Illustrative diagram — not live market data.

What it is

The correlation coefficient measures how closely two series have moved together over a lookback window, on a fixed scale from −1 to +1. A reading near +1 means the two symbols moved up and down together over the window; near −1 means they moved in consistently opposite directions; near 0 means no consistent linear relationship. On TradingView you measure correlation between two symbols by pulling the second symbol's series with request.security() and feeding both series into ta.correlation() with a lookback length — that is the whole recipe, though doing it without introducing repainting takes care (covered below). Traders use rolling correlation to describe relationships such as EURUSD versus GBPUSD, an index versus its constituents, or gold versus real-yield proxies. Two honesty notes. First, correlation is descriptive and historical: it summarizes co-movement in the window you measured, and correlations between instruments demonstrably change over time — a relationship measured today is not a stable property of the pair. Second, correlation is not causation and not a trading edge by itself. This is educational content, not financial advice, and all trading involves risk of loss.

How it works

The underlying statistic is the Pearson correlation: over the last n bars, take the covariance of the two series (the average of the products of their deviations from their respective means) and divide it by the product of their standard deviations. The division normalizes the result into the −1 to +1 range regardless of the instruments' price scales. On each new bar the window slides forward one bar, so the value updates continuously. The implementation detail that matters most on TradingView is how the second symbol's data arrives. request.security() evaluated on the current, still-forming bar returns values that can change until that bar closes — and with lookahead switched on, historical bars can even see data they could not have seen live. Both create repainting: the historical correlation plot looks different from what you would have seen in real time. The correct pattern is to request the other symbol's series offset by one bar (close[1]) with lookahead = barmerge.lookahead_off, and to compare it against your own chart's equally offset series, so both sides of the calculation use only confirmed information. One further subtlety: correlating raw prices of two trending instruments produces inflated readings, because both share a time trend; correlating bar-to-bar changes or returns gives a more honest picture of co-movement.

How traders read it

Common settings

Typical lookbacks run from 20 bars (fast, noisy) to 100 or more (slow, smooth); many platform defaults sit at 20 or 50. The comparison symbol and the source series (raw close versus one-bar change or return) matter as much as the length. Reference lines at 0 and around ±0.7 are common. Shorter windows react quickly to relationship changes but jump around; longer windows are statistically steadier but can describe a relationship that has already broken. As with all rolling statistics, changing the window changes every reading, so state your settings when quoting a correlation.

Strengths

Pitfalls to watch

Pine v6 example

//@version=6
indicator("Rolling Correlation (non-repainting)", overlay = false)

sym    = input.symbol("OANDA:GBPUSD", "Compare Symbol")
length = input.int(50, "Correlation Length", minval = 2)
tf     = input.timeframe("", "Timeframe")

// Confirmed-bar series from the other symbol: [1] offset with
// lookahead_off so historical values match what was visible live.
otherClose = request.security(sym, tf, close[1], lookahead = barmerge.lookahead_off)

// Compare against our own confirmed series so both sides align.
corr = ta.correlation(close[1], otherClose, length)

plot(corr, "Correlation", color = color.blue)
hline(1,    "+1",   color = color.gray)
hline(0.7,  "+0.7", color = color.new(color.gray, 50))
hline(0,    "0",    color = color.gray)
hline(-0.7, "-0.7", color = color.new(color.gray, 50))
hline(-1,   "-1",   color = color.gray)

Pro tip: When quoting a correlation, always attach three things: the window length, whether it was computed on prices or returns, and whether the request.security() call was offset and lookahead-safe — each one can change the number materially, and the third determines whether the historical plot was even achievable live. If a strategy idea depends on a correlation holding, test how that correlation behaved across different windows and regimes before trusting it. Educational content only, not financial advice; relationships between markets change, and all trading carries risk of loss.

Built an indicator from this? Run it through the Validator to catch look-ahead bias and repainting, or convert a strategy to Pine Script.

Educational only — not financial advice, not a recommendation to trade. No indicator is predictive; trading involves substantial risk of loss.

Catch the bug that compiles.Run auditGet Pro