OnTradeTransaction

 

Olá pessoal. Gostaria de saber do pessoal que programa aqui do fórum se vcs utilizam a função OnTradeTransaction e caso utilizem, qual a vossa opinião sobre ela. 

Pra quem não conhece ou gostaria de mais informações, o OnTradeTrasaction é uma função que lida com eventos assim como o OnTick, dentre outros, porem o evento que provoca o OnTick é um novo preço e no caso do OnTradeTransaction o que provoca um novo evento é modificar/abrir/fechar uma posição ou ordem, basicamente. 

 
achaa:

Olá pessoal. Gostaria de saber do pessoal que programa aqui do fórum se vcs utilizam a função OnTradeTransaction e caso utilizem, qual a vossa opinião sobre ela. 

Pra quem não conhece ou gostaria de mais informações, o OnTradeTrasaction é uma função que lida com eventos assim como o OnTick, dentre outros, porem o evento que provoca o OnTick é um novo preço e no caso do OnTradeTransaction o que provoca um novo evento é modificar/abrir/fechar uma posição ou ordem, basicamente. 

Olá Vitor, parabéns pelo tópico. Essa é uma daquelas funções que normalmente trazem mais confusão do que conclusões definitivas. Entretanto, você poderia ser um pouco mais específico na sua pergunta? Achei ela um pouco vaga, pois a palavra "opinião" deixa margem para muitas interpretações... Existe algum aspecto em particular que te interessa?

Para aqueles que não conhecem as funções de manipulação de eventos, seria interessante ler atentamente a documentação, uma vez que ela é bem detalhada na descrição de cada função.

Com relação à função OnTradeTransaction, ela engloba todas as funcionalidades de OnTrade e ainda inclui várias outras adicionais, sem nenhuma perda de funcionalidade. Com relação à minha "opinião", eu particularmente prefiro usar a função OnTrade quando é necessário tomar alguma decisão por conta da execução de uma operação, justamente pelo fato dessa última função ser mais específica que a primeira.

 
Bom, considerando que ha varias maneiras de codificar uma mesma estrategia, há algumas pessoas que preferem utilizar um tipo de handler por achar mais conveniente. Eu particularmente coloco o OnTradeTransaction em praticamente todos os EA's que faço. Meu objetivo com esse tópico é conhecer um pouco da metodologia que cada um usa pra programar. Como aprendi usar a linguagem sozinho, tenho interesse em conhecer novas visões da linguagem. Agradeço pela sua opinião.
 

Bom, eu utilizo o OnTradeTransaction. Até porque, eu não me acostumei a programar em MQL, e daí eu queria era "extrair" os dados do ambiente do MT para um plataforma que eu tivesse menos atritos.

Então precisava saber tudo o que acontecia no terminal, o mais rápido possível, sem ficar bloqueando. OnTrade não diz nada, mas OnTradeTransaction diz absolutamente tudo. Portanto foi o ponto de extração de dados (assim como OnTick e OnTimer).

Duas questões, no entanto. OnTradeTransaction é verborrágico. Tanto a função como as suas estruturas. Só depois de encarar as 4.000 páginas do manual que deu para sair do outro lado, de como extrair significado dos campos todos.

Mas a questão principal é que não há garantias de ordenação dos eventos. Isso está bem claro na documentação. Suspeito também que não há garantias de sequer receber os eventos.

 

Numa execução total de uma ordem você pode receber TRADE_TRANSACTION_ORDER_UPDATE, TRADE_TRANSACTION_ORDER_DELETE, TRADE_TRANSACTION_HISTORY_ADD, TRADE_TRANSACTION_DEAL_ADD nessa ordem. Ou seja, ordem altera quantidade em aberto para zero, ordem sai da lista de ordens vivas, ordem entra para histórico, execução entra para histórico. Verborrágico mas ordenado.

Mas pode receber também, digamos, um DEAL_ADD seguido de HISTORY_ADD e depois ainda um ORDER_DELETE fechando com um ORDER_UPDATE, significando ordem viva mesmo depois de 100% executada, ordem viva e no histórico ao mesmo tempo, atualização de ordem viva que já está no histórico, momento a momento.

Isso rapidamente se torna confuso se você tenta obter a mesma informação por meios diferentes (digamos, detectar execução parcial via ORDER_UPDATE e DEAL_ADD).

E a história de detectar a mesma coisa de duas maneiras diferentes surge os eventos separados garantem que você vai se deparar com a situação de:

1. Ordem retirada sem execução (ORDER_DELETE antes de DEAL_ADD)

2. Quantidade em aberto descasada (ORDER_UPDATE e DEAL_ADD, em qualquer ordem)

3. Ordem já inexistente mas "viva" no terminal (HISTORY_ADD antes de ORDER_DELETE).

 

O (3) nunca aconteceu comigo, mas o (1) e (2) simplesmente não tem solução. Como execução e atualização de ordem são informados em dois eventos separados, o descasamento ocorre. E como você não tem garantia da ordenação dos eventos, não tem como ordenar o código para pegar essa ou aquela transição.

Então tem de escolher só uma maneira de detectar o que aconteceu, porque tentar olhar em dois lugares ao mesmo tempo vai deixar o código confuso, e bem mais propensos a falhas.

 
cpf216:

Bom, eu utilizo o OnTradeTransaction. Até porque, eu não me acostumei a programar em MQL, e daí eu queria era "extrair" os dados do ambiente do MT para um plataforma que eu tivesse menos atritos.

Então precisava saber tudo o que acontecia no terminal, o mais rápido possível, sem ficar bloqueando. OnTrade não diz nada, mas OnTradeTransaction diz absolutamente tudo. Portanto foi o ponto de extração de dados (assim como OnTick e OnTimer).

....

Olá cpf216, ótima análise, obrigado por compartilhar, grande contribuição para o Fórum. Vi que teu cadastro é recente, espero que continues trazendo mais de tua experiência e volte sempre por aqui.

Parabéns também ao Vitor pela iniciativa do tópico, já comentada pelo Malacarne.

Acredito que a única forma de explorar bem esse assunto é entendendo mais profundamente a arquitetura do MT5, principalmente nas várias camadas existentes, pois estamos a meu ver estudando diferentes camadas de uma rede de roteamento de ordens. Como não temos isso abertamente disponível, o melhor que podemos fazer por aqui é inferir algumas coisas.

Na minha opinião o OnTradeTransaction é basicamente uma função de visibilidade das funcionalidades do fluxo de execução de ordens dos protocolos de comunicação (no protocolo FIX essas mensagens são agrupadas como do tipo 8 - Execution Report, para quem desejar aprofundar mais no assunto). Muito bom, portanto, que ela esteja disponível no MQL5, pois visibilidade é sempre bem-vinda. 

Mas, felizmente, não precisamos obrigatoriamente trabalhar nessa camada, pois existe uma abstração de estruturas e funções no MQL5 para mapear o fluxo de execução de ordens em camadas acima dessa.

Porém gostei bastante da abordagem do cpf216 e do Vitor, pois buscam o estudo, descoberta e o aprendizado em camadas que realmente não são fáceis de trabalhar.

Uma sugestão e forma de endereçar o entendimento nessa camada, que considero uma das mais viáveis, é tratar as mensagens não de forma combinacional, mas de forma sequencial, como por exemplo através de uma máquina de estados, já que a história passada e sequenciamento do fluxo de execução de ordens é fundamental.

Confesso que mesmo fazendo isso não é simples, até porque os protocolos como o FIX e outros na área estão em constante evolução, exigindo adaptações tanto do MQL5 como de nossos EAs. Não só isso, muitas vezes a codificação dos protocolos também não é precisa, já que depende de entendimento correto do programador.

Mas colocar o "dedo na ferida", como vocês estão propondo, é o caminho de melhor aprendizado da plataforma e do segmento quantitativo que conheço.

Obrigado e abs.

 
figurelli:

Na minha opinião o OnTradeTransaction é basicamente uma função de visibilidade das funcionalidades do fluxo de execução de ordens dos protocolos de comunicação (no protocolo FIX essas mensagens são agrupadas como do tipo 8 - Execution Report, para quem desejar aprofundar mais no assunto). Muito bom, portanto, que ela esteja disponível no MQL5, pois visibilidade é sempre bem-vinda.

Já eu vejo bem diferente, pelo menos na comparação com o FIX.

Ao se imprimir o preenchimento das três estruturas do OnTradeTransacion, verão que ela tem relação 1:1 com as janelas de Trade e History. Expõe sim um protocolo de comunicação, mas não um de fluxo de ordens, tratando-se do protocolo de atualização da interface do terminal.

Daí que OnTradeTransaction é uma forma de "ver" algoritmicamente o que foi (?) mudado na tela. Um jeito do seu EA saber que algo na tela mudou/mudará.

 

figurelli:

Mas, felizmente, não precisamos obrigatoriamente trabalhar nessa camada, pois existe uma abstração de estruturas e funções no MQL5 para mapear o fluxo de execução de ordens em camadas acima dessa.

Que seria?

OnTrade não fornece dado algum. É apenas um ponto de execução que é chamado. Ainda fica com o implementador de tudo memorizar e tudo comparar, para detectar a alteração.

OnTradeTransaction, no outro extremo, notifica tudo. Mas sem a garantia de ordem acaba impedindo, justamente, o mapeamento de um fluxo. Daí fica a complicação de tentar mapear todos os fluxos, ou de ir pela rota de tudo memorizar/comparar, talvez só diminuindo o esforço de comparação porque o MqlTradeTransaction dá a dica do que mudou (identificação da posição e/ou da ordem alterada).

 
cpf216:

Já eu vejo bem diferente, pelo menos na comparação com o FIX.

Ao se imprimir o preenchimento das três estruturas do OnTradeTransacion, verão que ela tem relação 1:1 com as janelas de Trade e History. Expõe sim um protocolo de comunicação, mas não um de fluxo de ordens, tratando-se do protocolo de atualização da interface do terminal.

Daí que OnTradeTransaction é uma forma de "ver" algoritmicamente o que foi (?) mudado na tela. Um jeito do seu EA saber que algo na tela mudou/mudará.

 

Que seria?

OnTrade não fornece dado algum. É apenas um ponto de execução que é chamado. Ainda fica com o implementador de tudo memorizar e tudo comparar, para detectar a alteração.

OnTradeTransaction, no outro extremo, notifica tudo. Mas sem a garantia de ordem acaba impedindo, justamente, o mapeamento de um fluxo. Daí fica a complicação de tentar mapear todos os fluxos, ou de ir pela rota de tudo memorizar/comparar, talvez só diminuindo o esforço de comparação porque o MqlTradeTransaction dá a dica do que mudou (identificação da posição e/ou da ordem alterada).

Como falei, o fluxo de ordens depende de uso de um algoritmo sequencial, como acontece com o processamento da maior parte dos protocolos.

A OnTradeTransaction é uma evolução da OnTrade, portanto isso é natural e a MQ provavelmente não eliminou a OnTrade para manter a compatibilidade com códigos antigos.

Processando eventos em tempo real você irá ganhar em tempo de detecção e reação, portanto se isso é fundamental nas suas estratégias (HFT, por exemplo), não vejo outro caminho, principalmente se você também estiver utilizando envio de ordens assíncronas.

Mas se não for esse o caso, e tudo que você precisa é abrir ou fechar uma posição, porque não fazer isso por polling?

Nesse sentido, pode simplesmente monitorar por polling estruturas como a MqlTradeResult e funções como as Trade functions e Checkup functions para abstrair o processamento em tempo real de mensagens e fluxo de ordens, o que acontece na maior parte das aplicações abertas no site, que não utilizam a OnTradeTransaction.

 
figurelli:

Como falei, o fluxo de ordens depende de uso de um algoritmo sequencial, como acontece com o processamento da maior parte dos protocolos.

A OnTradeTransaction é uma evolução da OnTrade, portanto isso é natural e a MQ provavelmente não eliminou a OnTrade para manter a compatibilidade com códigos antigos.

Processando eventos em tempo real você irá ganhar em tempo de detecção e reação, portanto se isso é fundamental nas suas estratégias (HFT, por exemplo), não vejo outro caminho, principalmente se você também estiver utilizando envio de ordens assíncronas.

Mas se não for esse o caso, e tudo que você precisa é abrir ou fechar uma posição, porque não fazer isso por polling?

Como eu já falei acima, queria justamente a informação mais atualizada possível, fora do ambiente do MT. Daí o pooling seria pouco eficiente, ficar gastando CPU a toa tentando detectar as alterações que podem ser muito mais facilmente avisados por OnTradeTransaction.

O problema é mais embaixo, na verdade. O manual é claro no sentido que a fila de eventos tem limitações. Daí que gastar CPU em pooling pode ter o efeito colateral de perder eventos de atualização (ticks e barras, inclusive), sem nenhuma forma de detecção.

figurelli:

Nesse sentido, pode simplesmente monitorar por polling estruturas como a MqlTradeResult e funções como as Trade functions e Checkup functions para abstrair o processamento em tempo real de mensagens e fluxo de ordens, o que acontece na maior parte das aplicações abertas no site, que não utilizam a OnTradeTransaction.

Eis que a esmagadora maioria das aplicações abertas são de ativo único, enquanto que eu já comecei montando operações estruturadas multi ativos. Daí que essa comparação com a maioria passa longe de ser relevante.

Pode até ser viável de fazer pooling com um único ativo, uma única posição, em processamento serial. Mas eis que o MT garante (exige até) que o processamento seja serial, já que ele nunca chama duas funções On* em paralelo. Daí a fica a questão, diferente, se essa maioria é natural ou se tem raízes no específico modelo de processamento.

 
cpf216:

Como eu já falei acima, queria justamente a informação mais atualizada possível, fora do ambiente do MT. Daí o pooling seria pouco eficiente, ficar gastando CPU a toa tentando detectar as alterações que podem ser muito mais facilmente avisados por OnTradeTransaction.

O problema é mais embaixo, na verdade. O manual é claro no sentido que a fila de eventos tem limitações. Daí que gastar CPU em pooling pode ter o efeito colateral de perder eventos de atualização (ticks e barras, inclusive), sem nenhuma forma de detecção.

Eis que a esmagadora maioria das aplicações abertas são de ativo único, enquanto que eu já comecei montando operações estruturadas multi ativos. Daí que essa comparação com a maioria passa longe de ser relevante.

Pode até ser viável de fazer pooling com um único ativo, uma única posição, em processamento serial. Mas eis que o MT garante (exige até) que o processamento seja serial, já que ele nunca chama duas funções On* em paralelo. Daí a fica a questão, diferente, se essa maioria é natural ou se tem raízes no específico modelo de processamento.

Por favor, lê de novo essa frase, principalmente o sublinhado: "Processando eventos em tempo real você irá ganhar em tempo de detecção e reação, portanto se isso é fundamental nas suas estratégias (HFT, por exemplo), não vejo outro caminho, principalmente se você também estiver utilizando envio de ordens assíncronas.".

Portanto é óbvio que o polling não se aplica a todas situações, e não estou defendendo isso, mas a realidade é que 99% das soluções, pelo menos as que você vai encontrar aqui no Fórum e Base de Código, são baseadas em polling e podem funcionar com a mesma eficácia sem sobrecarregar a CPU, basta você fazer a amostragem no momento correto e na frequência correta.

 

Este topico foi muito esclarecedor pessoal, gostei de mais do material e da forma que aprofundaram o assunto. 

Tenho um caso de uso especifico que gostaria de debater com voces, visto o amplo conhecimento no assunto sobre a assincronia dos eventos. 

Hoje utilizo o OnTradeTransaction para apenas uma necessidade que nao consegui resolver com polling conforme indicado. 

Preciso identificar o momento do fechamento de operacoes por Stop Loss ou por Take Profit. Para atribuir variaveis de controle para uso no OnTick. Porem pela assincronia nao tenho consegui os resultados desejados. 

Avalio pela discussao aqui apresentada, de que o recomendado seria eu criar dentro do OnTick uma forma de procurar se a operacao foi fechada, se ela nao existe mais, ou consultar no historico se ela esta la, nao estando mais na minha lista de posicoes abertas, para entao usar essa informacao. 

Seria essa recomendacao que estao fazendo? Nao sei se fui claro. 

Agradeco novamente por compartilharem essas informacoes no forum, foi de grande valia.

Razão: