Особенности языка mql5, тонкости и приёмы работы - страница 141

 

Ребята, очень нужная штука:

#define abort(ANY) do{printf("abort, file=%s,  line=%i", __FILE__, __LINE__); Alert(1/(uint)MathAbs(0));}while(false)

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

В журнале сообщение:

2019.08.19 21:28:14.364    lrp_last_7 (m_GBPCHF,M1)    abort, file=lrp_last_7.mq5,  line=299
2019.08.19 21:28:14.364    lrp_last_7 (m_GBPCHF,M1)    zero divide in 'lrp_last_7.mq5' (299,2)
 
fxsaber:

Особенность MT5-тестера, но решил опубликовать ее в этой ветке, потому что имеется косвенное отношение к сабжу.

Чтобы попасть в невидимую вкладку оптимизации, нужно выбрать полный перебор при отсутствии оптимизируемых параметров.


спс, все голову ломал как получить этот результат ))

 

Шаблоны в указателях функций не работают в части перегрузки возвращаемого параметра?

template<typename Out>
typedef Out (*Func0)(void);

int Select(void)
{
   return 10;
}

void OnStart()
{
   Func0<int> f = Select;
}

:

'<' - unexpected token  TestObj.mq5     24      9
'>' - name expected     TestObj.mq5     24      13

Если так:

void OnStart()
{
   Func0 f = Select;
}

Имеем вот это:

'Select' - cannot resolve function address      TestObj.mq5     15      14
'Select' - type mismatch        TestObj.mq5     15      14
 
Vasiliy Sokolov:

Шаблоны в указателях функций не работают в части перегрузки возвращаемого параметра?

А в C++ работают? Для подобных вопросов есть специальная тема

 

Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий

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

fxsaber, 2019.09.12 06:17

В отличие от MT4, MT5 не выводит в журнал входные параметры советников при его запуске или их изменении. Поэтому по логу невозможно определить, что запускалось в Терминале.

Исправить эту ситуацию может подобная функция.

#include <fxsaber\Expert.mqh> // https://www.mql5.com/ru/code/19003

// Выводит данные запущенного советника
string EAToString( const long Chart_ID = 0 )
{
  string Names[];
  MqlParam Params[];
  
  const int Flag = EXPERT::Parameters(Chart_ID, Params, Names);
  const int Size = ArraySize(Names);
  
  string Str = "Expert " + Params[0].string_value + ", expertmode = " + (string)Flag;
  
  for (int i = 0; i < Size; i++)
    Str += "\n" + Names[i] + " = " + Params[i + 1].string_value;
    
  return(Str);    
}


Применение

input int inInput1 = 1;
input int inInput2 = 2;

int OnInit()
{
  Print(EAToString());
  
  return(INIT_FAILED);
}


Результат

Test8 (EURUSD,M1)       Expert Experts\Test8.ex5, expertmode = 4
Test8 (EURUSD,M1)       inInput1 = 1
Test8 (EURUSD,M1)       inInput2 = 2


ЗЫ К сожалению, для скриптов не работает. MT4 сам выводит входные параметры скриптов, MT5 - нет.

 
Комментарии, не относящиеся к этой теме, были перенесены в "Любые вопросы новичков по MQL4 и MQL5, помощь и обсуждение по алгоритмам и кодам".
 

Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий

Тестер стратегий MetaTrader 5: ошибки, баги, предложения по улучшению работы

fxsaber, 2019.09.18 22:32

Получение последних настроек MT5-Тестера.

#include <WinAPI\fileapi.mqh>
#include <WinAPI\handleapi.mqh>

// Получает имя файла настроек последнего запуска MT5-Тестера.
string GetTesterINIFileName( ulong &Size )
{
  string Str = NULL;
  const string Path = ::TerminalInfoString(TERMINAL_PATH)+ "\\MQL5\\Profiles\\Tester\\";
  
  FIND_DATAW FindData;
  const HANDLE handle = kernel32::FindFirstFileW(Path + "*.ini", FindData);
  
  if (handle != INVALID_HANDLE)
  {     
    ulong MaxTime = 0;
    Size = 0;
    
    do
    {
      const ulong TempTime = ((ulong)FindData.ftLastWriteTime.dwHighDateTime << 32) + FindData.ftLastWriteTime.dwLowDateTime;
      
      if (TempTime > MaxTime)
      {
        MaxTime = TempTime;
        
        Str = ::ShortArrayToString(FindData.cFileName);
        Size = ((ulong)FindData.nFileSizeHigh << 32) + FindData.nFileSizeLow;;
      }      
    }
    while (kernel32::FindNextFileW(handle, FindData));    
    
    kernel32::FindClose(handle);
  }
  
  return((Str == NULL) ? NULL : Path + Str);   
}

#define GENERIC_READ  0x80000000
#define SHARE_READ    1
#define OPEN_EXISTING 3

// Получает настройки последнего запуска MT5-Тестера.
string GetTesterINI( void )
{
  string Str = NULL;
  
  ulong Size;
  const string FileName = GetTesterINIFileName(Size);
  
  if (FileName != NULL)
  {
    const HANDLE handle = kernel32::CreateFileW(FileName, GENERIC_READ, SHARE_READ, 0, OPEN_EXISTING, 0, 0);
    
    if (handle != INVALID_HANDLE)
    {
      uint Read;
      ushort Buffer[];
      
      ::ArrayResize(Buffer, (int)Size / sizeof(ushort));
            
      if (kernel32::ReadFile(handle, Buffer, (int)Size, Read, 0))      
        Str = ::ShortArrayToString(Buffer);
      
      kernel32::CloseHandle(handle);        
    }
  }
  
  return(Str);
}


Применение

// Советник при запуске одиночного прогона возвращает свои настройки.
input int inInput1 = 1;
input int inInput2 = 2;

int OnInit()
{
  if (MQLInfoInteger(MQL_TESTER) && !MQLInfoInteger(MQL_OPTIMIZATION))
    Print(GetTesterINI());
  
  return(INIT_FAILED);
}


Результат

2019.04.01 00:00:00   ;Одиночный тест советника: Test9, EURUSD M1, цены открытия, 2019.04.01 - 2019.09.18
2019.04.01 00:00:00   [Tester]
2019.04.01 00:00:00   Expert=Test9.ex5
2019.04.01 00:00:00   Symbol=EURUSD
2019.04.01 00:00:00   Period=M1
2019.04.01 00:00:00   Optimization=0
2019.04.01 00:00:00   Model=2
2019.04.01 00:00:00   FromDate=2019.04.01
2019.04.01 00:00:00   ToDate=2019.09.18
2019.04.01 00:00:00   ForwardMode=0
2019.04.01 00:00:00   Deposit=10000
2019.04.01 00:00:00   Currency=EUR
2019.04.01 00:00:00   ProfitInPips=1
2019.04.01 00:00:00   Leverage=100
2019.04.01 00:00:00   ExecutionMode=0
2019.04.01 00:00:00   OptimizationCriterion=6
2019.04.01 00:00:00   Visual=0
2019.04.01 00:00:00   [TesterInputs]
2019.04.01 00:00:00   inInput1=123||1||1||10||N
2019.04.01 00:00:00   inInput2=2||2||1||20||N

 

Forum on trading, automated trading systems and testing trading strategies

Scripts: Balance Graph HTML

fxsaber, 2019.09.19 09:56

Конвертер текстовых файлов в MQH.

void ChangeString( string &Str )
{
  StringReplace(Str, "\\", "\\\\");
  StringReplace(Str, "\"", "\\\"");
  
  Str = "\"" + Str + "\\r\\n\" + " + "\n";
  
  return;
}

bool TextFileToMQH( const string FileNameIn, const string FileNameOut )
{
  const int handleIn = FileOpen(FileNameIn, FILE_READ | FILE_TXT | FILE_ANSI);
  bool Res = (handleIn != INVALID_HANDLE);

  if (Res)  
  {
    const int handleOut = FileOpen(FileNameOut, FILE_WRITE | FILE_TXT | FILE_ANSI);
    
    if (Res = (handleOut != INVALID_HANDLE))
    {
      FileWriteString(handleOut, "string StrMQH = \n");
      
      while (!FileIsEnding(handleIn))
      {
        string Str = FileReadString(handleIn);
  
        ChangeString(Str);
        FileWriteString(handleOut, Str);
      }

      FileWriteString(handleOut, "NULL;\n");
  
      FileClose(handleOut);            
    }
    
    FileClose(handleIn);
  }
  
  return(Res);
}

void OnStart()
{
  TextFileToMQH("Graph.txt", "Graph.mqh");
}


Позволяет вставлять текстовые данные в исходник

#include <..\Files\Graph.mqh>
 
Особенности ResourceSave
const string ResourceNameFull = ObjectGetString(0, Name, OBJPROP_BMPFILE);
ResourceSave(ResourceNameFull, "test.bmp"); // false

const string ResourceNameShort = StringSubstr(ResourceNameFull, StringFind(ResourceNameFull, "::"));
ResourceSave(ResourceNameShort, "test.bmp"); // true
 
ResourceSave не работает в Тестере. Альтернатива ниже.
// Сохраняет ресурс в BMP-формате.
bool ResourceSaveBMP( const string ResourceName, const string FileName )
{
  struct BMPFILEHEADER
  {
    short Type;
    uint   Size;
    short Reserved1;
    short Reserved2;
    uint   OffBits;
  };
  
  struct BMPINFOHEADER
  {    
    uint   Size;
    uint   Width;
    uint   Height;
    short Planes;
    short BitCount;
    int   Compression;
    uint   SizeImage;
    int   XPelsPerMeter;
    int   YPelsPerMeter;
    int   ClrUsed;
    int   ClrImportant;
    
    void Set( void )
    {
      this.Size = sizeof(this);
      this.Planes = 1;
      this.BitCount = 32;
      this.SizeImage = this.Width * this.Height * (this.BitCount >> 3);
      
      return;      
    }
  };
  
  struct BMPHEADER
  {
    BMPFILEHEADER File;
    BMPINFOHEADER Info;
    
    void Set( void )
    {
      this.Info.Set();

      this.File.Type = 19778;
      this.File.OffBits = sizeof(this);
      this.File.Size = this.Info.SizeImage + this.File.OffBits;
      
      return;
    }
  } BMPHeader = {0};
  
  uint Data[];  
  bool Res = ResourceReadImage(ResourceName, Data, BMPHeader.Info.Width, BMPHeader.Info.Height);
  
  if (Res)
  {
    const int handle = FileOpen(FileName, FILE_WRITE | FILE_BIN);
    
    if (Res = (handle != INVALID_HANDLE))
    {      
      BMPHeader.Set();

      uint Picture[];
      
      const uint Size = ArrayResize(Picture, ArraySize(Data));
      
      for (uint i = 0; i < Size; i += BMPHeader.Info.Width)
        ArrayCopy(Picture, Data, i, Size - i - BMPHeader.Info.Width, BMPHeader.Info.Width);
              
      FileWriteStruct(handle, BMPHeader);
      FileWriteArray(handle, Picture);
      
      FileClose(handle);
    }
  }
  
  return(Res);
}


Применение

  ResourceSave(ResourceName, "test.bmp");  
  ResourceSaveBMP(ResourceName, "test2.bmp");