// Indicator Manual
JavaScript Indicators
Cree su propio indicador en el editor de scripts — ejemplos listos para usar, la biblioteca de cálculos integrada y cómo llevar su indicador al gráfico.

Para qué sirve
Todos los indicadores de QUANTIX los escribió alguien. El editor de scripts permite que ese alguien sea usted: describa lo que quiere ver y se dibujará en el gráfico junto a las herramientas integradas.
Si viene de TradingView, esta es nuestra respuesta a Pine Script. La diferencia es el lenguaje: aquí es JavaScript, así que cualquier ejemplo de un tutorial, un artículo o un asistente de IA funciona tal cual.
No hace falta empezar de cero
El editor se abre con un indicador que ya funciona. Cambie un número, pulse Save & Run y mire el gráfico. Esa es una primera sesión completa: todo lo que sigue es para cuando quiera más.
Su primer indicador en cinco pasos
- Abra el terminal y pulse el botón
</>Script en la barra de herramientas. - Escriba un nombre en el campo Name: así aparecerá en su lista de indicadores.
- En Params, indique el número con el que trabaja el indicador. En el ejemplo que se abre,
20es la longitud de la media móvil. - Elija Placement: Main dibuja sobre las velas, Sub abre un panel aparte debajo. Más sobre esta elección a continuación.
- Pulse Save & Run (o Ctrl / ⌘ + Enter). El indicador aparece en el gráfico y a partir de ahí vive en Indicators → Custom junto a los demás.
Ese es el ciclo completo. Todo lo demás en esta página trata de qué poner en el medio.
Main o Sub — decídalo antes de escribir
Esta única elección determina si su indicador se puede leer.
- Main — sobre el gráfico, en la escala de precios. Correcto para todo lo que se mide en dinero: medias móviles, bandas, canales, niveles.
- Sub — en su propio panel inferior, con su propia escala. Correcto para todo lo demás: un RSI de 0 a 100, un delta, una proporción, un volumen.
Ponga un oscilador en Main y la escala de precios se estirará de 0 a 100 para acomodarlo: las velas quedarán reducidas a un hilo plano. Si el gráfico se ve vacío de repente, casi siempre es por esto.
Las tres cosas que tiene su indicador
Piense en el editor como una cocina pequeña: hay tres cosas sobre la mesa y usted decide qué preparar.
Las velas — dataList
Todas las velas en pantalla, de la más antigua a la más reciente. De cada una puede tomar:
| Lo que escribe | Lo que obtiene |
|---|---|
d.close | Precio de cierre |
d.open | Precio de apertura |
d.high / d.low | Máximo y mínimo |
d.volume | Volumen |
d.timestamp | Hora de la vela |
La primera línea habitual de un indicador recoge uno de esos valores para todo el historial:
const closes = dataList.map(d => d.close)Sus números — params
Lo que escriba en el campo Params, separado por comas, llega como params[0], params[1], etc. Esto es lo que hace que un indicador sea ajustable en lugar de fijo:
// Params: 20, 2
const period = params[0] ?? 20
const width = params[1] ?? 2La parte ?? 20 es el valor que se usa si el campo está vacío. Déjelo siempre: es lo que mantiene el indicador funcionando antes de que alguien rellene el campo.
La caja de herramientas — TA
Los cálculos estándar, ya escritos y probados. Le pasa una lista de precios y una longitud, y le devuelve el resultado:
const ema = TA.ema(closes, period)| Llamada | Devuelve |
|---|---|
TA.sma(precios, longitud) | Media móvil simple |
TA.ema(precios, longitud) | Media móvil exponencial |
TA.wma(precios, longitud) | Media móvil ponderada |
TA.hma(precios, longitud) | Media móvil de Hull |
TA.rma(precios, longitud) | Suavizado de Wilder (el que hay dentro del RSI y del ATR) |
TA.stdev(precios, longitud) | Desviación estándar: cuánto se aleja el precio de su media |
TA.rsi(precios, longitud) | RSI, de 0 a 100 |
TA.macd(precios, rápida, lenta, señal) | MACD: dif, dea y macd a la vez |
TA.bollinger(precios, longitud, ancho) | Bandas de Bollinger: upper, mid, lower |
TA.tr(máximos, mínimos, cierres) | True Range |
TA.atr(máximos, mínimos, cierres, longitud) | ATR: volatilidad |
TA.vwap(máximos, mínimos, cierres, volúmenes) | VWAP |
TA.cci(máximos, mínimos, cierres, longitud) | CCI |
Qué debe devolver su indicador
Un valor por vela, para cada línea que quiera dibujar. La última línea del script dice qué líneas existen y cómo se llaman:
return closes.map((_, i) => ({
fast: fastEma[i],
slow: slowEma[i],
}))Dos nombres, dos líneas en el gráfico, identificadas en la leyenda como fast y slow. Añada un tercer nombre y tendrá una tercera línea, hasta 24.
Las primeras velas suelen ir vacías
Una media de 20 períodos no tiene nada que mostrar hasta que han pasado 20 velas, por eso la línea empieza algo más adentro del borde izquierdo. Es correcto, no un fallo: el indicador se niega a dibujar un número que no tiene.
Ejemplos listos para usar
Copie cualquiera en el editor, cambie los números y pulse Save & Run.
Dos medias móviles (Placement: Main)
El clásico. Params: 50, 200
const fastLength = params[0] ?? 50
const slowLength = params[1] ?? 200
const closes = dataList.map(d => d.close)
const fast = TA.ema(closes, fastLength)
const slow = TA.ema(closes, slowLength)
return closes.map((_, i) => ({
fast: fast[i],
slow: slow[i],
}))Bandas de Bollinger con una media (Placement: Main)
Es el script con el que arranca el editor. Params: 20
const period = params[0] ?? 20
const closes = dataList.map(d => d.close)
const boll = TA.bollinger(closes, period, 2)
const ema = TA.ema(closes, period)
return closes.map((_, i) => ({
upper: boll.upper[i],
basis: boll.mid[i],
lower: boll.lower[i],
ema: ema[i],
}))RSI con sus niveles (Placement: Sub)
Las dos últimas líneas son números fijos, así que se dibujan como guías planas en 70 y 30. Params: 14
const period = params[0] ?? 14
const closes = dataList.map(d => d.close)
const rsi = TA.rsi(closes, period)
return closes.map((_, i) => ({
rsi: rsi[i],
overbought: 70,
oversold: 30,
}))Volatilidad, para dimensionar un stop (Placement: Sub)
El ATR dice cuánto se mueve el instrumento en una vela media, lo que ayuda a elegir una distancia de stop que no sea arbitraria. Params: 14
const period = params[0] ?? 14
const highs = dataList.map(d => d.high)
const lows = dataList.map(d => d.low)
const closes = dataList.map(d => d.close)
const atr = TA.atr(highs, lows, closes, period)
return closes.map((_, i) => ({
atr: atr[i],
}))Presión compradora y vendedora (Placement: Sub)
No está limitado al conjunto estándar. Este ejemplo plantea una pregunta para la que la biblioteca no tiene respuesta hecha: dentro de cada vela, ¿el precio se mantuvo cerca del máximo o del mínimo, y cuánto volumen lo respaldó? Params: 21
const period = params[0] ?? 21
const pressure = dataList.map(d => {
const range = d.high - d.low
if (!range) return 0
const position = (d.close - d.low) / range // 1 = cerró en el máximo, 0 = en el mínimo
return (position - 0.5) * 2 * (d.volume ?? 0)
})
const smoothed = TA.ema(pressure, period)
return pressure.map((_, i) => ({
pressure: smoothed[i],
zero: 0,
}))Por encima de cero, las velas cierran cerca de sus máximos con volumen real. Por debajo, cerca de sus mínimos.
Gestionar sus indicadores
- Saved, a la izquierda del editor, lista todo lo que ha escrito. Pulse una fila para abrirla.
- New vacía el editor para la siguiente idea; sus scripts guardados siguen donde estaban.
- Reset devuelve el ejemplo inicial al editor. Nunca toca nada guardado.
- Indicators → Custom es donde viven sus indicadores terminados: actívelos, desactívelos, ocúltelos, elimínelos, o pulse el lápiz para volver a abrir uno en el editor.
Sus scripts se guardan en el navegador. Active Cloud Sync y viajarán con su cuenta a cualquier dispositivo donde inicie sesión.
Compartir y copias de seguridad
Export guarda el script actual como archivo; Import lo vuelve a cargar. Ese archivo es el indicador: envíelo a un colega, guárdelo como copia de seguridad o mantenga su colección en una carpeta.
Los indicadores publicados por el equipo de QUANTIX aparecen en Indicators → Custom como plantillas. Puede usarlas tal cual; para hacer una suya, expórtela, cambie lo que quiera y guárdela con otro nombre.
¿Es seguro?
Su indicador solo lee velas y dibuja. No tiene forma de llegar a internet, a su cuenta, a sus fondos ni a nada fuera del gráfico, y se ejecuta aparte del resto del terminal, así que un error en un script no puede romper la plataforma. Un script que se queda en un bucle se detiene al segundo y medio y se le informa.
Los límites prácticos: hasta 24 líneas dibujadas, las últimas 20 000 velas de historial y un script de hasta 24 000 caracteres — varias páginas de cálculos.
Si viene de TradingView
| En Pine Script | Aquí |
|---|---|
indicator() / study() al principio | El selector Placement: Main o Sub |
input.int(20) | El campo Params, leído como params[0] |
plot(series) | Un nombre en la lista devuelta |
ta.sma(close, 20) | TA.sma(closes, 20) |
na | null |
request.security() — otro símbolo o temporalidad | No disponible: el indicador ve el gráfico en el que está |
strategy() y backtesting | No disponible: aquí se dibujan indicadores, no se prueban operaciones |
Una costumbre que hay que soltar: Pine recorre las velas por usted, una a una. Aquí recibe todo el historial de golpe y dice qué hacer con él entero, y por eso todos los ejemplos terminan en map, la instrucción que significa «para cada vela».
Si no aparece nada
| Lo que ve | Qué significa |
|---|---|
| «Script must return an Array» | La última línea no empieza por return, o devuelve un solo valor en vez de uno por vela. |
| Las velas se convirtieron en una línea plana | Un oscilador en el panel Main. Cambie Placement a Sub. |
| La línea empieza lejos del borde izquierdo | Es normal: el indicador no tiene valor hasta que han pasado suficientes velas. |
| «Timeout» | El cálculo no termina. Suele ser un bucle dentro de otro; saque fuera la parte pesada. |
| No se dibuja nada y no hay error | Sus valores salieron vacíos. Devuelva por un momento un número fijo, por ejemplo { test: 1 }, compruebe que aparece la línea y vuelva a poner el cálculo real por partes. |
Pida ayuda para escribirlo
Como esto es JavaScript corriente, puede describir un indicador con palabras a cualquier asistente de IA, pedirlo como una función de JavaScript y pegar el resultado aquí. Dígale dos cosas: los valores salen de dataList (con close, open, high, low, volume) y el script debe devolver un objeto por vela.