Indicador Linear Regression Slope: fórmula, ajustes y cómo leerlo

La pendiente de regresión lineal ajusta una recta por mínimos cuadrados a los últimos N cierres y traza la pendiente de esa recta, expresada en precio por barra. Un valor positivo significa que la recta ajustada sube a lo largo de la ventana; uno negativo, que baja.

Senzoukria · Indicadores · Updated September 2026


Linear Regression Slope Momentum, en su propio panel debajo del gráfico.

Qué mide Linear Regression Slope

La regresión se calcula en forma centrada, midiendo el eje temporal desde el centro de la ventana y no desde su primera barra. Es una elección numérica, no estética: con cierres de futuros de cinco cifras, la fórmula de manual resta dos sumas grandes y casi iguales, lo que descarta aproximadamente la mitad de las cifras significativas. La ventana por defecto es de 20 barras, la misma ventana estadística que usan las bandas de Bollinger y el z-score de este catálogo. Como la suma de las desviaciones temporales al cuadrado es estrictamente positiva para cualquier ventana de dos barras o más, una ventana totalmente plana da una pendiente exactamente 0: un valor real, no una división por cero enmascarada. No se traza ningún valor antes de que la ventana esté completa.

La fórmula, tal como está implementada

No es la definición habitual en otros sitios: es lo que calcula el código que se distribuye, documentado junto a su implementación:

Entier ≥ `min` depuis les params (garde-fou UI). */ function intParam( params: Record<string, unknown>, key: string, fallback: number, min = 1, ): number { return Math.max(min, Math.floor(numParam(params, key, fallback))); } function toPoints( bars: readonly FootprintBar[], values: ReadonlyArray<number | null>, ): SeriesPoint[] { return bars.map((b, i) => ({ time: b.bucketTsNs, value: values[i] ?? null })); } /** Rendements alignés sur les barres : ret[i] = close[i] − close[i−1] ; ret[0] = null (pas de barre précédente). Cf. en-tête pour le choix différence vs log-return. */ function closeReturns(bars: readonly FootprintBar[]): Array<number | null> { return bars.map((b, i) => (i === 0 ? null : b.close - bars[i - 1].close)); } /** Les N derniers rendements se terminant à la barre `i`. `null` tant que la fenêtre n'est pas pleine — il faut i ≥ N puisque ret[0] n'existe pas. */ function returnWindow( rets: ReadonlyArray<number | null>, i: number, n: number, ): number[] | null { if (i < n) return null; const win: number[] = []; for (let j = i - n + 1; j <= i; j++) { const r = rets[j]; if (r === null) return null; win.push(r); } return win; } /** Les N derniers closes se terminant à la barre `i` (i ≥ N−1). */ function closeWindow( bars: readonly FootprintBar[], i: number, n: number, ): number[] { const win: number[] = new Array<number>(n); for (let j = 0; j < n; j++) win[j] = bars[i - n + 1 + j].close; return win; } /** Moyenne et Σ(x − moyenne)² — TWO-PASS (cf. en-tête). Tableau vide → ss = 0 et moyenne 0 : les appelants ne passent jamais de fenêtre vide, la garde `ss > 0` en aval couvre le cas. */ function meanSS(xs: readonly number[]): { mean: number; ss: number } { if (xs.length === 0) return { mean: 0, ss: 0 }; let sum = 0; for (const x of xs) sum += x; const mean = sum / xs.length; let ss = 0; for (const x of xs) { const d = x - mean; ss += d * d; } return { mean, ss }; } /** Corrélation de Pearson TWO-PASS entre deux séries de même longueur : r = Σ(x−x̄)(y−ȳ) / ( √Σ(x−x̄)² · √Σ(y−ȳ)² ) Deux racines SÉPARÉES au dénominateur (jamais √(Sxx·Syy)) : le produit de deux sommes de carrés déborderait sur des volumes cumulés. Sxx ou Syy nul (une des deux séries plate) → null : la corrélation est indéfinie, pas « 0 ». Borné dur [−1, 1] — l'arrondi f64 peut dépasser de 1 ulp sur une corrélation parfaite. */ function pearson(xs: readonly number[], ys: readonly number[]): number | null { const a = meanSS(xs); const b = meanSS(ys); if (!(a.ss > 0) || !(b.ss > 0)) return null; let sxy = 0; for (let i = 0; i < xs.length; i++) { sxy += (xs[i] - a.mean) * (ys[i] - b.mean); } return clamp(sxy / (Math.sqrt(a.ss) * Math.sqrt(b.ss)), -1, 1); } function clamp(v: number, lo: number, hi: number): number { return Math.min(hi, Math.max(lo, v)); } type Fit = { /** Pente b de y = a + b·t, en unités de PRIX PAR BARRE. */ slope: number; /** Valeur du fit au point COURANT : a + b·(n−1). */ value: number; /** Coefficient de détermination ∈ [0,1] ; null si la fenêtre est plate. */ r2: number | null; }; /** Moindres carrés y = a + b·t sur t = 0 (la plus ANCIENNE) … n−1 (la courante), formulation CENTRÉE : t̄ = (n−1)/2 ; Sxx = Σ(t−t̄)² = n(n²−1)/12 ; Sxy = Σ(t−t̄)(y−ȳ) b = Sxy/Sxx ; a = ȳ − b·t̄ ; fit(n−1) = ȳ + b·(n−1)/2 R² = Sxy² / (Sxx·Syy) (Syy = Σ(y−ȳ)²) Centrée et non « normale » (Σt·y) : sur des closes de futures à 5 chiffres, Σt·y et Σt·Σy sont deux grands nombres presque égaux — leur différence perd la moitié des chiffres significatifs. Sxx > 0 dès n ≥ 2, donc la pente n'a JAMAIS de division par zéro (une fenêtre plate rend une pente 0 EXACTE, pas un 0/0). Syy = 0 → R² null (variance nulle, cf. en-tête). n < 2 → null (pas de droite à ajuster). / function regressFit(ys: readonly number[]): Fit | null { const n = ys.length; if (n < 2) return null; const tBar = (n - 1) / 2; const { mean: yBar, ss: syy } = meanSS(ys); let sxx = 0; let sxy = 0; for (let t = 0; t < n; t++) { const dt = t - tBar; sxx += dt * dt; sxy += dt * (ys[t] - yBar); } const slope = sxy / sxx; // sxx = n(n²−1)/12 > 0 dès n ≥ 2 return { slope, value: yBar + slope * (n - 1 - tBar), r2: syy > 0 ? clamp((sxy * sxy) / (sxx * syy), 0, 1) : null, }; } /** Moment centré d'ordre p, convention POPULATION (÷N). */ function centralMoment( xs: readonly number[], mean: number, p: number, ): number { let acc = 0; for (const x of xs) acc += (x - mean) ** p; return acc / xs.length; } /** Dimension fractale de HIGUCHI (1988) sur une fenêtre de n valeurs : pour k = 1…kmax et m = 1…k (sous-séries décimées de pas k, départ m) : L_m(k) = [ Σ_{i=1..⌊(n−m)/k⌋} |x(m+ik) − x(m+(i−1)k)| · (n−1) / (⌊(n−m)/k⌋ · k) ] / k L(k) = moyenne des L_m(k) sur m L(k) ∝ k^(−D) ⇒ D = − pente de ln L(k) vs ln k (moindres carrés). Higuchi PLUTÔT que Katz ou box-counting : c'est l'estimateur de référence sur une série temporelle échantillonnée régulièrement (les barres le sont), il ne dépend d'aucune échelle d'amplitude (Katz mélange une distance de prix et un nombre de pas — donc dépend de l'instrument) et il se calcule en O(n·kmax) sans structure auxiliaire. D ∈ [1, 2] en théorie (1 = courbe lisse, 2 = bruit qui remplit le plan) ; l'estimateur n'est PAS borné artificiellement — on rend ce que la pente dit. kmax est clampé à ⌊n/2⌋ (au-delà, les sous-séries n'ont plus qu'un segment et L(k) n'a plus de sens) et à 2 minimum (une pente exige 2 points). Un L(k) nul (fenêtre plate, ou zigzag exactement en phase avec le pas k) rend le log-log indéfini → null : on ne trace pas une pente amputée. / function higuchiFd(x: readonly number[], kmaxParam: number): number | null { const n = x.length; const kmax = Math.min(Math.max(2, Math.floor(kmaxParam)), Math.floor(n / 2)); if (n < 4 || kmax < 2) return null; const lnK: number[] = []; const lnL: number[] = []; for (let k = 1; k <= kmax; k++) { let acc = 0; let used = 0; for (let m = 1; m <= k; m++) { const count = Math.floor((n - m) / k); if (count < 1) continue; let sum = 0; for (let i = 1; i <= count; i++) { sum += Math.abs(x[m + i * k - 1] - x[m + (i - 1) * k - 1]); } acc += (sum * (n - 1)) / (count * k * k); used += 1; } if (used === 0) return null; const lk = acc / used; if (!(lk > 0)) return null; // ln indéfini → pas de valeur inventée lnK.push(Math.log(k)); lnL.push(Math.log(lk)); } if (lnK.length < 2) return null; const a = meanSS(lnK); if (!(a.ss > 0)) return null; const yBar = meanSS(lnL).mean; let sxy = 0; for (let i = 0; i < lnK.length; i++) sxy += (lnK[i] - a.mean) * (lnL[i] - yBar); return -(sxy / a.ss); } // ── Défs — régression linéaire (le trio partage fenêtre et formule) ───────── /** Pente de la régression linéaire des N derniers closes (moindres carrés, formulation centrée — cf. `regressFit`), en PRIX PAR BARRE : > 0 = la droite monte. Défaut N=20 (la fenêtre statistique standard du catalogue, celle des Bollinger et du z-score). Warm-up (< N barres) → null ; fenêtre plate → 0 EXACT (Sxx > 0, ce n'est pas un 0/0).

Cómo leerlo

  • El signo indica hacia dónde apunta la recta ajustada en la ventana; no dice si el precio está ahora cerca de esa recta.
  • Compara la magnitud con el tamaño del tick del instrumento: una pendiente de un cuarto de tick por barra no dice lo mismo que una de dos ticks por barra.
  • Que la pendiente cruce cero significa que la recta de mejor ajuste de la ventana se ha aplanado y ha girado, lo que ocurre después de que el propio precio haya girado, ya que las barras más antiguas siguen pesando en el ajuste.
  • Combínala con el R-Squared del mismo periodo: la pendiente da la dirección y la inclinación, el R-Squared dice si una recta describe siquiera esa ventana.
  • En una pendiente por mínimos cuadrados, las barras más antiguas y más recientes de la ventana son las que más pesan, así que un valor atípico en un extremo mueve la recta más que uno en el centro.

Parámetros y valores por defecto

El periodo es 20 por defecto y admite de 2 a 500. Una ventana corta produce una pendiente que cambia de signo con frecuencia y reacciona en pocas barras; una larga da una lectura más estable cuyo signo resiste los retrocesos corrientes, a costa de reaccionar más tarde a un giro real.

Linear Regression Slope — parámetros disponibles en la aplicación, con los valores con los que se distribuye.
ParámetroTipoPor defectoRango
Periodnumber202 – 500

Lo que no muestra

La pendiente informa de la inclinación de un ajuste, nunca de su calidad: una ventana de puro ruido también tiene pendiente, y puede ser grande. La unidad es precio por barra, así que las lecturas no son comparables entre instrumentos, entre intervalos de barra ni a través de un roll de contrato de futuros donde el propio nivel de precio salta. Usa solo los cierres, así que los rangos, los gaps y la estructura intrabarra son invisibles. Tampoco intervienen el volumen ni el lado agresor: una pendiente fuerte con dos contratos por barra y otra con una participación intensa dan el mismo número.

Ver todos los indicadores

Esta página en otros idiomas

Frequently asked questions

¿Qué significa realmente el valor de la pendiente de regresión lineal?
Es la variación de precio por barra a lo largo de la recta que mejor se ajusta a los últimos N cierres. Una pendiente de 0,5 significa que la recta ajustada sube media unidad de precio de una barra a la siguiente; en una ventana de 20 barras, cuyos puntos primero y último están separados diecinueve barras, eso supone una subida de unas 9,5 unidades a lo largo de la recta. La unidad es la del precio del instrumento, así que el número solo tiene sentido junto al tamaño del tick de ese instrumento.
¿La pendiente de regresión lineal es lo mismo que la pendiente de una media móvil?
No. La pendiente de una media móvil compara dos valores consecutivos de una serie suavizada, lo que depende de cómo ese suavizado pondere los datos antiguos. La pendiente de regresión ajusta una sola recta a los N cierres a la vez e informa de su inclinación, así que cada barra de la ventana contribuye directamente al ajuste.
¿Por qué una ventana de precio plana muestra una pendiente exactamente cero?
El denominador de una pendiente por mínimos cuadrados solo depende del eje temporal, y es estrictamente positivo para cualquier ventana de dos barras o más. Una ventana en la que todos los cierres son idénticos produce, por tanto, un numerador de cero dividido entre un número positivo: un cero exacto, no un resultado indefinido.

Keep reading