Indicateur Linear Regression Slope : formule, réglages et lecture

La pente de régression linéaire ajuste une droite des moindres carrés sur les N dernières clôtures et trace la pente de cette droite, exprimée en prix par barre. Une valeur positive signifie que la droite ajustée monte sur la fenêtre ; une valeur négative, qu'elle descend.

Senzoukria · Indicateurs · Updated September 2026


Linear Regression Slope Momentum, dans son propre panneau sous le graphique.

Ce que mesure Linear Regression Slope

La régression est calculée sous forme centrée, l'axe du temps étant mesuré depuis le milieu de la fenêtre plutôt que depuis sa première barre. Ce choix est numérique, pas cosmétique : sur des clôtures de futures à cinq chiffres, la formule classique soustrait deux grandes sommes presque égales, ce qui fait perdre environ la moitié des chiffres significatifs. La fenêtre par défaut est de 20 barres, la même fenêtre statistique que celle des bandes de Bollinger et du z-score de ce catalogue. Comme la somme des carrés des écarts de temps est strictement positive pour toute fenêtre d'au moins deux barres, une fenêtre parfaitement plate donne une pente exactement nulle : une vraie valeur, pas une division par zéro masquée. Aucune valeur n'est tracée tant que la fenêtre n'est pas pleine.

La formule, telle qu’implémentée

Ce n'est pas la définition habituelle ailleurs : c'est ce que calcule le code livré, documenté à côté de son implémentation :

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).

Comment le lire

  • Le signe indique dans quel sens pointe la droite ajustée sur la fenêtre ; il ne dit pas si le prix se trouve actuellement près de cette droite.
  • Comparez l'amplitude au tick de l'instrument : une pente d'un quart de tick par barre n'a pas le même sens qu'une pente de deux ticks par barre.
  • Le passage de la pente par zéro signifie que la droite ajustée s'est aplatie puis inversée, ce qui se produit après le retournement du prix lui-même, puisque les barres plus anciennes pèsent encore sur l'ajustement.
  • Associez-la au R-Squared sur la même période : la pente donne la direction et l'inclinaison, le R-Squared dit si une droite décrit vraiment cette fenêtre.
  • Dans une pente des moindres carrés, les barres les plus anciennes et les plus récentes de la fenêtre pèsent le plus : une seule valeur aberrante à l'un des bords déplace davantage la droite qu'une valeur au milieu.

Paramètres et valeurs par défaut

La période vaut 20 par défaut et accepte de 2 à 500. Une fenêtre courte produit une pente qui change souvent de signe et réagit en quelques barres ; une fenêtre longue donne une lecture plus stable, dont le signe résiste aux replis ordinaires, au prix d'une réaction plus tardive à un véritable retournement.

Linear Regression Slope — paramètres exposés dans l’application, avec les valeurs livrées.
ParamètreTypePar défautBornes
Periodnumber202 – 500

Ce qu’il ne montre pas

La pente indique l'inclinaison d'un ajustement, jamais sa qualité : une fenêtre de pur bruit a aussi une pente, et elle peut être forte. L'unité est le prix par barre : les lectures ne sont comparables ni entre instruments, ni entre intervalles de barre, ni de part et d'autre d'un roll de contrat futures où le niveau de prix lui-même saute. Elle n'utilise que les clôtures : ranges, gaps et structure intrabarre sont invisibles. Le volume et le côté agresseur sont également absents : une forte pente sur deux contrats par barre et une forte pente sur une participation importante donnent le même nombre.

Voir tous les indicateurs

Cette page dans d’autres langues

Frequently asked questions

Que signifie concrètement la valeur de la pente de régression linéaire ?
C'est la variation de prix par barre le long de la droite qui s'ajuste le mieux aux N dernières clôtures. Une pente de 0,5 signifie que la droite ajustée monte d'une demi-unité de prix d'une barre à la suivante ; sur une fenêtre de 20 barres, dont le premier et le dernier point sont séparés de dix-neuf barres, cela représente une hausse d'environ 9,5 unités le long de la droite. L'unité est celle du prix de l'instrument : le nombre n'a de sens que rapporté au tick de cet instrument.
La pente de régression linéaire est-elle la même chose que la pente d'une moyenne mobile ?
Non. La pente d'une moyenne mobile compare deux valeurs consécutives d'une série lissée, et dépend donc de la façon dont ce lissage pondère les données anciennes. Une pente de régression ajuste une seule droite sur les N clôtures à la fois et en donne l'inclinaison : chaque barre de la fenêtre contribue directement à l'ajustement.
Pourquoi une fenêtre de prix plate affiche-t-elle une pente exactement nulle ?
Le dénominateur d'une pente des moindres carrés ne dépend que de l'axe du temps, et il est strictement positif pour toute fenêtre d'au moins deux barres. Une fenêtre dont toutes les clôtures sont identiques produit donc un numérateur nul divisé par un nombre positif : un zéro exact, pas un résultat indéfini.

Keep reading