Индикатор Linear Regression Slope: формула, настройки и чтение
Linear Regression Slope проводит прямую методом наименьших квадратов через последние N закрытий и выводит наклон этой прямой в единицах цены на бар. Положительное значение означает, что подобранная прямая растёт на протяжении окна; отрицательное — что она падает.
Senzoukria · Индикаторы · Updated September 2026
Linear Regression Slope — Моментум, в отдельной панели под графиком.
Что измеряет Linear Regression Slope
Регрессия вычисляется в центрированной форме: ось времени отсчитывается от середины окна, а не от его первого бара. Этот выбор вычислительный, а не косметический: на пятизначных закрытиях фьючерсов учебная формула вычитает две большие и почти равные суммы, теряя примерно половину значащих цифр. Окно по умолчанию — 20 баров, то же статистическое окно, что у полос Боллинджера и z-score в этом каталоге. Поскольку сумма квадратов отклонений по времени строго положительна для любого окна из двух и более баров, идеально плоское окно даёт наклон ровно 0 — реальное значение, а не замаскированное деление на ноль. Пока окно не заполнено, значение не выводится.
Формула — так, как она реализована
Это не привычное определение из других источников, а то, что вычисляет поставляемый код, задокументированное рядом с реализацией:
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).
Как его читать
- Знак говорит, куда направлена подобранная прямая в окне; он не говорит, находится ли цена сейчас рядом с этой прямой.
- Сравнивайте величину с размером тика инструмента: наклон в четверть тика на бар — совсем не то же самое, что два тика на бар.
- Переход наклона через ноль означает, что прямая наилучшего приближения выровнялась и развернулась, а это происходит уже после разворота самой цены, поскольку старые бары продолжают влиять на подгонку.
- Используйте в паре с R-Squared за тот же период: наклон даёт направление и крутизну, R-Squared говорит, описывает ли прямая это окно вообще.
- Самые старые и самые новые бары окна весят в наклоне МНК больше всего, поэтому единичный выброс на краю сдвигает прямую сильнее, чем в середине.
Параметры и значения по умолчанию
Период по умолчанию — 20, допустимо от 2 до 500. Короткое окно даёт наклон, который часто меняет знак и реагирует за несколько баров; длинное даёт более устойчивое значение, знак которого переживает обычные откаты, ценой более поздней реакции на настоящий разворот.
| Параметр | Тип | По умолчанию | Диапазон |
|---|---|---|---|
| Period | number | 20 | 2 – 500 |
Чего он не показывает
Наклон сообщает крутизну подгонки, но никогда не её качество: у окна чистого шума тоже есть наклон, и он может быть большим. Единица — цена на бар, поэтому значения несравнимы между инструментами, между интервалами баров и при ролловере фьючерсного контракта, когда скачет сам уровень цены. Используются только закрытия, поэтому диапазоны, гэпы и внутрибаровая структура невидимы. Нет и объёма со стороной агрессора: крутой наклон при двух контрактах на бар и крутой наклон при активном участии дают одно и то же число.
Похожие индикаторы
Эта страница на других языках
Frequently asked questions
- Что на самом деле означает значение наклона линейной регрессии?
- Это изменение цены на бар вдоль прямой, лучше всего приближающей последние N закрытий. Наклон 0,5 означает, что подобранная прямая поднимается на полединицы цены от бара к бару; в 20-баровом окне, где первая и последняя точки разделены девятнадцатью барами, это подъём примерно на 9,5 единицы вдоль прямой. Единица — ценовая единица инструмента, поэтому число имеет смысл только рядом с размером тика этого инструмента.
- Наклон линейной регрессии — это то же самое, что наклон скользящей средней?
- Нет. Наклон скользящей средней сравнивает два последовательных значения сглаженного ряда и зависит от того, как это сглаживание взвешивает старые данные. Наклон регрессии проводит одну прямую сразу через все N закрытий и сообщает её крутизну, так что каждый бар окна непосредственно участвует в подгонке.
- Почему плоское ценовое окно показывает наклон ровно ноль?
- Знаменатель наклона МНК зависит только от оси времени и строго положителен для любого окна из двух и более баров. Окно, в котором все закрытия одинаковы, поэтому даёт нулевой числитель, делённый на положительное число, — точный ноль, а не неопределённый результат.