Indicateur Parabolic SAR : formule, réglages et lecture
Le Parabolic SAR (Welles Wilder, 1978) imprime un point par barre à un niveau de stop and reverse qui se rapproche du prix à un rythme accéléré. Senzoukria utilise les facteurs d'origine de Wilder : une accélération qui démarre à 0,02, un pas de 0,02 et un plafond de 0,2.
Senzoukria · Indicateurs · Updated September 2026
Parabolic SAR — Moyennes et volatilité, sur le graphique des prix.
Ce que mesure Parabolic SAR
À chaque barre, le point avance depuis sa position précédente du facteur d'accélération multiplié par la distance au point extrême, le plus haut de la tendance haussière en cours ou le plus bas de la tendance baissière en cours. Deux règles donnent à l'implémentation son comportement exact. Le point est borné de façon à ne jamais pouvoir se placer à l'intérieur de l'amplitude des deux barres précédentes, ce qui empêche un retournement déclenché par le placement de l'indicateur lui-même. Et le facteur d'accélération n'augmente que lorsqu'un nouveau point extrême est atteint : une barre qui ne prolonge pas la tendance laisse le facteur où il est, détail fréquemment mal implémenté. À la bascule, l'ancien point extrême devient le nouveau point, l'extrême est réinitialisé au plus bas ou au plus haut de la barre courante, et le facteur revient à sa valeur de départ.
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 :
Sortie `bands` avec TROU SYNCHRONISÉ : une seule des trois lignes indéfinie ⇒ les trois valent null à cette barre. Une bande à moitié définie (basis sans bord, bord sans basis) n'a aucun sens à l'écran et laisserait le renderer inventer un remplissage. */ function bandsOut( bars: readonly FootprintBar[], upperVals: ReadonlyArray<number | null>, basisVals: ReadonlyArray<number | null>, lowerVals: ReadonlyArray<number | null>, color: string, fillAlpha: number, ): SeriesOutput { const upper: SeriesPoint[] = []; const basis: SeriesPoint[] = []; const lower: SeriesPoint[] = []; for (let i = 0; i < bars.length; i++) { const t = bars[i].bucketTsNs; const u = upperVals[i] ?? null; const m = basisVals[i] ?? null; const l = lowerVals[i] ?? null; const ok = u !== null && m !== null && l !== null; upper.push({ time: t, value: ok ? u : null }); basis.push({ time: t, value: ok ? m : null }); lower.push({ time: t, value: ok ? l : null }); } return { shape: "bands", upper, basis, lower, fillAlpha, style: { color, width: 1 }, }; } /** Milieu (max high + min low)/2 de la fenêtre de N barres se terminant en i — la « ligne médiane » d'Ichimoku (Tenkan/Kijun/Senkou B en dérivent toutes). Warm-up (< N barres) → null. */ function donchianMidSeries( bars: readonly FootprintBar[], period: number, ): Array<number | null> { const n = Math.max(1, Math.floor(period)); const out: Array<number | null> = new Array(bars.length).fill(null); for (let i = n - 1; i < bars.length; i++) { let hi = Number.NEGATIVE_INFINITY; let lo = Number.POSITIVE_INFINITY; for (let j = i - n + 1; j <= i; j++) { if (bars[j].high > hi) hi = bars[j].high; if (bars[j].low < lo) lo = bars[j].low; } out[i] = (hi + lo) / 2; } return out; } /** Moindres carrés y = a + b·t sur la fenêtre de n valeurs se terminant en i (t = 0 pour la plus ancienne, t = n−1 pour la courante). Sommes fermées : Σt = n(n−1)/2, Σt² = n(n−1)(2n−1)/6. Même fit que le LSMA d'averages2.ts — recopié pour que la famille reste autonome (fonction privée là-bas). */ function linFit( values: readonly number[], i: number, n: number, ): { a: number; b: number } { const sumT = (n * (n - 1)) / 2; const sumT2 = (n * (n - 1) * (2 * n - 1)) / 6; let sumY = 0; let sumTY = 0; for (let t = 0; t < n; t++) { const y = values[i - n + 1 + t]; sumY += y; sumTY += t * y; } const denom = n * sumT2 - sumT * sumT; // > 0 dès n ≥ 2 const b = denom > 0 ? (n * sumTY - sumT * sumY) / denom : 0; const a = (sumY - b * sumT) / n; return { a, b }; } /** SMA_P appliquée au SUFFIXE défini d'une série à préfixe null (sortie d'un étage précédent — suffixe contigu par construction). P ≤ 1 → identité. Défensif : un null APRÈS le début du suffixe → tout null (on ne recolle pas deux morceaux séparés par un trou). */ function smoothSuffix( values: ReadonlyArray<number | null>, period: number, ): Array<number | null> { const p = Math.max(1, Math.floor(period)); if (p === 1) return values.slice(); const out: Array<number | null> = new Array(values.length).fill(null); let start = 0; while (start < values.length && values[start] === null) start++; if (start >= values.length) return out; const defined: number[] = []; for (let i = start; i < values.length; i++) { const v = values[i]; if (v === null) return out; defined.push(v); } const s = smaSeries(defined, p); for (let j = 0; j < s.length; j++) out[start + j] = s[j]; return out; } // ── Sessions ──────────────────────────────────────────────────────────────── type SessionOHLC = { o: number; h: number; l: number; c: number }; /** O/H/L/C d'une session complète : open de la PREMIÈRE barre, close de la DERNIÈRE, extrêmes sur toutes les barres. Les tranches de `splitSessions` sont non vides par construction → extrêmes finis. */ function sessionOHLC( bars: readonly FootprintBar[], ses: SessionSlice, ): SessionOHLC { let h = Number.NEGATIVE_INFINITY; let l = Number.POSITIVE_INFINITY; for (let i = ses.start; i <= ses.end; i++) { if (bars[i].high > h) h = bars[i].high; if (bars[i].low < l) l = bars[i].low; } return { o: bars[ses.start].open, h, l, c: bars[ses.end].close }; } /** Projection « session N−1 → session N » commune aux trois familles de pivots : chaque session passée calcule ses niveaux et les trace sur la SUIVANTE (bord droit du chart pour la session courante). La première session chargée n'a pas de précédente → rien n'est inventé. */ function projectedPivots( bars: readonly FootprintBar[], color: string, levelsOf: (prev: SessionOHLC) => Array<[number, string]>, ctx: SeriesContext, ): SeriesOutput[] { const sessions = splitSessions(bars, ctx); const levels: SeriesLevel[] = []; for (let s = 1; s < sessions.length; s++) { const prev = sessionOHLC(bars, sessions[s - 1]); const cur = sessions[s]; const from = bars[cur.start].bucketTsNs; const to = s === sessions.length - 1 ? null : bars[cur.end].bucketTsNs; for (const [price, label] of levelsOf(prev)) { levels.push({ price, from, to, color, label }); } } return [{ shape: "levels", levels }]; } // ── Swing (Fibonacci) ─────────────────────────────────────────────────────── /** Jambe de swing des N dernières barres : plus haut, plus bas, et SENS. Sens = ordre d'apparition des deux extrêmes : le plus haut arrivé APRÈS le plus bas ⇒ jambe HAUSSIÈRE (on retrace vers le bas depuis le sommet) ; sinon jambe BAISSIÈRE. Égalité d'extrêmes (plusieurs barres au même prix) : on garde la DERNIÈRE occurrence (`>=` / `<=`) — c'est le retest le plus récent qui définit la jambe active, pas le premier contact. `null` si moins de N barres (une fenêtre partielle mentirait sur son lookback — règle du catalogue) ou si le range est nul (high = low : il n'y a aucune jambe à retracer, 7 niveaux confondus seraient du bruit). */ type SwingLeg = { hi: number; lo: number; up: boolean; from: number }; function lastSwingLeg( bars: readonly FootprintBar[], lookback: number, ): SwingLeg | null { const n = Math.max(1, Math.floor(lookback)); if (bars.length < n) return null; const start = bars.length - n; let hi = Number.NEGATIVE_INFINITY; let lo = Number.POSITIVE_INFINITY; let hiIdx = start; let loIdx = start; for (let i = start; i < bars.length; i++) { if (bars[i].high >= hi) { hi = bars[i].high; hiIdx = i; } if (bars[i].low <= lo) { lo = bars[i].low; loIdx = i; } } if (!(hi > lo)) return null; return { hi, lo, up: hiIdx >= loIdx, from: bars[start].bucketTsNs }; } // ── Défs ──────────────────────────────────────────────────────────────────── /** Parabolic SAR (Wilder, 1978) — points de stop-and-reverse. AMORÇAGE (barre 1 ; la barre 0 n'émet rien, elle sert de référence) : tendance = HAUSSIÈRE si close[1] ≥ close[0], baissière sinon (l'égalité part haussière — choix arbitraire mais DÉTERMINISTE, documenté) ; SAR[1] = low[0] en hausse / high[0] en baisse ; EP = high[1] en hausse / low[1] en baisse ; AF = afStart. PAS COURANT (i ≥ 2), dans cet ordre EXACT : 1. SAR[i] = SAR[i−1] + AF·(EP − SAR[i−1]) — l'accélération travaille sur la distance au point extrême, pas sur le prix ; 2. BRIDAGE sur les DEUX barres précédentes : en hausse SAR[i] ≤ min(low[i−1], low[i−2]) ; en baisse SAR[i] ≥ max(high[i−1], high[i−2]). Sans cette borne le SAR pourrait se placer à l'intérieur du range récent et déclencher un flip fantôme ; 3. BASCULE : en hausse, low[i] < SAR[i] ⇒ tendance BAISSIÈRE et SAR[i] = EP (l'ancien point extrême devient le stop), EP = low[i], AF remis à afStart. Symétriquement en baisse avec high[i] > SAR[i] ; 4. SANS bascule, MISE À JOUR DE L'AF : uniquement si un NOUVEAU point extrême est fait (high[i] > EP en hausse, low[i] < EP en baisse) → EP = ce nouvel extrême et AF = min(AF + afStep, afMax). Une barre qui n'étend pas la tendance ne fait PAS accélérer l'AF (erreur classique). Défauts de Wilder : afStart 0.02, afStep 0.02, afMax 0.2. Sortie : un dot par barre (à partir de la barre 1) au niveau du SAR, coloré par la tendance COURANTE — la barre de flip porte déjà la couleur de la nouvelle tendance.
Comment le lire
- Un point sous les barres signifie que l'état courant est haussier et que le point est le niveau qui le renverserait ; un point au-dessus signifie l'inverse.
- Des points qui se rapprochent du prix de plus en plus vite d'une barre à l'autre montrent que le facteur d'accélération a été relevé à plusieurs reprises, ce qui n'arrive que tant que la tendance fait de nouveaux extrêmes.
- Des points régulièrement espacés qui cessent de converger vous disent que la tendance ne s'étend plus, même si l'état n'a pas encore changé.
- La barre sur laquelle l'état bascule porte déjà la couleur du nouvel état : lisez le changement de couleur comme la bascule elle-même, pas comme un avertissement qui la précède.
Paramètres et valeurs par défaut
AF start et AF step valent 0,02 par défaut, tous deux réglables de 0,001 à 0,5, et AF max vaut 0,2 par défaut dans une plage de 0,01 à 1 ; ce sont les valeurs publiées par Wilder. Augmenter le départ ou le pas fait se rapprocher les points du prix plus tôt et raccourcit le temps moyen avant une bascule, tandis qu'augmenter le plafond laisse l'accélération continuer à croître dans une longue tendance. À un facteur de 1, le point sauterait directement sur le point extrême en une seule barre : c'est pourquoi le plafond reste normalement bien en deçà. Le premier point est émis à la deuxième barre de la série, amorcé sur le plus haut ou le plus bas de la première.
| Paramètre | Type | Par défaut | Bornes |
|---|---|---|---|
| AF start | number | 0.02 | 0.001 – 0.5 |
| AF step | number | 0.02 | 0.001 – 0.5 |
| AF max | number | 0.2 | 0.01 – 1 |
Ce qu’il ne montre pas
Le Parabolic SAR porte toujours un état : il n'est jamais neutre. Dans un marché sans direction, il bascule d'un sens à l'autre et produit une suite de retournements qui ne correspondent à aucune tendance. Il n'a aucun terme de volatilité au-delà des plus hauts et plus bas récents utilisés pour la borne : il ne s'adapte donc pas à un changement de régime comme le fait un stop fondé sur l'ATR. L'état initial est décidé en comparant les deux premières clôtures, l'égalité étant tranchée en haussier : un graphique chargé à partir d'une autre barre de départ peut donc démarrer dans l'autre état. Et tout le calcul est de la géométrie de prix : plus hauts, plus bas et clôtures décident de tout, sans aucun terme de volume.
Indicateurs liés
- SMA — Moyennes et volatilité
- EMA — Moyennes et volatilité
- WMA — Moyennes et volatilité
- Hull MA — Moyennes et volatilité
- ATR (Wilder) — Moyennes et volatilité
- Bollinger — Moyennes et volatilité
Cette page dans d’autres langues
Frequently asked questions
- Que représente un point du Parabolic SAR ?
- C'est le niveau de stop and reverse de cette barre. Tant que l'état de tendance est haussier, le point se tient sous le prix et remonte vers lui ; si le plus bas d'une barre passe sous le point, l'état se retourne et le point passe au-dessus du prix. Le point est un niveau calculé à partir des barres passées, pas une prévision de l'endroit où le prix ira.
- Quand le facteur d'accélération augmente-t-il ?
- Uniquement quand la tendance enregistre un nouveau point extrême, c'est-à-dire un plus haut supérieur en tendance haussière ou un plus bas inférieur en tendance baissière. Dans ce cas, le facteur augmente du pas, 0,02 par défaut, jusqu'au plafond de 0,2. Une barre qui ne prolonge pas la tendance laisse le facteur inchangé, et les points cessent de converger.
- Pourquoi le Parabolic SAR bascule-t-il si souvent en range ?
- Parce qu'il est toujours dans un état ou dans l'autre et que son niveau se rapproche du prix à chaque barre. En range, le prix n'a pas de direction durable : le point rattrape et se retourne à répétition. Le calcul est fait pour suivre une tendance existante et n'a aucun mécanisme pour signaler son absence.