Библиотеки: EAToMath

 

EAToMath:

Тестирование на истории в математическом режиме MT5-тестера.

EAToMath

Автор: fxsaber

 
Потрясающая библиотека! Благодарю за ваш код!
 
После запуска примера в тестере на графике автоматически загружается скрипт SymbolInfoSimple. Для чего это нужно?
 
Надо бы наверно уточнить, что поддерживаются только безындикаторные эксперты на основе MT4Orders.
 
Stanislav Korotky #:
Надо бы наверно уточнить, что поддерживаются только безындикаторные эксперты на основе MT4Orders.

Это указано в описании (тиковый MT4-style). При этом не в мат. режиме в виртуальном окружении индикаторные советники будут тоже работать.

 
hini #:
После запуска примера в тестере на графике автоматически загружается скрипт SymbolInfoSimple. Для чего это нужно?

Алгоритм запуска одиночного прохода при сохранении тиков.

  1. В Тестере каждый OnTick записывается в файл.
  2. После завершения прохода автоматически запускается скрипт RunMe.ex5 в Терминале.
  3. Этот скрипт в тихом режиме запускает исходный советник в Терминале.
  4. Исходный советник прописывает технические данные в свои настройки в Тестере.

Предполагаю, что в п.3. у вас запускается не исходный советник. Нужно смотреть логи.


Такие строки в журнале должны быть после запуска советника в тестере в режиме сохранения тиков.

2025.07.09 23:24:41.184 Scripts script RunMe (EURUSD,M1) loaded successfully
2025.07.09 23:24:41.216 Experts expert EAToMath_Example (EURUSD,M1) loaded successfully
2025.07.09 23:24:41.733 Scripts script RunMe (EURUSD,M1) removed
2025.07.09 23:24:41.918 Experts expert EAToMath_Example (EURUSD,M1) removed
 
FXSABER #:

保存即时报价时启动单次传递的算法。

  1. 在 Tester 中,每个 OnTick 都被写入一个文件。
  2. 段落完成后,RunMe.ex5 脚本会自动在终端中运行。
  3. 此脚本在终端中静默启动原始 Expert Advisor。
  4. 原始 Expert Advisor 在测试程序的设置中规定了技术数据。

我假设在第 3 段中。您没有运行原始的 Expert Advisor。您需要查看日志。


在测试器中以即时报价保存模式启动 Expert Advisor 后,这些行应该在日志中。


После запуска мгновенного котирования результат такой, не вижу указанной вами информации.

 
fxsaber #:

Алгоритм запуска одиночного прохода при сохранении тиков.

  1. В Тестере каждый OnTick записывается в файл.
  2. После завершения прохода автоматически запускается скрипт RunMe.ex5 в Терминале.
  3. Этот скрипт в тихом режиме запускает исходный советник в Терминале.
  4. Исходный советник прописывает технические данные в свои настройки в Тестере.

Предполагаю, что в п.3. у вас запускается не исходный советник. Нужно смотреть логи.


Такие строки в журнале должны быть после запуска советника в тестере в режиме сохранения тиков.

Понял(а), изучу этот вопрос ещё раз.
 
hini #:
Понял(а), изучу этот вопрос ещё раз.

У вас не запускается RunMe.ex5.


1. Вам надо сохранить RunMe.mq5 в ту папку, где находится MTTester.mqh. У меня это так.

Include\fxsaber\MultiTester\RunMe.mq5


Такое требование вызвано этой строкой кода.

#ifdef RUNEX5_SILENT
  #resource "RunMe.ex5" as uchar RunMe[] // https://www.mql5.com/ru/forum/478178/page10#comment_55702486
#endif // #ifdef RUNEX5_SILENT


2. RunMe.mq5 нужно скомпилировать без макроса FAKE.

3. Далее скомпилировать советник-пример для EAToMath. В нем будет такая строка.

EA_Test.mq4
'RunMe.ex5' as 'const uchar RunMe[19560]' 
code generated
0 errors, 0 warnings, 14178 msec elapsed, cpu='X64 Regular'


Если после этого не запускается автоматически RunMe.ex5, то причина в следующем алгоритме запуска.

1. Советник сохраняет RunMe.ex5 по этому пути.

Scripts\MTTester.mqh\RunMe.ex5

Убедитесь в наличие этого файла по данному пути.


2. Далее идет номер поиска этого файла в MQL5-папке через создание списка файлов с расширениями *.ex5 и *.py.

  static int GetEX5FileNames( const string FolderName, string &FileNames[] )
  {
    int Res = 0;

    FIND_DATAW FindData;
    const HANDLE handle = kernel32::FindFirstFileW(FolderName + "\\*", FindData);

    if (handle != INVALID_HANDLE)
    {
      do
      {
        if (FindData.cFileName[0] != '.')
        {
          string Name = FolderName + "\\" + ::ShortArrayToString(FindData.cFileName);

          if ((bool)(FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
            Res += MTTESTER::GetEX5FileNames(Name, FileNames);
          else if (::StringToLower(Name) && (((::StringSubstr(Name, ::StringLen(Name) - 4) == ".ex5") &&
                                             !MTTESTER::IsLibraryOrService(Name)) ||
                                             (::StringSubstr(Name, ::StringLen(Name) - 3) == ".py")))
          {
            FileNames[::ArrayResize(FileNames, ::ArraySize(FileNames) + 1) - 1] = Name;
            Res++;
          }
        }
      }
      while (kernel32::FindNextFileW(handle, FindData));

      kernel32::FindClose(handle);
    }

    return(Res);
  }
  static int GetNumberEX5( const HANDLE TerminalHandle, string FileName )
  {
    int Res = -1;

    const string Path = MTTESTER::GetTerminalDataPath(TerminalHandle);

    if (Path != "")
    {
      MTTESTER::RefreshNumbersEX5(TerminalHandle);

      string FileNames[];

      MTTESTER::GetEX5FileNames(Path + "\\MQL5\\Experts", FileNames);
      MTTESTER::GetEX5FileNames(Path + "\\MQL5\\Indicators", FileNames);
      MTTESTER::GetEX5FileNames(Path + "\\MQL5\\Scripts", FileNames);

      ::StringToLower(FileName);
      const int Len = ::StringLen(Path + "\\MQL5\\");

      for (Res = ::ArraySize(FileNames) - 1; (Res >= 0) && (::StringSubstr(FileNames[Res], Len) != FileName); Res--)
        ;
    }

    return(Res);
  }


3. После чего идет API-запуск c найденным номером.

      const int NumberEX5 = MTTESTER::GetNumberEX5(TerminalHandle, FileName);

      Res = (NumberEX5 >= 0) && !user32::SendMessageW(ChartHandle, user32::RegisterWindowMessageW("MetaTrader5_Internal_Message"), 0x1D, NumberEX5);


Если RunMe.ex5 не запускается, то причина может быть только одна - неправильное вычисление NumberEX5.


Я работаю в Portable-режиме, поэтому, возможно, что-то не учел для других конфигураций установленного терминала.

Возможно, у вас в MQL5-папке есть файлы с расширениями кроме *.ex5 и *.py, которые следовало бы учитывать при поиске NumberEX5.

 
fxsaber #:

Если RunMe.ex5 не запускается

Проверьте, что следующий скрипт запускает соответствующий EX5 (должен существовать).
#include <fxsaber\MultiTester\MTTester.mqh> // https://www.mql5.com/ru/code/26132
  
void OnStart()
{
  Print(MTTESTER::RunEX5("Experts\\Examples\\MACD\\MACD Sample.ex5", 0, false, -1)); // true
}
 
fxsaber #:
Далее скомпилировать советник-пример для EAToMath. В нем будет такая строка.
EA_Test.mq4                     
'RunMe.ex5' as 'const uchar RunMe[32006]'                       0
code generated                  0

На шаге 3 есть RunMe.ex5