English Русский 中文 Deutsch 日本語 Português
preview
Implementación de Deus EA: Trading automatizado con RSI y promedios móviles en MQL5

Implementación de Deus EA: Trading automatizado con RSI y promedios móviles en MQL5

MetaTrader 5Trading | 10 febrero 2025, 09:00
702 0
Duke825
[Eliminado]

Introducción

En este artículo, exploraremos los componentes esenciales del Asesor Experto Deus EA, incluyendo su lógica de trading, configuración de parámetros y el código MQL5 necesario para su implementación. Este artículo tiene como objetivo brindarle el conocimiento y las herramientas necesarias para desarrollar y mejorar su algoritmo comercial. Al utilizar Deus EA, podrá explorar el mundo del trading automatizado y descubrir nuevas oportunidades para sus iniciativas comerciales.      

Examinaremos la funcionalidad de Deus EA, una técnica de trading automatizada creada con MQL5. Nuestra discusión se centrará en cómo Deus EA incorpora medias móviles y el índice de fuerza relativa (RSI) para tomar decisiones comerciales. Al analizar estos indicadores, el EA determina los mejores puntos de entrada y salida del mercado para maximizar la rentabilidad del trading y minimizar el riesgo.

Deus EA es un sistema de trading automatizado diseñado para la plataforma MetaTrader 5 que genera señales de compra y venta basadas en medias móviles y el índice de fuerza relativa (RSI). Al identificar las tendencias del mercado y detectar condiciones de sobrecompra o sobreventa, busca mejorar las decisiones comerciales. Además, incluye herramientas de gestión de riesgos como órdenes de stop loss, órdenes de take profit y trailing stops. 


Descripción general de Deus EA 

Deus Expert Advisor (EA) se basa en indicadores como el índice de fuerza relativa (RSI) y las medias móviles para automatizar las decisiones comerciales. El objetivo de este EA es mejorar el rendimiento comercial y gestionar eficazmente el riesgo mediante el uso de estos indicadores para generar recomendaciones prácticas de compra y venta.

Los siguientes son los elementos clave de Deus EA:

  1. Medidas técnicas:
  • Índice de fuerza relativa (RSI): este oscilador de impulso mide qué tan rápido y cómo se mueven los precios, esto ayuda a determinar cuándo el mercado está sobrecomprado o sobrevendido y a responder rápidamente a los movimientos del mercado. En nuestro caso, el EA empleará un breve marco temporal RSI de 7 días, con umbrales establecidos en 35 para circunstancias de sobrecompra y 15 para circunstancias de sobreventa.
  • Promedios móviles (MA): para encontrar tendencias durante un período determinado, el promedio móvil nivela los datos de precios. Utilizaremos un promedio móvil simple (SMA) de 25 períodos en Deus EA para filtrar las señales comerciales y determinar la dirección general del mercado. 


          2. Lógica comercial:
    • Señal de compra: Cuando el precio está por encima de la media móvil y el RSI muestra una condición de sobreventa (por debajo de 15), lo que indica un posible movimiento de precio al alza y se coloca una orden de compra.

    • Señal de venta: Si el precio está por debajo de la media móvil y el RSI indica una condición de sobrecompra (por encima de 35), lo que sugiere una posible tendencia bajista y se coloca una orden de venta.


         3. Gestión de riesgos:
    • Stop Loss y Take Profit: En nuestro EA incluimos parámetros personalizables para los niveles de stop loss y take profit establecidos en 50 puntos cada uno, para ayudar a gestionar el riesgo y fijar las ganancias.
    • Trailing Stop: Utilizamos un trailing stop de 25 puntos para ajustar los niveles de stop loss a medida que el precio se mueve favorablemente, con el objetivo de asegurar ganancias y al mismo tiempo permitir que la operación permanezca abierta mientras el mercado se mueva en la dirección deseada.

          4. Gestión de pedidos:

    • Gestión de posiciones: El EA garantiza que solo una posición esté abierta a la vez cerrando cualquier posición existente antes de abrir una nueva, según las señales comerciales.

    El Deus EA tiene funciones de inicialización, procesamiento de ticks, apertura y cierre de posiciones y ajustes de trailing stop. Se implementa en MQL5, el lenguaje de programación utilizado en MetaTrader 5. La programación garantiza que se sigan las pautas de gestión de riesgos y que las señales comerciales se manejen de manera eficaz.

    Deus ayuda a automatizar los procedimientos comerciales, reducir la toma de decisiones emocionales y también mejorar los resultados comerciales mediante el uso de estas funciones. Este artículo ofrecerá una base para comprender las ideas de diseño y la funcionalidad de Deus EA. 


      Implementación en MQL5

      Primero necesitamos abrir posiciones comerciales. Abrimos las posiciones comerciales mediante la inclusión de un archivo que está dedicado a posiciones abiertas. 

      #include <Trade\Trade.mqh>
      CTrade trade;

      Aquí usamos el archivo de inclusión para incluir la biblioteca comercial. Esto permitirá que Deus EA obtenga acceso a funciones para operaciones comerciales. En este punto también definimos la clase CTrade que ofrece un alto nivel para realizar actividades comerciales. El EA puede usar la clase CTrade para administrar operaciones porque este archivo está incluido. En todo el EA, este objeto se utilizará para realizar diversas tareas comerciales, incluida la apertura, el cambio y el cierre de posiciones.

      En esta sección analizamos los parámetros de entrada cruciales de Deus EA. Deus EA es un algoritmo comercial complejo que utiliza los indicadores de media móvil y RSI para encontrar oportunidades comerciales. Al ajustar estos parámetros, los traders pueden hacer que el EA se comporte de la manera que mejor se adapte a sus tácticas comerciales únicas y a su tolerancia al riesgo.

      Los parámetros de entrada son los siguientes:

      input double Lots = 0.1;                     // Lot size
      input double StopLoss = 50;                  // Stop loss in points
      input double TakeProfit = 50;                // Take profit in points
      input double TrailingStop = 25;              // Trailing stop in points
      

      1. Lots (Volumen comercial)

      input double Lots = 0.1;                     // Lot size

      El tamaño de cada operación se especifica mediante la opción Lots. El EA está configurado para negociar 0.1 lotes en cada transacción en esta instancia. Los comerciantes pueden gestionar su exposición al riesgo de mercado variando el tamaño del lote. Un tamaño de lote más pequeño reduce tanto los posibles riesgos como las ganancias, mientras que un tamaño de lote más grande no solo aumenta las posibles ganancias sino que también aumenta los riesgos. Para equilibrar riesgos y ganancias, es esencial elegir el lote adecuado. 

             2. StopLoss (Stop Loss en puntos)

      input double StopLoss = 50;                  // Stop loss in points         

      La pérdida máxima permitida por operación está definida por la opción StopLoss y en nuestro caso se establece en 50 puntos. Para detener futuras pérdidas, la posición se cerrará automáticamente si el mercado va en contra de la transacción más allá de este punto. Esto protegerá su cuenta comercial contra grandes pérdidas.  

             3. TakeProfit (Toma de ganancias en puntos)

      input double TakeProfit = 50;                // Take profit in points

      Establecemos nuestro objetivo de beneficio para cada transacción en 50 puntos a través del parámetro TakeProfit. Para asegurar ganancias, la posición se cerrará automáticamente cuando el mercado cambie en este grado a favor de la operación. Esto asegurará las ganancias antes de cualquier posible reversión de las condiciones del mercado y, por lo tanto, mejorará la rentabilidad.

             4. TrailingStop (Puntos donde se detiene el trailing)

      input double TrailingStop = 25;              // Trailing stop in points

      Introducimos un stop loss mediante el parámetro TrailingStop, que se desplaza a favor de la operación. Cuando el mercado oscila a favor del trade, el stop dinámico, que inicialmente está fijado a 25 puntos del precio de entrada, se ajusta para fijar las ganancias. Esta función ayudará a los traders a beneficiarse de las fluctuaciones prolongadas del mercado y al mismo tiempo proteger sus ganancias.

      Los parámetros del indicador RSI:

      input int RSI_Period = 7;                   // RSI period
      input double RSI_Overbought = 35.0;         // RSI overbought level
      input double RSI_Oversold = 15.0;           // RSI oversold level

              5. RSI_Period (Período de cálculo del RSI)

      input int RSI_Period = 7;                   // RSI period
            

      El número de períodos utilizados para generar el índice de fuerza relativa (RSI) se especifica mediante el parámetro RSI_Period, que en nuestro caso se establece en 7. Un oscilador de momentum que mide las velocidades y variaciones en los movimientos de precios es el RSI. El RSI responde mejor a los movimientos de precios recientes durante un período corto, como 7, lo que resulta útil para identificar rápidamente situaciones de sobrecompra o sobreventa.

             6. RSI_Overbought (Nivel de sobrecompra del RSI)

      input double RSI_Overbought = 35.0;  

      El umbral para determinar la condición de sobrecompra está definido por el parámetro RSI_Overbought, que se establece en 35. Generalmente, un nivel de sobrecompra podría ser 70, pero utilizando esta técnica, 35 denota una posición de venta más agresiva. El EA activa una acción de venta cuando el RSI está por encima de este umbral, lo que indica que una reversión bajista del mercado puede ser inminente.

               7. RSI_Oversold (Niveles de sobreventa del RSI) 

      input double RSI_Oversold = 15.0;           // RSI oversold level
      

      El umbral de condición de sobreventa está definido por el parámetro RSI_Oversold, que tiene un valor de 15. Aunque este enfoque emplea un nivel más conservador para indicar posibles oportunidades de compra, un nivel de sobreventa típico podría ser 30. El EA activa una acción de compra cuando el RSI cae por debajo de este umbral porque percibe una posible reversión alcista del mercado.

      Parámetros de media móvil

      input int MA_Period = 25;                   // Moving Average period
      input ENUM_MA_METHOD MA_Method = MODE_SMA// Moving Average method
      input ENUM_APPLIED_PRICE MA_Price = PRICE_CLOSE; // Applied price for MA

             8. MA_Period (Período de media móvil)

      input int MA_Period = 25;                   // Moving Average period

       El período de cálculo de la media móvil (MA) está determinado por el parámetro MA_Period, que tiene un valor de 25. Los datos de precios se suavizan mediante la media móvil para detectar tendencias. Una ventana de 25 períodos ofrecerá una perspectiva completa sobre las tendencias del mercado; no solo eliminará el ruido de corto plazo, sino que también responderá a cambios de precios notables.    

             9. MA_Method (Método de media móvil)

      Moving Average period
      input ENUM_MA_METHOD MA_Method = MODE_SMA// Moving Average method

         El tipo de media móvil que se utiliza en este caso, la media móvil simple (SMA), está determinado por la opción MA_Method. La SMA es un indicador de tendencia simple que calcula el promedio de los precios de cierre durante un período determinado. Para diferentes sensibilidades, se podrían emplear técnicas alternativas como la media móvil exponencial (EMA), pero la media móvil simple (SMA) es un indicador de tendencia confiable y constante.

            10. MA_Price (Precio aplicado a MA)

      input ENUM_APPLIED_PRICE MA_Price = PRICE_CLOSE; // Applied price for MA
      

      El tipo de precio utilizado para el cálculo del promedio móvil se especifica mediante la opción MA_Price, que se establece en el precio PRICE_CLOSE. Esto indica que la MA se determina utilizando precios de cierre, que se emplean con frecuencia ya que representan el precio de cierre de una sesión de negociación. Al tomar esta decisión, se garantiza que la MA ofrecerá una indicación confiable de la tendencia general del mercado.

      El comportamiento comercial y la gestión de riesgos de Deus EA están determinados en gran medida por sus parámetros de entrada. Los traders pueden ajustar el EA para que se adapte mejor a sus objetivos comerciales únicos y a las condiciones actuales del mercado ajustando estos parámetros, que incluyen el volumen comercial, los controles de riesgo, las duraciones de los indicadores y los umbrales. Para utilizar plenamente Deus EA en el trading automático, es esencial comprender y modificar estas configuraciones adecuadamente.

      A continuación, analizamos nuestras nuevas variables de EA basadas en los indicadores de media móvil y RSI. Al comprender estos factores, podremos saber cómo el EA maneja la ejecución comercial y analiza los datos del mercado. 

      //--- Variables
      double rsiValue;  // RSI value
      double maValue;   // Moving Average value
      double Ask;
      double Bid;
      double Close; // Initializing Close array with two elements

      El valor RSI:

      double rsiValue;                            // RSI value

      El valor actual del índice de fuerza relativa (RSI) se almacena en la variable rsiValue. Como oscilador de momentum, el RSI ayuda a determinar cuándo el mercado está sobrecomprado o sobrevendido calculando la tasa y la variación de los cambios de precios.

      El tipo de precio y el período RSI designado se utilizan para determinar el valor RSI. Deus EA utiliza los parámetros definidos por el usuario y los datos de precios más recientes para calcular el RSI.

      Cuando el valor RSI cae por debajo del nivel RSI_Oversold, el EA lo interpreta como una señal de compra. Esto implica que el mercado podría estar sobrevendido y podría tener una reversión al alza.

      Por otro lado, si el valor RSI cruza por encima del nivel RSI_Overbought, es una señal de venta. Esto significa que el mercado podría estar sobrecomprado y podría retroceder a la baja. 

      El valor de la media móvil:

      double maValue;                             // Moving Average value

      El valor actual de la media móvil (MA) se almacena en la variable maValue. Al suavizar los datos de precios a lo largo de un período de tiempo predeterminado, este indicador facilita la identificación de tendencias.

      El promedio móvil se calcula utilizando la técnica, el tipo de precio y el período seleccionado. El precio de cierre del período designado se utiliza para calcular la MA en nuestro EA.

      Tendencia: La tendencia del mercado que se encuentra actualmente en vigor está respaldada por el valor MA. Cuando el precio está por encima de la MA, el EA cree que el mercado está en una tendencia alcista y cuando está por debajo de la MA, cree que el mercado está en una tendencia bajista.

      Señal de entrada: La producción de señales comerciales depende de la relación entre los valores RSI y MA. Por ejemplo, si el precio de cierre anterior fue mayor que el valor MA y el RSI está por debajo del nivel RSI_Oversold, entonces una señal de compra se considera legítima. Los valores RSI y MA se combinan en Deus EA para ayudarlo a tomar decisiones comerciales inteligentes.

      double Ask;

      El precio de venta actual del activo se almacena en la variable de venta. Este es el precio de compra del activo para los comerciantes. Establece el precio de entrada para órdenes de compra en la función OpenPosition. El precio de venta es el mayor precio que se puede encontrar en ese momento para comprar el activo. El seguimiento preciso de este coste garantiza que las órdenes de compra se envíen de forma adecuada. 

      double Bid;

      El precio de oferta actual del activo se registra en la variable Bid. Este es el precio de venta del activo para los comerciantes. Establece el precio de entrada para órdenes de venta en la función OpenPosition. El mejor precio que se puede obtener para vender el activo se refleja en el precio de oferta.

      double Close[];

      El precio de cierre del activo para un período particular se almacena en la matriz Close. Se amplía en este EA para almacenar valores para el uso más actual. La matriz se utiliza para producir señales comerciales y analizar los movimientos de precios. Para decidir si introducir una señal de compra o venta, se compara el valor con los precios de cierre del período anterior (Close[1]) y el período más reciente (Close[0]). Esta comparación nos ayudará a determinar si el precio va a subir o bajar. 

      void ApplyTrailingStop();

      Esta función ayudará en la implementación de un mecanismo de trailing stop. Si el precio de mercado actual se mueve a favor del stop loss de la posición, la función itera a través de todas las posiciones abiertas y modifica el stop loss. Esta función garantiza que el stop loss se mantenga en su posición más beneficiosa incluso si el precio del mercado cambia en contra de la operación estableciendo un stop dinámico.

      void OpenPosition(CTrade trade, int orderType);

      Dependiendo del tipo de orden, este método está destinado a abrir nuevas posiciones comerciales. La función determina el take profit, stop loss y el precio de entrada en función del tipo de orden. La transacción se lleva a cabo utilizando parámetros calculados mediante el objeto CTrade. Esto ayudará al EA a generar señales que podrían ser esenciales para iniciar operaciones en el mercado.

      void ClosePositions(int orderType);

      Con esta función se cierran las posiciones comerciales de un tipo de orden particular. Se iteran todas las posiciones abiertas y la función cierra aquellas que se ajustan al tipo de orden designado. Esto ayudará a eliminar posiciones que ya no se ajustan a la estrategia comercial o al estado del mercado, mejorando así la gestión comercial.

      //--- Function prototypes
      void ApplyTrailingStop();
      void OpenPosition(CTrade trade, int orderType);

      Luego combinamos estos prototipos de funciones para darle al EA la capacidad de manejar posiciones comerciales de manera efectiva. El método OpenPosition inicia operaciones en función de las condiciones del mercado, la función ClosePositions controla y cierra operaciones según sea necesario y la función ApplyTrailingStop mejora la gestión de operaciones modificando los stop loss. Todas estas características combinadas permiten que el EA reaccione rápidamente a los cambios del mercado y realice operaciones de manera efectiva. 

      Pasemos ahora a la función OnInit. Deus EA utiliza la función OnInit para comenzar a operar. Está destinado a realizar operaciones basadas en indicadores de Media Móvil y RSI. 

      //+------------------------------------------------------------------+
      //| Expert initialization function                .        |
      //+------------------------------------------------------------------+
      int OnInit()
        {
         Print("Deus  EA initialized successfully.");
         return(INIT_SUCCEEDED);
        }

      Cuando se inicia el terminal o se carga el EA en un gráfico, la función OnInit se invoca una vez. Inicializar variables, establecer indicadores y realizar cualquier otra operación de configuración que necesite el uso de esta función. Luego descomponemos sus partes de la siguiente manera:  

       
         Print("Deus  EA initialized successfully.");

      El objetivo de esta línea de código es imprimir el mensaje que confirma la finalización exitosa de la inicialización en el registro del Asesor Experto (EA). Un componente crucial de cada EA es el registro. Por lo tanto, podremos comprobar que el EA se ha cargado e inicializado sin ningún problema. También es útil para depurar y asegurarse de que el EA esté preparado para comenzar a procesar datos del mercado y ejecutar operaciones. 

      return(INIT_SUCCEEDED);
        }

      La declaración de retorno (INIT_SUCCEEDED) sirve para notificar a la plataforma MetaTrader que el proceso de inicialización se ha completado. El EA debe devolver INIT_SUCCEEDED para pasar a las siguientes etapas, como la función OnTick, que es donde se lleva a cabo la lógica comercial principal. La función podría devolver INIT_FAILED, deteniendo el funcionamiento del EA y evitando posibles fallas durante la operación, si la inicialización ha fallado por algún motivo. 

      A continuación, veamos la función OnDeinit, esta función es crucial para preservar la confiabilidad e integridad de su EA. Discutiremos el papel de esta función. Cuando se vuelve a compilar un EA, se elimina del gráfico. Esta acción activa la función OnDinit y le ofrece la oportunidad de realizar tareas de limpieza y asegurarse de que los recursos se liberen adecuadamente y se completen los pasos de último momento. 

      //+------------------------------------------------------------------+
      //| Expert deinitialization function                                 |
      //+------------------------------------------------------------------+
      void OnDeinit(const int reason)
        {
         Print("Deus  EA deinitialized. Reason: ", reason);
        }

      La razón detrás de la desinicialización se proporciona a través del parámetro de motivo en la función OnDeinit. Esto puede ayudar a depurar y determinar por qué se desinicializó el EA. Utilizamos la función de impresión en Deus EA para registrar este motivo.

      void OnDeinit(const int reason)
        {
         Print("Deus  EA deinitialized. Reason: ", reason);
        }

      Puede determinar si el EA se eliminó explícitamente, se volvió a compilar o fue el resultado del cierre de la terminal consultando este registro sencillo, que puede ofrecer información útil durante las etapas de desarrollo y prueba.

      Aunque el motivo de desinicialización es el único que registra nuestra implementación actual de OnDeinit, esta función se puede ampliar a cualquier procedimiento de limpieza necesario. Por ejemplo, es posible que necesite cerrar cualquier recurso abierto, liberar identificadores de archivos o guardar el estado actual. Se pueden evitar fugas de recursos y se puede garantizar una reinicialización limpia del EA con una limpieza adecuada. Esto es crucial en situaciones de trading en tiempo real, cuando la confiabilidad y la estabilidad son fundamentales. Un manejo correcto garantiza que los problemas de rendimiento de ejecuciones anteriores no interferirán con la capacidad del EA para recargar o reiniciar.

      Pasamos ahora a la función OnTick, la función OnTick que es esencial para el proceso de toma de decisiones en tiempo real del EA. Cada vez que se recibe un nuevo tick de precio, se llama a esta función, que luego le da al EA la capacidad de evaluar el estado del mercado y realizar transacciones utilizando técnicas preestablecidas. Estas son las funciones principales de la función OnTick y cómo combina los componentes de estrategia de Deus EA:

      • Obtención de información del mercado; 

      Cuando la función OnTick se inicia por primera vez, ayuda a obtener la mayor cantidad de datos del mercado.

          Ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
          Bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);
          ArrayResize(Close, 2);
          Close[0] = iClose(_Symbol, _Period, 0);
          Close[1] = iClose(_Symbol, _Period, 1);

        Este código guarda los precios de cierre más recientes y obtiene los precios de oferta y demanda. Para garantizar que la matriz Close tenga suficiente espacio para almacenar el precio de cierre más reciente, se utiliza ArrayResize.

        • Cálculo del Indicador Técnico; 

        El promedio móvil y el índice de fuerza relativa se calculan mediante el algoritmo.

         //--- Calculate RSI value
           rsiValue = iRSI(_Symbol, _Period, RSI_Period, PRICE_CLOSE, 0);
           if (rsiValue == WRONG_VALUE)
             {
              Print("Error calculating RSI");
              return;
             }
           
           //--- Calculate Moving Average value
           maValue = iMA(_Symbol, _Period, MA_Period, 0, MA_Method, MA_Price, 0);
           if (maValue == WRONG_VALUE)
             {
              Print("Error calculating Moving Average");
              return;
             }

          Mientras que el valor MA ayuda a determinar la dirección de la tendencia, el valor RSI indica las condiciones de sobrecompra o sobreventa. Antes de continuar con las comprobaciones, asegúrese de que los números sean exactos.

          • Generación de señales comerciales; luego de calcular los indicadores, la función busca señales de compra y venta:
            //--- Check for Buy Signal
             if(rsiValue < RSI_Oversold && Close[1] > maValue)
               {
                if(PositionsTotal() == 0)
                  {
                   ClosePositions(ORDER_TYPE_SELL);
                   OpenPosition(ORDER_TYPE_BUY);
                  }
               }
             
             //--- Check for Sell Signal
             if(rsiValue > RSI_Overbought && Close[1] < maValue)
               {
                if(PositionsTotal() == 0)
                  {
                   ClosePositions(ORDER_TYPE_BUY);
                   OpenPosition(ORDER_TYPE_SELL);
                  }
             }

            Se emite una señal de compra cuando el precio de cierre actual está por encima de la media móvil y el RSI está por debajo del umbral de sobreventa. Esta situación apunta a una posible reversión al alza. 

            Se emite una señal de venta cuando el precio de cierre está por debajo de la media móvil y el RSI por encima del umbral de sobrecompra. Esta situación sugiere una posible reversión a la baja.

            • Aplicación de Trailing Stop; Para minimizar las pérdidas y salvaguardar las ganancias, la función OnTick incorpora la lógica para aplicar trailing stop.
               //--- Apply trailing stop if specified
               if (TrailingStop > 0)
                 {
                  ApplyTrailingStop();
                 }

              Cuando se establece el parámetro de stop dinámico, esta sección garantiza que el mecanismo de stop dinámico esté activado. Para bloquear las ganancias, la función ApplyTrailingStop modifica el nivel de stop loss a medida que el precio se mueve en la dirección deseada.

              • Posiciones de apertura y cierre: utilizando la posición de apertura, la función OpenPosition intenta abrir una posición después de determinar el precio de entrada, el stop loss y los niveles de take profit. Posición de cierre; todas las posiciones son iteradas por la función ClosePositions, que cierra aquellas que corresponden al tipo de orden dado.

              Esto explica cómo Deus EA se adapta dinámicamente a las situaciones del mercado mediante la función OnTick. Esta función utiliza los indicadores RSI y MA para producir señales comerciales y trailing stops para salvaguardar las ganancias. Con esta estrategia, se garantiza que el EA protegerá las ganancias y también responderá a los cambios del mercado. A continuación se muestra el código completo de la función OnTick:

              //+------------------------------------------------------------------+
              //| Expert tick function                                             |
              //+------------------------------------------------------------------+
              void OnTick()
                {
                  Ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
                  Bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);
                  ArrayResize(Close, 2);
                  Close[0] = iClose(_Symbol, _Period, 0);
                  Close[1] = iClose(_Symbol, _Period, 1);
                  
                  
                 //--- Calculate RSI value
                 rsiValue = iRSI(_Symbol, _Period, RSI_Period, PRICE_CLOSE, 0);
                 if (rsiValue == WRONG_VALUE)
                   {
                    Print("Error calculating RSI");
                    return;
                   }
                 
                 //--- Calculate Moving Average value
                 maValue = iMA(_Symbol, _Period, MA_Period, 0, MA_Method, MA_Price, 0);
                 if (maValue == WRONG_VALUE)
                   {
                    Print("Error calculating Moving Average");
                    return;
                   }
              
                 //--- Check for Buy Signal
                 if(rsiValue < RSI_Oversold && Close[1] > maValue)
                   {
                    if(PositionsTotal() == 0)
                      {
                       ClosePositions(ORDER_TYPE_SELL);
                       OpenPosition(ORDER_TYPE_BUY);
                      }
                   }
                 
                 //--- Check for Sell Signal
                 if(rsiValue > RSI_Overbought && Close[1] < maValue)
                   {
                    if(PositionsTotal() == 0)
                      {
                       ClosePositions(ORDER_TYPE_BUY);
                       OpenPosition(ORDER_TYPE_SELL);
                      }
                 }
                 
                 //--- Apply trailing stop if specified
                 if (TrailingStop > 0)
                   {
                    ApplyTrailingStop();
                   }

              Ahora que hemos terminado con la función OnTick, veamos libremente las funciones de utilidad de nuestro EA. Para que Deus EA ejecute una operación basada en señales de los indicadores RSI y media móvil, la función de apertura es esencial. Esta función garantiza que las órdenes de compra y venta se realicen con precisión, teniendo en cuenta los factores de gestión de riesgos.

              void OpenPosition(int orderType)

              El tipo de orden a colocar está determinado por el único parámetro, tipo de orden, que acepta la función OpenPosition. Para órdenes de compra y venta, respectivamente, esto podría ser ORDER_TYPE_BUY o ORDER_TYPE_SELL. El tipo de orden determina el precio del pedido dentro de la función.

              double price = (orderType == ORDER_TYPE_BUY) ? Ask : Bid;

              Al utilizar el precio (Ask) para una orden de compra, se utiliza el precio (Bid) para una orden de venta.

              Para controlar el riesgo y asegurar las ganancias, se determinan los umbrales de stop loss (SL) y take profit (TP): 

              double sl = (orderType == ORDER_TYPE_BUY) ? price - StopLoss * _Point : price + StopLoss * _Point;
              double tp = (orderType == ORDER_TYPE_BUY) ? price + TakeProfit * _Point : price - TakeProfit * _Point;

              El take profit se coloca por encima del precio de la orden y el stop loss se establece por debajo para las órdenes de compra. El take profit y el stop loss para las órdenes de venta se colocan debajo y encima del precio de la orden respectivamente. La función PositionOpen de la clase CTrade se utiliza para abrir la posición real:

              bool result = trade.PositionOpen(_Symbol, orderType, Lots, price, sl, tp, "Deus  EA");
                 

              Esta técnica requiere varios parámetros: 

              • -{ Symbol}: El símbolo utilizado para operar, como EURUSD.
              • -{ orderType}: El tipo de orden (venta o compra).
              • -"Lots": El tamaño del lote de la orden.
              • -{price}: El precio de compra o venta de la orden.
              • -{sI}: El nivel de cálculo del stop loss. 
              • -{tp}: El umbral de toma de ganancias determinado.
              • -"Deus EA": Una declaración relacionada con la orden.

              Después de un intento de abrir la posición, la función verifica el resultado y registra un mensaje cuando es necesario.

              if(result)
                   {
                    Print("Order opened successfully. Type: ", orderType, ", Price: ", price);
                   }
                 else
                   {
                    Print("Failed to open order. Error code: ", GetLastError());
                   }
                }

              Si el pedido se abre correctamente, se imprime un acuse de recibo. Si no se puede abrir el pedido, se utiliza GetLastError para recuperar el código del problema, que luego se anota para solucionar el problema. 

              El código completo para la función para abrir posiciones es el siguiente:

              //+------------------------------------------------------------------+
              //| Function to open a position                          |
              //+------------------------------------------------------------------+
              void OpenPosition(int orderType)
                {
                 double price = (orderType == ORDER_TYPE_BUY) ? Ask : Bid;
                 double sl = (orderType == ORDER_TYPE_BUY) ? price - StopLoss * _Point : price + StopLoss * _Point;
                 double tp = (orderType == ORDER_TYPE_BUY) ? price + TakeProfit * _Point : price - TakeProfit * _Point;
                 
                 bool result = trade.PositionOpen(_Symbol, orderType, Lots, price, sl, tp, "Deus  EA");
                 
                 if(result)
                   {
                    Print("Order opened successfully. Type: ", orderType, ", Price: ", price);
                   }
                 else
                   {
                    Print("Failed to open order. Error code: ", GetLastError());
                   }
                }  
               )    

              Hemos terminado con una de las funciones de utilidad, veamos ahora otra, que es una función para cerrar posiciones. Para garantizar que las posiciones no deseadas sean eliminadas por los parámetros de la estrategia comercial, la función ClosePositions de Deus EA es esencial. Cuando se cumplen ciertas condiciones, esta función está destinada a gestionar la lógica de cierre de posiciones de un tipo particular (compra o venta). Examinemos las operaciones de esta función y su importancia para el plan más amplio. 

              void OpenPosition(int orderType)

              El tipo de posición a cerrar se especifica mediante un único argumento orderType, que es tomado por la función Closepositions. ORDER_TYPE_SELL o ORDER_TYPE_BUY son los valores posibles para este parámetro. La función recorre todas las posiciones abiertas en este momento y cierra las relevantes.  

              for(int i = PositionsTotal() - 1; i >= 0; i--)
                   {
                    if(PositionSelectByIndex(i))
                      {
                       if(PositionGetInteger(POSITION_TYPE) == orderType)
                         {
                          if(!trade.PositionClose(ticket)
                            {
                             Print("Failed to close position. Error code: ", GetLastError());
                            }
                        }
                   }
                }

              El bucle avanza hacia atrás, comenzando en el último punto. Debido a que cerrar una posición reduce el recuento general de posiciones, es posible que se interrumpa un ciclo de iteración hacia adelante, lo que hace necesaria esta iteración inversa. PositionSelectByIndex(i) se utiliza para elegir la posición en el índice dado {i}.

              La función verifica si la ubicación elegida coincide con el {orderType} dado dentro del bucle.

              if(PositionGetInteger(POSITION_TYPE) == orderType)

              Si {orderType} no es igual a este valor, la posición no debe cerrarse. La función intenta cerrar la posición si el tipo coincide.

              if(!trade.PositionClose(ticket)
                            {
                             Print("Failed to close position. Error code: ", GetLastError());
                            }
                        }
                   }
                }

              Una posición se cierra al intentar identificarla por su número de ticket {trade.PositionClose(ticket)}). Se imprime un mensaje de error con el código de error obtenido por GetLastError() si la posición no se puede cerrar. Esto ayuda a identificar la causa de la imposibilidad de cerrar la posición y facilita la resolución de problemas.

              Deus EA puede bloquear ganancias cerrando posiciones ganadoras cuando alcanzan un determinado nivel de ganancias. Esto se logra asegurándose de que las posiciones seleccionadas se cierren en condiciones específicas.

              El código completo de la función para cerrar la posición es el siguiente:

              //+------------------------------------------------------------------+
              //| Function to close positions                                      |
              //+------------------------------------------------------------------+
              void ClosePositions(int orderType)
                {
                 for(int i = PositionsTotal() - 1; i >= 0; i--)
                   {
                    if(PositionSelectByIndex(i))
                      {
                       if(PositionGetInteger(POSITION_TYPE) == orderType)
                         {
                          if(!trade.PositionClose(ticket)
                            {
                             Print("Failed to close position. Error code: ", GetLastError());
                            }
                        }
                   }
                }
              

              Por último, pasemos a nuestra última función de utilidad, que es una función para aplicar el trailing stop. Puedes detener pérdidas adicionales cerrando operaciones perdedoras. Siguiendo las pautas, como abstenerse de mantener posiciones de compra y venta al mismo tiempo y realizar operaciones de cobertura. El trailing stop modifica los niveles de stop loss cuando el precio del mercado se desplaza a favor de una posición abierta. El método ApplyTrailingStop en Deus EA garantiza que esta función se aplique de manera efectiva. El trailing stop limita las pérdidas potenciales al tiempo que fija las ganancias mediante el seguimiento de las fluctuaciones del mercado. Analicemos cómo funciona la función.

              void ApplyTrailingStop()

              Dado que esto se aplica a todas las posiciones abiertas en el símbolo actual, el método ApplyTrailingStop no requiere ningún parámetro. Al igual que la función ClosePositions, la función comienza iterando a través de todas las posiciones abiertas: 

              for (int i = PositionsTotal() - 1; i >= 0; i--)
                   {
                    if (PositionSelectByIndex(i) && PositionGetSymbol() == _Symbol)

              El bucle avanza hacia atrás, comenzando en la última posición. 

              -{PositionSelectByIndex(i)}: esta función elige la entrada en el índice{i}. Verifica que la posición esté asociada con el símbolo comercial activo utilizando {PositionGetSymbol()==_Symbol}.

              La función utiliza la distancia del stop dinámico y el precio de mercado actual para determinar el nuevo nivel de stop:

               double price = (PositionGetInteger(POSITION_TYPE) == ORDER_TYPE_BUY) ? Bid : Ask;
               double sl = (PositionGetInteger(POSITION_TYPE) == ORDER_TYPE_BUY) ? price - TrailingStop * _Point : price + TrailingStop * _Point;
                       

              El trailing stop para posiciones de compra se establece por debajo del precio {bid}. El trailing stop se posiciona por encima del precio {Ask} para operaciones de venta. Luego, la función utiliza PositionModify para aplicar el nuevo nivel de stop loss después de determinar si es apropiado: 

              if (PositionGetInteger(POSITION_TYPE) == ORDER_TYPE_BUY && PositionGetDouble(POSITION_SL) < sl)
                         {
                          if (!trade.PositionModify(PositionGetInteger(POSITION_TICKET), sl, PositionGetDouble(POSITION_TP)))
                            {
                             Print("Failed to modify position. Error code: ", GetLastError());
                            }
                         }
                       else if (PositionGetInteger(POSITION_TYPE) == ORDER_TYPE_SELL && PositionGetDouble(POSITION_SL) > sl)
                         {
                          if (!trade.PositionModify(PositionGetInteger(POSITION_TICKET), sl, PositionGetDouble(POSITION_TP)))
                            {
                             Print("Failed to modify position. Error code: ", GetLastError());
                            }
                         }
                      }

              Solo cuando el nuevo nivel de stop loss ({sI)} excede el stop loss existente, se modifica el stop loss de sus posiciones. Además, cuando el nuevo nivel de stop loss es menor que el stop loss existente, se actualiza para las posiciones de venta.

              Se imprime un mensaje de error que contiene el código de error si la modificación de la posición no se realiza correctamente. Esto ayuda a solucionar problemas y también ayuda a aclarar el motivo por el cual no se utilizó el trailing stop.

              El código completo para la función que aplica el trailing stop es el siguiente:

              //+------------------------------------------------------------------+
              //| Function to apply trailing stop                                  |
              //+------------------------------------------------------------------+
              void ApplyTrailingStop()
                {
                 for (int i = PositionsTotal() - 1; i >= 0; i--)
                   {
                    if (PositionSelectByIndex(i) && PositionGetSymbol() == _Symbol)
                      {
                       double price = (PositionGetInteger(POSITION_TYPE) == ORDER_TYPE_BUY) ? Bid : Ask;
                       double sl = (PositionGetInteger(POSITION_TYPE) == ORDER_TYPE_BUY) ? price - TrailingStop * _Point : price + TrailingStop * _Point;
                       
                       if (PositionGetInteger(POSITION_TYPE) == ORDER_TYPE_BUY && PositionGetDouble(POSITION_SL) < sl)
                         {
                          if (!trade.PositionModify(PositionGetInteger(POSITION_TICKET), sl, PositionGetDouble(POSITION_TP)))
                            {
                             Print("Failed to modify position. Error code: ", GetLastError());
                            }
                         }
                       else if (PositionGetInteger(POSITION_TYPE) == ORDER_TYPE_SELL && PositionGetDouble(POSITION_SL) > sl)
                         {
                          if (!trade.PositionModify(PositionGetInteger(POSITION_TICKET), sl, PositionGetDouble(POSITION_TP)))
                            {
                             Print("Failed to modify position. Error code: ", GetLastError());
                            }
                         }
                      }

              El código completo del artículo es el siguiente:

              //+------------------------------------------------------------------+
              //|                     Deus  EA                                      |
              //|     Copyright 2024, MetaQuotes Ltd.                              |
              //|                    https://www.mql5.com                          |
              //+------------------------------------------------------------------+
              #include <Trade\Trade.mqh>
              CTrade trade;
              
              //--- Input parameters
              input double Lots = 0.1;                 // Lot size
              input double StopLoss = 50;              // Stop loss in points
              input double TakeProfit = 50;            // Take profit in points
              input double TrailingStop = 25;          // Trailing stop in points
              
              //--- RSI parameters
              input int RSI_Period = 7;                // RSI period
              input double RSI_Overbought = 35.0;      // RSI overbought level
              input double RSI_Oversold = 15.0;        // RSI oversold level
              
              //--- Moving Average parameters
              input int MA_Period = 25;                // Moving Average period
              input ENUM_MA_METHOD MA_Method = MODE_SMA;  // Moving Average method
              input ENUM_APPLIED_PRICE MA_Price = PRICE_CLOSE; // Applied price for MA
              
              //--- Variables
              double rsiValue;  // RSI value
              double maValue;   // Moving Average value
              double Ask;
              double Bid;
              double Close[2];  // Initializing Close array with two elements
              
              //--- Function prototypes
              void ApplyTrailingStop();
              void OpenPosition(CTrade &trade, int orderType); // Pass CTrade by reference
              void ClosePositions(int orderType);           // pass orderType directly
               
              //+------------------------------------------------------------------+
              //| Expert initialization function                                   |
              //+------------------------------------------------------------------+
              int OnInit()
                {
                 Print("Deus  EA initialized successfully.");
                 return(INIT_SUCCEEDED);
                }
               
              //+------------------------------------------------------------------+
              //| Expert deinitialization function                                 |
              //+------------------------------------------------------------------+
              void OnDeinit(const int reason)
                {
                 Print("Deus  EA deinitialized. Reason: ", reason);
                }
              
              //+------------------------------------------------------------------+
              //| Expert tick function                                             |
              //+------------------------------------------------------------------+
              void OnTick()
                {
                //--- Update current prices
                  Ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
                  Bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);
                  ArrayResize(Close, 2);
                   Close[0] = iClose(_Symbol, Period(), 0);
                  Close[1] = iClose(_Symbol, Period(), 1);
                 
                  
                 //--- Calculate RSI value
                 rsiValue = iRSI(_Symbol, _Period, RSI_Period, PRICE_CLOSE, 0);
                 if (rsiValue == WRONG_VALUE)
                   {
                    Print("Error calculating RSI");
                    return;
                   
                 //--- Calculate Moving Average value
                 maValue = iMA(_Symbol, _Period, MA_Period, 0, MA_Method, MA_Price, 0);
                 if (maValue == WRONG_VALUE)
                   {
                    Print("Error calculating Moving Average");
                    return;
                   }
              
                 //--- Check for Buy Signal
                 if(rsiValue < RSI_Oversold && Close[1] > maValue)
                   {
                    if(PositionsTotal() == 0)
                      {
                       ClosePositions(ORDER_TYPE_SELL);
                       OpenPosition(ORDER_TYPE_BUY);
                      }
                   }
                 
                 //--- Check for Sell Signal
                 if(rsiValue > RSI_Overbought && Close[1] < maValue)
                   {
                    if(PositionsTotal() == 0)
                      {
                       ClosePositions(ORDER_TYPE_BUY);
                       OpenPosition(ORDER_TYPE_SELL);
                      }
                    }
                 
                 //--- Apply trailing stop if specified
                 if(TrailingStop > 0)
                   {
                    ApplyTrailingStop();
                   }
                 }
                 
              //+------------------------------------------------------------------+
              //| Function to open a position                                      |
              //+------------------------------------------------------------------+
              void OpenPosition(int orderType)
                {
                 //--- Determine price stop loss, and take profit levels 
                 double price = (orderType == ORDER_TYPE_BUY) ? Ask : Bid;
                 double sl = (orderType == ORDER_TYPE_BUY) ? price - StopLoss * _Point : price + StopLoss * _Point;
                 double tp = (orderType == ORDER_TYPE_BUY) ? price + TakeProfit * _Point : price - TakeProfit * _Point;
                 
                 
                 bool result = trade.PositionOpen(_Symbol, orderType, Lots, price, sl, tp, "Deus  EA");
                 
                 if(result)
                   {
                    Print("Order opened successfully. Type: ", orderType, ", Price: ", price);
                   }
                 else
                   {
                    Print("Failed to open order. Error code: ", GetLastError());
                   }
                }
              
              //+------------------------------------------------------------------+
              //| Function to close positions                                      |
              //+------------------------------------------------------------------+
              void ClosePositions(int orderType)
                {
                 for(int i = PositionsTotal() - 1; i >= 0; i--)
                   {
                    if(PositionSelectByIndex(i))
                      {
                      //--- Check if the positions type matches the order type to be closed
                       if(PositionGetInteger(POSITION_TYPE) == orderType)
                         {
                         ulong ticket = PositionGetInteger(POSITION_TICKET);
                          if(!trade.PositionClose(ticket)
                            {
                             Print("Failed to close position. Error code: ", GetLastError());
                            }
                          }
                        }
                     }
                   }
              
              
              //+------------------------------------------------------------------+
              //| Function to apply trailing stop                                  |
              //+------------------------------------------------------------------+
              void ApplyTrailingStop()
                {
                 for (int i = PositionsTotal() - 1; i >= 0; i--)
                   {
                    if (PositionSelectByIndex(i) && PositionGetSymbol() == _Symbol)
                      {
                       double price = (PositionGetInteger(POSITION_TYPE) == ORDER_TYPE_BUY) ? Bid : Ask;
                       double sl = (PositionGetInteger(POSITION_TYPE) == ORDER_TYPE_BUY) ? price - TrailingStop * _Point : price + TrailingStop * _Point;
                       
                       //--- Trailing  stop logic for buy positions 
                       if (PositionGetInteger(POSITION_TYPE) == ORDER_TYPE_BUY && PositionGetDouble(POSITION_SL) < sl)
                         {
                          if (!trade.PositionModify(PositionGetInteger(POSITION_TICKET), sl, PositionGetDouble(POSITION_TP)))
                            {
                             Print("Failed to modify position. Error code: ", GetLastError());
                            }
                         }
                      
                       //--- Trailing stop logic for sell positions
                       else if (PositionGetInteger(POSITION_TYPE) == ORDER_TYPE_SELL && PositionGetDouble(POSITION_SL) > sl)
                         {
                          if (!trade.PositionModify(PositionGetInteger(POSITION_TICKET), sl, PositionGetDouble(POSITION_TP)))
                            {
                             Print("Failed to modify position. Error code: ", GetLastError());
                            }
                         }
                      }
                    }
                     

              ¡Enhorabuena! Hasta este punto, hemos implementado nuestro Deus EA para automatizar el comercio.

              Aquí están los resultados de nuestras pruebas.



              Resultados obtenidos:


              La prueba fue USDJYP y la prueba retrospectiva es del 10/07/2024 al 06/08/2024 en el gráfico de H1. Modelado; todos los ticks. Los parámetros utilizados son los que utilizamos para estudiar la implementación.  

              Este tipo de estrategia es mejor en EURUSD y USDJPY, pero solo para aquellos que no necesitan una alta tasa de ganancias. A continuación se muestran los parámetros que hemos utilizado para realizar la prueba para nuestro EA:


              Conclusión

              Deus EA utiliza promedios móviles y el índice de fuerza relativa (RSI) para generar señales comerciales, mostrando una estrategia comercial avanzada que integra indicadores técnicos para administrar y capitalizar las oportunidades del mercado. Esta guía ha detallado la lógica comercial, el control de riesgos y el código MQL5 que sustenta el EA, que automatiza las decisiones comerciales para mejorar la consistencia y reducir el sesgo emocional.

              Del gráfico podemos aprender que los parámetros pequeños para la optimización no solo reducen el riesgo sino que también aumentan la pérdida. Por lo tanto, antes de implementar un EA en una negociación en vivo, es fundamental realizar pruebas exhaustivas y optimizarlos en diferentes símbolos. Esto ayudará a garantizar que funcione bien en diferentes condiciones de mercado y se alinee con objetivos comerciales específicos.

              Es necesario realizar un seguimiento y ajustes periódicos para mantener la eficacia de Deus EA y sistemas automatizados similares. Este artículo proporciona información y herramientas esenciales necesarias para implementar y optimizar eficazmente Deus EA para el trading. Cualquier ayuda adicional que necesites podrás acceder a ella desde MQL5.


              Traducción del inglés realizada por MetaQuotes Ltd.
              Artículo original: https://www.mql5.com/en/articles/15431

              Archivos adjuntos |
              Deus_EA.mq5 (9.28 KB)
              Aprendizaje automático y Data Science (Parte 29): Consejos esenciales para seleccionar los mejores datos de divisas para el entrenamiento de IA Aprendizaje automático y Data Science (Parte 29): Consejos esenciales para seleccionar los mejores datos de divisas para el entrenamiento de IA
              En este artículo, profundizamos en los aspectos cruciales de la elección de los datos de Forex más relevantes y de alta calidad para mejorar el rendimiento de los modelos de IA.
              Características del Wizard MQL5 que debe conocer (Parte 30): Normalización por lotes en el aprendizaje automático Características del Wizard MQL5 que debe conocer (Parte 30): Normalización por lotes en el aprendizaje automático
              La normalización por lotes es el preprocesamiento de datos antes de introducirlos en un algoritmo de aprendizaje automático, como una red neuronal. Esto siempre se hace teniendo en cuenta el tipo de activación que utilizará el algoritmo. Por lo tanto, exploramos los diferentes enfoques que se pueden adoptar para aprovechar los beneficios de esto, con la ayuda de un Asesor Experto ensamblado por un asistente.
              Creación de un asesor experto integrado de MQL5 y Telegram (Parte 1): Envío de mensajes desde MQL5 a Telegram Creación de un asesor experto integrado de MQL5 y Telegram (Parte 1): Envío de mensajes desde MQL5 a Telegram
              En este artículo, creamos un Asesor Experto (EA) en MQL5 para enviar mensajes a Telegram usando un bot. Configuramos los parámetros necesarios, incluido el token de API del bot y el ID de chat, y luego realizamos una solicitud HTTP POST para entregar los mensajes. Posteriormente, gestionamos la respuesta para garantizar una entrega exitosa y solucionar cualquier problema que surja en caso de falla. Esto garantiza que enviemos mensajes desde MQL5 a Telegram a través del bot creado.
              Integración de MQL5 con paquetes de procesamiento de datos (Parte 1): Análisis avanzado de datos y procesamiento estadístico Integración de MQL5 con paquetes de procesamiento de datos (Parte 1): Análisis avanzado de datos y procesamiento estadístico
              La integración permite un flujo de trabajo continuo en el que los datos financieros sin procesar de MQL5 se pueden importar a paquetes de procesamiento de datos como Jupyter Lab para realizar análisis avanzados que incluyen pruebas estadísticas.