
Ejemplo de toma de beneficios optimizada automáticamente y parámetros de indicadores con SMA y EMA
Introducción
En el mundo en constante evolución del trading algorítmico, la innovación es clave para mantenerse a la vanguardia. Hoy, nos complace presentar un sofisticado Asesor Experto (EA) que combina el aprendizaje automático con el análisis técnico tradicional para navegar en los mercados de divisas. Este EA aprovecha un modelo ONNX junto con indicadores técnicos cuidadosamente optimizados para tomar decisiones comerciales en los mercados de divisas.
El enfoque del EA es multifacético y utiliza la predicción de precios de un modelo de aprendizaje automático, técnicas de seguimiento de tendencias y optimización de parámetros adaptativos. Está diseñado para operar principalmente en acciones #AAPL, aunque tiene la flexibilidad de adaptarse a otros instrumentos. Con características como tamaño de lote dinámico, trailing stops y ajuste automático a las condiciones del mercado, este EA representa una combinación de tecnología de vanguardia y principios comerciales probados por el tiempo.
Explicación de los indicadores utilizados:
- Media móvil simple (Simple Moving Average, SMA): el EA utiliza un promedio móvil simple con un período optimizado de forma adaptativa. La SMA ayuda a identificar la dirección general de la tendencia y se utiliza junto con el precio y otros indicadores para generar señales comerciales.
- Media móvil exponencial (Exponential Moving Average, EMA): también se emplea una media móvil exponencial, con su período optimizado dinámicamente. La EMA responde más rápidamente a los cambios de precios recientes que la SMA, lo que proporciona una perspectiva diferente sobre la dirección de la tendencia.
- Rango verdadero promedio (Average True Range, ATR): si bien no se calcula explícitamente en el código, el EA utiliza cálculos basados en ATR para establecer los niveles de stop loss y take profit. Esto permite ajustar el tamaño de las posiciones a la volatilidad y gestionar el riesgo.
- Modelo de aprendizaje automático: el EA incorpora un modelo ONNX (Open Neural Network Exchange) para la predicción de precios. Este modelo toma una serie de datos de precios recientes e intenta predecir el próximo movimiento de precios, añadiendo un elemento predictivo a la estrategia de negociación.
Estos indicadores se combinan de forma sofisticada y sus parámetros se optimizan dinámicamente en función de las condiciones recientes del mercado. El EA también incluye funciones como trailing stops y cálculos de expectativas morales para gestionar eficazmente las posiciones abiertas.
La combinación de estos indicadores, junto con el componente de aprendizaje automático, permite al EA adaptarse a las condiciones cambiantes del mercado e identificar potencialmente oportunidades de negociación en diversos estados del mercado.
Desglose del código
1. Configuración inicial e inclusiones
El código comienza con la información sobre los derechos de autor e incluye las bibliotecas necesarias, como Trade.mqh.
#include <Trade\Trade.mqh>
2. Variables y parámetros globales:
- Se definen los parámetros del modelo ONNX, incluido el tamaño de la muestra y los controladores.
- Se declaran los parámetros de entrada para los indicadores (SMA, EMA, ATR) y las operaciones comerciales.
- Se definen enumeraciones y constantes para el movimiento de precios y números mágicos.
#resource "/Files/model.EURUSD.D1.1_1_2024.onnx" as uchar ExtModel[];
input group "----- Indicators Parameters -----" int SMA_Period = 20; int EMA_Period = 50; input double StopLossATR = 1.5; input double TakeProfitATR = 3.0; input int OptimizationDays = 1; // Hours between optimizations input int LookbackPeriod = 7; // Hours loockback periods input int MinSMAPeriod = 5; // Period min para SMA input int MaxSMAPeriod = 50; // Periodo max para SMA input int MinEMAPeriod = 5; // Periodo min para EMA input int MaxEMAPeriod = 50; // Periodo max para EMA
#define MAGIC_SE 12321
datetime lastOptimizationTime = 0; double optimizedTakeProfit = 0.0;//InpTakeProfit; double optimizedStopLoss = 0.0;//InpStopLoss;
double InpTakeProfit1 ; double InpStopLoss1;
3. Función de inicialización (OnInit):
- Configura el modelo ONNX desde un búfer.
- Inicializa indicadores técnicos (SMA, EMA).
- Llama funciones para optimizar indicadores y parámetros comerciales.
int OnInit() { //--- create a model from static buffer ExtHandle = OnnxCreateFromBuffer(ExtModel, ONNX_DEFAULT); if(ExtHandle == INVALID_HANDLE) { Print("OnnxCreateFromBuffer error ", GetLastError()); return(INIT_FAILED); } //--- set input and output shapes const long input_shape[] = {1, SAMPLE_SIZE, 1}; if(!OnnxSetInputShape(ExtHandle, ONNX_DEFAULT, input_shape)) { Print("OnnxSetInputShape error ", GetLastError()); return(INIT_FAILED); } const long output_shape[] = {1, 1}; if(!OnnxSetOutputShape(ExtHandle, 0, output_shape)) { Print("OnnxSetOutputShape error ", GetLastError()); return(INIT_FAILED); } SMAHandle = iMA(_Symbol, _Period, SMA_Period, 0, MODE_SMA, PRICE_CLOSE); // Ensure correct period if(SMAHandle == INVALID_HANDLE) { Print("Error initializing SMA indicator: ", GetLastError()); return INIT_FAILED; } EMAHandle = iMA(_Symbol, _Period, EMA_Period, 0, MODE_EMA, PRICE_CLOSE); // Ensure correct index if(EMAHandle == INVALID_HANDLE) { Print("Error initializing EMA indicator: ", GetLastError()); return INIT_FAILED; }
trade.SetDeviationInPoints(Slippage); trade.SetExpertMagicNumber(MAGIC_SE);
OptimizeIndicators(); OptimizeParameters(); return(INIT_SUCCEEDED); }
4. Función de desinicialización (OnDeinit):
Libera controladores para el modelo ONNX y los indicadores.
//+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { if(ExtHandle != INVALID_HANDLE) { OnnxRelease(ExtHandle); ExtHandle = INVALID_HANDLE; } IndicatorRelease(SMAHandle); IndicatorRelease(EMAHandle); }
5. Lógica comercial principal (OnTick):
- Comprueba si el mercado está cerrado.
- Optimiza periódicamente los indicadores y parámetros comerciales.
- Actualiza la lógica del trailing stop.
- Predice el movimiento de precios utilizando el modelo ONNX.
- Comprueba las condiciones de posiciones abiertas/cerradas según predicciones e indicadores.
//+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { if(IsMarketClosed()) // Verificar si el mercado está cerrado { return; // Si el mercado está cerrado, no hacer nada } static datetime lastOptimizationTime2 = 0; if(TimeCurrent() - lastOptimizationTime2 >= OptimizationDays * PeriodSeconds(PERIOD_H1)) { OptimizeIndicators(); lastOptimizationTime2 = TimeCurrent(); // Actualizar los indicadores con los nuevos períodos IndicatorRelease(SMAHandle); IndicatorRelease(EMAHandle); SMAHandle = iMA(_Symbol, _Period, SMA_Period, 0, MODE_SMA, PRICE_CLOSE); EMAHandle = iMA(_Symbol, _Period, EMA_Period, 0, MODE_EMA, PRICE_CLOSE); } //--- Optimización cada 2 días if(TimeCurrent() - lastOptimizationTime >= PeriodSeconds(PERIOD_H1) * HoursAnalyze) { OptimizeParameters(); lastOptimizationTime = TimeCurrent(); } //--- if(NewBarTS()==true)//gather statistics and launch trailing stop { double open=iOpen(_Symbol,TFTS,1); CalcLvl(up,(int)MathRound((iHigh(_Symbol,TFTS,1)-open)/_Point)); CalcLvl(dn,(int)MathRound((open-iLow(_Symbol,TFTS,1))/_Point)); buy_sl=CalcSL(dn); buy_tp=CalcTP(up); sell_sl=CalcSL(up); sell_tp=CalcTP(dn); if(TypeTS==Simple)//simple trailing stop SimpleTS(); if(TypeTS==MoralExp)//Moral expectation METS(); if(TypeTS==None)//None TS return; } double bid=SymbolInfoDouble(_Symbol,SYMBOL_BID); if(bid==SLNeutral || bid<=SLBuy || (SLSell>0 && bid>=SLSell)) { for(int i=PositionsTotal()-1; i>=0; i--) { ulong ticket=PositionGetTicket(i); if(PositionSelectByTicket(ticket)==true) trade.PositionClose(ticket); } } //--- //--- check new day if(TimeCurrent() >= ExtNextDay) { GetMinMax(); ExtNextDay = TimeCurrent(); ExtNextDay -= ExtNextDay % PeriodSeconds(PERIOD_D1); ExtNextDay += PeriodSeconds(PERIOD_D1); } //--- check new bar if(TimeCurrent() < ExtNextBar) return; ExtNextBar = TimeCurrent(); ExtNextBar -= ExtNextBar % PeriodSeconds(); ExtNextBar += PeriodSeconds(); //--- check min and max float close = (float)iClose(_Symbol, _Period, 0); if(ExtMin > close) ExtMin = close; if(ExtMax < close) ExtMax = close; double sma[], ema[];//, willr[]; CopyBuffer(SMAHandle, 0, 0, 1, sma); CopyBuffer(EMAHandle, 0, 0, 1, ema); //CopyBuffer(WillRHandle, 0, 0, 1, willr); //--- predict next price PredictPrice(); //--- check trading according to prediction and indicators if(ExtPredictedClass >= 0) { if(PositionSelect(_Symbol)) CheckForClose(sma[0], ema[0]);//, willr[0]); else CheckForOpen(sma[0], ema[0]);//, willr[0]); } }
6. Funciones comerciales:
- CheckForOpen: determina si se debe abrir una posición de compra o venta según predicciones y señales de indicadores.
- CheckForClose: comprueba si las posiciones actuales deben cerrarse según las predicciones.
//+------------------------------------------------------------------+ //| Check for open position conditions | //+------------------------------------------------------------------+ void CheckForOpen(double sma, double ema)//, double willr) { MqlRates rates[]; ArraySetAsSeries(rates,true); int copied = CopyRates(_Symbol,0,0,1,rates); if(copied <= 0) { Print("Error copying rates: ", GetLastError()); return; } double Close[1]; Close[0]=rates[0].close; double close = Close[0]; ENUM_ORDER_TYPE signal = WRONG_VALUE; Print("ExtPredictedClass ",ExtPredictedClass); //--- check signals if(ExtPredictedClass == 2)//PRICE_DOWN) { Print("ExtPredictedClass Sell ",ExtPredictedClass); Print("close ",close, " sma ",sma, " ema ", ema);//, " willr ", willr); // Venta if((close < sma && close < ema))// || willr > -20) { signal = ORDER_TYPE_SELL; Print("Order Sell detected"); } } else if(ExtPredictedClass == 0)//PRICE_UP) { Print("ExtPredictedClass Buy ",ExtPredictedClass); Print("close ",close, " sma ",sma, " ema ", ema);//, " willr ", willr); // Compra if((close > sma && close > ema))// || willr < -80) { signal = ORDER_TYPE_BUY; Print("Order Buy detected"); } } //--- open position if possible according to signal if(signal != WRONG_VALUE && TerminalInfoInteger(TERMINAL_TRADE_ALLOWED)) { Print("Proceding open order"); double price, sl=0, tp=0; double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID); double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK); MqlTradeRequest request = {}; MqlTradeResult result = {}; request.action = TRADE_ACTION_DEAL; request.symbol = _Symbol; request.deviation = Slippage; request.magic = MAGIC_SE; request.type_filling = ORDER_FILLING_FOK; //request.comment = "AKWr"; double lotaje; if(signal == ORDER_TYPE_SELL) { price = bid; Print("Price: ",price); if(inp_lot_type == LOT_TYPE_FIX) lotaje=inp_lot_fix ; else lotaje=get_lot(price); if(!CheckVolumeValue(lotaje)) return; if(!InpUseStops && ATR) { sl = NormalizeDouble(bid + StopLossATR * ATRValue, _Digits); tp = NormalizeDouble(ask - TakeProfitATR * ATRValue, _Digits); if(!CheckMoneyForTrade(_Symbol, lotaje,ORDER_TYPE_SELL)) { Print("No hay suficiente margen para abrir la posición"); return; } request.type = ORDER_TYPE_SELL; request.price = SymbolInfoDouble(_Symbol, SYMBOL_BID); request.volume = lotaje; request.sl = sl; request.tp = tp; request.comment = "SEW Opened sell order"; } if(!InpUseStops && ATR) { sl = 0; tp = 0; } else { InpTakeProfit1 =optimizedTakeProfit; InpStopLoss1= optimizedStopLoss; sl = NormalizeDouble(bid + InpStopLoss1*_Point, _Digits); tp = NormalizeDouble(ask - InpTakeProfit1*_Point, _Digits); } } else { price = ask; Print("Price: ",price); if(inp_lot_type == LOT_TYPE_FIX) lotaje=inp_lot_fix ; else lotaje=get_lot(price); if(!CheckVolumeValue(lotaje)) return; if(!InpUseStops) { sl = NormalizeDouble(ask - StopLossATR * ATRValue, _Digits); tp = NormalizeDouble(bid + TakeProfitATR * ATRValue, _Digits); if(!CheckMoneyForTrade(_Symbol, lotaje,ORDER_TYPE_BUY)) { Print("No hay suficiente margen para abrir la posición"); return; } request.type = ORDER_TYPE_BUY; request.price = SymbolInfoDouble(_Symbol, SYMBOL_ASK); request.volume = lotaje; request.sl = sl; request.tp = tp; request.comment = "SEW Opened buy order"; } if(!InpUseStops && ATR) { sl = 0; tp = 0; } else { InpTakeProfit1 =optimizedTakeProfit; InpStopLoss1= optimizedStopLoss; sl = NormalizeDouble(ask - InpStopLoss1*_Point, _Digits); tp = NormalizeDouble(bid + InpTakeProfit1*_Point, _Digits); } } Print("No InpUseStops used"); //ExtTrade.PositionOpen(_Symbol, signal, lotaje, price, sl, tp); if(!CheckMoneyForTrade(_Symbol, lotaje, (ENUM_ORDER_TYPE)signal)) { Print("No hay suficiente margen para abrir la posición"); return; } Print("Volume ", lotaje); request.type = signal; request.price = price;//SymbolInfoDouble(_Symbol, SYMBOL_ASK); request.volume = lotaje; request.sl = sl; request.tp = tp; request.comment = "SEW"; if(!OrderSend(request, result)) { Print("Error opening the order: ", GetLastError()); return; } } } //+------------------------------------------------------------------+ //| Check for close position conditions | //+------------------------------------------------------------------+ void CheckForClose(double sma, double ema)//, double willr) { if(InpUseStops) return; bool bsignal = false; //--- position already selected before long type = PositionGetInteger(POSITION_TYPE); //--- check signals if(type == POSITION_TYPE_BUY && ExtPredictedClass == 2)//PRICE_DOWN) bsignal = true; if(type == POSITION_TYPE_SELL && ExtPredictedClass == 0)//PRICE_UP) bsignal = true; //--- close position if possible if(bsignal && TerminalInfoInteger(TERMINAL_TRADE_ALLOWED)) { ExtTrade.PositionClose(_Symbol); CheckForOpen(sma, ema);//, willr); } }
7. Predicción de precios (PredictPrice):
Utiliza el modelo ONNX para predecir el movimiento futuro de precios.
//+------------------------------------------------------------------+ //| Predict next price | //+------------------------------------------------------------------+ void PredictPrice(void) { static vectorf output_data(1); static vectorf x_norm(SAMPLE_SIZE); if(ExtMin >= ExtMax) { Print("ExtMin >= ExtMax"); ExtPredictedClass = -1; return; } if(!x_norm.CopyRates(_Symbol, _Period, COPY_RATES_CLOSE, 1, SAMPLE_SIZE)) { Print("CopyRates ", x_norm.Size()); ExtPredictedClass = -1; return; } float last_close = x_norm[SAMPLE_SIZE - 1]; x_norm -= ExtMin; x_norm /= (ExtMax - ExtMin); if(!OnnxRun(ExtHandle, ONNX_NO_CONVERSION, x_norm, output_data)) { Print("OnnxRun"); ExtPredictedClass = -1; return; } float predicted = output_data[0] * (ExtMax - ExtMin) + ExtMin; float delta = last_close - predicted; if(fabs(delta) <= 0.00001) ExtPredictedClass = PRICE_SAME; else if(delta < 0) ExtPredictedClass = PRICE_UP; else ExtPredictedClass = PRICE_DOWN; // Debugging output Print("Predicted price: ", predicted, " Delta: ", delta, " Predicted Class: ", ExtPredictedClass); }
8. Funciones del Trailing Stop:
Varias funciones (AllTS, METS, SimpleTS) implementan diferentes estrategias de trailing stop.
Todo explicado en este artículo: El stop dinámico en el trading - Artículos MQL5
9. Funciones de optimización:
- OptimizeParameters: prueba diferentes valores de take profit y stop loss para encontrar configuraciones óptimas.
- OptimizeIndicators: encuentra los mejores períodos para los indicadores SMA y EMA.
void OptimizeParameters() { double bestTakeProfit = InpTakeProfit1; double bestStopLoss = InpStopLoss1; double bestPerformance = -DBL_MAX; for(int tp = 65; tp <= 500; tp += 5) // rango de TakeProfit { for(int sl = 65; sl <= 500; sl += 5) // rango de StopLoss { double performance = TestStrategy(tp, sl); if(performance > bestPerformance) { bestPerformance = performance; bestTakeProfit = tp; bestStopLoss = sl; //Print("Best Take Profit",bestTakeProfit); //Print("Best Stop Loss",bestStopLoss); } } } optimizedTakeProfit = bestTakeProfit; optimizedStopLoss = bestStopLoss; Print("Optimized TakeProfit: ", optimizedTakeProfit); Print("Optimized StopLoss: ", optimizedStopLoss); }
void OptimizeIndicators() { datetime startTime = TimeCurrent() - LookbackPeriod * PeriodSeconds(PERIOD_H1); datetime endTime = TimeCurrent(); int bestSMAPeriod = SMA_Period; int bestEMAPeriod = EMA_Period; double bestPerformance = -DBL_MAX; for(int smaPeriod = MinSMAPeriod; smaPeriod <= MaxSMAPeriod; smaPeriod++) { for(int emaPeriod = MinEMAPeriod; emaPeriod <= MaxEMAPeriod; emaPeriod++) { double performance = TestIndicatorPerformance(smaPeriod, emaPeriod, startTime, endTime); if(performance > bestPerformance) { bestPerformance = performance; bestSMAPeriod = smaPeriod; bestEMAPeriod = emaPeriod; } } } SMA_Period = bestSMAPeriod; EMA_Period = bestEMAPeriod; Print("Optimized SMA Period: ", SMA_Period); Print("Optimized EMA Period: ", EMA_Period); }
10. Funciones de utilidad y administración del dinero:
Funciones para el cálculo del tamaño del lote, verificación de volumen, verificación de cierre del mercado, incluye funciones para verificar si hay suficiente dinero para las operaciones y para normalizar los tamaños de los lotes, etc.
bool IsMarketClosed() { datetime currentTime = TimeCurrent(); MqlDateTime tm; TimeToStruct(currentTime, tm); int dayOfWeek = tm.day_of_week; int hour = tm.hour; // Verifica si es fin de semana if(dayOfWeek <= Sunday || dayOfWeek >= Saturday) { return true; } // Verifica si está fuera del horario habitual de mercado (ejemplo: 21:00 a 21:59 UTC) if(hour >= after || hour < before) // Ajusta estos valores según el horario del mercado { return true; } return false; } //+------------------------------------------------------------------+ //| Check the correctness of the order volume | //+------------------------------------------------------------------+ bool CheckVolumeValue(double volume)//,string &description) { //--- minimal allowed volume for trade operations double min_volume=SymbolInfoDouble(Symbol(),SYMBOL_VOLUME_MIN); if(volume<min_volume) { //description=StringFormat("Volume is less than the minimal allowed SYMBOL_VOLUME_MIN=%.2f",min_volume); return(false); } //--- maximal allowed volume of trade operations double max_volume=SymbolInfoDouble(Symbol(),SYMBOL_VOLUME_MAX); if(volume>max_volume) { //description=StringFormat("Volume is greater than the maximal allowed SYMBOL_VOLUME_MAX=%.2f",max_volume); return(false); } //--- get minimal step of volume changing double volume_step=SymbolInfoDouble(Symbol(),SYMBOL_VOLUME_STEP); int ratio=(int)MathRound(volume/volume_step); if(MathAbs(ratio*volume_step-volume)>0.0000001) { //description=StringFormat("Volume is not a multiple of the minimal step SYMBOL_VOLUME_STEP=%.2f, the closest correct volume is %.2f", //volume_step,ratio*volume_step); return(false); } //description="Correct volume value"; return(true); } //+------------------------------------------------------------------+ bool CheckMoneyForTrade(string symb,double lots,ENUM_ORDER_TYPE type) { //--- Getting the opening price MqlTick mqltick; SymbolInfoTick(symb,mqltick); double price=mqltick.ask; if(type==ORDER_TYPE_SELL) price=mqltick.bid; //--- values of the required and free margin double margin,free_margin=AccountInfoDouble(ACCOUNT_MARGIN_FREE); //--- call of the checking function if(!OrderCalcMargin(type,symb,lots,price,margin)) { //--- something went wrong, report and return false Print("Error in ",__FUNCTION__," code=",GetLastError()); return(false); } //--- if there are insufficient funds to perform the operation if(margin>free_margin) { //--- report the error and return false Print("Not enough money for ",EnumToString(type)," ",lots," ",symb," Error code=",GetLastError()); return(false); } //--- checking successful return(true); }
double get_lot(double price) { if(inp_lot_type==LOT_TYPE_FIX) return(normalize_lot(inp_lot_fix)); double one_lot_margin; if(!OrderCalcMargin(ORDER_TYPE_BUY,_Symbol,1.0,price,one_lot_margin)) return(inp_lot_fix); return(normalize_lot((AccountInfoDouble(ACCOUNT_BALANCE)*(inp_lot_risk/100))/ one_lot_margin)); } //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< double normalize_lot(double lt) { double lot_step = SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_STEP); lt = MathFloor(lt / lot_step) * lot_step; double lot_minimum = SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_MIN); lt = MathMax(lt, lot_minimum); return(lt); }
Características principales:
- Utiliza aprendizaje automático (modelo ONNX) para la predicción de precios.
- Combina indicadores técnicos (SMA, EMA) con predicciones ML (Machine Learning) para decisiones comerciales.
- Implementa múltiples estrategias de trailing stop.
- Incluye optimización periódica de los parámetros del indicador y configuraciones comerciales.
- Tiene gestión de riesgos incorporada (dimensionamiento de lotes, verificación de dinero).
- Considera el horario del mercado para realizar operaciones.
Este asesor experto (EA) es bastante sofisticado y combina el análisis técnico tradicional con el aprendizaje automático para el trading de divisas. También incluye varias funciones de gestión y optimización de riesgos para adaptarse a las condiciones cambiantes del mercado.
Este análisis indica que la estrategia de trading automatizado demostró rentabilidad con un sólido índice Sharpe de 6,21. Sin embargo, tiene una alta caída que sugiere la necesidad de una gestión cuidadosa del riesgo. La capacidad de la estrategia para lograr ganancias consistentes, como lo muestra la curva de capital, refleja su potencial para aplicaciones comerciales en el mundo real. Las optimizaciones futuras podrían centrarse en reducir las caídas y mejorar el factor de recuperación para mejorar el rendimiento general.
Resumen
Este artículo presenta un innovador Asesor Experto (EA) para trading algorítmico en el mercado Forex, diseñado específicamente para operar con Apple Inc. Acciones de Apple (#AAPL). El EA representa una combinación sofisticada de aprendizaje automático y análisis técnico tradicional, con el objetivo de navegar por las complejidades de los mercados de divisas con precisión y adaptabilidad.
En el núcleo de este EA se encuentra un modelo ONNX (Open Neural Network Exchange), que actúa como componente de aprendizaje automático. Este modelo tiene la tarea de predecir los movimientos de precios basándose en datos recientes del mercado, añadiendo un elemento prospectivo a la estrategia comercial. El EA combina estas predicciones con indicadores técnicos establecidos, a saber, la media móvil simple (SMA) y la media móvil exponencial (EMA), para generar señales comerciales.
El enfoque del EA es multifacético e incorpora varias características clave:
- Optimización dinámica: tanto los indicadores técnicos como los parámetros comerciales están sujetos a una optimización periódica. Esto permite que el EA se adapte a las condiciones cambiantes del mercado, mejorando potencialmente su rendimiento a lo largo del tiempo.
- Gestión de riesgos adaptativa: el EA emplea un tamaño de lote dinámico y utiliza cálculos de rango verdadero promedio (ATR) para establecer niveles de stop loss y take profit. Este enfoque tiene como objetivo ajustar el tamaño de las posiciones y la exposición al riesgo en función de la volatilidad actual del mercado.
- Múltiples estrategias de trailing stop: el EA implementa varios métodos de trailing stop, lo que permite una gestión flexible de las posiciones abiertas y potencialmente maximizar las ganancias mientras se minimizan las pérdidas.
- Conocimiento de las condiciones del mercado: el sistema está diseñado para tener en cuenta los horarios y las condiciones del mercado, garantizando que las operaciones solo se ejecuten cuando sea apropiado.
El artículo proporciona un desglose detallado de la estructura del código de EA y explica sus componentes clave:
- Inicialización: Esta fase configura el modelo ONNX y los indicadores técnicos, preparando el EA para su funcionamiento.
- Lógica comercial principal: la funcionalidad principal que decide cuándo abrir o cerrar posiciones en función de las señales combinadas del modelo de aprendizaje automático y los indicadores técnicos.
- Predicción de precios: utiliza el modelo ONNX para pronosticar movimientos de precios futuros.
- Funciones de optimización: ajusta periódicamente los parámetros del indicador y las configuraciones comerciales para mantener la efectividad en condiciones variables del mercado.
- Gestión de riesgos: incluye funciones para el cálculo del tamaño del lote, la gestión del dinero y la verificación de las condiciones del mercado.
El rendimiento del EA se evaluó mediante pruebas retrospectivas sobre datos de acciones de AAPL. Los resultados mostraron una rentabilidad prometedora con un índice de Sharpe de 6,21, lo que indica fuertes retornos ajustados al riesgo. Sin embargo, el análisis también reveló cifras de reducción relativamente altas, lo que sugiere áreas para posibles mejoras en la gestión de riesgos.
Conclusión
Bueno, el Asesor Experto (Expert Advisor, EA) que tenemos hoy es un gran salto. Utiliza una combinación de tecnología inteligente (aprendizaje automático) y métodos probados (análisis técnico) para brindar a los operadores decisiones invaluables exclusivas para miembros sobre cómo invertir en acciones de AAPL y otros símbolos.
El EA combinó un modelo ONNX para predecir precios con indicadores técnicos optimizados. Esta combinación implica que puede responder tanto a cambios de precios instantáneos como a movimientos más lentos hacia desarrollos a más largo plazo.
Uno de los aspectos atractivos de este EA es que tiene un sistema de gestión de riesgos cohesivo. Por ejemplo, utiliza tamaños de lote dinámicos (cambia el tamaño de tus operaciones según las condiciones del mercado), niveles de stop loss y take profit basados en ATR (impone límites a lo que puedes perder si las cosas salen mal o a tus ganancias cuando están a tu favor), así como múltiples estrategias de trailing stop con respecto al cambio de precio. Estas herramientas están diseñadas para proteger tu dinero sin que te lo quiten de manera oculta o injusta.
Otra gran cosa acerca de este EA es que actualiza sus indicadores y parámetros comerciales con bastante regularidad. Esto le permitirá seguir el ritmo del mercado cambiante, un componente muy importante para seguir siendo eficaz a lo largo del tiempo.
Sin embargo, los resultados siguen siendo algo decepcionantes a partir del análisis retrospectivo que muestra cómo habría funcionado el EA en el pasado. Aunque los resultados parecen buenos en términos de ganancias y gestión de riesgos, también mostraron algunas caídas importantes (una gran caída en el valor), lo que indica que la gestión de riesgos podría reforzarse. Las futuras versiones del EA pueden incluir mejores protecciones o transacciones más cautelosas durante épocas muy volátiles.
Aunque fue creado para negociar acciones de AAPL, los principios que lo rigen pueden aplicarse fácilmente a otros mercados financieros. Tal flexibilidad hace que valga la pena utilizar este instrumento tanto en el trading actual como modelo para futuros sistemas algorítmicos.
Se trata de un EA de trading automatizado complejo y muy prometedor: una combinación de tecnología de vanguardia y métodos tradicionales, fuerte en gestión de riesgos y adaptable a las condiciones cambiantes del mercado. Sin embargo, al igual que cualquier otra herramienta comercial, requiere monitoreo regular, actualización y pruebas en escenarios del mundo real para garantizar su correcto funcionamiento a lo largo del tiempo.
Por último, si bien este EA parece tener mucho potencial pero se necesita más trabajo en él y mucha optimización, es importante recordar que el trading siempre implica riesgo y el rendimiento pasado no garantiza el éxito futuro. Si está considerando utilizar este o cualquier sistema automatizado, asegúrese de comprender los riesgos, haga su tarea e idealmente pruébelo en un entorno simulado antes de usar dinero real.
Espero que disfrutes leyendo este artículo tanto como yo disfruto escribiéndolo, espero que puedas hacer que este EA sea mucho mejor y obtengas buenos resultados. Este es un buen ejemplo de cómo implementar la optimización automática con stops y con indicadores. Una vez más, espero que les haya gustado esto. ¡Salud!
Traducción del inglés realizada por MetaQuotes Ltd.
Artículo original: https://www.mql5.com/en/articles/15476





- 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