Bibliotecas: MultiTester - página 30

 
Stanislav Korotky #:

Não vi nas alterações de código-fonte que algo foi feito com a área de transferência.

  static bool GetSettings2( string &Str, const int Attempts = 10 )
  {
    bool Res = false;

    if (MTTESTER::LockWaiting())
    {
      Res = MTTESTER::GetSettings(Str, Attempts);

      MTTESTER::Lock(false);
    }

    return(Res);
  }

Se você executar a otimização, ela não utilizará todos os núcleos disponíveis de uma só vez? Não entendo como um único teste "tirou" um núcleo da otimização (na verdade, até mesmo dois agentes de otimização do MT estão marcados como desativados).

Acho que escrevi isso imediatamente. O Terminal de otimização tem dois agentes desativados. Cada agente habilitado ocupa um núcleo.

 
fxsaber #:

Acho que escrevi isso imediatamente. O Terminal de otimização tem dois agentes desativados. Cada agente habilitado usa um kernel.

Ele não diz explicitamente nada sobre a desativação manual (ou outra configuração de agentes) - e essa nuance ainda é ignorada. Esse é o motivo pelo qual tenho uma pergunta sobre a quantidade de trabalho paralelo que é automatizado. Com base no tópico e na descrição do blog, pensei ingenuamente que a automação completa havia sido feita.

O LockWaiting foi visto - foi ele que eu formulei como trabalho de bloqueio de arquivo. Está claro que o bloqueio pode ser usado para acessar recursos, inclusive a área de transferência. Confusão terminológica.

PS. Talvez eu tenha entendido algo errado, mas se apenas o acesso exclusivo à área de transferência fosse necessário, então o mesmo bloqueio (um loop com verificações periódicas) é mais lógico para fazer nas funções da própria área de transferência (OpenClipboard, que já é mencionado no código-fonte).

 
Stanislav Korotky #:

Ele não diz explicitamente nada sobre a desativação manual (ou outra configuração de agentes), e essa nuance ainda é ignorada. É exatamente por isso que tenho uma pergunta sobre o quanto o trabalho paralelo é automatizado. Com base no tópico e na descrição do blog, pensei ingenuamente que a automação completa estava concluída.

Automação total no lado do MQ. Em qualquer máquina, mesmo trabalhando com um terminal, eu desligo um ou dois agentes para poder trabalhar na máquina sem atrasos.


Terminal1 (Otimização): Agentes 3000-3017 - ativados, 30018-3019 - desativados. Assim, em todos os terminais, porque todos os outros terminais são uma cópia completa do primeiro. Nenhuma configuração manual é feita.

Terminal2 - para passes únicos.


Dois cenários.

  1. Primeiro, executei a otimização no Terminal1, 3000-3017 foram ativados. Em seguida, passagens únicas no Terminal2 - 3018 funciona.
  2. Primeiro executei passes únicos no Terminal2, 3000 foi ativado. Em seguida, otimização no Terminal1 - executando 3001-3018.
Tudo é automatizado no lado do MQ. É uma questão de um minuto para você verificar. O diálogo levou muito mais tempo.
 
Stanislav Korotky #:

PS. Provavelmente entendi algo errado, mas se apenas o acesso excepcional à área de transferência fosse necessário, seria mais lógico fazer o mesmo bloqueio (loop com verificações periódicas) nas funções da própria área de transferência (OpenClipboard, que já é mencionado nos códigos-fonte).

Não vejo a lógica dessa solução.

 
fxsaber #:

Automação total no lado do MQ. Em qualquer máquina, mesmo que eu trabalhe com um terminal, desligo um ou dois agentes para que eu possa trabalhar na máquina sem atrasos.


Terminal1 (Otimização): Agentes 3000-3017 - ativados, 30018-3019 - desativados. Assim, em todos os terminais, porque todos os outros terminais são uma cópia completa do primeiro. Nenhuma configuração manual é feita.

Terminal2 - para passes únicos.


Dois cenários.

  1. Primeiro, executei a otimização no Terminal1, 3000-3017 estão ativos. Em seguida, executei singles no Terminal2 - 3018 está em execução.
  2. Primeiro, executei singles no Terminal2, com 3000 em execução. Em seguida, a otimização no Terminal1 - 3001-3018 funciona.
Tudo é automatizado no lado do MQ. É uma questão de um minuto para você verificar. O diálogo levou muito mais tempo.

Se essa descrição estivesse no blog, não haveria dúvidas. Novamente, essa descrição significa configuração manual de agentes, na minha opinião, e não automação. Não há nada para verificar.

 
Stanislav Korotky #:

Se essa descrição estivesse no blog, não haveria dúvidas. Novamente, essa descrição significa configuração manual de agentes, na minha opinião, e não automação. Não há nada para verificar.

Não há configuração manual. Você não pode fazer nada com os agentes, o comportamento não será alterado. Surpreendente.

 
fxsaber #:

Não há configuração manual. Você não pode fazer nada com os agentes, o comportamento não mudará. Surpreendente.

Foi declarado "para evitar possíveis conflitos ao trabalhar com testadores paralelos". Essa frase é enganosa no contexto dos núcleos, porque o que está sendo feito de fato é a configuração manual dos agentes. Por algum motivo, você insiste em associar a alocação de portas aos núcleos. As portas não podem se sobrepor, mas os kernels (processos) podem - isso depende apenas da pré-configuração. Suponho que tenhamos apenas noções diferentes de resolução automática de conflitos entre processos paralelos.

 
Stanislav Korotky #:

Foi declarado "para contornar possíveis conflitos ao trabalhar com testadores paralelos". Essa frase é enganosa no contexto dos kernels, porque, de fato, a configuração manual dos agentes é feita.

Você interpretou mal a palavra "circunvenção". O problema ocorre quando vários terminais estão trabalhando com a área de transferência ao mesmo tempo. Antigamente, os trabalhos de um terminal podiam entrar acidentalmente em outro terminal. Agora isso está excluído.

 

As seguintes alterações estão disponíveis no MTTester.mqh.

  • GetLastTstCacheFileName agora retorna o nome do arquivo tst SEM o caminho.
  • GetLastTstCache tem a capacidade de buscar o arquivo tst que corresponde à passagem recém-concluída. Isso evita que arquivos tst errôneos sejam buscados.
  • O ClickStart funciona corretamente mesmo quando o Testador reage instantaneamente quando o botão Iniciar é pressionado. Nesses casos, o ClickStart reconhece que o botão Iniciar foi pressionado com sucesso.
 

Às vezes, você precisa fazer a mesma coisa nos terminais de trabalho. A automação dessa ação é mostrada abaixo no exemplo.


É necessário coletar dados em cada terminal executando um script semelhante RunMe.mq5.

#include <fxsaber\MultiTester\MTTester.mqh> // https://www.mql5.com/pt/code/26132
  
void OnStart()
{
  if (MTTESTER::LockWaiting()) // Se você quiser executar ações sequencialmente.
  {
    const int handle = ::FileOpen(__FILE__, FILE_WRITE | FILE_READ | FILE_ANSI | FILE_COMMON);

    // Escreva os dados necessários no arquivo.
    if (handle != INVALID_HANDLE)      
    {
      FileSeek(handle, 0, SEEK_END);
      FileWriteString(handle, "Account = " + (string)AccountInfoInteger(ACCOUNT_LOGIN) + ", " +
                              "Balance = " + (string)AccountInfoDouble(ACCOUNT_BALANCE) + "\n");
      
      FileClose(handle);
    }

    MTTESTER::Lock(false); // Liberar o bloqueio de execução paralela.
  }
}


É assim que isso é feito.

// Execute o script em todos os terminais.

#include <fxsaber\MultiTester\MTTester.mqh> // https://www.mql5.com/pt/code/26132
  
void OnStart()
{
  HANDLE Handles[]; 
  
  // Percorrer todos os terminais
  for (int i = MTTESTER::GetTerminalHandles(Handles) - 1; i >= 0; i--)
    MTTESTER::RunEX5("Scripts\\RunMe.ex5", Handles[i], true); // e executar o script apropriado em cada um deles.
}


Como resultado, coletamos dados de todos os terminais com um clique. Graças a MTTESTER::RunEX5 - executa o EX5 no terminal necessário (portátil).