Quaisquer perguntas de recém-chegados sobre MQL4 e MQL5, ajuda e discussão sobre algoritmos e códigos - página 607

 
Vitaly Gorbunov:

O fato de ter identificado em algum lugar o número de pedidos que você precisa é bom, mas neste bloco você passa por todos os pedidos novamente e os verifica!

Quebre o código corretamente e você verá de imediato!

É claro que você pode recalcular isso novamente. Mas isso não faz a diferença. O operador do if() não executa "de outra forma". este é apenas um caso, e havia outros.
 
for(int h = OrdersTotal()-1; h >= 0; h--)
    {
     if(OrderSelect(h, SELECT_BY_POS))
      {
       if((cnt_OO >= 2))
        {
       if((OrderMagicNumber() == Magic)&&(OrderLots() <= Lots/Prikup - Dplus))
        {
         Nextstep  = NextStep;
         BaseNext  = OrderOpenPrice();
         LotsNext  = NormalizeDouble(OrderLots()*K,lotDigit);
         if(NewPB > 0)
          PBcloseON = true;
         Alert ("Pospedny Order NEXT  ",OrderTicket());
         Alert ("Otkritih orderov  ",cnt_OO);
//         break;
        }
       break;
       }
         LotsNext    = NormalizeDouble(Lots*Prikup,lotDigit); 
         Alert ("Otkritih orderov NEXT net ");
        Alert ("Otkritih orderov  ",cnt_OO);
         break;
     
        }}

Experimente assim!

Eu não vejo mais nada em seu código!

Jogue outros casos, vamos ver o que há de errado aí :)

Após um cuidadoso estudo de lógica, eu fiz engenharia reversa de seu código.

Aconteceu algo parecido com isto

if(cnt_OO>0) //Если нет ордеров то и не надо ни чего делать
{
  for(int h = OrdersTotal()-1; h >= 0; h--)
   {
    if(OrderSelect(h, SELECT_BY_POS))
     {
      if(cnt_OO==1)
         {
          //Если ордер один проверяем тот ли ордер (майджик и прочее) и что то там делаем
         }
      else
         {
          //Если ордеров больше чем 1 проверяем те ли ордера (майджик и прочее) и что то там делаем
         }
     }
   }
   
}
 

Podemos fazer isso dessa maneira. Mas o tutorial diz que se a condição não for cumprida, os comandos após o fechamento do bloco por meio de um parêntese para processar a condição do operador if() são processados. Isso não acontece.

Havia mais uma falha:

     if((OrderSelect(i,SELECT_BY_POS,MODE_HISTORY))&&(OrderMagicNumber() == Magic)&&(OrderLotsOld==zLots))
      {
       

Se eu adicionei mais uma condição à primeira, se o operador - a próxima - não funcionou

Tenho duas sugestões

1. Estúpido testador de estratégia. Como estas situações ocorrem na fase de depuração do programa, você tem que ser um completo idiota para verificá-la em uma conta real. E em uma conta demo, também, porque é difícil reproduzir a situação de reinício. O fato de o testador ser um idiota nos diz que a ordem de fechamento de várias ordens na janela MT4 muitas vezes não corresponde à ordem real se o fechamento ocorrer de uma só vez. Isto pode ser visto claramente se você recalcular as últimas encomendas no programa. Este erro me fez passar uma semana tentando descobrir quem era louco.

A própria lógica do funcionamento do testador, mesmo na história do tick, está longe da vida real. É muito crítico para o meu algoritmo.

2. como um palpite. Uma pergunta a gurus especialmente avançados não apenas em MQL/MT4, mas também a especialistas em sistemas.

- Eu tenho dois EAs idênticos no mesmo par em janelas diferentes. Quando eu executo os EAs, por exemplo, na segunda-feira depois que o computador está desligado para o fim de semana, ambos começam a trabalhar ao mesmo tempo quando aparece o primeiro tique. Esperava que um trabalhasse primeiro para restaurar o estado e depois o outro. Quem teve sorte, trabalhou primeiro.

De fato, as mensagens de recuperação de dados são mistas. Em outras palavras, a execução do programa é interrompida por alguma condição, por exemplo, o temporizador do sistema e depois continua. Situações interessantes ocorrem quando, por exemplo, se muda para outra conta para verificar como ela está indo. As condições para verificar a conta estão no início do programa e no momento de retornar à conta inicial o programa está no meio e não dá a mínima para o que a conta está lá agora.

Encontrei uma saída - no início de cada bloco eu verifico o número da conta. Não tenho certeza onde quer que seja suposto estar.

 

Amon1953 você olhou para a primeira versão que consertei? Será que funciona? Exatamente como está escrito no manual if() e funciona por muitos anos de uso. O problema está no seu código, você coloca uma pausa em um bloco errado.

if((OrderSelect(i,SELECT_BY_POS,MODE_HISTORY))&&(OrderMagicNumber() == Magic)&&(OrderLotsOld===zLots)) você deve verificar o que é atribuído às variáveis.

No segundo ponto - ambas as corujas estarão funcionando em paralelo, portanto as mensagens delas serão misturadas. Para fazer o que você descreve, você precisa implementar semaforização entre as cópias da coruja. E é muito interessante que algo estranho aconteça quando eu mudo a conta. Eu gostaria muito de ver OnInit e OnDeinit. O mais provável é que o problema exista.

 
Vitaly Gorbunov:

Amon1953 você olhou para a primeira versão que consertei? Será que funciona? Exatamente como está escrito no manual if() e funciona por muitos anos de uso. O problema está no seu código, você coloca uma pausa em um bloco errado.

if((OrderSelect(i,SELECT_BY_POS,MODE_HISTORY))&&(OrderMagicNumber() == Magic)&&(OrderLotsOld===zLots)) você deve verificar o que é atribuído às variáveis.

No segundo ponto - ambas as corujas estarão funcionando em paralelo, portanto as mensagens delas serão misturadas. Para fazer o que você descreve, você precisa implementar semaforização entre as cópias da coruja. E é muito interessante que algo estranho aconteça quando eu mudo a conta. Eu gostaria muito de ver OnInit e OnDeinit. O mais provável é que o problema exista.

Não a verifiquei porque precisamos sair do laço pela última ordem (é a primeira da lista).

Não sou um programador experiente e não entendo totalmente o funcionamento do OnInit e do OnDeinit. É por isso que eles não são usados no meu código, mas parecem permitir que o programa seja executado sem interrupção no meio.

Eu não entendo semáforo também, os conselheiros são instalados em janelas diferentes e têm majores diferentes

 
Meu conselho para você, se você só recentemente começou a programar, é que estude novamente as bases da programação básica. Sem ofensa, mas você é muito difícil de se comunicar.
 
Vitaly Gorbunov:
Meu conselho para você, se você só recentemente começou a programar, é que estude novamente as bases da programação básica. Sem ofensa, mas você é muito difícil de se comunicar.
Obrigado. Esta seção é para iniciantes. Mesmo este tipo de comunicação tem me beneficiado. É difícil fazer tanto o algoritmo EA como escrever o código do programa (além disso, a linguagem de programação é bastante nova para mim)
 
Amon1953:
Obrigado. Esta é uma seção para iniciantes. Mesmo este tipo de comunicação tem me beneficiado. É difícil fazer tanto o algoritmo EA quanto o código do programa (especialmente porque a linguagem de programação é bastante nova para mim)
Parece que você precisa melhorar o básico! Já que não entendo bem do seu código que tipo de lógica você quer implementar, tente explicar em palavras o que você quer fazer. E eu tentarei explicar onde você tem um erro.
 
Vitaly Gorbunov:
Parece que você precisa apertar a base! Já que não entendo bem de seu código qual lógica você quer implementar, tente explicar em palavras o que você quer fazer. E vou tentar explicar onde você cometeu um erro.

Eu já expliquei o que preciso antes. Vou tentar esclarecer os detalhes.

Ao reiniciar a EA, é necessário restaurar o estado anterior, pois o algoritmo é uma cadeia de ordens. A primeira ordem é a básica, e podemos calcular os parâmetros das próximas ordens na cadeia a partir dela. Por exemplo, o volume da segunda encomenda é 50% da base, o terceiro 75%, e assim por diante. Ao reiniciar um EA, precisamos saber o volume da linha de base e da última encomenda, já que o volume da próxima encomenda será calculado a partir da última. Por exemplo, existem 3 ordens em aberto. Para calcular a próxima (quarta) ordem, precisamos encontrar o volume da última ordem em aberto.

Se houver apenas um pedido, significa que é o pedido base e, neste caso, não estamos interessados nele, ele é tratado por outra unidade.

O algoritmo é muito simples. Mas só funciona com dois operadores se().

 
Amon1953:

Eu já expliquei o que preciso antes. Vou tentar esclarecer os detalhes.

Ao reiniciar a EA, é necessário restaurar o estado anterior, pois o algoritmo é uma cadeia de ordens. A primeira ordem é a básica, e podemos calcular os parâmetros das próximas ordens na cadeia a partir dela. Por exemplo, o volume da segunda encomenda é 50% da base, o terceiro 75%, e assim por diante. Ao reiniciar um EA, precisamos saber o volume da linha de base e da última encomenda, já que o volume da próxima encomenda será calculado a partir da última. Por exemplo, existem 3 ordens em aberto. Para calcular a próxima (quarta) ordem, precisamos encontrar o volume da última ordem em aberto.

Se houver apenas um pedido, significa que é o pedido base e, neste caso, não estamos interessados nele, ele é tratado por outra unidade.

O algoritmo é muito simples. Mas só funciona com dois operadores se().

Amon1953:

Não o verifiquei porque precisamos sair do loop pela última ordem (é o primeiro da lista).

Não sou um programador experiente e não entendo bem o funcionamento do OnInit e do OnDeinit. É por isso que eles não são usados no meu código, mas parecem permitir que o programa seja executado sem interrupção no meio.

Sobre o semáforo, também não é claro. Os Conselheiros Especialistas são instalados em diferentes janelas e têm diferentes majors.

Por favor, leia a documentação:

OnInit

A função OnInit() é o manipulador de eventos Init (). Pode ser dotipo vazio ou int, não tem parâmetros:

nuloOnInit();

Os eventos Init são gerados imediatamente após o carregamento de um Expert Advisor ou indicador. A função OnInit() é utilizada para inicialização. Se OnInit() tiver o valor int de retorno, o código de retorno não zero significa inicialização sem sucesso, e gera o evento Deinit com o código de motivo de inicializaçãoREASON_INITFAILED.

Também é preciso classificar a visibilidade das variáveis.

События клиентского терминала - Программы MQL4 - Справочник MQL4
События клиентского терминала - Программы MQL4 - Справочник MQL4
  • docs.mql4.com
Сразу же после того, как клиентский терминал загрузит программу (эксперт или пользовательский индикатор) и запустит процесс инициализации глобальных переменных, будет послано событие Init, которое обрабатывается функцией OnInit(), если она есть. Это событие также генерируется после смены финансового инструмента и/или периода графика, после...