
Creación de un modelo de restricción de tendencia de velas (Parte 8): Desarrollo de un asesor experto (II)
Contenido:
Introducción
En nuestro artículo anterior, exploramos la creación de un asesor experto (EA) utilizando el indicador Trend Constraint V1.09, complementado por el script Trend Constraint R-R de ejecución manual para colocar rectángulos de riesgo y recompensa. Aunque esta configuración proporcionaba señales de negociación perspicaces y una visualización mejorada, requería una intervención manual que podría racionalizarse. Con el ritmo acelerado de los entornos comerciales, se hace evidente la necesidad de una solución más eficaz. Muchos operadores buscan sistemas integrados que funcionen de forma autónoma, reduciendo la necesidad de supervisión constante y ejecución manual.
Este artículo da el siguiente paso en nuestra serie guiándole a través del desarrollo de un asesor experto independiente (EA) que no sólo incorpora las capacidades de análisis de tendencias de Trend Constraint V1.09, sino que también integra funcionalidades de riesgo-recompensa directamente en el EA. Nuestro objetivo es dotar a los operadores de una solución «todo en uno» utilizando MQL5 en la plataforma MetaTrader 5, ofreciendo una mayor automatización y un funcionamiento sin problemas para seguir el ritmo de las demandas del mercado.
Para lograrlo, revisaremos las etapas fundacionales cubiertas en Parte 1, Parte 2, y Parte 3, tomando prestada la lógica necesaria para que el EA realice sus tareas de trading. Ahora, combinaremos todas estas partes y su lógica para escribir el Asesor Experto.
A continuación se muestra un resumen de las condiciones que generan señales en el indicador tal como se implementa en MQL5:
Condición de compra (larga):
Condición de venta (corta):
- La vela del día debe ser alcista.
- En un marco de tiempo inferior dentro de una vela alcista D1, necesitamos una confluencia de señales. Específicamente, el indicador incorporado, como el índice de fuerza relativa (RSI), debería indicar una condición de sobreventa y el promedio de movimiento rápido debe cruzar por encima del promedio de movimiento lento.
- La vela del día debe ser bajista.
- En un marco de tiempo inferior dentro de una vela bajista D1, necesitamos una confluencia de señales. Específicamente, el indicador incorporado, como el índice de fuerza relativa (RSI), debería indicar una condición de sobrecompra, y el promedio de movimiento rápido debe cruzar por debajo del promedio de movimiento lento.
Creación del asesor experto
Usamos la aplicación MetaEditor para escribir nuestro EA en MQL5. Lo más importante es tener presente los cimientos. A continuación se muestra la estructura resumida de nuestro EA.
Resumen de la arquitectura de la mayoría de los EAs:
- Inicialización (OnInit): configure los indicadores y variables necesarios.
- Bucle principal (OnTick): procesa los ticks entrantes para evaluar las condiciones del mercado y tomar decisiones comerciales.
- Gestión comercial (OnTrade): gestionar eventos relacionados con el comercio.
- Pruebas (OnTester y funciones relacionadas): proporcionar estructura para optimizar y evaluar el rendimiento del EA en el Probador de estrategias.
- Interacción del usuario (OnChartEvent): opcional, pero permite la interacción con el EA a través de eventos de gráficos.
Creo que el borrador en el diagrama de bloques a continuación ayudará a aclarar el resultado deseado, haciéndolo más fácil de entender.
Un diagrama de bloques aproximado de las partes del EA y cómo se interrelacionan.
Esta estructura garantiza que nuestro EA esté bien organizado y sea capaz de gestionar eficazmente las diversas tareas necesarias para implementar nuestra estrategia comercial. Dividiré el proceso de desarrollo en subsecciones, pero los desarrolladores avanzados pueden omitir las etapas (1) y (2) y pasar directamente a las subsecciones (3).(1) Lanzamiento del EA por defecto (plantilla) en el MetaEditor.
(2) Personalización de la plantilla.
(3) Escribir la lógica de Trend Constraint EA en la plantilla preparada.
(1) Lanzamiento de la plantilla
En MetaEditor, pulse Ctrl + N para iniciar un nuevo archivo, y elija «Asesor Experto (Plantilla)» como se muestra en la imagen de abajo:
Lanzar un nuevo Asesor Experto (Plantilla).
Tenga en cuenta que los datos del autor y los enlaces ya están disponibles cuando lanzo un nuevo proyecto debido a los proyectos anteriores que tengo en mi ordenador. Puedes personalizarlos tú mismo.
(2) Personalización de la plantilla
La intención detrás de este escrito no es sólo demostrar mi capacidad de codificación, sino también impactar a quienes recién comienzan a entender el proceso para que puedan aplicar las habilidades adquiridas en el futuro. En este punto, estamos mirando la plantilla, que puede no parecer significativa para un novato. Antes de comenzar a codificar en la plantilla de esqueleto, extraeré y explicaré brevemente las funciones más importantes necesarias. Luego procederemos a completar los detalles, escribiendo el código EA para satisfacer nuestras necesidades. Este enfoque es crucial ya que te permitirá iniciar otros proyectos propios, diferentes a los que nos centramos ahora, sin ninguna dificultad.
El esqueleto proporciona la base sobre la que más adelante construiremos la lógica para nuestro EA.
Aquí está la plantilla generada por MetaEditor:
//+------------------------------------------------------------------+ //| Trend Constraint Expert.mq5 | //| Copyright 2024, Clemence Benjamin | //| https://www.mql5.com/en/users/billionaire2024/seller | //+------------------------------------------------------------------+ #property copyright "Copyright 2024, Clemence Benjamin" #property link "https://www.mql5.com/en/users/billionaire2024/seller" #property version "1.00" //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- //--- return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { //--- } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { //--- } //+------------------------------------------------------------------+ //| Trade function | //+------------------------------------------------------------------+ void OnTrade() { //--- } //+------------------------------------------------------------------+ //| Tester function | //+------------------------------------------------------------------+ double OnTester() { //--- double ret=0.0; //--- //--- return(ret); } //+------------------------------------------------------------------+ //| TesterInit function | //+------------------------------------------------------------------+ void OnTesterInit() { //--- } //+------------------------------------------------------------------+ //| TesterPass function | //+------------------------------------------------------------------+ void OnTesterPass() { //--- } //+------------------------------------------------------------------+ //| TesterDeinit function | //+------------------------------------------------------------------+ void OnTesterDeinit() { //--- } //+------------------------------------------------------------------+ //| ChartEvent function | //+------------------------------------------------------------------+ void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam) { //--- } //+------------------------------------------------------------------+
A partir de la plantilla, analicemos las funciones clave esenciales para nuestros Asesores Expertos:
- Función OnInit(): Esta función se ejecuta una vez cuando se inicializa el EA y configura indicadores, variables o recursos necesarios para la operación. La inicialización adecuada garantiza que todos los recursos necesarios estén listos antes de que el EA comience a procesar los datos del mercado. En su «Trend Constraint EA», el indicador RSI y otras variables cruciales normalmente se inicializarían aquí.
- Función OnDeinit(): Esta función se llama cuando se desinicializa el EA, como cuando se elimina de un gráfico o se apaga el terminal. Se utiliza para limpiar recursos, como liberar indicadores o cerrar archivos, para evitar pérdidas de memoria u otros problemas.
- Función OnTick(): Esta función principal se activa cada vez que se recibe un nuevo tick (actualización del precio) para el símbolo al que está vinculado el EA. En su «Trend Constraint EA», incluiría la lógica para comprobar las condiciones del mercado, como la tendencia D1 y los niveles del RSI, y tomar decisiones de negociación como abrir o cerrar posiciones.
- Función OnTrade(): Llamada que ocurre cuando hay un evento de operación, como colocar, modificar o cerrar una orden, esta función es vital para monitorear el estado de la operación y reaccionar a los cambios. Por ejemplo, podría usarlo para rastrear cuándo se abre una operación y ajustar el comportamiento del EA en consecuencia.
- Función OnTester(): Esta función se utiliza durante la prueba de la estrategia para devolver un valor doble, que sirve como criterio personalizado para la optimización. Le permite definir una métrica personalizada, como el factor de beneficio o la reducción, para evaluar el rendimiento del EA al realizar pruebas en el Probador de estrategias.
- Funciones OnTesterInit(), OnTesterPass(), y OnTesterDeinit(): Estas funciones son específicas para la prueba y optimización de estrategias, gestionando el inicio, pases en curso y finalización de las pruebas en el Probador de Estrategias. Proporcionan un mayor control sobre el proceso de pruebas mediante la inicialización de recursos, la recopilación de datos y la limpieza después de las pruebas.
- Función OnChartEvent(): Esta función maneja eventos del gráfico, como clics del ratón o pulsaciones de teclas, permitiendo la interacción con el EA mientras se está ejecutando. Si su EA incluye interacción del usuario, como cambiar parámetros o activar acciones a través de eventos gráficos, esta función es esencial.
Una vez comprendidas estas funciones, podemos ver cómo estructurar la lógica dentro de ellas. Sin embargo, las funciones proporcionadas por la plantilla podrían no ser suficientes para la complejidad del EA que estamos desarrollando. Pueden ser necesarias funciones adicionales, y tendremos que justificar y explicar su inclusión para cumplir los requisitos específicos de nuestro «Trend Constraint EA».
Funciones adicionales no incluidas en la plantilla de Asesor Experto pero necesarias para nuestro proyecto:- Funciones de indicador (por ejemplo, iRSI): se utilizan para calcular indicadores como RSI que son fundamentales para su estrategia comercial.
- Funciones comerciales (clase CTrade): se utilizan para gestionar órdenes y posiciones, como colocar órdenes de compra/venta, establecer stop loss y modificar posiciones.
//+------------------------------------------------------------------+ //| Trend Constraint Expert Advisor.mq5| //| Copyright 2024, Clemence Benjamin| //| https://www.mql5.com/en/users/billionaire2024/seller| //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { // Initialization code here rsi_handle = iRSI(_Symbol, PERIOD_CURRENT, RSI_Period, PRICE_CLOSE); if (rsi_handle == INVALID_HANDLE) { Print("Failed to create RSI indicator handle"); return(INIT_FAILED); } // Any other initialization tasks return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { // Cleanup code here IndicatorRelease(rsi_handle); // Release RSI indicator handle // Any other deinitialization tasks } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { // Main trading logic goes here // Determine market conditions (e.g., daily trend, RSI levels) // Check for trade conditions and execute orders if necessary // Implement trailing stop logic if necessary } //+------------------------------------------------------------------+ //| Trade event function | //+------------------------------------------------------------------+ void OnTrade() { // Handle trade events (e.g., order placement, modification, closure) } //+------------------------------------------------------------------+ //| Tester function | //+------------------------------------------------------------------+ double OnTester() { double ret = 0.0; // Custom optimization criteria (if any) go here return(ret); } //+------------------------------------------------------------------+ //| TesterInit function | //+------------------------------------------------------------------+ void OnTesterInit() { // Initialization for testing (if needed) } //+------------------------------------------------------------------+ //| TesterPass function | //+------------------------------------------------------------------+ void OnTesterPass() { // Actions after each optimization pass (if needed) } //+------------------------------------------------------------------+ //| TesterDeinit function | //+------------------------------------------------------------------+ void OnTesterDeinit() { // Cleanup after testing (if needed) } //+------------------------------------------------------------------+ //| Chart event function | //+------------------------------------------------------------------+ void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam) { // Handle chart events (e.g., mouse clicks, key presses) here } //+------------------------------------------------------------------+
(3) Escritura de la lógica de restricción de tendencia.
Ahora, podemos pasar a escribir la lógica para cada función que constituye nuestro Asesor Experto. Construyamos nuestro programa paso a paso:
Incluyendo la biblioteca comercial:
Comenzamos por incluir la biblioteca de operaciones, que es necesaria porque la clase CTrade dentro de esta biblioteca proporciona las funciones necesarias para ejecutar operaciones comerciales como abrir, modificar y cerrar posiciones. Al incluir esta biblioteca, permitimos que el EA interactúe con el mercado y gestione las operaciones mediante programación.
#include <Trade\Trade.mqh> // Include the trade libraryDefinición de los parámetros de entrada:
A continuación, definimos los parámetros de entrada, que los usuarios pueden ajustar para que coincidan con sus preferencias comerciales. Estos parámetros incluyen el período RSI, los niveles de sobrecompra y sobreventa, el tamaño del lote, el Stop Loss, el Take Profit y el Trailing Stop. Al escribir estas líneas de entrada, nos aseguramos de que el EA pueda personalizarse para diferentes condiciones del mercado. El programa utilizará estos valores para tomar decisiones sobre cuándo entrar y salir de las operaciones.
// Input parameters input int RSI_Period = 14; // RSI period input double RSI_Overbought = 70.0; // RSI overbought level input double RSI_Oversold = 30.0; // RSI oversold level input double Lots = 0.1; // Lot size input double StopLoss = 100; // Stop Loss in points input double TakeProfit = 200; // Take Profit in points input double TrailingStop = 50; // Trailing Stop in pointsDeclaración de variables globales:
Luego declaramos variables globales como RSI_value y RS1_handle, que almacenarán el valor y el identificador de RSI, respectivamente, así como una instancia de la clase CTrade. Al declarar estas variables, garantizamos que el EA pueda mantener el estado en diferentes funciones, lo que permite que el programa acceda y modifique estos valores según sea necesario durante su operación.
// Global variables double rsi_value; int rsi_handle; CTrade trade; // Declare an instance of the CTrade classInicializando el Asesor Experto:
En la función OnInit, creamos el controlador del indicador RSI utilizando la función iRSI. Este paso es crucial porque el programa necesita este manejador para obtener los valores RSI en cada tick. Si no se puede crear el manejador, hemos escrito el programa para que devuelva INIT_FAILED, impidiendo que el EA se ejecute sin este componente crítico. Esto garantiza que el programa sólo se ejecute cuando esté totalmente equipado para analizar los datos del mercado.
int OnInit() { // Create an RSI indicator handle rsi_handle = iRSI(_Symbol, PERIOD_CURRENT, RSI_Period, PRICE_CLOSE); if (rsi_handle == INVALID_HANDLE) { Print("Failed to create RSI indicator handle"); return(INIT_FAILED); } return(INIT_SUCCEEDED); }Desinicialización del Asesor Experto:
Para gestionar los recursos de forma eficaz, implementamos la función OnDeinit para liberar el manejador del indicador RSI cuando el EA se elimina del gráfico. Al escribir este código de limpieza, evitamos fugas de memoria y nos aseguramos de que los recursos se liberan correctamente. El programa ejecutará esta limpieza automáticamente cuando se desinicialice, manteniendo un rendimiento óptimo.
void OnDeinit(const int reason) { // Release the RSI indicator handle IndicatorRelease(rsi_handle); }Aplicación de la lógica comercial básica:
La lógica comercial central reside en la función OnTick, que diseñamos para que se ejecute en cada tick del mercado. Primero, escribimos código para determinar la tendencia diaria actual comparando los precios de apertura y cierre de la vela diaria. Este análisis permite al programa identificar si el mercado es alcista o bajista, lo que es vital para tomar decisiones comerciales informadas.
void OnTick() { // Determine current daily trend (bullish or bearish) double daily_open = iOpen(_Symbol, PERIOD_D1, 0); double daily_close = iClose(_Symbol, PERIOD_D1, 0); bool is_bullish = daily_close > daily_open; bool is_bearish = daily_close < daily_open;Recuperación de valores RSI:
Luego recuperamos el valor RSI usando CopyBuffer y el controlador RSI que se creó anteriormente. Al escribir esto, nos aseguramos de que el programa pueda evaluar si el mercado está en un estado de sobrecompra o sobreventa. El programa utilizará este valor RSI en su proceso de toma de decisiones, determinando si cumple las condiciones para ingresar a una operación.
// Get the RSI value for the current bar double rsi_values[]; if (CopyBuffer(rsi_handle, 0, 0, 1, rsi_values) <= 0) { Print("Failed to get RSI value"); return; } rsi_value = rsi_values[0];Cierre de posiciones ante cambio de tendencia:
También incluimos lógica para cerrar cualquier posición abierta si la tendencia del mercado cambia. Por ejemplo, si la tendencia cambia de alcista a bajista, el EA cerrará cualquier posición de compra abierta y viceversa. Al redactar esta salvaguarda, garantizamos que el programa mantenga la alineación con el sentimiento predominante del mercado, lo cual es crucial para minimizar el riesgo.
// Close open positions if the trend changes for (int i = PositionsTotal() - 1; i >= 0; i--) { if (PositionSelect(PositionGetSymbol(i))) // Corrected usage { int position_type = PositionGetInteger(POSITION_TYPE); ulong ticket = PositionGetInteger(POSITION_TICKET); // Get the position ticket if ((position_type == POSITION_TYPE_BUY && is_bearish) || (position_type == POSITION_TYPE_SELL && is_bullish)) { trade.PositionClose(ticket); // Use the ulong variable directly } } }Comprobación de condiciones de compra y venta:
Para las condiciones de compra y venta, escribimos lógica para verificar una tendencia alcista combinada con un RSI de sobreventa para órdenes de compra y una tendencia bajista combinada con un RSI de sobrecompra para órdenes cortas. Al programar estas condiciones, garantizamos que el EA solo ingrese a operaciones cuando los indicadores de tendencia y de impulso estén de acuerdo. El programa monitoreará estas condiciones y ejecutará operaciones en consecuencia, asegurando un enfoque disciplinado hacia el trading.
// Check for buy condition (bullish trend + RSI oversold) if (is_bullish && rsi_value < RSI_Oversold) { // No open positions? Place a buy order if (PositionsTotal() == 0) { double price = SymbolInfoDouble(_Symbol, SYMBOL_ASK); double sl = price - StopLoss * _Point; double tp = price + TakeProfit * _Point; // Open a buy order trade.Buy(Lots, _Symbol, price, sl, tp, "TrendConstraintExpert Buy"); } } // Check for sell condition (bearish trend + RSI overbought) if (is_bearish && rsi_value > RSI_Overbought) { // No open positions? Place a sell order if (PositionsTotal() == 0) { double price = SymbolInfoDouble(_Symbol, SYMBOL_BID); double sl = price + StopLoss * _Point; double tp = price - TakeProfit * _Point; // Open a sell order trade.Sell(Lots, _Symbol, price, sl, tp, "TrendConstraintExpert Sell"); } }Implementación de un mecanismo de Trailing Stop:
Por último, implementamos un mecanismo de trailing stop para proteger las ganancias a medida que el mercado se mueve a favor de una posición abierta. Al escribir esta lógica de Stop Loss, nos aseguramos de que el EA ajuste dinámicamente el Stop Loss para fijar las ganancias y al mismo tiempo permitir que la operación continúe mientras el mercado siga siendo favorable. El programa gestionará automáticamente el Trailing Stop, garantizando que responda a los movimientos del mercado para maximizar las ganancias y minimizar las pérdidas.
// Apply trailing stop for (int i = PositionsTotal() - 1; i >= 0; i--) { if (PositionSelect(PositionGetSymbol(i))) // Corrected usage { double price = PositionGetDouble(POSITION_PRICE_OPEN); double stopLoss = PositionGetDouble(POSITION_SL); double current_price; if (PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY) { current_price = SymbolInfoDouble(_Symbol, SYMBOL_BID); if (current_price - price > TrailingStop * _Point) { if (stopLoss < current_price - TrailingStop * _Point) { trade.PositionModify(PositionGetInteger(POSITION_TICKET), current_price - TrailingStop * _Point, PositionGetDouble(POSITION_TP)); } } } else if (PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL) { current_price = SymbolInfoDouble(_Symbol, SYMBOL_ASK); if (price - current_price > TrailingStop * _Point) { if (stopLoss > current_price + TrailingStop * _Point || stopLoss == 0) { trade.PositionModify(PositionGetInteger(POSITION_TICKET), current_price + TrailingStop * _Point, PositionGetDouble(POSITION_TP)); } } } } } }
Nuestro EA final con encabezado y otras propiedades:
//+------------------------------------------------------------------+ //| Trend Constraint Expert.mq5 | //| Copyright 2024, Clemence Benjamin | //| https://www.mql5.com/en/users/billionaire2024/seller | //+------------------------------------------------------------------+ #property copyright "Copyright 2024, Clemence Benjamin" #property link "https://www.mql5.com/en/users/billionaire2024/seller" #property version "1.00" #property description "A System that seeks to Long D1 Bullish sentiment and short D1 Bearish sentiment" #property strict #include <Trade\Trade.mqh> // Include the trade library // Input parameters input int RSI_Period = 14; // RSI period input double RSI_Overbought = 70.0; // RSI overbought level input double RSI_Oversold = 30.0; // RSI oversold level input double Lots = 0.1; // Lot size input double StopLoss = 100; // Stop Loss in points input double TakeProfit = 200; // Take Profit in points input double TrailingStop = 50; // Trailing Stop in points // Global variables double rsi_value; int rsi_handle; CTrade trade; // Declare an instance of the CTrade class //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { // Create an RSI indicator handle rsi_handle = iRSI(_Symbol, PERIOD_CURRENT, RSI_Period, PRICE_CLOSE); if (rsi_handle == INVALID_HANDLE) { Print("Failed to create RSI indicator handle"); return(INIT_FAILED); } return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { // Release the RSI indicator handle IndicatorRelease(rsi_handle); } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { // Determine current daily trend (bullish or bearish) double daily_open = iOpen(_Symbol, PERIOD_D1, 0); double daily_close = iClose(_Symbol, PERIOD_D1, 0); bool is_bullish = daily_close > daily_open; bool is_bearish = daily_close < daily_open; // Get the RSI value for the current bar double rsi_values[]; if (CopyBuffer(rsi_handle, 0, 0, 1, rsi_values) <= 0) { Print("Failed to get RSI value"); return; } rsi_value = rsi_values[0]; // Close open positions if the trend changes for (int i = PositionsTotal() - 1; i >= 0; i--) { if (PositionSelect(PositionGetSymbol(i))) // Corrected usage { int position_type = PositionGetInteger(POSITION_TYPE); ulong ticket = PositionGetInteger(POSITION_TICKET); // Get the position ticket if ((position_type == POSITION_TYPE_BUY && is_bearish) || (position_type == POSITION_TYPE_SELL && is_bullish)) { trade.PositionClose(ticket); // Use the ulong variable directly } } } // Check for buy condition (bullish trend + RSI oversold) if (is_bullish && rsi_value < RSI_Oversold) { // No open positions? Place a buy order if (PositionsTotal() == 0) { double price = SymbolInfoDouble(_Symbol, SYMBOL_ASK); double sl = price - StopLoss * _Point; double tp = price + TakeProfit * _Point; // Open a buy order trade.Buy(Lots, _Symbol, price, sl, tp, "TrendConstraintExpert Buy"); } } // Check for sell condition (bearish trend + RSI overbought) if (is_bearish && rsi_value > RSI_Overbought) { // No open positions? Place a sell order if (PositionsTotal() == 0) { double price = SymbolInfoDouble(_Symbol, SYMBOL_BID); double sl = price + StopLoss * _Point; double tp = price - TakeProfit * _Point; // Open a sell order trade.Sell(Lots, _Symbol, price, sl, tp, "TrendConstraintExpert Sell"); } } // Apply trailing stop for (int i = PositionsTotal() - 1; i >= 0; i--) { if (PositionSelect(PositionGetSymbol(i))) // Corrected usage { double price = PositionGetDouble(POSITION_PRICE_OPEN); double stopLoss = PositionGetDouble(POSITION_SL); double current_price; if (PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY) { current_price = SymbolInfoDouble(_Symbol, SYMBOL_BID); if (current_price - price > TrailingStop * _Point) { if (stopLoss < current_price - TrailingStop * _Point) { trade.PositionModify(PositionGetInteger(POSITION_TICKET), current_price - TrailingStop * _Point, PositionGetDouble(POSITION_TP)); } } } else if (PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL) { current_price = SymbolInfoDouble(_Symbol, SYMBOL_ASK); if (price - current_price > TrailingStop * _Point) { if (stopLoss > current_price + TrailingStop * _Point || stopLoss == 0) { trade.PositionModify(PositionGetInteger(POSITION_TICKET), current_price + TrailingStop * _Point, PositionGetDouble(POSITION_TP)); } } } } } } //+------------------------------------------------------------------+ //HAPPY DEVELOPING!
Llegados a esta etapa, podemos proceder a probar nuestro programa. He incluido mi experiencia de prueba a continuación.
Pruebas
Para probar "Trend Constraint EA" en el Probador de estrategias de MetaTrader 5, comenzaremos configurando una prueba retrospectiva utilizando datos históricos para evaluar el rendimiento del EA. Este proceso nos permitirá simular su estrategia comercial bajo diversas condiciones de mercado, ayudándonos a analizar la rentabilidad, la gestión de riesgos y la eficacia general. Tenemos que seleccionar nuestro marco de tiempo deseado (en este caso, el marco de tiempo M1), los parámetros de entrada y el entorno comercial, y observar qué tan bien se adhiere el EA a la lógica de seguimiento de tendencias y a las condiciones RSI. Esta prueba es crucial para afinar el experto antes de considerar el trading en vivo. Soy fanático de Boom 500 Index y me encantó probar el EA en este hermoso par.
Configuración del Probador de estrategias: Trend Constraint EA.
Rendimiento de Trend Constraint en el probador.
Resultado del probador 01/2023 - 12/2023.
Conclusión
Me alegra que hayamos llegado a la conclusión de esta maravillosa discusión tipo tutorial. Nuestro objetivo era crear un asesor experto (EA) independiente que no requiera la instalación de ningún indicador específico. Espero que esta discusión te haya inspirado a comprender la estructura del desarrollo de EA y te haya proporcionado un punto de partida sólido. Nos centramos en los conceptos más fundamentales para garantizar que la base sea fácil de comprender. La capacidad de personalizar el EA ingresando varios factores permite experimentar con valores para encontrar las configuraciones más rentables.
Hemos desarrollado con éxito un asesor experto basado en nuestra idea inicial, y podemos observar ejecuciones de órdenes en el Probador. Sin embargo, aún queda mucho por mejorar. Trend Constraint EA debe perfeccionarse, sobre todo en sus condiciones de entrada, para mejorar la rentabilidad en función de las tendencias diarias predominantes. Esta vez, no incluimos un número mágico, y al probarlo en una cuenta demo real, me di cuenta de que el EA estaba afectando a otras órdenes que ya estaban colocadas.
Una ventaja de este desarrollo, comparado con el anterior que dependía de un indicador instalado, es que ahora tenemos un único archivo portátil para ejecutar. Esto no significa que nuestros esfuerzos anteriores fueran en vano, sino que aprendimos valiosas lecciones y las herramientas de aquel proyecto siguen siendo útiles para futuros empeños. Nuestro objetivo es seguir perfeccionando el EA para obtener los mejores resultados posibles a medida que avancemos en nuestra serie.
A continuación, codificaremos un número mágico, mejoraremos nuestras técnicas de entrada y aumentaremos aún más nuestra creatividad en este desarrollo. ¡Feliz trading!
Archivo | Descripción |
---|---|
Trend Constraint Expert.mq5 | Código fuente. |
Traducción del inglés realizada por MetaQuotes Ltd.
Artículo original: https://www.mql5.com/en/articles/15322
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.





- 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