Pon "Me gusta" y sigue las noticias
Deje un enlace a él, ¡qué los demás también lo valoren!
Evalúe su trabajo en el terminal MetaTrader 5
- Visualizaciones:
- 26
- Ranking:
- Publicado:
-
¿Necesita un robot o indicador basado en este código? Solicítelo en la bolsa freelance Pasar a la bolsa
Los precios brutos de divisas y futuros son no estacionarios: los modelos estándar de regresión y clasificación entrenados con ellos adolecen de un grave sesgo de anticipación y de correlaciones espurias. La solución simplista —la diferenciación entera— elimina la no estacionariedad, pero destruye toda la memoria de los precios en el proceso, descartando precisamente la estructura de autocorrelación que necesita un modelo predictivo.
La diferenciación fraccionaria de ancho fijo (FFD), introducida en el capítulo 5 de *Advances in Financial Machine Learning* (López de Prado, 2018), resuelve este problema mediante una diferenciación de orden no entero d ∈ (0, 1) que es justo la necesaria para alcanzar la estacionariedad, al tiempo que conserva la máxima memoria. Esta propuesta ofrece una implementación en MQL5 apta para producción de dicho método.

Ilustración en dos paneles del resultado de la FFD: precio bruto no estacionario (a) y serie FFD estacionaria (b) con la ventana de retrospectiva marcada
Componentes
- FFDEngine.mqh — Biblioteca de solo encabezado que contiene la clase CFFDEngine. Proporciona Init(), Compute() (una sola barra) y ComputeBuffer() (búfer completo del indicador con optimización prev_calculated ). No hay asignación dinámica de memoria tras OnInit().
- FFD.mq5 — Indicador personalizado que envuelve CFFDEngine. Traza la serie FFD en una ventana de gráfico independiente. Admite todos los valores de ENUM_APPLIED_PRICE.
Cómo funciona el algoritmo
El vector de ponderación viene definido por la relación de recurrencia (ecuación 5.4 de AFML):
w[0] = 1 w[k] = -w[k-1] * (d - k + 1) / k, k = 1, 2, ...
La iteración se detiene cuando |w[k]| < umbral. A continuación, el vector se invierte, de modo que el precio más antiguo de la ventana retrospectiva recibe la menor ponderación y el precio más reciente recibe 1,0. El valor FFD en la barra i es el producto escalar del vector de ponderación invertido con la ventana de precios logarítmicos [i−anchura, …, i].
Para d = 0,4 y umbral = 1e-5, la anchura de la ventana es de 1 457 barras. Para umbral = 1e-3, es de 54 barras. El umbral controla el equilibrio entre estacionariedad y memoria: los valores más pequeños conservan más memoria a costa de un requisito de retrospectiva más amplio.
Parámetros de entrada
| Parámetro | Valor por defecto | Descripción |
|---|---|---|
| InpD | 0,4 | Orden de diferenciación fraccionaria. Rango típico: 0,1–0,9. Los valores superiores a 0,5 producen una diferenciación casi entera; los valores inferiores a 0,1 producen precios casi brutos. El valor óptimo de d es el valor mínimo que supera una prueba ADF al nivel de significación elegido; véase el artículo complementario para conocer el procedimiento de búsqueda en Python. |
| InpThreshold | 1e-5 | Umbral de ponderación τ. La iteración se detiene cuando |w[k]| < τ. Los valores más pequeños producen una ventana más amplia y una mejor conservación de la memoria, pero requieren más barras históricas antes de obtener el primer resultado válido. Rango recomendado: de 1e-4 a 1e-5. |
| InpUseLog | true | Aplica ln(precio) antes de la diferenciación. Recomendado para series de precios sin procesar (cierres, aperturas, máximos, mínimos). Establece «false» solo cuando la entrada ya sea una serie de rentabilidades o de rentabilidades logarítmicas. |
| InpPrice | PRICE_CLOSE | Tipo de precio aplicado. Acepta cualquier valor de ENUM_APPLIED_PRICE: PRICE_OPEN, PRICE_HIGH, PRICE_LOW, PRICE_CLOSE, PRICE_MEDIAN, PRICE_TYPICAL, PRICE_WEIGHTED. |
Instalación
- Copia FFDEngine.mqh en tu carpeta MQL5\Include\ (o en la subcarpeta especificada durante la descarga de CodeBase; consulta las ubicaciones de los archivos más abajo).
- Copia FFD.mq5 en MQL5\Indicators\Downloads\ (se coloca allí automáticamente al descargar CodeBase).
- Compila ambos archivos en MetaEditor. El indicador debería compilarse sin advertencias bajo #property strict.
- Añade FFD a cualquier gráfico. La ventana del indicador aparecerá debajo del gráfico principal una vez que se haya completado la ventana de retrospectiva (ancho + 1 barra).
Uso de CFFDEngine en tu propio EA o indicador
FFDEngine.mqh es una biblioteca de solo encabezado. Inclúyela y llama a Init() una vez en OnInit():
#include <FFDEngine.mqh> //--- Instancia global del motor de diferenciación fraccional de ancho fijo CFFDEngine g_engine; //+------------------------------------------------------------------+ //| Función de inicialización de Expert | //+------------------------------------------------------------------+ int OnInit() { //--- Inicializar el motor FFD con d=0,4, umbral=1e-5 y la transformación logarítmica activada //--- Esta configuración crea una ventana de ponderación de memoria estática durante la fase de inicialización del EA if(!g_engine.Init(0.4, 1 e-5, true)) { Print("FFD engine init failed"); return(INIT_FAILED); } return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Función de ticks de Expert | //+------------------------------------------------------------------+ void OnTick() { //--- Consultar el motor para averiguar exactamente cuántas barras históricas se necesitan //--- para calcular un valor FFD válido en función del umbral de corte int need = g_engine.GetMinBars(); double close[]; //--- Obtener la profundidad necesaria de los datos históricos de precios. //--- Si el historial aún no está sincronizado o es insuficiente, omite la ejecución para evitar errores. if(CopyClose(_Symbol, _Period, 0, need, close) < need) return; //--- Asegúrate de que la indexación de la matriz coincida con el orden cronológico (la barra más antigua en el índice 0) //--- para alinear correctamente con las transformaciones de la matriz del vector de peso FFD invertida ArraySetAsSeries(close, false); //--- Calcular el valor de salida estacionario, con diferencias fraccionarias, para la barra actual en tiempo real double ffd_value = g_engine.Compute(close, need); //--- Utiliza ffd_value como característica para tu modelo. }
Validación cruzada con Python
El archivo complementario FFDValidation.mq5 (disponible en la descarga del artículo) exporta los valores de FFD a un archivo CSV. El script de Python ffd_cross_validate.py vuelve a calcular los mismos valores utilizando la biblioteca afml y los compara barra por barra. En 5 000 barras del EURUSD H1 con d = 0,4 y umbral = 1e-5, la diferencia absoluta máxima es inferior a 1e-12.
Notas sobre el rendimiento
- Asignación del vector de pesos: una vez en OnInit(). Sin asignación en la ruta de ticks.
- Cálculo por barra: producto escalar de complejidad O(anchura). En hardware moderno, un producto escalar sobre 1 457 elementos se completa en menos de 50 μs.
- ComputeBuffer() utiliza el argumento prev_calculated para omitir las barras ya calculadas; solo se vuelve a calcular la barra actual incompleta en cada tick.
Referencias y artículo complementario
- López de Prado, M. (2018). Advances in Financial Machine Learning, capítulo 5 (Diferenciación fraccionaria), pp. 76–95. Wiley.
- Teoría completa, implementación en Python y búsqueda de parámetros basada en ADF: Ingeniería de características para el aprendizaje automático — Parte 2: Implementación de la diferenciación fraccionaria de ancho fijo en MQL5, por Patrick M. Njoroge.
- Herramientas de validación complementarias: FFDValidation.mq5 y ffd_cross_validate.py — incluidas en el paquete de descarga del artículo.
Traducción del inglés realizada por MetaQuotes Ltd.
Artículo original: https://www.mql5.com/en/code/72499
Oscilador TRIX de tendencia a largo plazo
Oscilador de impulso y tendencia a largo plazo basado en un filtrado dual de TRIX y LWMA.
Institutional Kinematic Price Physics (Velocity and Acceleration)
Un motor físico cuantitativo que aplica el cálculo diferencial a la evolución de los precios, extrayendo la verdadera velocidad del mercado (primera derivada) y la aceleración del mercado (segunda derivada) para predecir el agotamiento de la tendencia antes de que se produzca.
Accumulation/Distribution
El indicador Accumulation/Distribution (Acumulación/Distribución) queda determinado por los cambios que se producen en el precio y en el volumen.
Accelerator Oscillator (AC)
El indicador Acceleration/Deceleration (AC, Aceleración/Desaceleración) mide la aceleración y la desaceleración de la fuerza impulsora del mercado.