Indicatore Linear Regression Slope: formula, impostazioni e lettura
La Linear Regression Slope adatta una retta ai minimi quadrati alle ultime N chiusure e traccia la pendenza di quella retta, espressa in prezzo per barra. Un valore positivo significa che la retta stimata sale lungo la finestra; un valore negativo, che scende.
Senzoukria · Indicatori · Updated September 2026
Linear Regression Slope — Momentum, in un pannello separato sotto il grafico.
Che cosa misura Linear Regression Slope
La regressione è calcolata in forma centrata, con l'asse del tempo misurato dal centro della finestra anziché dalla sua prima barra. È una scelta numerica, non estetica: sulle chiusure dei futures a cinque cifre, la formulazione da manuale sottrae due somme grandi e quasi uguali, perdendo circa metà delle cifre significative. La finestra predefinita è di 20 barre, la stessa finestra statistica usata dalle bande di Bollinger e dallo z-score di questo catalogo. Poiché la somma degli scarti temporali al quadrato è strettamente positiva per qualsiasi finestra di due o più barre, una finestra perfettamente piatta produce una pendenza esattamente pari a 0: un valore reale, non una divisione per zero mascherata. Prima che la finestra sia piena, non viene tracciato alcun valore.
La formula, così come è implementata
Non è la definizione consueta altrove: è ciò che calcola il codice distribuito, documentato accanto alla sua implementazione:
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).
Come leggerlo
- Il segno indica in che direzione punta la retta stimata sulla finestra; non dice se il prezzo è attualmente vicino a quella retta.
- Confronta l'ampiezza con il tick size dello strumento: una pendenza di un quarto di tick per barra è un'affermazione diversa da una pendenza di due tick per barra.
- La pendenza che incrocia lo zero significa che la retta di miglior adattamento sulla finestra si è appiattita e invertita, il che avviene dopo che il prezzo stesso ha girato, perché le barre più vecchie pesano ancora sulla stima.
- Abbinala all'R-Squared sullo stesso periodo: la pendenza dà direzione e inclinazione, l'R-Squared dice se una retta descrive davvero quella finestra.
- In una pendenza ai minimi quadrati, le barre più vecchie e più recenti della finestra pesano di più, quindi un singolo valore anomalo a uno dei due estremi sposta la retta più di uno al centro.
Parametri e valori predefiniti
Il periodo vale 20 per default e accetta valori da 2 a 500. Una finestra corta produce una pendenza che cambia segno spesso e reagisce in poche barre; una finestra lunga produce una lettura più stabile, il cui segno resiste ai normali ritracciamenti, a costo di reagire più tardi a una vera svolta.
| Parametro | Tipo | Predefinito | Intervallo |
|---|---|---|---|
| Period | number | 20 | 2 – 500 |
Ciò che non mostra
La pendenza indica l'inclinazione di una stima, mai la sua qualità: anche una finestra di puro rumore ha una pendenza, e può essere grande. L'unità è il prezzo per barra, quindi le letture non sono confrontabili tra strumenti, tra intervalli di barra o al rollover di un contratto futures, dove il livello di prezzo stesso salta. Usa solo le chiusure, quindi range, gap e struttura interna alla barra sono invisibili. Mancano anche il volume e il lato aggressore: una pendenza ripida con due contratti per barra e una pendenza ripida con una partecipazione forte producono lo stesso numero.
Indicatori correlati
Questa pagina in altre lingue
Frequently asked questions
- Cosa significa concretamente il valore della pendenza di regressione lineare?
- È la variazione di prezzo per barra lungo la retta che meglio si adatta alle ultime N chiusure. Una pendenza di 0,5 significa che la retta stimata sale di mezza unità di prezzo da una barra all'altra; su una finestra di 20 barre, i cui primo e ultimo punto distano diciannove barre, è un rialzo di circa 9,5 unità lungo la retta. L'unità è quella di prezzo dello strumento, quindi il numero ha senso solo accanto al tick size di quello strumento.
- La pendenza di regressione lineare è la stessa cosa della pendenza di una media mobile?
- No. La pendenza di una media mobile confronta due valori consecutivi di una serie smussata, e dipende da come quello smussamento pesa i dati vecchi. Una pendenza di regressione adatta un'unica retta a tutte le N chiusure insieme e ne riporta l'inclinazione, quindi ogni barra della finestra contribuisce direttamente alla stima.
- Perché una finestra di prezzo piatta mostra una pendenza esattamente pari a zero?
- Il denominatore di una pendenza ai minimi quadrati dipende solo dall'asse del tempo ed è strettamente positivo per qualsiasi finestra di due o più barre. Una finestra in cui tutte le chiusure sono identiche produce quindi un numeratore pari a zero diviso per un numero positivo: uno zero esatto, non un risultato indefinito.