De principiante a experto: Indicador de fuerza de soporte y resistencia (SRSI)
Contenido
- Introducción
- Resumen del artículo
- Evidencia de la naturaleza del mercado actual
- Implementación de MQL5 para desarrollar el SRSI
- Pruebas y resultados
- Conclusión
- Archivo adjunto (archivo fuente del SRSI)
Introducción
Los mercados respetan sistemáticamente los niveles de precios anteriores que han influido en sus movimientos. El día típico de un operador suele comenzar dibujando manualmente estos niveles clave utilizando la conocida herramienta de líneas de MetaTrader 5. Sin embargo, este proceso manual puede dar lugar a que se pasen por alto niveles destacados o se juzgue erróneamente su importancia, lo que pone de relieve la necesidad de una solución automatizada.
Uno podría preguntarse por qué es necesaria la automatización. Aunque los seres humanos destacamos en tareas complejas y creativas y en adaptarnos a nuevas situaciones, a menudo nos cuesta mantener la coherencia y manejar grandes volúmenes de datos. La investigación realizada por Mark Angelo D. Julian, Danilo B. Villarino y Kristine T. Soberano en su artículo del 7 de julio de 2024, «The Human Brain Versus Computer: Which is Smarter?» (El cerebro humano frente a la computadora: ¿cuál es más inteligente?), subraya este punto. Su estudio revela que, aunque los seres humanos destacan en la comprensión del contexto, los ordenadores son muy superiores en velocidad de procesamiento, precisión de datos y realización de cálculos repetitivos. Este contraste impulsa nuestro desarrollo continuo de algoritmos para el comercio y el análisis de datos.
Resumen del artículo
Hoy aplicaremos técnicas de resolución de problemas utilizando la programación MQL5 para abordar el reto mencionado anteriormente. Este debate está dirigido a operadores de todos los niveles, desde principiantes hasta expertos, ya que abordamos conceptos clave que afectan a todos. Como ya sabes, MetaTrader 5 es básicamente un montón de datos de precios, herramientas de análisis e información histórica. Las series de velas japonesas, por ejemplo, son barras calculadas que representan los precios de apertura, máximo, mínimo y cierre, y los indicadores populares, como las medias móviles, se derivan de estos valores. Imagina revisar manualmente 5000 velas japonesas: este proceso no solo es tedioso, sino que también es propenso a errores. Por eso es tan beneficioso automatizar la identificación de los niveles de soporte y resistencia.
Aunque ya existen varias herramientas disponibles en el mercado, tanto gratuitas como de pago, hoy exploramos un enfoque único. Esta sesión no solo trata sobre el producto final, sino también sobre compartir los conocimientos de programación MQL5 que necesita para crear su propia solución personalizada. A continuación se presenta un resumen de las ventajas del indicador de fuerza de soporte y resistencia (SRSI) que estamos desarrollando:
- Procesamiento eficiente de datos: analiza datos históricos exhaustivos de velas japonesas para identificar niveles clave.
- Automatización continua: funciona de forma automática y continua, lo que reduce los errores manuales.
- Diferenciación de niveles: Identifica tanto los niveles de soporte y resistencia débiles como los fuertes.
- Imágenes claras: Proporciona una representación visual clara de estos niveles críticos.
- Notificaciones completas: Ofrece notificaciones al usuario a través de Terminal y notificaciones push.
En las siguientes secciones, comenzaremos recopilando datos históricos de precios utilizando los gráficos de MetaTrader 5 y los niveles de soporte y resistencia identificados manualmente. Este análisis inicial proporcionará pruebas que compararán el comportamiento actual del mercado con el rendimiento pasado. A continuación, nos sumergiremos en el proceso de desarrollo, donde compartiré y desglosaré el código de nuestro indicador personalizado, explicando cada línea en detalle para asegurarme de que comprendas completamente cómo implementar MQL5 y traducir tus ideas en código.
Por último, revisaremos el proceso de pruebas y presentaremos nuestros resultados, lo que le permitirá mejorar sus habilidades de programación y obtener una solución funcional. Tómate tu tiempo, sigue el proceso y disfruta del viaje por el mundo de la programación.
Evidencia de la naturaleza del mercado actual
Mi plataforma MetaTrader 5 está conectada al bróker, lo que me proporciona acceso a una amplia gama de pares de operaciones. Dependiendo del tipo de cuenta, puedo operar con pares de volatilidad, pares de divisas, pares de acciones y mucho más. La imagen proporcionada muestra una amplia selección de pares adicionales disponibles para operar. Para esta investigación, elegí varios pares de esta colección para analizarlos.
Para ver los pares que ofrece su bróker y añadirlos a su lista de observación del mercado, simplemente pulse CTRL + U en su teclado o haga clic en el icono rojo redondeado (como se muestra en la imagen de abajo) para abrir la ventana Símbolos. A continuación, haga doble clic en el par deseado para añadirlo automáticamente a su lista.

Símbolos en MetaTrader 5
Pares sintéticos
Comencé mi análisis con un par sintético bajo los índices de volatilidad: el índice Volatility 75 (1s), en el marco temporal semanal. Cuando se introdujo este par alrededor de 2020, inicialmente era caro, pero pronto experimentó una caída prolongada, formando una fuerte tendencia bajista durante semanas. Los traders que vendieron el par en corto durante ese período probablemente obtuvieron ganancias significativas. Sin embargo, mi principal enfoque se centra en la estructura del mercado, particularmente en los últimos tres años.
La tendencia bajista sostenida probablemente condicionó a los traders a adoptar una mentalidad de seguimiento de tendencias, esperando nuevas caídas. Sin embargo, como se muestra en la imagen a continuación, la dinámica del mercado ha cambiado. El marco temporal superior ahora exhibe una estructura de rango entrecortado, con características similares observadas en marcos temporales inferiores. Estas condiciones dificultan que los operadores de swing puedan operar con eficacia.
En estas circunstancias, la acción del precio basada en el soporte y la resistencia se vuelve crucial para identificar oportunidades comerciales clave. La imagen a continuación ilustra este comportamiento del mercado, reforzando la importancia de un enfoque estructurado para el análisis técnico.

Índice Volatility 75 (1s)
Acciones
Analicé el gráfico semanal de US Tech y es evidente que el mercado ha tenido una tendencia al alza, con correcciones periódicas a lo largo del camino. Estas correcciones a menudo conducen a fases de consolidación, donde el movimiento de precios se desacelera antes de reanudar la tendencia. En un mercado con tendencia alcista, las correcciones suelen establecer fuertes zonas de soporte, reforzando el impulso alcista.
En este marco temporal superior, es difícil identificar los patrones precisos que influyen en la acción del precio en marcos temporales inferiores. Sin embargo, a medida que profundicemos, veremos cómo el concepto de soporte y resistencia sigue siendo aplicable en diferentes períodos de tiempo, lo que nos permite observar varios patrones de mercado con más detalle.

US Tech 100 Semanal
Pares de divisas
El gráfico semanal del EURUSD revela una pequeña fase de impulso seguida de un prolongado período de fluctuaciones. Este comportamiento es evidente en el marco temporal superior y se extiende también a los marcos temporales inferiores. La conclusión clave aquí es la acción del precio dentro de un rango extendido, lo que resalta cómo el mercado pasa un tiempo significativo consolidándose en lugar de seguir una tendencia. La imagen a continuación sirve como prueba de este comportamiento prolongado del mercado dentro de un rango definido.

EURUSD Semanal
En conclusión, del ejercicio anterior se desprende claramente que, si bien los precios de mercado experimentan tendencias al alza o a la baja, dependen en gran medida de los niveles de precios anteriores para su comprobación y validación. Durante las fases de consolidación, estos niveles horizontales, según el marco temporal elegido, se convierten en áreas clave donde el precio tiende a reaccionar.
Sin embargo, no todos los niveles son lo suficientemente fuertes como para desencadenar un movimiento de precios significativo. Además, incluso los niveles de soporte o resistencia bien establecidos no garantizan una reacción del precio, pero sí ofrecen una mayor probabilidad de influir en el comportamiento del mercado si se demuestra que son fuertes.
En la siguiente sección, revisaremos brevemente los fundamentos del soporte y la resistencia antes de sumergirnos en el desarrollo del algoritmo.
Implementación de MQL5 para desarrollar el SRSI
Definición de soporte y resistencia
El soporte se define generalmente como una zona de demanda en la que convergen múltiples niveles de precios, lo que indica que los compradores se inclinan por intervenir y empujar el precio al alza. Esta zona representa un «suelo» para el mercado, donde la acumulación de interés comprador tiende a impedir nuevas caídas.
- En términos prácticos, el soporte no suele ser un precio único, sino una zona en la que los mínimos anteriores o múltiples puntos de contacto han generado confianza en los compradores.
Por el contrario, la resistencia es una zona de oferta en la que convergen múltiples niveles de precios, lo que sugiere que es probable que los vendedores intervengan y hagan bajar el precio. Esta zona actúa como un «techo» para el mercado, donde la presión vendedora supera a la compradora, lo que a menudo impide que el precio siga subiendo. Al igual que el soporte, la resistencia se observa normalmente como un rango en lugar de un nivel preciso, debido a la presencia de múltiples máximos o puntos de contacto que refuerzan el interés de venta.
Teniendo esto en cuenta, trabajar con el soporte y la resistencia se vuelve mucho más sencillo. En el siguiente vídeo, te mostraré mi rutina para que veas cómo suelo dibujar estas líneas.
Diseño e implementación del algoritmo
Necesitamos que el programa reproduzca la forma en que identifico y marco manualmente las zonas de soporte y resistencia. Después de revisar el vídeo, he resumido aquí los pasos clave:
- Identificar puntos de inflexión extremos: Son máximos (para la resistencia) o mínimos (para el soporte) significativos en los que el precio cambia de dirección.
- Busque otros puntos de prueba: busque niveles de precios adicionales en los que el precio sea igual o se sitúe dentro de los 5 pips del punto de inflexión extremo, lo que confirma su importancia.
- Formar zonas de rebote: Crear zonas rectangulares que abarquen los puntos de giro extremos y sus puntos de prueba, con la zona extendiéndose alrededor de estos toques.
- Personalizar las dimensiones de la zona:
- Altura: El tamaño vertical del rectángulo de la zona (en pips) debe ser ajustable.
- Ancho: El tamaño horizontal de la zona (en barras de velas a la derecha) debe ser ajustable.
Por lo general, configuraremos nuestro programa para que analice un número personalizable de velas, identificando las condiciones que cumplen nuestros criterios y dibujando las formas, líneas y etiquetas adecuadas. También proporcionaremos opciones de entrada para controlar diversas funciones del programa. Para las alertas, implementaremos notificaciones push y alertas en el terminal, que se enviarán periódicamente en intervalos personalizables de 4 horas. A diferencia de otros indicadores, los niveles de soporte y resistencia no requieren un seguimiento constante, por lo que este enfoque garantiza notificaciones oportunas sin alertas excesivas. A continuación, explico los detalles paso a paso, junto con fragmentos de código.
Cuando abre MetaEditor y elige crear un nuevo indicador personalizado, le proporciona una plantilla básica con la que trabajar. Esta plantilla es como un lienzo en blanco que ayuda a los desarrolladores a empezar, y es donde construiremos nuestro indicador SRSI. Así es como se ve:
//+------------------------------------------------------------------+ //| _SRSI.mq5 | //| Copyright 2025, Metaquotes Ltd | //| https://www.mql5.com/ | //+------------------------------------------------------------------+ #property copyright "Copyright 2025, Metaquotes Ltd" #property link "https://www.mql5.com/" #property version "1.00" #property indicator_chart_window //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- indicator buffers mapping //--- return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Custom indicator iteration function | //+------------------------------------------------------------------+ int OnCalculate(const int rates_total, const int prev_calculated, const datetime &time[], const double &open[], const double &high[], const double &low[], const double &close[], const long &tick_volume[], const long &volume[], const int &spread[]) { //--- //--- return value of prev_calculated for next call return(rates_total); } //+------------------------------------------------------------------+
Utilizaremos esto como guía fundamental, asegurándonos de que todas las funciones clave se implementen correctamente. En los siguientes pasos, completaremos la plantilla, integraremos nuevas funciones y proporcionaremos explicaciones detalladas sobre sus funcionalidades. Por favor, siga leyendo hasta el final para obtener una comprensión completa.
Paso 1: Personalización de las propiedades del indicador
Para empezar, personalizamos las propiedades del indicador para adaptarlo a nuestras necesidades y cumplir con los requisitos de MetaTrader 5. Actualizamos los detalles sobre derechos de autor y enlaces para reflejar nuestra propia información. Añadimos una configuración para una comprobación de errores más estricta con el fin de detectar errores durante el desarrollo. El indicador está configurado para mostrarse en la ventana principal del gráfico. Dado que MetaTrader 5 requiere al menos un búfer, definimos un único búfer «ficticio» oculto, ya que nuestro indicador utilizará objetos personalizados (líneas y rectángulos) en lugar de datos de búfer trazados.
#property copyright "Clemence Benjamin" #property link "https://www.mql5.com/en/users/billionaire2024/seller" #property version "1.00" #property strict // Enforces stricter error checking #property indicator_chart_window #property indicator_buffers 1 // MT5 requires at least one buffer #property indicator_plots 1 // Ties to the buffer (even if unused for plotting)
Paso 2: Añadir entradas de usuario
A continuación, añadimos entradas configurables por el usuario para que el indicador sea adaptable. Incluimos una opción para establecer cuántas barras pasadas analiza el indicador, un rango de precios (por ejemplo, 7 pips por defecto) para detectar pruebas de nivel, un número mínimo de pruebas necesarias para que un nivel se considere fuerte y una opción para mostrar u ocultar zonas rectangulares alrededor de los niveles fuertes. Estas entradas permiten a los usuarios ajustar el comportamiento del indicador sin alterar el código.
input int InpLookBack = 1000; // Number of bars to analyze input double InpTestProximity = 0.0007; // Price range for tests (e.g., 7 pips) input int InpMinTests = 3; // Minimum tests for strong levels input bool InpShowRectangles = true; // Show zones as rectangles
Paso 3: Creación de un búfer ficticio
MetaTrader 5 exige que cada indicador tenga al menos un búfer, aunque no se muestre. Creamos una matriz global para que actúe como este búfer ficticio. Durante la inicialización, lo vinculamos a una ranura de búfer y lo ocultamos del gráfico. Esto cumple con los requisitos de MetaTrader 5 y nos permite centrarnos en trazar niveles de soporte y resistencia personalizados.
double DummyBuffer[]; Cómo utilizarlo:
int OnInit() { SetIndexBuffer(0, DummyBuffer, INDICATOR_DATA); // Bind buffer to index 0 PlotIndexSetInteger(0, PLOT_DRAW_TYPE, DRAW_NONE); // Hide it from the chart return(INIT_SUCCEEDED); }
Paso 4: Definición de estructuras de datos
Para mantener nuestros datos organizados, utilizamos enumeraciones y estructuras. Definimos una enumeración para categorizar los niveles (por ejemplo, soporte fuerte, resistencia débil) para mayor claridad. Una estructura para los niveles de precios almacena el precio, el recuento de pruebas, el tipo y el tiempo de identificación de cada nivel. Otra estructura define zonas alrededor de niveles fuertes, manteniendo sus precios máximos y mínimos y su rango temporal. También configuramos matrices globales para almacenar niveles fuertes, niveles débiles y zonas, además de una variable para rastrear la última hora de alerta.
enum ENUM_LEVEL_TYPE { LEVEL_STRONG_SUPPORT, // Strong support level LEVEL_STRONG_RESISTANCE, // Strong resistance level LEVEL_WEAK_SUPPORT, // Weak support level LEVEL_WEAK_RESISTANCE // Weak resistance level }; struct PriceLevel { double price; // Price value of the level int test_count; // Number of times price tested it ENUM_LEVEL_TYPE type; // Strong or weak, support or resistance datetime time; // Time the level was identified }; struct Zone { double top; // Top price of the zone double bottom; // Bottom price of the zone datetime start_time; // When the zone starts datetime end_time; // When the zone ends (current time) }; PriceLevel StrongLevels[]; // Array for strong levels PriceLevel WeakLevels[]; // Array for weak levels Zone Zones[]; // Array for strong level zones datetime LastAlertTime = 0; // Tracks the last alert time
Paso 5: Detección de puntos de oscilación
Los niveles de soporte y resistencia suelen formarse en los máximos y mínimos oscilantes. Creamos una función para identificar máximos oscilantes comprobando si el máximo de una barra supera los máximos de las 5 barras anteriores y posteriores, lo que marca un pico. Del mismo modo, una función para los mínimos oscilantes comprueba si el mínimo de una barra está por debajo de los mínimos de las 5 barras circundantes, lo que indica un mínimo. El uso de una ventana de 5 barras a cada lado garantiza que estos puntos sean significativos.
bool IsSwingHigh(int index, const double &high[]) { int window = 5; // Check 5 bars on each side for (int i = 1; i <= window; i++) { if (index - i < 0 || index + i >= ArraySize(high)) return false; // Out of bounds if (high[index] <= high[index - i] || high[index] <= high[index + i]) return false; // Not a peak } return true; } bool IsSwingLow(int index, const double &low[]) { int window = 5; // Check 5 bars on each side for (int i = 1; i <= window; i++) { if (index - i < 0 || index + i >= ArraySize(low)) return false; // Out of bounds if (low[index] >= low[index - i] || low[index] >= low[index + i]) return false; // Not a trough } return true; }
Paso 6: Recuento de pruebas de precios
La fuerza de un nivel depende de la frecuencia con la que el precio lo pone a prueba. Agregamos una función para contar estas pruebas examinando las barras después de un punto de giro. Comprueba si el máximo o mínimo de cada barra cae dentro del rango de precios definido del nivel, incrementando un contador para cada prueba. El recuento total de pruebas determina si el nivel es fuerte o débil según el umbral mínimo del usuario.
int CountLevelTests(double price, int start_index, const double &high[], const double &low[]) { int tests = 0; for (int i = start_index + 1; i < ArraySize(high); i++) { if (MathAbs(high[i] - price) <= InpTestProximity || MathAbs(low[i] - price) <= InpTestProximity) { tests++; } } return tests; }
Paso 7: Niveles de procesamiento
Procesamos cada punto de giro en un nivel mediante una función dedicada. Registra el precio, el recuento de pruebas, la hora y el tipo (fuerte/débil, soporte/resistencia) en función de si es un máximo o un mínimo y cumple el umbral de prueba. Para niveles fuertes, también define una zona con un rango de precios alrededor del nivel. Luego, el nivel se almacena en la matriz apropiada (fuerte o débil) para su uso posterior.
void ProcessLevel(int index, double price, bool is_high, const double &high[], const double &low[], const datetime &time[]) { PriceLevel level; level.price = price; level.test_count = CountLevelTests(price, index, high, low); level.time = time[index]; if (is_high) { level.type = (level.test_count >= InpMinTests) ? LEVEL_STRONG_RESISTANCE : LEVEL_WEAK_RESISTANCE; } else { level.type = (level.test_count >= InpMinTests) ? LEVEL_STRONG_SUPPORT : LEVEL_WEAK_SUPPORT; } if (level.test_count >= InpMinTests) { ArrayResize(StrongLevels, ArraySize(StrongLevels) + 1); StrongLevels[ArraySize(StrongLevels) - 1] = level; Zone zone; zone.start_time = time[index]; zone.end_time = TimeCurrent(); zone.top = price + InpTestProximity; zone.bottom = price - InpTestProximity; ArrayResize(Zones, ArraySize(Zones) + 1); Zones[ArraySize(Zones) - 1] = zone; } else { ArrayResize(WeakLevels, ArraySize(WeakLevels) + 1); WeakLevels[ArraySize(WeakLevels) - 1] = level; } }
Paso 8: Dibujar en el gráfico
Para mostrar los niveles, utilizamos dos funciones de renderizado. Se dibujan niveles fuertes con un rectángulo gris (si está habilitado) para la zona y una línea sólida (azul para soporte, roja para resistencia), además de una etiqueta ("SS" o "SR"). El otro dibuja niveles débiles con una línea discontinua (azul claro para soporte, rosa para resistencia) y una etiqueta ("WS" o "WR"). Cada objeto recibe un nombre único en función del momento para garantizar una gestión adecuada en el gráfico.
void RenderZone(const Zone &zone, const PriceLevel &level) { string name = "Zone_" + TimeToString(zone.start_time); if (InpShowRectangles) { ObjectCreate(0, name, OBJ_RECTANGLE, 0, zone.start_time, zone.top, zone.end_time, zone.bottom); ObjectSetInteger(0, name, OBJPROP_COLOR, clrLightGray); ObjectSetInteger(0, name, OBJPROP_FILL, true); } string line_name = "Line_" + TimeToString(level.time); ObjectCreate(0, line_name, OBJ_HLINE, 0, 0, level.price); ObjectSetInteger(0, line_name, OBJPROP_COLOR, (level.type == LEVEL_STRONG_SUPPORT) ? clrBlue : clrRed); ObjectSetString(0, line_name, OBJPROP_TEXT, (level.type == LEVEL_STRONG_SUPPORT) ? "SS" : "SR"); } void RenderWeakLine(const PriceLevel &level) { string name = "WeakLine_" + TimeToString(level.time); ObjectCreate(0, name, OBJ_HLINE, 0, 0, level.price); ObjectSetInteger(0, name, OBJPROP_STYLE, STYLE_DASH); ObjectSetInteger(0, name, OBJPROP_COLOR, (level.type == LEVEL_WEAK_SUPPORT) ? clrLightBlue : clrPink); ObjectSetString(0, name, OBJPROP_TEXT, (level.type == LEVEL_WEAK_SUPPORT) ? "WS" : "WR"); }
Paso 9: Envío de alertas
Incluimos una función para enviar alertas sobre niveles fuertes sin spammar al usuario. Comprueba si ha transcurrido una hora desde la última alerta y si existen niveles fuertes. Si es así, crea un mensaje con el tipo, el precio y el precio actual del último nivel fuerte y luego lo muestra. El tiempo de alerta se actualiza para evitar notificaciones frecuentes.
void SendPeriodicAlert(double current_price) { if (TimeCurrent() - LastAlertTime < 3600) return; // Wait 1 hour between alerts if (ArraySize(StrongLevels) == 0) return; // No strong levels, no alert PriceLevel latest = StrongLevels[ArraySize(StrongLevels) - 1]; string message = "SRZones Alert: Strong " + ((latest.type == LEVEL_STRONG_SUPPORT) ? "Support" : "Resistance") + " at " + DoubleToString(latest.price, 5) + ", Current Price: " + DoubleToString(current_price, 5); Alert(message); LastAlertTime = TimeCurrent(); }
Paso 10: Borrar dibujos antiguos
Para mantener el gráfico limpio, agregamos una función para eliminar objetos antiguos. Elimina todas las zonas dibujadas previamente, líneas de nivel fuertes y líneas de nivel débiles utilizando prefijos de nombre específicos. Esto se ejecuta antes de cada recálculo completo para actualizar la pantalla con los niveles actuales.
void ClearDisplayObjects() { ObjectsDeleteAll(0, "Zone_"); // Delete all zones ObjectsDeleteAll(0, "Line_"); // Delete strong lines ObjectsDeleteAll(0, "WeakLine_"); // Delete weak lines }
Paso 11: Ejecución de la lógica en OnCalculate
Finalmente, unimos todo en la función de cálculo principal. Al iniciar o cuando se forma una nueva barra, borra los objetos antiguos y restablece las matrices. Determina un punto de partida basado en el período de retrospección definido por el usuario, lo que garantiza datos suficientes para la detección de oscilaciones. Recorre las barras, identifica los máximos y mínimos del swing, los procesa en niveles y los almacena. Luego, muestra todos los niveles fuertes y débiles y busca alertas. La función devuelve el número de barras procesadas a MetaTrader 5.
int OnCalculate(const int rates_total, const int prev_calculated, const datetime &time[], const double &open[], const double &high[], const double &low[], const double &close[], const long &tick_volume[], const long &volume[], const int &spread[]) { if (prev_calculated == 0 || rates_total > prev_calculated) { // Full recalc on start or new bar ClearDisplayObjects(); ArrayResize(StrongLevels, 0); ArrayResize(WeakLevels, 0); ArrayResize(Zones, 0); int start = MathMax(5, rates_total - InpLookBack); // Start within lookback period for (int i = start; i < rates_total - 5; i++) { // Leave room for swing checks if (IsSwingHigh(i, high)) ProcessLevel(i, high[i], true, high, low, time); if (IsSwingLow(i, low)) ProcessLevel(i, low[i], false, high, low, time); } for (int i = 0; i < ArraySize(StrongLevels); i++) { RenderZone(Zones[i], StrongLevels[i]); } for (int i = 0; i < ArraySize(WeakLevels); i++) { RenderWeakLine(WeakLevels[i]); } SendPeriodicAlert(close[rates_total - 1]); } return(rates_total); // Tell MT5 how many bars were processed }
Después de ensamblar todas las piezas y resolver varios problemas, compilamos con éxito nuestro producto final, que se adjunta al final de esta discusión. En la siguiente sección, compartiremos nuestra experiencia de prueba y brindaremos reflexiones finales en la conclusión.
Pruebas y resultados
El primer paso consistió en lanzar el indicador y agregarlo al gráfico con la configuración predeterminada, utilizando EURUSD como referencia. Otros pares de divisas pueden requerir ajustes iniciales, particularmente el valor del pip, para que el indicador se muestre correctamente. Por ejemplo, al probar el índice Volatility 75 (1s), no aparecieron zonas hasta que ajusté la configuración de pip a 70.
Inicialmente, como se muestra en la imagen de abajo, el ancho del rectángulo era relativamente pequeño y requería personalización para aumentar su tamaño, lo cual ajustamos en la siguiente imagen. Todas las configuraciones respondieron bien, con cambios notables en el gráfico. Además, todas las etiquetas se muestran claramente y tienes la opción de ocultarlas según sea necesario.

Agregar el indicador de fuerza de soporte y resistencia (SRSI) al gráfico.

Personalización y configuración de SRSI
En el lanzamiento inicial, el indicador envía una alerta que muestra el nivel de soporte o resistencia predominante junto con el precio actual. Esto ayuda a los usuarios a anticipar posibles zonas de oferta y demanda. A continuación se muestra un registro de expertos que muestra los detalles de la alerta.
2025.03.10 07:44:42.548 _SRSI (EURUSD,M15) Alert: Key Level: SR at 1.08715 | Current Price: 1.09021 2025.03.10 07:54:04.239 _SRSI (EURUSD,M15) Alert: Key Level: SR at 1.08715 | Current Price: 1.09033 2025.03.10 07:55:04.965 _SRSI (EURUSD,M5) Alert: Key Level: SR at 1.09013 | Current Price: 1.09044 2025.03.10 09:25:13.506 _SRSI (EURUSD,M5) Alert: Key Level: SR at 1.09013 | Current Price: 1.09210 2025.03.10 11:26:46.761 _SRSI (EURUSD,M5) Alert: Key Level: SR at 1.09013 | Current Price: 1.09192
Además, hay una opción para notificaciones push en la configuración, mientras que las notificaciones del terminal están habilitadas de forma predeterminada. Si se activa una alerta, la ventana de alerta aparecerá automáticamente en la pantalla del terminal.
Ventana de alertas de terminal: Indicador SRSI funcionando
Conclusión
Nuestro objetivo de discusión se ha logrado con éxito con el desarrollo de un indicador libre de errores. A partir de nuestras pruebas, se cumplieron los objetivos de diseño, entregando la funcionalidad esperada. Ahora, puedo dibujar sin esfuerzo mis líneas de soporte y resistencia con solo unos pocos clics, y el algoritmo las examina automáticamente para comprobar su confiabilidad. Como habrás notado en el vídeo, el proceso manual puede ser bastante lento, pero con el algoritmo, estos niveles se calculan instantáneamente con cada tick. A lo largo de este proceso, reunimos información valiosa sobre MQL5 para el desarrollo de indicadores y, si bien el rendimiento del indicador se puede evaluar con el tiempo, hay varias formas en que los desarrolladores avanzados pueden refinarlo y ampliarlo.
En este enfoque, introdujimos estructuras como un medio para escribir código más profesional y organizado. Sin embargo, siempre hay margen de mejora y creo que tienes tus propias ideas y sugerencias para mejorar esta herramienta. Eres bienvenido a modificarlo y experimentar con él, y no dudes en compartir tus ideas en los comentarios a continuación.
Espero que esta discusión te haya resultado interesante. Hasta la próxima: ¡feliz codificación y operaciones exitosas, compañeros desarrolladores!
Archivo adjunto (archivo fuente del SRSI)
| Archivo | Descripción |
|---|---|
| _SRSI.mq5 | Un indicador de fuerza de soporte y resistencia que dibuja dinámicamente zonas rectangulares ajustables, etiquetando claramente el soporte fuerte (SS) y la resistencia fuerte (SR). Además, traza líneas discontinuas para indicar niveles de soporte (WS) y resistencia (WR) más débiles para una mejor visualización. |
Traducción del inglés realizada por MetaQuotes Ltd.
Artículo original: https://www.mql5.com/en/articles/17450
Advertencia: todos los derechos de estos materiales pertenecen a MetaQuotes Ltd. Queda totalmente prohibido el copiado total o parcial.
Este artículo ha sido escrito por un usuario del sitio web y refleja su punto de vista personal. MetaQuotes Ltd. no se responsabiliza de la exactitud de la información ofrecida, ni de las posibles consecuencias del uso de las soluciones, estrategias o recomendaciones descritas.
Redes neuronales en el trading: Detección adaptativa de anomalías del mercado (DADA)
Desarrollo de un kit de herramientas para el análisis de la acción del precio (Parte 17): Asesor experto TrendLoom Tool
Particularidades del trabajo con números del tipo double en MQL4
Desarrollo de un kit de herramientas para el análisis de la acción del precio (Parte 16): Introducción a la teoría de los cuartos (II) - Intrusion Detector EA
- Aplicaciones de trading gratuitas
- 8 000+ señales para copiar
- Noticias económicas para analizar los mercados financieros
Usted acepta la política del sitio web y las condiciones de uso
Me gusta mucho tu artículo y lo he probado con pares FX que parecen funcionar bien... ¿Qué pasa con los índices como US30? ¿cuáles son los ajustes que usted recomienda? he intentado establecer la proximidad de texto a 0,035 y los resultados parecen extraños
Gracias.
Gracias.
Hola Amigo
Estoy siguiendo sus artículos y son informativos. Gracias por compartir y difundir el conocimiento.
He intentado 21Period ATR múltiple como a continuación:
gTestProximity = (MathMax((75/_Digits),0.10*getATR(rates_total - 1))); // (n*getATR(index) sustituido por ...InpTextProximity;
gMinDistance = (MathMax((150/_Digits),0.20*getATR(rates_total - 1))); // (n*getATR(index) reemplazado por ...InpMinWeakDistance;
Esto me ayudó a obtener SRZones para ambos pares EURUSD y XAUUSD con bastante diferencia en los valores de allí 1.08000 a 3000.00.
Puede ser útil para los lectores de su artículo con más ajuste fino un poco. A continuación, la configuración del indicador podría ser universal para la mayoría de los símbolos.
Hola Amigo
Estoy siguiendo sus artículos y son informativos. Gracias por compartir y difundir conocimientos.
He intentado 21Period ATR múltiple como abajo:
gTestProximity = (MathMax((75/_Digits),0.10*getATR(rates_total - 1))); // (n*getATR(index) sustituido por ...InpTextProximity;
gMinDistance = (MathMax((150/_Digits),0.20*getATR(rates_total - 1))); // (n*getATR(index) reemplazado por ...InpMinWeakDistance;
Esto me ayudó a obtener SRZones para ambos pares EURUSD y XAUUSD con bastante diferencia en los valores de allí 1.08000 a 3000.00.
Puede ser útil para los lectores de su artículo con más ajuste fino un poco. A continuación, la configuración del indicador podría ser universal para la mayoría de los símbolos.
Hola, mi buen amigo @Anil Varma.
¡Gracias por compartir este enfoque único! Definitivamente voy a darle una oportunidad.
Hola Amigo
Estoy siguiendo sus artículos y son informativos. Gracias por compartir y difundir conocimientos.
He intentado 21Period ATR múltiple como abajo:
gTestProximity = (MathMax((75/_Digits),0.10*getATR(rates_total - 1))); // (n*getATR(index) sustituido por ...InpTextProximity;
gMinDistance = (MathMax((150/_Digits),0.20*getATR(rates_total - 1))); // (n*getATR(index) reemplazado por ...InpMinWeakDistance;
Esto me ayudó a obtener SRZones para ambos pares EURUSD y XAUUSD con bastante diferencia en los valores de allí 1.08000 a 3000.00.
Puede ser útil para los lectores de su artículo con más ajuste fino un poco. A continuación, la configuración del indicador podría ser universal para la mayoría de los símbolos.
¿Podría compartir su versión del indicador ATR?
Hola
¿Podrías compartir tu versión del indicador ATR?
Hola @Evgeny Fedorenko
En primer lugar lo siento por responder demasiado tarde, en realidad he desviado mi atención a Quant curso de Modelización Financiera.
En segundo lugar no he creado ningún indicador para mí, sólo trató de Clemence Benjamin código del indicador con el ajuste sugerido en mi post.
Espero que esto te ayude.