Indicateur RSI : formule, réglages et lecture
Le RSI (Relative Strength Index) compare la taille moyenne des clôtures en hausse à celle des clôtures en baisse sur une fenêtre d'observation et rend cet équilibre sur une échelle de 0 à 100. Senzoukria le calcule avec le lissage original de Wilder sur les clôtures de barres, avec une période de 14 par défaut.
Senzoukria · Indicateurs · Updated September 2026
RSI — Momentum, dans son propre panneau sous le graphique.
Ce que mesure RSI
Le chiffre rend la proportion entre gain moyen et perte moyenne à l'intérieur de la fenêtre lissée, pas la distance parcourue par le prix. La série est amorcée avec la moyenne simple des quatorze premières variations de clôture à clôture : rien n'est tracé tant que ces quatorze variations n'ont pas été consommées. Ensuite, chaque barre met à jour les deux moyennes par la récursion de Wilder, qui garde en mémoire toutes les variations antérieures avec un poids décroissant. Trois cas limites sont définis explicitement : une fenêtre composée uniquement de gains renvoie 100, une fenêtre composée uniquement de pertes renvoie 0, et une fenêtre parfaitement plate, où les deux moyennes valent zéro, ne renvoie aucune valeur plutôt que 100, parce qu'un marché qui n'a pas bougé ne porte aucune information directionnelle. Le calcul est continu et n'est jamais remis à zéro à la frontière d'une séance.
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 :
Période entière ≥ `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 })); } /** SMA N sur série à trous : null dès qu'UNE valeur de la fenêtre est null — moyenner autour d'un trou mentirait sur la période effective. */ function smaNullable( values: ReadonlyArray<number | null>, period: number, ): Array<number | null> { const n = Math.max(1, Math.floor(period)); const out: Array<number | null> = new Array<number | null>(values.length).fill(null); for (let i = n - 1; i < values.length; i++) { let sum = 0; let ok = true; for (let j = i - n + 1; j <= i; j++) { const v = values[j]; if (v === null) { ok = false; break; } sum += v; } if (ok) out[i] = sum / n; } return out; } /** EMA N sur une série dont les valeurs définies forment un SUFFIXE contigu (sortie d'un lissage précédent) : l'EMA tourne sur le suffixe, le préfixe reste null. Série toute-null (ou trou interne — impossible dans nos usages) → tout-null, on ne devine pas. */ function suffixEma( values: ReadonlyArray<number | null>, period: number, ): Array<number | null> { const out: Array<number | null> = new Array<number | null>(values.length).fill(null); const start = values.findIndex((v) => v !== null); if (start < 0) return out; const defined: number[] = []; for (let i = start; i < values.length; i++) { const v = values[i]; if (v === null) return out; // pas un suffixe contigu → dégradation propre defined.push(v); } const ema = emaSeries(defined, period); for (let j = 0; j < ema.length; j++) out[start + j] = ema[j]; return out; } /** Égalités RSI (documentées) : marché PLAT (les deux moyennes nulles) → null — pas d'information directionnelle (déviation assumée du Pine `down==0 → 100`, qui afficherait 100 sur du plat) ; que des gains → 100 ; que des pertes → 0. */ function rsiValue(avgGain: number, avgLoss: number): number | null { if (avgLoss === 0 && avgGain === 0) return null; if (avgLoss === 0) return 100; if (avgGain === 0) return 0; return 100 - 100 / (1 + avgGain / avgLoss); } /** RSI de Wilder sur une série de valeurs (closes ici, série RSI pour le StochRSI). Graine = moyenne SIMPLE des N premières variations, puis lissage Wilder ; premier point à l'indice N (N variations consommées). */ function wilderRsiSeries( values: readonly number[], period: number, ): Array<number | null> { const n = Math.max(1, Math.floor(period)); const out: Array<number | null> = new Array<number | null>(values.length).fill(null); if (values.length < n + 1) return out; let avgGain = 0; let avgLoss = 0; for (let i = 1; i <= n; i++) { const ch = values[i] - values[i - 1]; if (ch > 0) avgGain += ch; else avgLoss -= ch; } avgGain /= n; avgLoss /= n; out[n] = rsiValue(avgGain, avgLoss); for (let i = n + 1; i < values.length; i++) { const ch = values[i] - values[i - 1]; avgGain = (avgGain * (n - 1) + Math.max(0, ch)) / n; avgLoss = (avgLoss * (n - 1) + Math.max(0, -ch)) / n; out[i] = rsiValue(avgGain, avgLoss); } return out; } /** %K brut : 100·(close − LL_N)/(HH_N − LL_N) sur high/low des barres. Fenêtre PLATE (HH == LL) → null : 0/0 = pas d'information (même règle que delta-percent). */ function rawStochK( bars: readonly FootprintBar[], period: number, ): Array<number | null> { const n = Math.max(1, Math.floor(period)); const out: Array<number | null> = new Array<number | null>(bars.length).fill(null); for (let i = n - 1; i < bars.length; i++) { let hh = Number.NEGATIVE_INFINITY; let ll = Number.POSITIVE_INFINITY; for (let j = i - n + 1; j <= i; j++) { if (bars[j].high > hh) hh = bars[j].high; if (bars[j].low < ll) ll = bars[j].low; } const range = hh - ll; out[i] = range > 0 ? (100 * (bars[i].close - ll)) / range : null; } return out; } function typicalPrice(b: FootprintBar): number { return (b.high + b.low + b.close) / 3; } /** True range de la barre i — TR[0] = high − low (pas de close précédent), même définition que `atrSeries` (averages.ts). */ function trueRangeAt(bars: readonly FootprintBar[], i: number): number { const b = bars[i]; if (i === 0) return b.high - b.low; const pc = bars[i - 1].close; return Math.max(b.high - b.low, Math.abs(b.high - pc), Math.abs(b.low - pc)); } // ── Defs ──────────────────────────────────────────────────────────────────── /** RSI (Wilder, 1978) — lissage WILDER : gain = max(0, close − closeₚ) ; loss = max(0, closeₚ − close) graine = moyenne simple des N premiers gains/losses (à l'indice N) ; puis avg = (avg·(N−1) + x)/N ; RSI = 100 − 100/(1 + avgGain/avgLoss) Égalités : cf. `rsiValue` (plat → null, tout-gain → 100, tout-perte → 0). CONTINU — pas de reset session. Défaut N=14 (Wilder).
Comment le lire
- Une valeur au-dessus de 70 signifie que les clôtures en hausse ont dominé la fenêtre lissée. Dans une tendance installée, le RSI peut y rester longtemps : lisez-le comme la description de ce qui s'est déjà produit, pas comme un signal de retournement.
- Une valeur sous 30 décrit le cas symétrique : les clôtures en baisse ont dominé la fenêtre.
- La ligne des 50 sépare les fenêtres où le gain moyen dépasse la perte moyenne de celles où c'est l'inverse. Un franchissement change cet équilibre ; il n'établit pas une tendance à lui seul.
- Une divergence, où le prix inscrit un plus haut supérieur pendant que le RSI inscrit un plus haut inférieur, dit que la seconde jambe a été construite avec des clôtures en hausse plus petites que la première. Confrontez-la au footprint des deux jambes avant de conclure.
- Une coupure dans la ligne signifie que la fenêtre était plate et qu'aucune valeur n'était définie. Un trou n'est pas une valeur de zéro.
Paramètres et valeurs par défaut
La période vaut 14 par défaut, le choix de Wilder lui-même, et accepte 2 à 200. Une période plus courte réagit plus fortement à chaque nouvelle clôture et touche les zones 30 et 70 bien plus souvent ; une période plus longue aplatit la courbe et rend les extrêmes rares. Le réglage de couleur change seulement le tracé de la ligne dans son panneau.
| Paramètre | Type | Par défaut | Bornes |
|---|---|---|---|
| Period | number | 14 | 2 – 200 |
Ce qu’il ne montre pas
Le RSI lit les clôtures et rien d'autre. Savoir si une jambe a été faite par des acheteurs qui prennent l'ask ou par des vendeurs qui se retirent est une distinction qui vit dans les colonnes bid × ask d'une barre de footprint, et aucune lecture de cette ligne ne la retrouve. Comme la série est continue d'une séance à l'autre, un gap de nuit entre dans le calcul comme une seule grande variation de clôture à clôture, puis continue d'influencer les moyennes pendant de nombreuses barres. Le lissage de Wilder a une longue mémoire par construction : une barre hors norme reste visible dans la valeur bien après son impression. Les passages plats produisent de vraies coupures dans la ligne, pas une valeur par défaut.
Indicateurs liés
- Stochastic — Momentum
- Stoch RSI — Momentum
- CCI — Momentum
- ROC — Momentum
- Williams %R — Momentum
- Momentum — Momentum
Cette page dans d’autres langues
Frequently asked questions
- Que veut dire un RSI à 70 ?
- Un RSI à 70 signifie que, sur la fenêtre d'observation, la clôture en hausse moyenne valait environ 2,33 fois la clôture en baisse moyenne. Il décrit une période où les clôtures acheteuses ont dominé ; ce n'est pas une mesure de la distance que le prix peut encore parcourir, et dans un marché en tendance la valeur peut rester au-dessus de 70 pendant de nombreuses barres consécutives.
- Ce RSI est-il le même que sur les autres plateformes de graphiques ?
- Le lissage est la récursion standard de Wilder amorcée par une moyenne simple des N premières variations, ce qui correspond aux implémentations habituelles. Un cas diffère volontairement : quand le gain moyen et la perte moyenne valent tous les deux zéro, c'est-à-dire quand le marché a été parfaitement plat, Senzoukria ne renvoie aucune valeur, là où certaines versions dérivées de Pine renvoient 100.
- Le RSI est-il remis à zéro au début de chaque séance ?
- Non. La série RSI est ici continue : les moyennes lissées se reportent d'une séance à la suivante. La première variation d'une nouvelle séance est donc l'écart entre la clôture précédente et la nouvelle, un écart qui peut être large sur des contrats futures qui tradent en séances séparées.