
Creación de un modelo de restricción de tendencia de velas (Parte 9): Asesor Experto de múltiples estrategias (I)
Contenido principal:
- Introducción
- Discusión sobre las 7 estrategias famosas seleccionadas
- Incorporación de un número mágico
- Implementación de la estrategia de seguimiento de tendencias
- Resultados de las pruebas
- Conclusión
Introducción
Desde el principio de esta serie de artículos, hemos hecho hincapié en alinear a nuestros expertos con el sentimiento predominante de las velas diarias (D1). La forma de la vela diaria ha servido como principal característica orientativa. Sin embargo, necesitábamos reducir la escala a plazos inferiores para identificar los niveles de entrada en el mercado D1. Por ejemplo, en el marco temporal M1, queríamos que el mercado alcanzara niveles extremos en el Índice de Fuerza Relativa (RSI) para señalar posibles operaciones para el Asesor Experto. En esta etapa inicial, no introdujimos demasiadas estrategias para mantener el contenido fácil de entender para los principiantes.
Sin embargo, existe una amplia colección de estrategias para estudiar e integrar en el algoritmo de nuestro Asesor Experto Trend Constraint. Hoy analizaremos en detalle algunas estrategias conocidas desarrolladas por figuras influyentes del trading, a quienes llamo los "Padres del Mercado". Esta fase de nuestra discusión ampliará nuestra comprensión, manteniendo el tema original del título. También abordaremos las limitaciones de las estrategias discutidas en nuestro desarrollo anterior, que se centraron principalmente en RSI y la lógica de restricción. Además, exploraremos cómo incorporar nuevas estrategias al Asesor Experto.
Antes de profundizar en las siete estrategias principales, retrocedamos y recapitulemos la lógica restrictiva en nuestro código:
Una condición de vela alcista en MQL5:
void OnTick() { // Determine current daily trend (bullish ) double daily_open = iOpen(_Symbol, PERIOD_D1, 0); double daily_close = iClose(_Symbol, PERIOD_D1, 0); bool is_bullish = daily_close > daily_open; }
Una condición de vela bajista en MQL5:
void OnTick() { // Determine current daily trend (bearish) double daily_open = iOpen(_Symbol, PERIOD_D1, 0); double daily_close = iClose(_Symbol, PERIOD_D1, 0); bool is_bearish = daily_close < daily_open; }
En el código anterior, el sentimiento del período de tiempo superior sirve como nuestro factor limitante. En este caso optamos por el marco temporal D1.
Implementación de la condición de restricción:
Ahora que hemos establecido el sentimiento bajista y alcista de nuestra vela diaria, podemos utilizar ''if()'' junto con nuestra lógica de condición de entrada.
Para un día alcista:
if (is_bullish) { // Logic for bullish trend Print("The daily trend is bullish."); // You can add your trading logic here, for example: // if (OrderSelect(...)) { /* Place buy order */ } }
Para un día bajista:
if (is_bearish) { // Logic for bearish trend Print("The daily trend is bearish."); // You can add your trading logic here, for example: // if (OrderSelect(...)) { /* Place sell order */ } }
Al final de este tema usted podrá apreciar:
1. Otras estrategias y el hombre detrás de ellas.
2. Incorporación de nueva estrategia en los módulos del Asesor Experto existente.
3. Implementación de un número mágico.
En resumen, los tres puntos clave descritos anteriormente proporcionarán a los operadores una mejor comprensión de las diversas estrategias y las motivaciones detrás de ellas, así como conocimientos sobre la implementación de MQL5 para integrar nuevas estrategias en el código existente.
Antes de comenzar a desarrollar el código principal, centrémonos en discutir estas estrategias basadas en mi investigación en el próximo segmento. Verá la necesidad de ampliar nuestras estrategias de Asesores Expertos, especialmente porque el mercado está en constante evolución. Estas estrategias compuestas son esenciales para adaptarse a cualquier escenario de mercado. Cuando una estrategia falla, siempre hay otra que se puede emplear. He hecho todo lo posible para descubrir los aspectos matemáticos que sustentan cada estrategia, ya que estas funciones matemáticas sirven como elemento fundamental para el desarrollo eficiente de algoritmos.
Luego de revisar el Asesor Experto reciente, encontré algunos errores de advertencia que posiblemente haya notado si siguió leyendo. Vea la imagen a continuación:
Una advertencia de compilación.
Ese error estaba en la línea 78 y la columna 28. Lo veo resaltado a continuación:
Advertencia en la línea 78, columna 28.
Esta advertencia es una de las más sencillas de solucionar, ya que se explica por sí sola. Aquí hay un fragmento de código con la solución:
long position_type = PositionGetInteger(POSITION_TYPE);
La solución anterior consistía en sustituir int por long.
Nuestro último código fuente de Trend Constraint se proporciona aquí, pero también puede volver a visitar el artículo anterior para obtener el archivo fuente. Asegúrese de practicar la depuración del código como lo hicimos anteriormente antes de implementar las nuevas funciones.
//+------------------------------------------------------------------+ //| 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 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 { long 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)); } } } } } } //+------------------------------------------------------------------+
La discusión sobre las 7 estrategias famosas seleccionadas
Operar en el mercado Forex requiere una combinación de habilidad y estrategia. A lo largo de los años, han surgido diversos enfoques que pueden ayudar a los traders a maximizar sus posibilidades de éxito. Aquí, profundizaré brevemente en siete estrategias efectivas de trading de Forex, cada una basada en principios matemáticos esenciales y teorías desarrolladas por economistas y traders influyentes. Una vez que la estrategia se absorbe en la mente, resulta más fácil implementar la habilidad de codificación y crear un algoritmo para la estrategia.(I) Estrategia de seguimiento de tendencias
La estrategia de seguimiento de tendencias se basa en los principios de Charles Henry Dow, quien formuló la Teoría de Dow a finales del siglo XIX (1896). Dow creía que los mercados se mueven según tendencias y que identificar estas tendencias puede brindar importantes oportunidades comerciales. Las matemáticas en las que se basa el seguimiento de tendencias suelen emplear medias móviles, en las que los operadores utilizan la media móvil simple (SMA) para suavizar las fluctuaciones de los precios.
La fórmula real de la Media Móvil Simple (Simple Moving Average, SMA) es:
Donde:
- N es el número de periodos (o puntos de datos).
- (P_i) es el precio (o valor) en el periodo (i-ésimo).
Esta fórmula calcula el precio medio a lo largo de N periodos. Investigaciones de apoyo, como los trabajos de Richard Dennis y su experimento de las «Tortugas» en la década de 1980, demuestran que el seguimiento de tendencias puede reportar importantes beneficios, sobre todo en mercados con fuertes tendencias.
(II) Negociación por rangos
La negociación por rangos se basa en los conceptos de niveles de soporte y resistencia, cruciales para el análisis técnico. Estos conceptos fueron bien documentados por J. Welles Wilder en su libro «New Concepts in Technical Trading Systems» (1978). Los operadores identifican el soporte como un nivel de precios en el que el interés comprador impide los descensos, mientras que la resistencia dificulta las subidas de precios. La base matemática para calcular los puntos pivote, un método habitual para identificar estos niveles, viene dada por:
La fórmula real para el Punto Pivote (Pivot Point , PP) es:
Donde:
- High es el precio más alto del período de negociación anterior.
- Low es el precio más bajo del período de negociación anterior.
- Close es el precio de cierre del período de negociación anterior.
Esta fórmula calcula el punto central de pivote utilizado en el análisis técnico para determinar los posibles niveles de soporte y resistencia para el próximo período de negociación. Estudios como el de John Murphy en «Technical Analysis of the Financial Markets» (1986) destacan que los niveles de soporte y resistencia sirven a menudo como indicadores psicológicos que pueden ayudar a los operadores a tomar decisiones con conocimiento de causa.
(III) Operaciones de ruptura
Las operaciones de ruptura aprovechan la creencia de que se producen movimientos de precios sustanciales cuando los precios rompen los niveles de soporte o resistencia establecidos. Richard Donchian introdujo esta estrategia en la década de 1950, y su trabajo con los Canales de Donchian hace hincapié en el uso de la volatilidad para identificar los puntos de ruptura. Los operadores calculan los canales de Donchian utilizando el máximo más alto (Highest High, HH) y el mínimo más bajo (Lowest Low, LL) durante un período determinado:
(Banda superior = HH)(Banda inferior = LL)
Canal Donchian.
Las investigaciones en finanzas conductuales respaldan la idea de que los traders a menudo siguen las rupturas debido al comportamiento de manada, lo que refuerza el impulso en la dirección de la ruptura. El trabajo publicado por investigadores como Daniel Kahneman y Amos Tversky en su artículo de 1979, «Prospect Theory: An Analysis of Decision under Risk», de 1979, pone de relieve cómo los factores psicológicos influyen en el comportamiento bursátil durante las rupturas.(IV) Operaciones de carry trade
El carry trade aprovecha los diferenciales de tasas de interés entre dos monedas, basándose en teorías de paridad de tasas de interés (Interest Rate Parity, IRP). Este principio hunde sus raíces en las teorías económicas formuladas a principios del siglo XX, en particular por economistas como Paul Samuelson en obras como «Fundamentos del análisis económico» (1947).
La fórmula básica para calcular la rentabilidad esperada de una operación de carry trade viene dada por:
Donde:
- (i_high) e (i_low) son los tipos de interés de las divisas de alto y bajo rendimiento, respectivamente.
- (Delta S) representa la variación esperada del tipo de cambio.
(V) Scalping
El scalping es una estrategia de trading de alta frecuencia que explota pequeños movimientos de precios, respaldada por la teoría de microestructura del mercado (Market Microstructure Theory, MMT). Esta teoría ha evolucionado gracias al trabajo de varios investigadores, entre ellos Lawrence Harris en «Market Making and the Financial Performance of Nasdaq Firms» (1998). Los scalpers ejecutan múltiples operaciones en períodos de tiempo cortos, buscando sacar provecho de cambios mínimos de precios.
Las métricas importantes para los scalpers incluyen los diferenciales entre oferta y demanda y el análisis del flujo de órdenes, a menudo calculados a través de varias métricas como:
Donde:
- (Selling Price) es el precio al que se vende el activo.
- (Buying Price) es el precio al que se compró originalmente el activo.
- (Transaction Costs) son todas las tarifas o costos asociados con el proceso de compra y venta (por ejemplo, tarifas de corredores, impuestos).
La gestión del riesgo es fundamental, ya que unas pocas operaciones desfavorables pueden provocar pérdidas importantes.
(VI) Análisis fundamental
El análisis fundamental consiste en examinar los indicadores económicos y los factores geopolíticos que influyen en la valoración de las divisas. Iniciado por Benjamin Graham y David Dodd en «Security Analysis» (1934), este enfoque hace hincapié en la importancia de evaluar el valor intrínseco de las divisas. Los operadores utilizan diversos indicadores, como el crecimiento del Producto Interior Bruto (Gross Domestic Product, GDP) y las tasas de desempleo, para tomar decisiones con conocimiento de causa. También pueden adaptarse técnicas matemáticas, como la relación precio/beneficios de las acciones;
Donde:
- (Market Price per share) es el precio actual de una acción de la empresa.
- Earnings per Share (EPS) es el beneficio de la empresa asignado a cada acción ordinaria en circulación.
Numerosos estudios avalan la eficacia del análisis fundamental, especialmente durante la publicación de importantes informes económicos o anuncios de los bancos centrales, que a menudo provocan importantes movimientos del mercado.
(VII) Utilización de indicadores técnicos
El análisis técnico, basado en las ideas de Charles Dow y otros, parte de la base de que los movimientos pasados de los precios pueden proporcionar información sobre el comportamiento futuro. Para medir el impulso del mercado se emplean diversos indicadores técnicos, como el Índice de Fuerza Relativa (Relative Strength Index, RSI). El RSI se calcula mediante la fórmula:
Donde:
- (RS) representa las ganancias y pérdidas medias durante un periodo determinado.
Investigaciones de apoyo, como la de Thomas Bulkowski en «Encyclopedia of Candlestick Charts» (2008), muestran que ciertos patrones e indicadores pueden mejorar la precisión de las operaciones, permitiendo a los operadores anticiparse a los movimientos del mercado basándose en la acción histórica de los precios. Cada una de estas estrategias se basa en teorías fundamentales, principios matemáticos e investigaciones exhaustivas que fundamentan las decisiones de los operadores en el mercado Forex. Comprender los entresijos de estas estrategias puede mejorar significativamente la capacidad de un operador para navegar por las complejidades del mercado de divisas y, en última instancia, conducir a resultados más informados y rentables. Empleando estas estrategias cuidadosamente, los operadores pueden desarrollar un enfoque de negociación sólido y adaptado a sus preferencias individuales y a su tolerancia al riesgo.
Incorporación de un número mágico
Los números mágicos en MQL5 sirven como una herramienta de organización fundamental, similar a una firma única que un Asesor Experto (EA) utiliza para marcar sus operaciones. Piense que cada EA tiene su propio identificador personal que estampa en cada operación que abre. Esto es particularmente útil en cuentas que ejecutan numerosas estrategias simultáneamente, ya que ayuda al EA a mantener sus operaciones limpiamente segregadas de las demás.
Al definir el número mágico como un parámetro de entrada, se consigue flexibilidad, lo que permite realizar ajustes en la configuración de EA sin tener que volver a profundizar en el código fuente. Cuando el EA explora las posiciones abiertas, utiliza este número para encontrar rápidamente las operaciones que le corresponden.
La función PositionGetInteger(POSITION_MAGIC) recupera el número mágico asociado a cada operación, lo que permite al EA decidir su siguiente paso: si modificar, supervisar o cerrar una posición. Para un operador o desarrollador, esto significa menos preocupaciones por interferencias accidentales entre diferentes estrategias y una depuración más sencilla, ya que cada operación puede rastrearse hasta su estrategia de origen. Así, la incorporación y gestión eficaz de los números mágicos garantiza que sus estrategias de negociación sigan siendo precisas y estén bien organizadas en los mercados financieros.
He aquí un fragmento de código que muestra la incorporación:
input int MagicNumber = 12345678; // Define a unique magic number for the EA // Within the OnTick() or relevant function for (int i = 0; i < PositionsTotal(); i++) { if (PositionGetSymbol(i) == _Symbol && PositionSelect(PositionGetSymbol(i))) { long currentMagicNumber = PositionGetInteger(POSITION_MAGIC); if (currentMagicNumber == MagicNumber) { // Check if the position belongs to this EA // Perform actions on this position, like closing or modifying } } } // When opening a new trade double price = SymbolInfoDouble(_Symbol, SYMBOL_ASK); double sl = price - StopLoss * _Point; double tp = price + TakeProfit * _Point; if (trade.Buy(Lots, _Symbol, price, sl, tp, "TrendFollowing Buy")) { Print("Buy order placed with Magic Number: ", MagicNumber); } else { Print("Error placing buy order: ", GetLastError());
Aplicación de la estrategia de seguimiento de tendencias
De las estrategias seleccionadas anteriormente, la mayoría de ellas no pueden ser implementadas en nuestro programa ya que carecen de algunos datos necesarios para utilizarlas en el momento actual, por ejemplo, Carry Trade, no es factible sólo con este código, ya que implica diferenciales de tipos de interés, y el análisis fundamental requiere datos económicos externos detallando PIB, tasas de empleo, etc. Para ahorrar para una mayor exploración en el futuro, nos centraremos en la estrategia más factible.
El seguimiento de tendencias es un enfoque que identifica y opera en la dirección de una tendencia sostenida del mercado, utilizando técnicas como promedios móviles para confirmar la dirección de la tendencia. Nuestro código experto ya utiliza RSI para medir condiciones de sobrecompra o sobreventa, pero la integración de promedios móviles puede refinar aún más el proceso de toma de decisiones. En este caso, utilizamos una media móvil a corto plazo (50 periodos) y una media móvil a largo plazo (200 periodos) para determinar la dirección de la tendencia. Si la media a corto plazo cruza por encima de la media a largo plazo, es señal de una tendencia alcista; por el contrario, si cruza por debajo, indica una tendencia bajista. La integración de este método ayuda a confirmar tendencias alcistas o bajistas, mejorando la precisión de las entradas de operaciones junto con las condiciones del RSI.
Este es nuestro fragmento de código para calcular medias móviles antes de integrarlo en el programa principal.
//Calculate moving averages double ma_short = iMA(_Symbol, PERIOD_CURRENT, 50, 0, MODE_EMA, PRICE_CLOSE, 0); double ma_long = iMA(_Symbol, PERIOD_CURRENT, 200, 0, MODE_EMA, PRICE_CLOSE, 0); //Determine the trend direction bool is_uptrend = ma_short > ma_long; bool is_downtrend = ma_short < ma_long; if (is_bullish && is_uptrend && rsi_value < RSI_Oversold) { // Implement buy order logic here } if (is_bearish && is_downtrend && rsi_value > RSI_Overbought) { // Implement sell order logic here }
Para incorporar eficazmente una estrategia de seguimiento de tendencias en un Asesor Experto existente, comenzamos por mejorar la lógica de inicialización y procesamiento dentro de sus módulos. A partir de la función OnInit(), introducimos el cálculo de dos medias móviles exponenciales (Exponential Moving Averages, EMA) críticas, normalmente una de 50 periodos para tendencias a corto plazo y otra de 200 periodos para tendencias a largo plazo, utilizando la función iMA.
A medida que avanzamos con el método OnTick(), estas EMA se recalculan con cada nuevo tick del mercado, lo que permite al EA determinar la dirección actual de la tendencia del mercado; un cruce en el que la EMA a corto plazo se eleva por encima de la de largo plazo señala una tendencia alcista, mientras que un cruce en el que cae por debajo indica una tendencia bajista.
Integrando estas señales de tendencia con el análisis RSI existente, creamos condiciones en las que el algoritmo abre órdenes de compra durante la tendencia alcista confirmada cuando el RSI está sobrevendido, y órdenes de venta durante la tendencia bajista cuando el RSI está sobrecomprado.
Utilizando la clase CTrade para la ejecución, establecemos meticulosamente los parámetros de stop loss, take profit y trailing stop, garantizando una sólida gestión del riesgo. Además, dentro del mismo bucle OnTick(), se incorpora un sistema para cerrar con elegancia cualquier posición existente en caso de que la tendencia identificada se invierta, alineando así cada operación con la dirección verificada del mercado. A través de estas actualizaciones estratégicas, el EA se adapta hábilmente para emplear una estrategia de seguimiento de tendencias, integrándola a la perfección con sus funcionalidades actuales y mejorando la eficacia general de las operaciones.
He aquí un programa totalmente integrado:
//+------------------------------------------------------------------+ //| 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 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 input int MagicNumber = 12345678; // Magic number for this EA // Global variables double rsi_value; int rsi_handle; CTrade trade; // Declare an instance of the CTrade class // Variables for moving averages double ma_short; double ma_long; //+------------------------------------------------------------------+ //| 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() { // Calculate moving averages ma_short = iMA(_Symbol, PERIOD_CURRENT, 50, 0, MODE_EMA, PRICE_CLOSE); ma_long = iMA(_Symbol, PERIOD_CURRENT, 200, 0, MODE_EMA, PRICE_CLOSE); // Determine trend direction bool is_uptrend = ma_short > ma_long; bool is_downtrend = ma_short < ma_long; // 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 = 0; i < PositionsTotal(); i++) // Correct loop initialization { if (PositionGetSymbol(i) == _Symbol && PositionSelect(PositionGetSymbol(i))) // Select position by symbol { long position_type = PositionGetInteger(POSITION_TYPE); long currentMagicNumber = PositionGetInteger(POSITION_MAGIC); ulong ticket = PositionGetInteger(POSITION_TICKET); if (currentMagicNumber == MagicNumber) // Ensure only this EA's orders are checked { if ((position_type == POSITION_TYPE_BUY && is_downtrend) || (position_type == POSITION_TYPE_SELL && is_uptrend)) { trade.PositionClose(ticket); } } } } // Check for buy condition (uptrend + RSI oversold) if (is_uptrend && rsi_value < RSI_Oversold) { // No open positions? Place a buy order bool open_position = false; for (int i = 0; i < PositionsTotal(); i++) // Correct loop initialization { if (PositionGetSymbol(i) == _Symbol && PositionSelect(PositionGetSymbol(i))) { long currentMagicNumber = PositionGetInteger(POSITION_MAGIC); if (currentMagicNumber == MagicNumber) { open_position = true; break; } } } if (!open_position) { double price = SymbolInfoDouble(_Symbol, SYMBOL_ASK); double sl = price - StopLoss * _Point; double tp = price + TakeProfit * _Point; // Open a buy order if (trade.Buy(Lots, _Symbol, price, sl, tp, "TrendFollowing Buy")) Print("Buy order placed with Magic Number: ", MagicNumber); else Print("Error placing buy order: ", GetLastError()); } } // Check for sell condition (downtrend + RSI overbought) if (is_downtrend && rsi_value > RSI_Overbought) { // No open positions? Place a sell order bool open_position = false; for (int i = 0; i < PositionsTotal(); i++) // Correct loop initialization { if (PositionGetSymbol(i) == _Symbol && PositionSelect(PositionGetSymbol(i))) { long currentMagicNumber = PositionGetInteger(POSITION_MAGIC); if (currentMagicNumber == MagicNumber) { open_position = true; break; } } } if (!open_position) { double price = SymbolInfoDouble(_Symbol, SYMBOL_BID); double sl = price + StopLoss * _Point; double tp = price - TakeProfit * _Point; // Open a sell order if (trade.Sell(Lots, _Symbol, price, sl, tp, "TrendFollowing Sell")) Print("Sell order placed with Magic Number: ", MagicNumber); else Print("Error placing sell order: ", GetLastError()); } } // Apply trailing stop for (int i = 0; i < PositionsTotal(); i++) // Correct loop initialization { if (PositionGetSymbol(i) == _Symbol && PositionSelect(PositionGetSymbol(i))) // Select position by symbol { long currentMagicNumber = PositionGetInteger(POSITION_MAGIC); if (currentMagicNumber == MagicNumber) // Apply trailing stop only to this EA's positions { 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)); } } } } } } } //+------------------------------------------------------------------+
Resultados de las pruebas
Probé el Asesor Experto en el índice B00M 500 y observé las órdenes. Sin embargo, aún queda mucho por hacer para evitar que se hagan varios pedidos simultáneamente. El rendimiento en una cuenta demo de 10.000 dólares muestra resultados positivos, pero los resultados pueden no ser los mismos con cuentas reales y de menor capitalización. Es importante tener en cuenta que este sistema no garantiza beneficios; está pensado para fines educativos, experimentos e investigación.
Lanzamiento del Asesor Experto sobre el índice Boom 500.
Resulta de la prueba en el índice Boom 500 en 2019.
Conclusión
En conclusión, nuestra discusión sobre la construcción de un Asesor Experto de estrategias múltiples utilizando MQL5 se centró en la comprensión de los orígenes de las principales estrategias existentes y la integración de una estrategia de seguimiento de tendencia junto con elementos clave como el Índice de Fuerza Relativa (Relative Strength Index, RSI). El componente de seguimiento de tendencias utiliza medias móviles para determinar la dirección de la tendencia del mercado, lo que permite a los operadores alinear sus posiciones con movimientos a más largo plazo que suelen ser más estables y potencialmente más rentables. Al emplear estas medias móviles, nuestro sistema puede identificar tendencias alcistas y bajistas, lo que facilita la toma de decisiones de negociación informadas basadas en direcciones de mercado bien definidas.
La incorporación estratégica de una metodología de seguimiento de tendencias complementa el uso del RSI, que es esencial para identificar las condiciones de sobrecompra y sobreventa del mercado. Juntos, estos componentes crean un enfoque completo que capta tanto el impulso de la tendencia como se alinea con el concepto fundamental de la serie, Trend Constraint. Otra mejora fundamental realizada durante nuestro desarrollo fue la integración de los números mágicos, una función inicialmente ausente que resulta crucial para una gestión precisa de las operaciones en entornos con múltiples estrategias. Los números mágicos sirven como identificadores únicos, ayudan a mantener separadas las estrategias y permiten a los operadores seguir y gestionar cada una de ellas de forma independiente.
De las siete estrategias que hemos considerado, hasta ahora sólo hemos aplicado una, lo que deja muchas posibilidades para explorar en el futuro. Compile y pruebe el archivo fuente adjunto para evaluar su rendimiento y recoger ideas para implementarlo en sus propios proyectos. ¡Feliz trading!
Traducción del inglés realizada por MetaQuotes Ltd.
Artículo original: https://www.mql5.com/en/articles/15509





- 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