Indicador RSI: fórmula, ajustes y cómo leerlo
El RSI (Relative Strength Index) compara el tamaño medio de los cierres al alza con el de los cierres a la baja dentro de una ventana y expresa ese equilibrio en una escala de 0 a 100. Senzoukria lo calcula con el suavizado original de Wilder sobre los cierres de cada barra, con un periodo por defecto de 14.
Senzoukria · Indicadores · Updated September 2026
RSI — Momentum, en su propio panel debajo del gráfico.
Qué mide RSI
El número expresa la proporción entre la ganancia media y la pérdida media dentro de la ventana suavizada, no la distancia que ha recorrido el precio. La serie arranca con la media simple de los catorce primeros cambios de cierre a cierre, de modo que no se dibuja nada hasta haber consumido esos catorce cambios; a partir de ahí cada barra actualiza ambas medias con la recursión de Wilder, que conserva en memoria todos los cambios anteriores con un peso decreciente. Hay tres casos límite definidos de forma explícita: una ventana con solo ganancias devuelve 100, una ventana con solo pérdidas devuelve 0, y una ventana completamente plana, con ambas medias a cero, no devuelve ningún valor en lugar de 100, porque un mercado que no se ha movido no aporta ninguna información direccional. El cálculo es continuo y nunca se reinicia en el cambio de sesión.
La fórmula, tal como está implementada
No es la definición habitual en otros sitios: es lo que calcula el código que se distribuye, documentado junto a su implementación:
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).
Cómo leerlo
- Una lectura por encima de 70 significa que los cierres al alza han dominado la ventana suavizada. En una tendencia sostenida el RSI puede quedarse ahí mucho tiempo, así que léelo como la descripción de lo que ya ha ocurrido, no como una señal de giro.
- Una lectura por debajo de 30 describe el caso espejo: los cierres a la baja han dominado la ventana.
- La línea de 50 separa las ventanas en las que la ganancia media supera a la pérdida media de aquellas en las que ocurre lo contrario. Cruzarla cambia ese equilibrio; por sí solo no establece una tendencia.
- Una divergencia, cuando el precio marca un máximo más alto y el RSI uno más bajo, indica que el segundo tramo se construyó con cierres al alza más pequeños que el primero. Contrástalo con el footprint de ambos tramos antes de concluir nada.
- Un corte en la línea significa que la ventana estaba plana y no había ningún valor definido. Un hueco no es un valor de cero.
Parámetros y valores por defecto
El periodo por defecto es 14, la elección del propio Wilder, y admite de 2 a 200. Un periodo más corto reacciona con más fuerza a cada nuevo cierre y toca las zonas de 30 y 70 mucho más a menudo; uno más largo aplana la curva y hace raros los extremos. El ajuste de color solo cambia cómo se dibuja la línea en su panel.
| Parámetro | Tipo | Por defecto | Rango |
|---|---|---|---|
| Period | number | 14 | 2 – 200 |
Lo que no muestra
El RSI lee cierres y nada más. Si un tramo lo hicieron compradores barriendo el ask o vendedores apartándose es una distinción que vive en las columnas bid × ask de una barra de footprint, y ninguna lectura de esta línea la recupera. Como la serie es continua entre sesiones, un hueco de la noche entra en el cálculo como un único cambio de cierre a cierre muy grande y sigue influyendo en las medias durante muchas barras. El suavizado de Wilder tiene por diseño una memoria larga, así que una barra desmesurada sigue visible en el valor mucho después de haberse impreso. Los tramos planos producen huecos reales en la línea, no una lectura por defecto.
Indicadores relacionados
- Stochastic — Momentum
- Stoch RSI — Momentum
- CCI — Momentum
- ROC — Momentum
- Williams %R — Momentum
- Momentum — Momentum
Esta página en otros idiomas
Frequently asked questions
- ¿Qué significa un RSI de 70?
- Un RSI de 70 significa que, en la ventana analizada, el cierre medio al alza fue aproximadamente 2,33 veces el cierre medio a la baja. Describe un periodo en el que dominaron los cierres compradores; no mide cuánto recorrido le queda al precio, y en un mercado con tendencia el valor puede mantenerse por encima de 70 durante muchas barras seguidas.
- ¿Es este RSI el mismo que el de otras plataformas de gráficos?
- El suavizado es la recursión estándar de Wilder inicializada con una media simple de los N primeros cambios, que es lo que hacen las implementaciones habituales. Un caso difiere a propósito: cuando la ganancia media y la pérdida media son ambas cero, es decir, el mercado ha estado perfectamente plano, Senzoukria no devuelve ningún valor, mientras que algunas versiones derivadas de Pine devuelven 100 en esa situación.
- ¿Se reinicia el RSI al empezar cada sesión?
- No. Aquí la serie del RSI es continua: las medias suavizadas pasan de una sesión a la siguiente. El primer cambio de una sesión nueva es, por tanto, el hueco entre el cierre anterior y el nuevo, que puede ser grande en contratos de futuros que se negocian en sesiones separadas.