Merkmale der Sprache mql5, Feinheiten und Techniken - Seite 141

 

Leute, das ist eine sehr nützliche Sache:

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

Unterbricht die Ausführung im Falle eines kritischen Fehlers, es werden keine Destruktoren aufgerufen (sorry, aber so geht es wenigstens). Zumindest eine Alternative in Ermangelung von Standardanaloga und Ausnahmen.

Logmeldung:

2019.08.19 21:28:14.364 lrp_last_7 (m_GBPCHF,M1) abort, file=lrp_last_7.mq5, line=299<br / translate="no">2019.08.19 21:28:14.364 lrp_last_7 (m_GBPCHF,M1) zero divide in 'lrp_last_7.mq5' (299,2)
 
fxsaber:

Es handelt sich um eine Funktion des MT5-Testers, aber ich habe beschlossen, sie in diesem Thread zu veröffentlichen, weil sie indirekt mit diesem Thema zusammenhängt.

Um zur unsichtbaren Optimierungs-Registerkarte zu gelangen, sollte man "Full Brute Force" ohne zu optimierende Parameter auswählen.


Ups, ich habe mich gefragt, wie man zu diesem Ergebnis kommt ))

 

Templates in Funktionszeigern funktionieren nicht in Bezug auf das Überladen des Rückgabeparameters?

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

Wenn ja:

void OnStart()
{
   Func0 f = Select;
}

Wir haben das hier:

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

Templates in Funktionszeigern funktionieren nicht in Bezug auf das Überladen des Rückgabeparameters?

Funktionieren sie in C++? Für solche Fragen gibt es ein eigenes Thema

 

Forum zum Thema Handel, automatisierte Handelssysteme und Testen von Handelsstrategien

Bibliotheken: Experte

fxsaber, 2019.09.12 06:17

Im Gegensatz zu MT4 protokolliert MT5 die EA-Eingabeparameter nicht, wenn er ausgeführt oder geändert wird. Daher lässt sich aus dem Protokoll nicht erkennen, was im Terminal ausgeführt wurde.

Diese Funktion kann hier Abhilfe schaffen.

#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);    
}


Die Anwendung

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

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


Ergebnis

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


SZZ Leider funktioniert es nicht für Skripte. MT4 selbst zeigt die Eingabeparameter von Skripten an, MT5 nicht.

 
Kommentare, die sich nicht auf dieses Thema beziehen, wurden nach "Fragen von Neulingen zu MQL4 und MQL5, Hilfe und Diskussion über Algorithmen und Codes" verschoben.
 

Forum zum Thema Handel, automatisierte Handelssysteme und Testen von Handelsstrategien

MetaTrader 5 Strategy Tester: Bugs, Bugs, Verbesserungsvorschläge

fxsaber, 2019.09.18 22:32

Die neuesten Einstellungen des MT5-Testers erhalten.

#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);
}


Die Anwendung

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

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


Ergebnis

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 zum Thema Handel, automatisierte Handelssysteme und Testen von Handelsstrategien

Skripte: Balance Graph HTML

fxsaber, 2019.09.19 09:56

Konverter von Textdateien nach 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");
}


Ermöglicht Ihnen das Einfügen von Textdaten in eine Quelle

#include <..\Files\Graph.mqh>
 
Merkmale von 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 funktioniert nicht im Tester. Die Alternative steht unten.
// Сохраняет ресурс в 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);
}


Anmeldung

  ResourceSave(ResourceName, "test.bmp");  
  ResourceSaveBMP(ResourceName, "test2.bmp");
Grund der Beschwerde: