Erros típicos e como lidar com eles quando se lida com o ambiente comercial - página 2

 

fxsaber:

A função que indica a necessidade de um embrulho é marcada em vermelho. Seu problema é descrito aqui. Alguns podem se lembrar que este é um antigo problema de reabertura de posição, que em tempos antigos foi resolvido por Sleep, esperando que a posição fosse aberta após OrderSend. Mas, na verdade, este problema não tem nada a ver com a OrderSend. Você deve ser capaz de ler corretamente o ambiente comercial.

O exemplo certo é simples.

A lista de pedidos, assim como a lista de posições, não é atualizada instantaneamente. Acho que não podemos passar sem o Sleep-crutch.

Provavelmente mais correto é OnTradeTransaction

 
Aleksey Lebedev:

A lista de pedidos, como a lista de posições, não é atualizada instantaneamente. imho, não podemos passar sem o Sleep-crutch.

Provavelmente, seria melhor usar OnTradeTransaction.

Se houver um problema esperando pela atualização ambiental, como Sleep pode ajudar? Ajudará ou não.

Portanto, a abordagem deve ser do outro lado: após enviar uma ordem para abrir uma posição ou definir uma ordem pendente, devemos esperar pelo resultado e não enviar mais ordens para abrir ou definir. Portanto, precisamos de uma bandeira que nós mesmos administramos em vez de confiar no Sleep que só dá atraso na execução do programa, mas não verifica o resultado de um pedido comercial enviado pelo próprio programa que deve saber o que fazer depois disso - colocar uma bandeira e trabalhar de acordo com a lógica de espera de resultados. Depois de esperar pelo resultado, a bandeira é retirada.

 
Artyom Trishkin:

Pergunta: O que acontecerá se depois de enviar uma ordem de comércio até o próximo tick a ordem de mercado não for colocada pelo servidor?

Será exatamente o mesmo que no MT4 - se não houver nada, não será contado.


Pode haver várias razões para tal ordem comercial

  1. OrderSend ou OrderSendAsync de terceiros - não do programa em que lemos o ambiente comercial. Pode até não ser do terminal em que o programa está sendo executado. Neste caso, nada pode ser feito. Em tais situações, tudo é igual ao que acontece no MT4.
  2. OrderSend ou OrderSendAsync - são iniciados a partir do programa no qual o ambiente comercial é lido. No caso da OrderSend, tudo está claro, pois a OrderSend terminará sua execução com um resultado claro. No caso do OrderSendAsync podemos fazer duas coisas - passar dados para os próximos eventos de acordo com o primeiro paradigma, ou fazer OrderAsyncWait() (eu não tenho o código), como é feito em uma simulação assíncrona regular de transferência de dados em MT4 (implementação de múltiplos threads).
Eu provavelmente deveria dizer algumas palavras sobre a OrderSendAsync no MT4. Em qualquer etapa da execução do programa é possível ver o quão ocupado é um fio comercial correspondente e o que exatamente ele está fazendo. Neste sentido, a assíncronia personalizada no MT4 nos dá muito mais possibilidades do que a do MT5. Mas no MT4 ela é implementada executando "clientes" em cada gráfico, ou seja, caros. No MT5 é possível escrever a mesma funcionalidade e mesmo sem muitos gráficos - rodando o script em um objeto OBJ_CHART, mas ainda assim haverá um pequeno atraso. Isto é, OrderSendAsyncCustom será ligeiramente mais lento que OrderSendAsync, mas ainda assim será muito mais rápido que OrderSendAsync + todas as vantagens da implementação personalizada.
 
Aleksey Lebedev:

A lista de pedidos, como a lista de posições, não é atualizada instantaneamente. imho, não podemos passar sem o Sleep-crutch.

Provavelmente, seria mais correto usar OnTradeTransaction

A MqlTradeTransaction pode ser necessária somente quando se escolhe o paradigma apropriado ao trabalhar com a OrderSendAsync. Em outros casos, OnTradeTransaction == OnTrade no sentido e não desempenha mais papel do que OnTick ou OnTimer.


Fórum sobre comércio, sistemas automatizados de comércio e testes estratégicos

Erros típicos e como corrigi-los quando se trabalha com um ambiente comercial

fxsaber, 2018.02.19 22:36

Existem dois paradigmas de trabalho com o ambiente comercial, a escrita de EAs.

  1. As entradas de eventos (OnTick, OnTimer, etc.) dependem uma da outra. Há informações que DEVEM ter entre eventos (não para velocidade, como cache, mas para usabilidade). Por exemplo, precisamos salvar o resultado do OrderSendAsync e usá-lo na OnTradeTransaction. As caches NÃO são informações obrigatórias e são utilizadas apenas para acelerar. É por isso que não os consideramos de imediato.
  2. As entradas de eventos (OnTick, OnTimer, etc.) NÃO dependem uma da outra. Cada entrada é do zero. Mais ou menos como um Roteiro que você mesmo executa em cada evento.

Destacado denota que o mesmo código comercial é executado em cada On-function. O código não comercial correspondente completa tudo o resto.

 
fxsaber:

Será exatamente o mesmo que no MT4 - se não houver nada, não será contado.

Isto é - no próximo tique o programa envia um novo pedido de abertura. Como resultado, temos o mesmo problema - múltiplas aberturas.

O Conselheiro Especialista deve ter a seguinte lógica:

  1. Recebemos um sinal para abrir uma posição ou definir uma ordem pendente
  2. Verifique o número de ordens/posições, se não houver sinal para abrir uma nova posição - saída (para o ponto 1).
  3. Verifique a bandeira de espera de resposta do servidor:
    1. Bandeira está hasteada - saída (para o passo 1)
    2. Bandeira omitida - continuar
  4. A bandeira é omitida - enviar uma ordem comercial (o número de tentativas é limitado) e verificar o código de retorno
    1. A ordem foi executada - colocar a bandeira de espera
    2. Ordem falhada - chamar a função de correção de ordem comercial e ir para o ponto 4
  5. A bandeira de espera é hasteada - verifique a mudança do ambiente comercial
    1. O ambiente comercial não mudou - saída (vá para o passo 1).
    2. O ambiente mudou - um pedido pendente é feito ou uma posição é aberta - retire a bandeira de espera e saia (para o passo 1).
 
Artyom Trishkin:

Isto é, no próximo tick, o software envia um novo pedido de abertura. Como resultado, temos o mesmo problema - múltiplas aberturas.

Seria bom ler o post inteiro.

A EA deve ter a seguinte lógica:

  1. Recebemos um sinal para abrir uma posição ou definir uma ordem pendente
  2. Verifique o número de ordens/posições, se não houver sinal para abrir uma nova posição - saída (para o ponto 1).
  3. Verifique a bandeira de espera de resposta do servidor:
    1. Bandeira está hasteada - saída (para o passo 1)
    2. Bandeira omitida - continuar
  4. A bandeira é omitida - enviar uma ordem comercial (o número de tentativas é limitado) e verificar o código de retorno
    1. A ordem foi executada - colocar a bandeira de espera
    2. Ordem falhada - chamar a função de correção de ordem comercial e ir para o ponto 4
  5. A bandeira de espera é hasteada - verifique a mudança do ambiente comercial
    1. O ambiente comercial não mudou - saída (para o passo 1).
    2. O ambiente mudou - um pedido pendente é feito ou uma posição é aberta - retire a bandeira de espera e saia (para o passo 1).

A bandeira de espera só está disponível para o segundo caso e OrderSendAsync. Para OrderSend, a bandeira de espera não é de todo necessária. OrderSendAsync sem bandeira de espera é OrderAsyncWait().

Você pode verificar qualquer teoria na prática.

Guiado por resultados práticos.
 
fxsaber:

É uma boa idéia ler o post na íntegra.

A bandeira de espera só é possível para o segundo caso e OrderSendAsync. Para a OrderSend a bandeira de espera não é de todo necessária. OrderSendAsync sem bandeira de espera é OrderAsyncWait().

Qualquer teoria pode ser testada na prática

Eu sou guiado por resultados práticos.

Bem, eu escrevi para o modo assíncrono. Com o sincronismo não é preciso esperar - o resultado já está lá na resposta da consulta.

 
Artyom Trishkin:

Bem, eu escrevi para o modo assíncrono.

Uma resposta detalhada foi dada desde o início.

 
fxsaber:

Uma resposta ampliada foi dada desde o início.

Eu devo ter lido mal :)

Não vi nenhum passo para contornar o erro de múltipla descoberta. Somente "paradigmas" gerais ;)

É por isso que delineei a lógica aproximada, que é redundante - a bandeira é verificada em uma função (invólucro) que abre posições / estabelece ordens pendentes. Ou talvez também na função de rastreamento de sinal.

Você tem que pensar na melhor maneira.

 
Artyom Trishkin:

a bandeira é verificada na função (invólucro) de abertura de posições/colocação de ordens pendentes. Ou talvez também na função de rastreamento de sinal.

Eu prefiro muito a solução via OrderAsyncWait(), quando a saída do On-function é sempre feita sem estado suspenso. Então a próxima leitura do ambiente comercial com uma ardósia limpa é a mais relevante possível.

O uso de OrderSendAsync deve ser sempre apropriado. A única situação em que isso pode acontecer é o envio de várias (> 1) ordens comerciais, independentes umas das outras, no mesmo sinal. Portanto, a coisa da OrderSendAsync nunca faz sentido em todos os outros casos.


SZZY Há um tópico separado onde a OrderSendAsync é muito relevante - os multi-conselheiros: vários TS independentes em um único Expert Advisor. A OrderSend raramente é adequada lá e mesmo OrderAsyncWait( const string Symb) não é boa, uma vez que, em princípio, não é permitido o sono.