Rolling Percentile Indicator
- Indicadores
- Versión: 1.0
1. ¿Qué hace este indicador?
El indicador de percentiles móviles traza tres líneas en el gráfico de precios. Cada línea representa un percentil de los últimos N precios (la ventana móvil):
- Línea superior (verde): el percentil superior, el 75.º por defecto.
- Mediana (blanca, gruesa): el percentil 50, siempre fijo.
- Línea inferior (roja): el percentil inferior, el 25.º por defecto.
Se trata de un canal no paramétrico. Mientras que las bandas de Bollinger asumen que el precio tiene una distribución aproximadamente en forma de campana y lo miden mediante una media y una desviación estándar, este indicador simplemente clasifica los precios recientes y determina dónde se sitúan los percentiles elegidos. No parte de ningún supuesto de distribución, y una barra extrema no puede desviar las líneas del mismo modo que lo hace con la desviación estándar.
2. Cómo se calcula
Para cada barra i, el indicador realiza lo siguiente:
- Recopila el precio seleccionado de las últimas barras de InpPeriod, terminando en la barra i, incluida esta.
- Ordena esos precios de menor a mayor.
- Para cada percentil p, calcula la posición pos = (p / 100) × (N − 1).
- Si pos se encuentra entre dos valores ordenados, se realiza una interpolación lineal entre ellos. En caso contrario, se toma directamente el valor correspondiente a pos.
Este es el mismo método «lineal» que utilizan pandas rolling().quantile() y el percentil por defecto de NumPy. He reproducido el algoritmo en Python y lo he comparado con pandas en una serie de 500 barras: la mayor diferencia fue de aproximadamente 2×10⁻¹³, lo que equivale al ruido de coma flotante. Las primeras InpPeriod − 1 barras no tienen valores, exactamente igual que pandas con el requisito de ventana completa.
A modo de referencia, con la ventana predeterminada de 50, el percentil 25 se sitúa en la posición 12,25 tras la ordenación y el 75 en la posición 36,75, por lo que ambos son valores interpolados y no precios reales.
3. Entradas
| Datos de entrada | Por defecto | Significado | Rango válido |
|---|---|---|---|
| InpPeriod | 50 | Tamaño de la ventana móvil en barras. | Número entero de al menos 2 (véase la sección 8) |
| InpP75 | 75,0 | Percentil superior. A pesar de su nombre, se puede establecer en 90, 95, 99, etc. | Por encima de InpP25, como máximo 100 |
| InpP25 | 25,0 | Percentil inferior. | Como mínimo 0, por debajo de InpP75 |
| InpPriceType | PRICE_CLOSE | Serie de precios ordenada por: apertura, máximo, mínimo, cierre, mediana, típico o ponderado. | Cualquiera de los valores de ENUM_APPLIED_PRICE |
El percentil de la mediana se fija en 50 y no admite valores de entrada.
Importante: la versión 1.00 no valida estos valores. Los valores que se salgan de los rangos indicados anteriormente pueden provocar que el indicador deje de funcionar con un error de «matriz fuera de rango». Véase la sección 8.
4. Elección de la configuración
Par de percentiles
| Par | La banda contiene | Uso habitual |
|---|---|---|
| 25 / 75 | El 50 % de los precios (rango intercuartílico) | Zona de valor y equilibrio. El precio se sitúa fuera de ella aproximadamente la mitad del tiempo, por lo que es una herramienta de contexto, no un indicador de activación. |
| 10 / 90 | 80 % central | Equilibrado: lo suficientemente frecuente como para ser útil, lo suficientemente selectivo como para tener sentido. |
| 5 / 95 | 90 % medio | Zonas de extensión para configuraciones de fade o sweep. |
| 1 / 99 | 98 % medio | Casi extremos. Con N = 50, estos valores son prácticamente el máximo y el mínimo del intervalo, por lo que el canal se comporta como un canal de Donchian. |
Longitud de la ventana
| Ventana | Característica |
|---|---|
| 20–30 | Rápida, reacciona al tramo actual, más ruidosa. |
| 50 (por defecto) | Contexto de oscilaciones intradía. |
| 100–200 | Contexto de rango estructural o de negociación, más lento y suave. |
Para que el percentil de una ventana sea significativo, se necesitan suficientes observaciones: por debajo de unas 20 barras, los percentiles 5.º y 95.º se reducen a los valores extremos y no aportan nada.
Precio aplicado
- Cierre: el valor por defecto y el más claro para las reglas basadas en el cierre.
- Típico o Mediana: más suave, menos sensible a las mechas.
- Máximo y mínimo juntos: adjunta dos copias, una en el máximo (para la línea superior) y otra en el mínimo (para la línea inferior), para construir un canal de rango que respete las mechas. Esta es una configuración habitual cuando se desean referencias de barrido de liquidez.
5. Instalación y conexión
- Guarda RollingPercentiles.mq5 en la carpeta MQL5\Indicators de tu terminal.
- Ábrelo en MetaEditor y compílalo (F7). No debe dar ningún error.
- Añádelo a un gráfico desde el Navegador. Se traza en la ventana principal del gráfico, no en una subventana.
Nota sobre el color: la mediana es blanca por defecto. En una plantilla de gráfico clara resulta invisible, así que cámbiala en la pestaña «Colores» del indicador.
6. Interpretación de las tres líneas
Mediana (equilibrio). El punto medio del precio reciente. Si el precio se sitúa por encima de una mediana ascendente, significa que los compradores controlan el mercado; si se sitúa por debajo de una mediana descendente, significa que son los vendedores quienes lo controlan. La mediana es robusta, por lo que un único pico apenas la altera.
Ancho de la banda (régimen de volatilidad). La distancia entre las líneas superior e inferior es un indicador de volatilidad. Una banda que se estrecha indica compresión; una banda que se ensancha indica expansión. Dado que los percentiles ignoran los extremos, el ancho responde a la volatilidad sostenida más que a una barra atípica.
Posición dentro de la ventana (prima y descuento). Un precio por encima de la mediana se cotiza en la mitad superior de la ventana reciente (prima); por debajo de ella, en la mitad inferior (descuento). Esto encaja perfectamente en un marco de equilibrio.
Índices de amortiguación para uso con EA o iCustom: el amortiguador 0 es el percentil superior, el amortiguador 1 es la mediana y el amortiguador 2 es el percentil inferior. Ten en cuenta que la línea superior es el índice 0 y la línea inferior es el índice 2.
Una propiedad que debes comprender
La ventana incluye la barra actual, y las bandas son percentiles del propio precio. Por su propia naturaleza, el precio pasa aproximadamente el 25 % del tiempo por encima del percentil 75 y el 25 % por debajo del 25. Por lo tanto, un cierre por encima de la línea superior es habitual y no constituye por sí solo una señal de ruptura. Utiliza un percentil alto (95 o 99) o combina las líneas con la estructura del mercado.
7. Ejemplos de marcos de negociación
Se trata de plantillas de proceso, no de señales. Cada una de ellas requiere una confirmación por parte de la estructura del mercado y del contexto de la sesión, así como una invalidación clara.
A. Rotura de rango en el extremo (régimen de rango)
- Contexto: ancho de la banda plano o en contracción, mediana más o menos plana, sin ruptura de la estructura en el marco temporal superior.
- Configuración: el precio se desplaza más allá de la línea del percentil 5 o del 95, absorbe liquidez de forma evidente (máximos o mínimos iguales) y cierra de nuevo dentro de la banda.
- Entrada: al cerrar de nuevo dentro de la banda.
- Stop: más allá del extremo del barrido más 0,5 × ATR(14).
- Objetivo 1: la mediana (cerrar aproximadamente la mitad de la posición). Objetivo 2: la línea opuesta del percentil 25 o 75.
- Riesgo: fraccional fijo, entre el 0,25 % y el 0,50 % del capital por operación. No realizar la operación si el objetivo es inferior a 1,5R.
B. Continuación de la tendencia a partir de la mediana (regime de tendencia)
- Contexto: la mediana presenta una inclinación clara, el ancho de la banda se amplía y la estructura en marcos temporales superiores forma máximos sucesivos (HH/HL) o mínimos sucesivos (LH/LL).
- Configuración: retroceso hasta la mediana en situación de descuento (posición larga) o de prima (posición corta), con un CHoCH o una reacción ante un bloque de órdenes en el marco temporal inferior.
- Entrada: al cierre de la vela de confirmación.
- Stop: más allá del oscilación del retroceso, o más allá del mínimo o máximo estructural, con un margen de ATR.
- Objetivo: la línea del percentil 90 o 95; a continuación, seguir la estructura.
- Riesgo: 0,25-0,75 % por operación, con límites de pérdida diarios y semanales estrictos. No se realiza el promedio a la baja.
Evitar: operar cada vez que se toque las líneas del 25 % y el 75 %. Las líneas indican dónde se encuentra el precio en su distribución reciente, no por qué va a revertirse.
8. Comparación con el indicador similar más cercano
El equivalente integrado en MT5 más cercano son las bandas de Bollinger. Tiene la misma estructura: tres líneas, una ventana, un precio aplicado, una línea central y una envolvente superior e inferior. El canal de Donchian es el caso límite de este indicador (los percentiles 0 y 100 son el mínimo y el máximo de la ventana). Lo confirmé numéricamente en la prueba de pandas: la línea del percentil 100 equivale al máximo móvil.
| Aspecto | Percentiles móviles | Bandas de Bollinger |
|---|---|---|
| Línea central | Mediana (percentil 50) | Media móvil (SMA por defecto) |
| Envolvente | Percentiles seleccionados de los precios reales | Media ± k × desviación estándar |
| Supuesto de distribución | Ninguna | Aproximadamente normal |
| Sensibilidad a los valores atípicos | Baja | Alta: un pico exagera la desviación de toda la ventana |
| Significado del ancho de banda | Dispersión del X % de los precios situados en el medio | Un múltiplo de la dispersión |
| Colas gruesas (divisas, oro) | Se gestionan de forma natural | Las bandas subestiman o sobreestiman los extremos reales |
| Cobertura | Fija por diseño (un par 5/95 siempre abarca el 90 % de la ventana) | Varía según la forma de la distribución |
| Ponderación de la ventana | Ponderación igual, por lo que el retraso es similar al de una media móvil simple (SMA) | Ponderación igual (modo SMA) |
| Parámetros | Ventana, dos percentiles, precio | Ventana, múltiplo de desviación, desplazamiento, precio |
| Coste de cálculo | Ordenar por barra (más pesado) | Sumas acumuladas (muy ligero) |
| Opciones de desplazamiento y estilo | Ninguna en la v1.00 | Sí |
Prueba de valores atípicos (sintética). En un paseo aleatorio simulado de 500 barras con una ventana de 50, añadí un único pico de 40 puntos dentro de una ventana. El ancho estándar de la banda de Bollinger de 2σ pasó de 4,69 a 23,08 (aproximadamente 4,9 veces más ancho), mientras que el ancho de la banda de los percentiles 25/75 pasó de 1,77 a 1,79. En el caso de los picos provocados por noticias y las mechas de «stop-run», esta es la ventaja práctica: las bandas de percentiles siguen describiendo dónde se produjo la mayor parte de la actividad bursátil.
Donde las bandas de Bollinger siguen siendo mejores: cálculo muy rápido, opciones integradas de desplazamiento y estilo, y una convención ampliamente aceptada (20, 2) que otros operadores reconocen. Donde los percentiles móviles son mejores: instrumentos asimétricos o con picos, operaciones de barrido de liquidez y referencias de rango estables.
9. Revisión de los resultados y las limitaciones conocidas en la versión 1.00
El algoritmo principal es correcto. Las deficiencias se centran exclusivamente en la robustez y el acabado.
| # | Conclusión | Gravedad | Solución recomendada |
|---|---|---|---|
| 1 | No se valida la entrada. Un valor de `InpPeriod` igual a 0 o inferior da como resultado un índice inicial negativo y un índice final fuera del rango de la matriz. Los percentiles superiores a 100 (o inferiores a 0) tienen un índice fuera de la ventana. He reproducido este error en la prueba equivalente de pandas: el valor 101 genera un error de índice. | Alta | Validar en OnInit y devolver INIT_PARAMETERS_INCORRECT junto con una explicación del motivo. Exigir un período de al menos 2, donde 0 ≤ inferior < superior ≤ 100. |
| 2 | Los percentiles invertidos se aceptan sin aviso (el valor de entrada inferior es mayor que el superior), por lo que los colores y las etiquetas son erróneos. | Medio | Misma validación, o intercambiar automáticamente. |
| 3 | Asignación por barra y ordenación completa. Se crea una nueva matriz y se rellena de nuevo para cada barra, recalculando el precio aplicado para cada elemento. El coste es aproximadamente barras × ventana × log(ventana), lo cual se nota en ventanas grandes y historiales largos. | Medio | Calcular el precio una vez por barra en una matriz. Reutilizar un búfer de ventana. Para un uso intensivo, mantener una ventana ordenada de forma incremental (inserción/eliminación mediante búsqueda binaria), lo que hace que cada barra sea aproximadamente lineal en la ventana. |
| 4 | Etiquetas estáticas del gráfico. La ventana de datos siempre muestra «75.º» y «25.º», incluso si se establecen 90 y 10. | Bajo | Establece las etiquetas en OnInit con PlotIndexSetString(..., PLOT_LABEL, ...). |
| 5 | No se utiliza PLOT_DRAW_BEGIN ni se especifica explícitamente el relleno con el valor vacío para las barras de calentamiento. Funciona porque el terminal inicializa los búferes con el valor vacío, pero es mejor ser explícito. | Bajo | Establece PLOT_DRAW_BEGIN en InpPeriod − 1 y PLOT_EMPTY_VALUE en EMPTY_VALUE. |
| 6 | La mediana blanca no se ve en las plantillas claras. | Bajo | Elige un color neutro, como el dorado o el azul dodger. |
| 7 | No hay nombre abreviado. | Bajo | IndicatorSetString(INDICATOR_SHORTNAME, ...) que muestre el periodo y los percentiles. |
| 8 | Comportamiento de las barras en tiempo real (por diseño). La barra más reciente se incluye en su propia ventana, por lo que las líneas de la última barra se mueven con cada tick. Las barras cerradas no cambian. | Información | Utiliza los valores de cierre de las barras (shift 1) en cualquier EA o regla. |
Lo que es correcto y merece la pena conservar: la gestión de la dirección de la serie (los arrays se utilizan de más antiguo a más reciente, de forma coherente), el recálculo incremental a partir de prev_calculated − 1, el valor de retorno limpio de OnCalculate y los cálculos de interpolación.
10. Resolución de problemas
El indicador desaparece justo después de añadirlo, con un mensaje de «matriz fuera de rango» en el registro de Expertos o en el Diario. Comprueba las entradas con la tabla de la sección 3. Se trata del problema de entradas no validadas.
No se dibujan líneas. O bien el gráfico tiene menos barras que InpPeriod, o bien el historial aún se está cargando. Desplázate hacia atrás o espera a que termine de descargarse el historial.
No veo la mediana. Es blanca sobre un gráfico blanco. Cambia su color en la pestaña «Colores».
El último valor no deja de cambiar. Es lo esperado: la barra en tiempo real todavía se encuentra dentro de su propia ventana. Las barras cerradas nunca cambian.
La terminal va lenta con una ventana grande. Reduce el InpPeriod, reduce el número de barras cargadas en el gráfico o solicita la versión incremental optimizada.
11. Referencia rápida
| Elemento | Valor |
|---|---|
| Ventana | Gráfico (principal) |
| Gráficos y zonas de amortiguación | 3 y 3 |
| Área de amortiguación 0 | Percentil superior (línea verde) |
| Zona de amortiguación 1 | Mediana (línea gruesa blanca) |
| Intervalo 2 | Percentil inferior (línea roja) |
| Método | Ventana ordenada, interpolación lineal (compatible con pandas) |
| Primera barra válida | InpPeriod − 1 |
| Actualizaciones | Solo la última barra, hasta que cierre |
| Configuración inicial segura | 50 barras, 10 / 90, Cierre |
