Indicador Awesome Oscillator: fórmula, ajustes y cómo leerlo
El Awesome Oscillator es el histograma de momentum de Bill Williams: la media móvil simple de 5 periodos del precio medio de la barra menos la de 34 periodos. Se dibuja en un panel aparte y es positivo cuando el centro del rango a corto horizonte está por encima del de largo horizonte.
Senzoukria · Indicadores · Updated September 2026
Awesome Oscillator — Momentum, en su propio panel debajo del gráfico.
Qué mide Awesome Oscillator
La entrada es el precio medio, (máximo + mínimo) / 2, y no el cierre: Williams quería el movimiento del centro de la subasta a través de dos horizontes, y el cierre es una única instantánea de fin de barra, ruidosa en futuros intradía. Los dos términos son medias móviles simples corrientes — en la definición original no hay suavizado exponencial ni de Wilder, y aquí tampoco. Los valores por defecto 5/34 vienen del trabajo diario de Williams, aproximadamente una semana frente a un mes, y se mantienen intactos por paridad con otras plataformas. No se emite ningún punto del histograma hasta que la media lenta está completa, de modo que las primeras barras quedan en blanco en lugar de aproximarse.
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, même helper que momentum.ts / stats.ts). */ function intParam( params: Record<string, unknown>, key: string, fallback: number, min = 1, ): number { return Math.max(min, Math.floor(numParam(params, key, fallback))); } function clamp(v: number, lo: number, hi: number): number { return Math.min(hi, Math.max(lo, v)); } function toPoints( bars: readonly FootprintBar[], values: ReadonlyArray<number | null>, ): SeriesPoint[] { return bars.map((b, i) => ({ time: b.bucketTsNs, value: values[i] ?? null })); } /** Histogramme : une barre sans valeur n'émet PAS de point (contrat `HistogramPoint`, pas de trou représentable). */ function histPoints( bars: readonly FootprintBar[], values: ReadonlyArray<number | null>, ): HistogramPoint[] { const out: HistogramPoint[] = []; for (let i = 0; i < bars.length; i++) { const v = values[i]; if (v !== null && v !== undefined) { out.push({ time: bars[i].bucketTsNs, value: v }); } } return out; } /** 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; } /** WMA N (poids linéaires 1..N, le plus récent pèse N) tolérante aux trous : null dès qu'une valeur manque dans la fenêtre. Même formule que `helpers.wmaSeries`, qui n'accepte que des `number[]`. */ function wmaNullable( values: ReadonlyArray<number | null>, period: number, ): Array<number | null> { const n = Math.max(1, Math.floor(period)); const denom = (n * (n + 1)) / 2; const out: Array<number | null> = new Array<number | null>(values.length).fill(null); for (let i = n - 1; i < values.length; i++) { let acc = 0; let ok = true; for (let j = 0; j < n; j++) { const v = values[i - n + 1 + j]; if (v === null) { ok = false; break; } acc += v * (j + 1); } if (ok) out[i] = acc / denom; } return out; } /** EMA N (graine SMA) sur une série dont les valeurs définies forment un SUFFIXE contigu — sortie d'un lissage précédent. Le préfixe reste null ; série toute-null ou trou interne → tout-null (dégradation propre, on ne devine pas). Copie locale de la primitive de momentum.ts (non exportée). */ 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; defined.push(v); } const ema = emaSeries(defined, period); for (let j = 0; j < ema.length; j++) out[start + j] = ema[j]; return out; } /** ROC en POURCENT : 100·(x[i] − x[i−N])/x[i−N]. Référence NULLE → null (pas de division par zéro déguisée) — même règle que `roc` (momentum.ts). */ function rocPercentSeries( 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); for (let i = n; i < values.length; i++) { const ref = values[i - n]; if (ref !== 0) out[i] = (100 * (values[i] - ref)) / ref; } return out; } /** Prix médian de la barre — l'entrée de Bill Williams et d'Ehlers. */ function hl2(b: FootprintBar): number { return (b.high + b.low) / 2; } /** Égalités RSI, STRICTEMENT celles de `rsi` (momentum.ts) : marché PLAT (les deux moyennes nulles) → null (pas d'information directionnelle) ; 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 quelconque (closes, ou série de streaks pour Connors). Graine = moyenne SIMPLE des N premières variations, puis lissage Wilder avg = (avg·(N−1) + x)/N ; premier point à l'indice N. Copie locale de la primitive de momentum.ts (non exportée) — même formule, mêmes égalités, donc `connors-rsi` et `rsi` restent cohérents à l'écran. */ 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; } /** AO de Bill Williams — factorisé parce que l'Accelerator le consomme : SMA_fast(hl2) − SMA_slow(hl2), null tant que la LENTE n'est pas amorcée. */ function awesomeSeries( bars: readonly FootprintBar[], fast: number, slow: number, ): Array<number | null> { const mid = bars.map(hl2); const f = smaSeries(mid, fast); const s = smaSeries(mid, slow); return mid.map((_, i) => { const a = f[i]; const b = s[i]; return a !== null && b !== null ? a - b : null; }); } /** Étage « stochastique + lissage exponentiel à facteur fixe » de Schaff — factorisé parce que STC l'applique DEUX FOIS (cf. sa déf) : %K = 100·(x − min(x, cycle))/(max(x, cycle) − min(x, cycle)) état ← (premier %K défini) puis état + f·(%K − état) Fenêtre PLATE (max == min) ou incomplète → sortie null ET ÉTAT FIGÉ : on ne nourrit pas la récurrence avec un %K inventé, et on ne reconduit pas la dernière valeur (le `nz(f1[1])` des portages Pine peindrait un plateau faux). Un trou ainsi créé se propage aux fenêtres suivantes qui le contiennent — c'est le comportement voulu. / function schaffStage( src: ReadonlyArray<number | null>, cycle: number, factor: number, ): Array<number | null> { const n = Math.max(2, Math.floor(cycle)); const out: Array<number | null> = new Array<number | null>(src.length).fill(null); let state: number | null = null; for (let i = n - 1; i < src.length; i++) { let lo = Number.POSITIVE_INFINITY; let hi = Number.NEGATIVE_INFINITY; let ok = true; for (let j = i - n + 1; j <= i; j++) { const v = src[j]; if (v === null) { ok = false; break; } if (v < lo) lo = v; if (v > hi) hi = v; } const cur = src[i]; if (!ok || cur === null) continue; // trou → état figé, sortie null const range = hi - lo; if (!(range > 0)) continue; // fenêtre plate → null, jamais 0 const k = (100 * (cur - lo)) / range; state = state === null ? k : state + factor * (k - state); out[i] = state; } return out; } // ── Défs — Bill Williams ──────────────────────────────────────────────────── /** Awesome Oscillator (Bill Williams) — lissage SMA SIMPLE (pas d'EMA, pas de Wilder ; c'est la définition originale) sur le PRIX MÉDIAN : hl2 = (high + low)/2 AO = SMA_fast(hl2) − SMA_slow(hl2) POURQUOI hl2 et pas le close : Williams mesure le déplacement du CENTRE de l'enchère sur deux horizons ; le close n'est qu'un instantané de fin de barre, très bruité en intraday futures. Défauts 5/34 (Williams) — la paire « une semaine / un mois » de son analyse quotidienne, gardée telle quelle pour la parité avec ATAS/TradingView. HISTOGRAMME : warm-up (< slow barres) → AUCUN point. Le renderer colore par SIGNE (contrat `SeriesOutput.histogram`) ; Bill Williams colore par SENS DE VARIATION barre à barre — écart assumé et documenté, le shape du moteur ne transporte pas de couleur par point.
Cómo leerlo
- Por encima de cero, el centro del rango a corto horizonte está por encima del de largo horizonte; por debajo de cero, al revés. La línea de cero es el único nivel que define la fórmula.
- La distancia al cero mide cuánto se han separado los dos horizontes: eso es magnitud de momentum, no convicción.
- Barras que se encogen mientras el precio sigue avanzando dicen que las dos medias están convergiendo y que el movimiento se desacelera.
- Un máximo de precio más alto frente a un máximo de AO más bajo es una divergencia de momentum: la descripción de lo que ya ha ocurrido, no un pronóstico.
- En un mercado equilibrado las barras oscilan muy pegadas al cero y los cambios de signo significan poco.
Parámetros y valores por defecto
rápida (5) y lenta (34) fijan los dos horizontes de promediado; es la distancia entre ellos, más que su tamaño absoluto, lo que gobierna la amplitud. Acercarlas da un histograma más tranquilo con cambios de signo frecuentes; separarlas da oscilaciones mayores y más lentas, y un calentamiento más largo. Los dos colores solo afectan a la visualización.
| Parámetro | Tipo | Por defecto | Rango |
|---|---|---|---|
| Fast SMA | number | 5 | 1 – 200 |
| Slow SMA | number | 34 | 2 – 500 |
Lo que no muestra
El Awesome Oscillator es solo precio: no le llega volumen, delta ni información del libro, así que no puede separar una subida que se encontró con ventas agresivas de otra que no se encontró con nada. Va con retraso por construcción, ya que ambos términos son medias rezagadas. El precio medio ignora además dónde cerró la barra, así que una barra que se dio la vuelta con fuerza hacia su cierre se lee igual que otra que aguantó en máximos. Una nota sobre la visualización: aquí las barras se colorean según el signo del valor, mientras que Williams coloreaba cada barra según su cambio respecto de la anterior, así que los mismos datos pueden verse distintos de una plataforma a otra.
Indicadores relacionados
Esta página en otros idiomas
Frequently asked questions
- ¿Por qué el Awesome Oscillator usa el precio medio en vez del cierre?
- Williams lo diseñó para seguir el centro de la subasta a través de dos horizontes, y el precio medio, (máximo + mínimo) / 2, resume dónde negoció la barra en lugar de dónde le tocó pararse. El cierre es un único instante al final de la barra y es ruidoso en barras intradía cortas. Como consecuencia, el oscilador ignora un cierre fuerte dentro de un rango por lo demás invariable.
- ¿Qué significa un cruce de la línea de cero del Awesome Oscillator?
- Significa que la media de 5 periodos del precio medio ha cruzado la de 34 periodos, es decir, que el horizonte corto ha pasado de un lado al otro del horizonte largo. Es una afirmación sobre dos medias rezagadas, y ambas ya se han movido antes de que se imprima el cruce. En condiciones de rango las dos medias están muy juntas y los cruces ocurren con diferencias mínimas.
- ¿Los periodos 5 y 34 tienen que quedarse en sus valores por defecto?
- No: ambos son editables, de 1 a 200 para la media rápida y de 2 a 500 para la lenta. Los valores por defecto son los del propio Williams y se mantienen para que las lecturas coincidan con las de otras plataformas que usan el mismo par. Cambiarlos cambia la amplitud y el calentamiento, así que las comparaciones con gráficos en ajustes por defecto dejan de valer.