Discusión sobre el artículo "Algoritmos avanzados de ejecución de órdenes en MQL5: TWAP, VWAP y órdenes Iceberg"
Buen artículo.
¿Qué pares recomienda para este Algo?
¿Qué plazos? M5, M30 etc.
¿En qué sesión?
Gracias y saludos
Prueba de su algo.
EN el archivo, ExecutionAlgorithm.mqh, añadido este request.type_filling línea = ORDER_FILLING_IOC; en la colocación de la orden para solucionar el problema de colocación de pedidos.
Probado en M5, abrió sólo 1 operación durante 2 meses, no abrió ninguna orden parcial.
Probado en H1, nunca aplicó el SL, o TP y todas las operaciones cerraron con pérdidas.
también durante la compilación genera advertencias
sugiera cómo probar el algo,
Time frame. y cualquier otra recomendación.
también al compilar genera warnings
he cambiado la línea de código
m_volumeProfile[intervalIndex] += rates[i].tick_volu
a
Se fijaron las advertencias
Ahora necesito que guidence con respecto a mis otras preguntas, como
marco de tiempo
y también
por qué todas las operaciones durante backtest resultado en la pérdida
cómo probar este gran trabajo de usted ..
sugiera cómo probar el algo,
Time frame. y cualquier otra recomendación.
Las advertencias no son el problema pero podrían arreglarse rápidamente. Pero sí sería genial si el autor pudiera mostrar paso a paso qué ajustes y entradas utilizó para el backtest.
Estoy de acuerdo con Dominic ya que las advertencias son sólo advertencias. Los resultados de I_Virgo son probablemente porque utilizó el marco de tiempo y el par de divisas equivocado. Desde el informe de Back Test, de casi 2000 barras, debe haber sido M1 o M5 como el marco de tiempo con un par desconocido.
Sería bueno si MQ añadiera el marco de tiempo y el par de divisas o pares y también separara los resultados de los pares en más detalles en el informe de la prueba retrospectiva para que pudiéramos replicar más de cerca los resultados de la prueba retrospectiva del autor, así como determinar su aplicabilidad en los pares de divisas. Además, sería extremadamente útil si el EA pudiera publicar texto en el gráfico mientras se está ejecutando.
Yo también creo que es un gran artículo y el plan para estudiarlo a fondo en previsión de la adaptación de sus técnicas a otras EAs
CapeCoddah
//+------------------------------------------------------------------+ //| Clase base para todos los algoritmos de ejecución| //+------------------------------------------------------------------+ class CExecutionAlgorithm { protected: string m_symbol; // Símbolo comercial double m_totalVolume; // Volumen total a ejecutar double m_executedVolume; // Volumen ya ejecutado double m_remainingVolume; // Volumen restante por ejecutar datetime m_startTime; // Hora de inicio de la ejecución datetime m_endTime; // Hora final de ejecución int m_slippage; // Deslizamiento permitido en puntos bool m_isActive; // ¿Está activo el algoritmo? // Estadísticas double m_avgExecutionPrice; // Precio medio de ejecución int m_totalOrders; // Número total de pedidos realizados int m_filledOrders; // Número de pedidos ejecutados public: // Constructor CExecutionAlgorithm(string symbol, double volume, datetime startTime, datetime endTime, int slippage); // Destructor virtual ~CExecutionAlgorithm(); // Métodos virtuales a implementar por las clases derivadas virtual bool Initialize(); virtual bool Execute() = 0; virtual bool Update() = 0; virtual bool Terminate() = 0; // Métodos comunes bool IsActive() { return m_isActive; } double GetExecutedVolume() { return m_executedVolume; } double GetRemainingVolume() { return m_remainingVolume; } double GetAverageExecutionPrice() { return m_avgExecutionPrice; } // Métodos auxiliares bool PlaceOrder(ENUM_ORDER_TYPE orderType, double volume, double price = 0.0); bool ModifyOrder(ulong ticket, double price, double sl, double tp); bool CancelOrder(ulong ticket); void UpdateAverageExecutionPrice(double price, double volume); // Método auxiliar para obtener el modo de llenado apropiado ENUM_ORDER_TYPE_FILLING GetFillingMode(); }; //+------------------------------------------------------------------+ //| Constructor| //+------------------------------------------------------------------+ CExecutionAlgorithm::CExecutionAlgorithm(string symbol, double volume, datetime startTime, datetime endTime, int slippage) { m_symbol = symbol; m_totalVolume = volume; m_executedVolume = 0.0; m_remainingVolume = volume; m_startTime = startTime; m_endTime = endTime; m_slippage = slippage; m_isActive = false; m_avgExecutionPrice = 0.0; m_totalOrders = 0; m_filledOrders = 0; } //+------------------------------------------------------------------+ //| Destructor| //+------------------------------------------------------------------+ CExecutionAlgorithm::~CExecutionAlgorithm() { // Limpiar los recursos si es necesario } //+------------------------------------------------------------------+ //| Inicializar el algoritmo| //+------------------------------------------------------------------+ bool CExecutionAlgorithm::Initialize() { // Validar entradas if(m_symbol == "" || m_totalVolume <= 0.0) { Print("Invalid inputs for execution algorithm"); return false; } // Comprobar si el símbolo existe if(!SymbolSelect(m_symbol, true)) { Print("Symbol not found: ", m_symbol); return false; } // Restablecer estadísticas m_executedVolume = 0.0; m_remainingVolume = m_totalVolume; m_avgExecutionPrice = 0.0; m_totalOrders = 0; m_filledOrders = 0; return true; } //+------------------------------------------------------------------+ //| Obtener el modo de relleno apropiado para el símbolo | //+------------------------------------------------------------------+ ENUM_ORDER_TYPE_FILLING CExecutionAlgorithm::GetFillingMode() { // Obtener modos de llenado de símbolos int filling_modes = (int)SymbolInfoInteger(m_symbol, SYMBOL_FILLING_MODE); // Compruebe los modos de llenado disponibles por orden de preferencia if((filling_modes & SYMBOL_FILLING_FOK) == SYMBOL_FILLING_FOK) return ORDER_FILLING_FOK; else if((filling_modes & SYMBOL_FILLING_IOC) == SYMBOL_FILLING_IOC) return ORDER_FILLING_IOC; else return ORDER_FILLING_RETURN; } //+------------------------------------------------------------------+ //| Hacer un pedido| //+------------------------------------------------------------------+ bool CExecutionAlgorithm::PlaceOrder(ENUM_ORDER_TYPE orderType, double volume, double price = 0.0) { // Validar entradas if(volume <= 0.0) { Print("Invalid order volume"); return false; } // Preparar la solicitud MqlTradeRequest request; MqlTradeResult result; ZeroMemory(request); request.symbol = m_symbol; request.volume = volume; request.type = orderType; request.deviation = m_slippage; request.magic = 123456; // Número mágico de identificación // Establecer la acción y el precio adecuados en función del tipo de orden if(orderType == ORDER_TYPE_BUY || orderType == ORDER_TYPE_SELL) { // Orden de mercado request.action = TRADE_ACTION_DEAL; request.type_filling = GetFillingMode(); if(orderType == ORDER_TYPE_BUY) request.price = SymbolInfoDouble(m_symbol, SYMBOL_ASK); else request.price = SymbolInfoDouble(m_symbol, SYMBOL_BID); } else { // Orden pendiente request.action = TRADE_ACTION_PENDING; if(price <= 0.0) { Print("Price must be specified for pending orders"); return false; } request.price = price; } // Enviar el pedido if(!OrderSend(request, result)) { Print("OrderSend error: ", GetLastError()); return false; } // Comprobar el resultado if(result.retcode != TRADE_RETCODE_DONE) { Print("OrderSend failed with code: ", result.retcode, " - ", result.comment); return false; } // Actualizar estadísticas m_totalOrders++; // Para las órdenes de mercado, actualizar inmediatamente las estadísticas de ejecución if(orderType == ORDER_TYPE_BUY || orderType == ORDER_TYPE_SELL) { m_filledOrders++; UpdateAverageExecutionPrice(request.price, volume); m_executedVolume += volume; m_remainingVolume -= volume; } Print("Order placed successfully. Ticket: ", result.order, " Volume: ", volume, " Price: ", request.price); return true; } //+------------------------------------------------------------------+ //| Modificar un pedido existente| //+------------------------------------------------------------------+ bool CExecutionAlgorithm::ModifyOrder(ulong ticket, double price, double sl, double tp) { // Preparar la solicitud MqlTradeRequest request; MqlTradeResult result; ZeroMemory(request); request.action = TRADE_ACTION_MODIFY; request.order = ticket; request.price = price; request.sl = sl; request.tp = tp; // Enviar la solicitud de modificación if(!OrderSend(request, result)) { Print("OrderModify error: ", GetLastError()); return false; } // Comprobar el resultado if(result.retcode != TRADE_RETCODE_DONE) { Print("OrderModify failed with code: ", result.retcode, " - ", result.comment); return false; } Print("Order modified successfully. Ticket: ", ticket); return true; } //+------------------------------------------------------------------+ //| Cancelar un pedido existente| //+------------------------------------------------------------------+ bool CExecutionAlgorithm::CancelOrder(ulong ticket) { // Preparar la solicitud MqlTradeRequest request; MqlTradeResult result; ZeroMemory(request); request.action = TRADE_ACTION_REMOVE; request.order = ticket; // Enviar la solicitud de anulación if(!OrderSend(request, result)) { Print("OrderCancel error: ", GetLastError()); return false; } // Comprobar el resultado if(result.retcode != TRADE_RETCODE_DONE) { Print("OrderCancel failed with code: ", result.retcode, " - ", result.comment); return false; } Print("Order cancelled successfully. Ticket: ", ticket); return true; } //+------------------------------------------------------------------+ //| Actualizar el precio medio de ejecución| //+------------------------------------------------------------------+ void CExecutionAlgorithm::UpdateAverageExecutionPrice(double price, double volume) { // Calcular el nuevo precio medio de ejecución if(m_executedVolume > 0.0) { // Media ponderada de los precios antiguos y nuevos m_avgExecutionPrice = (m_avgExecutionPrice * m_executedVolume + price * volume) / (m_executedVolume + volume); } else { // Primera ejecución m_avgExecutionPrice = price; } } //+------------------------------------------------------------------+
- 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
Artículo publicado Algoritmos avanzados de ejecución de órdenes en MQL5: TWAP, VWAP y órdenes Iceberg:
«Claro», dirás encogiéndote de hombros, «pero yo no muevo sumas institucionales». Aquí está la clave: no tienes por qué hacerlo. Tanto si está desplegando medio lote como un puñado de minilotes, la volatilidad puede seguir afectando a su ejecución. Estas herramientas te ayudan a:
Pasa desapercibido: Las órdenes Iceberg, en particular, ocultan el tamaño real de tu orden, lo que mantiene a los algoritmos entrometidos en la incertidumbre.
El panorama democratizado actual significa que la misma tecnología de ejecución que antes requería presupuestos multimillonarios ahora puede funcionar en su estación de operaciones personal. Al incorporar el código MQL5 optimizado para las estrategias TWAP, VWAP e Iceberg en su plataforma, se dotará de la potencia institucional sin abandonar el ámbito minorista.
Autor: N Soumik