Discussão do artigo "Algoritmos avançados de execução de ordens em MQL5: TWAP, VWAP e ordens Iceberg"
Ótimo artigo!
Quais pares você recomenda para esse Algo?
Quais os períodos de tempo? M5, M30 etc.
Em qual sessão?
Obrigado e cordiais saudações
Testando seu algoritmo.
No arquivo ExecutionAlgorithm.mqh, adicionei esta linha request.type_filling = ORDER_FILLING_IOC; ao colocar a ordem para corrigir o problema de colocação da ordem.
Testado novamente no M5, ele abriu apenas uma negociação por um período de 2 meses, nenhuma ordem parcial foi aberta.
Testado no H1, ele nunca aplicou o SL ou TP e todas as negociações foram fechadas com prejuízo.
Também durante a compilação, ele gera avisos
Sugira como testar o algoritmo,
período de tempo e quaisquer outras recomendações.
também durante a compilação, ele gera avisos
Alterei a linha de código
m_volumeProfile[intervalIndex] += rates[i].tick_volu
para
Isso corrigiu os avisos
Agora preciso de sua orientação em relação às minhas outras dúvidas, como
Time frame
E também
por que todas as negociações durante o backtest resultam em perda
como testar esse excelente trabalho de vocês...
Sugira como testar o algoritmo,
período de tempo e quaisquer outras recomendações.
Os avisos não são o problema, mas podem ser corrigidos rapidamente. Mas, sim, seria ótimo se o autor pudesse mostrar passo a passo quais configurações e entradas ele usou para o backtest.
Concordo com Dominic, pois os avisos são apenas avisos. Os resultados de I_Virgo provavelmente se devem ao fato de ele ter usado o período de tempo e o par de moedas errados. Pelo relatório do Back Test, de quase 2.000 barras, deve ter sido M1 ou M5 como o período de tempo com um par desconhecido.
Seria bom se a MQ adicionasse o período de tempo e o par ou pares de moedas e também separasse os resultados dos pares em mais detalhes no relatório de back-test para que pudéssemos replicar mais de perto os resultados do back-test do autor, bem como determinar sua aplicabilidade nos pares de moedas estrangeiras.
Também acho que é um ótimo artigo e planejo estudá-lo minuciosamente na expectativa de adaptar suas técnicas a outros EAs
CapeCoddah
//+------------------------------------------------------------------+ //| Classe base para todos os algoritmos de execução| //+------------------------------------------------------------------+ class CExecutionAlgorithm { protected: string m_symbol; // Símbolo de negociação double m_totalVolume; // Volume total a ser executado double m_executedVolume; // Volume já executado double m_remainingVolume; // Volume restante para execução datetime m_startTime; // Hora de início da execução datetime m_endTime; // Hora de término da execução int m_slippage; // Deslizamento permitido em pontos bool m_isActive; // O algoritmo está ativo no momento // Estatísticas double m_avgExecutionPrice; // Preço médio de execução int m_totalOrders; // Número total de pedidos feitos int m_filledOrders; // Número de pedidos atendidos public: // Construtor CExecutionAlgorithm(string symbol, double volume, datetime startTime, datetime endTime, int slippage); // Destruidor virtual ~CExecutionAlgorithm(); // Métodos virtuais a serem implementados por classes derivadas virtual bool Initialize(); virtual bool Execute() = 0; virtual bool Update() = 0; virtual bool Terminate() = 0; // Métodos comuns 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 obter o modo de preenchimento apropriado ENUM_ORDER_TYPE_FILLING GetFillingMode(); }; //+------------------------------------------------------------------+ //| Construtor| //+------------------------------------------------------------------+ 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; } //+------------------------------------------------------------------+ //| Destruidor| //+------------------------------------------------------------------+ CExecutionAlgorithm::~CExecutionAlgorithm() { // Limpar os recursos, se necessário } //+------------------------------------------------------------------+ //| Inicializar o algoritmo| //+------------------------------------------------------------------+ bool CExecutionAlgorithm::Initialize() { // Validar entradas if(m_symbol == "" || m_totalVolume <= 0.0) { Print("Invalid inputs for execution algorithm"); return false; } // Verificar se o símbolo existe if(!SymbolSelect(m_symbol, true)) { Print("Symbol not found: ", m_symbol); return false; } // Redefinir estatísticas m_executedVolume = 0.0; m_remainingVolume = m_totalVolume; m_avgExecutionPrice = 0.0; m_totalOrders = 0; m_filledOrders = 0; return true; } //+------------------------------------------------------------------+ //| Obter o modo de preenchimento apropriado para o símbolo //+------------------------------------------------------------------+ ENUM_ORDER_TYPE_FILLING CExecutionAlgorithm::GetFillingMode() { // Obter modos de preenchimento de símbolos int filling_modes = (int)SymbolInfoInteger(m_symbol, SYMBOL_FILLING_MODE); // Verifique os modos de preenchimento disponíveis em ordem de preferência 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; } //+------------------------------------------------------------------+ //| Fazer um 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 a solicitação 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 para identificação // Definir ação e preço apropriados com base no tipo de ordem if(orderType == ORDER_TYPE_BUY || orderType == ORDER_TYPE_SELL) { // Ordem 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 { // Ordem pendente request.action = TRADE_ACTION_PENDING; if(price <= 0.0) { Print("Price must be specified for pending orders"); return false; } request.price = price; } // Enviar o pedido if(!OrderSend(request, result)) { Print("OrderSend error: ", GetLastError()); return false; } // Verificar o resultado if(result.retcode != TRADE_RETCODE_DONE) { Print("OrderSend failed with code: ", result.retcode, " - ", result.comment); return false; } // Atualizar estatísticas m_totalOrders++; // Para ordens a mercado, atualizar as estatísticas de execução imediatamente 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 um pedido existente| //+------------------------------------------------------------------+ bool CExecutionAlgorithm::ModifyOrder(ulong ticket, double price, double sl, double tp) { // Preparar a solicitação MqlTradeRequest request; MqlTradeResult result; ZeroMemory(request); request.action = TRADE_ACTION_MODIFY; request.order = ticket; request.price = price; request.sl = sl; request.tp = tp; // Enviar a solicitação de modificação if(!OrderSend(request, result)) { Print("OrderModify error: ", GetLastError()); return false; } // Verificar o 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 um pedido existente| //+------------------------------------------------------------------+ bool CExecutionAlgorithm::CancelOrder(ulong ticket) { // Preparar a solicitação MqlTradeRequest request; MqlTradeResult result; ZeroMemory(request); request.action = TRADE_ACTION_REMOVE; request.order = ticket; // Enviar a solicitação de cancelamento if(!OrderSend(request, result)) { Print("OrderCancel error: ", GetLastError()); return false; } // Verificar o 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; } //+------------------------------------------------------------------+ //| Atualizar o preço médio de execução| //+------------------------------------------------------------------+ void CExecutionAlgorithm::UpdateAverageExecutionPrice(double price, double volume) { // Calcular o novo preço médio de execução if(m_executedVolume > 0.0) { // Média ponderada dos preços antigos e novos m_avgExecutionPrice = (m_avgExecutionPrice * m_executedVolume + price * volume) / (m_executedVolume + volume); } else { // Primeira execução m_avgExecutionPrice = price; } } //+------------------------------------------------------------------+
- Aplicativos de negociação gratuitos
- 8 000+ sinais para cópia
- Notícias econômicas para análise dos mercados financeiros
Você concorda com a política do site e com os termos de uso
Novo artigo Algoritmos avançados de execução de ordens em MQL5: TWAP, VWAP e ordens Iceberg foi publicado:
"Claro", você talvez diga, dando de ombros, "mas eu não movimento volumes institucionais". A questão é justamente esta: você não precisa. Quer você opere meio lote ou alguns minilotes, a volatilidade ainda pode distorcer sua execução. Essas ferramentas ajudam você a:
Permanecer discreto: Em especial, as ordens Iceberg ocultam o tamanho real da sua ordem, deixando algoritmos curiosos apenas tentando adivinhar.
No ambiente democratizado atual, as mesmas tecnologias de execução que antes exigiam orçamentos milionários agora podem rodar no seu terminal pessoal de trading. Ao adicionar à sua plataforma um código MQL5 refinado para estratégias TWAP, VWAP e Iceberg, você passa a contar com poder de fogo institucional sem sair do segmento de varejo.
Autor: N Soumik