QA GATE · GOOD 18/18 automated ai-check.js · 18 readability, YMYL and image gates · mechanics verified against vike-indicators · live real-data chart embedded
Burstiness (sentence-length SD)10.2
Lexical diversity (MATTR-50)0.82
Consecutive similar sentences2
Repeated paragraph starts (≥3)0
AI-marker phrases0
Demonstrated experience2
Avg sentence length (words)18.2
Repeated 5-grams0
H2 section balance (50–500w)0 off
YMYL risk disclaimeryes
Mechanics verified vs codeyes
Primary keyword coverageyes
Internal links + CTA5
Content visuals7
Every figure has a caption7/7
Alt / caption text coverage100%
Distributed (≥1 per section)6/7 (86%)
Filenames sluggedn/a (inline)
Live interactive chart4 real
Port parity vs Python twin344,012 values
tsf − linearreg = slope59,118 bars
Learn · Trading Indicators · Statistics

Linear Regression Slope: The Number Our Engine Returns

A linear regression slope is the gradient of the straight line that fits recent closes best. Our engine computes it as batch_linearreg_slope, over a default window of fourteen bars, and hands back a single number per bar with no scaling, no smoothing and no interpretation attached.

That plainness is the whole point, and it is also where people get hurt. The returned figure is measured in the price series' own units per bar, so it means something completely different on Bitcoin than on a token worth a hundredth of a cent — a gap this page puts at roughly seven billion to one on live data. Below is the arithmetic exactly as the crate runs it, the identity you can use to check any implementation, and three ways the raw output misleads.

What a linear regression slope measures

DODO/USDT daily — a real 14-bar regression fit detected 2026-06-09, the steepest 14-bar fit on this tape: +3.31% of price per bar, and price moved -8.1% over the next 20 sessions.

Fit a straight line through a run of closes so that the squared distances from the line are as small as they can be. The gradient of that line is the answer.

Positive means the fit tilts up over the window; negative means it tilts down. Steepness is how fast, in price per bar. Nothing about the construction predicts the next bar, and nothing about it says whether the fit is any good — a wildly scattered set of closes and a tidy staircase can share an identical gradient, because the residuals never reach the output.

Below is the steepest fourteen-bar fit on the whole tape we scanned: DODO, at 3.31% of price each bar. Price then gave back 8.1% across the following month, which is the first thing to know about this indicator and the reason the rest of the page is about mechanics rather than signals.

The exact slope our engine computes

14 closes in, one gradient outone barx = 0, 1, …, 13 — BARS, not datescloses only: no high, low or volumeb = (p·Σxy − Σx·Σy) / (p·Σx² − (Σx)²)returned — price units per bara = (Σy − b·Σx) / pcomputed, then discardedresiduals are never measured at all
What batch_linearreg_slope does per bar. The intercept exists inside the helper and does not leave it, and nothing in the kernel reports how well the line actually fitted.

Ordinary least squares in closed form, over an x-axis that counts bars.

How Vike computes it. For every bar i, batch_linearreg_slope takes the fourteen closes ending at i inclusive and labels them x = 0 through 13. It computes the exact integer sums Σx and Σx², folds Σy and Σxy over the window, and returns b = (p·Σxy − Σx·Σy) / (p·Σx² − (Σx)²). The intercept is computed too but thrown away — only the gradient leaves the function. Bars before the window fills return NaN.

When I ported this one I transcribed the crate kernel, transcribed the Python function beside it, then ran both across 243 Binance pairs and their full daily history. That is 344,012 compared values, worst absolute difference 1.876e-11, and every warm-up mask agreeing bar for bar.

Only 44.36% of the values came back bit-identical, and the cause is worth naming because it is not a bug in either file. CPython's builtin sum() compensates its floating-point error while the Rust port folds naively, and the crate's own module header says it does that deliberately to stay bit-compatible with its sibling ports. One rounding philosophy apart, eleven decimal places down.

The slope carries units, and that decides how you can use it

the same indicator, the same day, four price scalesleft: what the function returns  ·  right: the same fit divided by priceBTC-134.96321 / bar-0.212% of price / barclose 63668ETH-1.16492 / bar-0.061% of price / barclose 1907.05DOGE+0.00102 / bar+0.938% of price / barclose 0.1091SHIB+1.991e-08 / bar+0.315% of price / barclose 6.32e-06raw readings span a factor of 6.8 billion — the normalised ones span less than sixteen
Why a threshold on the raw slope is a statement about one asset at one price. The engine returns the left column; nothing in it performs the division on the right.
RAD/USDT daily — a real 14-bar regression fit detected 2026-06-13, a slope of -0.001% of price per bar — the fit is level, and the reading says only that.

Here is the single most important property of the number, and it is invisible if you only ever look at one chart.

Because x counts bars and y is price, b is priced in dollars per bar. On the last bar of our Bitcoin tape it read −134.96. On Ethereum, −1.16. On Dogecoin, +0.00102, and on SHIB, +0.0000000199. Those four readings span a factor of about 6.8 billion, and every one of them describes an unremarkable two-week drift.

Normalise by price and the picture inverts completely: −0.212%, −0.061%, +0.938% and +0.315% of price per bar. Dogecoin, whose raw slope is the smallest of the three majors by five orders of magnitude, has by far the steepest trend of the four. Our engine does not do that division for you, and any threshold you set on the raw value is therefore a threshold about one asset at one price level.

RAD, below, shows the other end of the range: a fit sitting at −0.001% of price a bar, which is a line level to three decimal places. Compare that with any moving average reading, where the output is a price and so at least stays on the chart's own axis. A gradient is not a price, and it does not belong on the price scale.

The angle output, and where it stops working

linearreg_angle = degrees( atan( slope ) )90°slope, price per bar (log)BTC: 69.9% of 3,274 readingsETH: 4.0% of 3,195 readingsDOGE: 0.0% of 2,406 readingsbeyond 89 degrees
The curve is the arctangent, and the assets on the right are where each one lives on it. Identical code, and the reading is informative on a cheap asset and pinned on an expensive one.

Our crate also ships linearreg_angle, which is this same gradient passed through degrees(atan(b)).

Look at what that expression takes the arctangent of. A quantity in dollars per bar goes into a function whose argument is supposed to be a pure ratio, so the result depends on how expensive the asset is rather than on how steeply it moved. Above a gradient of about 57 the arctangent has already passed 89 degrees, and everything steeper is squeezed into the last fraction of a degree.

I measured how often that happens. On Bitcoin, 69.9% of the 3,274 angle readings sat beyond 89 degrees, so the output was effectively pinned for two thirds of that history. Ethereum reached the ceiling on 4.0% of bars, and Dogecoin never got there at all — 0.0%, because its prices stay small enough that the arctangent still has somewhere to go.

Identical code, then, gives an informative reading on a cheap asset and a saturated constant on an expensive one. Dividing by price before taking the arctangent fixes it. No default setting anywhere does that.

Warm-up, sign and an identity you can check

GNS/USDT daily — a real 14-bar regression fit detected 2026-04-02, the slope changed sign here, to +0.55% of price per bar.
Warm-up is NaN, never zero: 3,159 unavailable readings across 243 tapes, exactly 13 per symbol. Zero is a real slope that means “flat”, and over 344,012 genuine readings the fit came out exactly flat 0.0% of the time.

Three smaller details separate a correct reimplementation from a plausible one.

Warm-up returns NaN, never zero. Across 243 tapes that is 3,159 unavailable readings, exactly thirteen per symbol — and the choice matters, because zero is a real slope value that means "flat" while NaN cannot be mistaken for anything. Several of our candlestick detectors initialise to zero instead and lose that distinction, which is a difference in kind rather than in style.

Then the sign census. Over 344,012 readings the gradient was positive 44.5% of the time and negative 55.5%, and it landed on exactly zero in 0.00% of cases — a least-squares fit through fourteen genuine prices essentially never comes out flat, so "the slope turned positive" is a thing that happens constantly rather than an event.

The identity is the useful part. linearreg returns a + b(p−1) and tsf returns a + b·p, both from this same fit, so subtracting one from the other must give back the gradient exactly. Measured over 59,118 bars, the largest discrepancy was 7.905e-14. That is floating-point noise. If your implementation fails that check, the bug is in the fit rather than in the slope itself, which is a much easier place to look. The GNS window below catches a sign change, at just over half a percent of price a bar.

Where linear regression slope fails

POND/USDT daily — a real 14-bar regression fit detected 2026-05-02, a +1.30%-per-bar rise in the fit, then a -46.8% fall over the next 20 sessions.

Lag first, since it is arithmetic rather than opinion.

A fourteen-bar fit is dominated by bars that are already a week old, so the gradient keeps rising for several sessions after a top. That is not a flaw to tune away — a shorter window reacts sooner and reports noise, exactly the trade every smoothed tool makes, as the trading indicators overview sets out.

Fit quality never reaches you. The function computes residuals nowhere, so a gradient through a clean trend and a gradient through violent chop are indistinguishable in the output. The crate does ship std_error for precisely this, and reading the two together is a habit I learned after being fooled by a confident-looking gradient over a window that was pure noise.

And a steep slope is a record, not a promise. POND, below, printed a fit rising at 1.30% of price per bar, and then fell 46.8% over the twenty sessions that followed. The kernel was right about every bar it read. It simply had nothing to say about the ones it had not.

Frequently asked questions

What does the linear regression slope indicator tell you? The gradient of a least-squares line through the last fourteen closes, in price units per bar. It describes the window and says nothing about what follows it.

Is there a good linear regression slope value? There is no threshold that transfers, because the raw figure scales with price — our four sample assets spanned a factor of 6.8 billion on one day. Divide by price first if you want a number that means the same thing on two charts.

How does linear regression slope differ from the angle output? linearreg_angle is degrees(atan(slope)). On Bitcoin that saturated past 89 degrees on 69.9% of bars, so the angle carried less information than the gradient it came from.

Is linear regression slope the same as a moving average? No. An average returns a price level; this returns a rate of change, and the two live on different axes. Pairing it with a momentum tool like the MACD tells you more than pairing it with another trend measure.

Why does the indicator return nothing for the first bars? The window is not full, so there is no fit. Our engine returns NaN there rather than zero, for exactly thirteen bars at the default period.

This is educational material, not financial advice. A gradient describes closes that have already printed, every figure above was measured on past bars, and trading carries substantial risk of loss.

Read the trading indicators overview