Características del lenguaje mql5, sutilezas y técnicas - página 141

 

Chicos, esto es algo muy útil:

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

Interrumpe la ejecución en caso de error crítico, no se llamará a los destructores (lo siento, pero al menos así). Al menos alguna alternativa en ausencia de análogos y excepciones estándar.

Mensaje de registro:

2019.08.19 21:28:14.364 lrp_last_7 (m_GBPCHF,M1) abortado, file=lrp_last_7.mq5, line=299<br / translate="no">2019.08.19 21:28:14.364 lrp_last_7 (m_GBPCHF,M1) división a cero en 'lrp_last_7.mq5' (299,2)
 
fxsaber:

Es una característica de MT5 tester, pero he decidido publicarla en este hilo, porque está indirectamente relacionada con este tema.

Para llegar a la pestaña de optimización invisible hay que seleccionar fuerza bruta total sin parámetros a optimizar.


oops, me preguntaba cómo obtener este resultado ))

 

¿Las plantillas en los punteros de las funciones no funcionan en términos de sobrecarga del parámetro de retorno?

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

Si es así:

void OnStart()
{
   Func0 f = Select;
}

Tenemos esto:

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

¿Las plantillas en los punteros de las funciones no funcionan en términos de sobrecarga del parámetro de retorno?

¿Funcionan en C++? Hay un tema especial para estas preguntas

 

Foro sobre comercio, sistemas de comercio automatizados y prueba de estrategias de comercio

Bibliotecas: Experto

fxsaber, 2019.09.12 06:17

A diferencia de MT4, MT5 no registra los parámetros de entrada del EA cuando se ejecuta o cambia. Por lo tanto, no hay manera de saber a partir del registro lo que se estaba ejecutando en la Terminal.

Esta función puede remediar esta situación.

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


Aplicando

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

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


Resultado

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


SZZ Por desgracia, no funciona para los guiones. La propia MT4 muestra los parámetros de entrada de los scripts, MT5 no.

 
Los comentarios no relacionados con este tema han sido trasladados a "Cualquier pregunta de los novatos en MQL4 y MQL5, ayuda y discusión sobre algoritmos y códigos".
 

Foro sobre trading, sistemas de trading automatizados y pruebas de estrategias de trading

Probador de Estrategias de MetaTrader 5: errores, fallos, sugerencias de mejora

fxsaber, 2019.09.18 22:32

Obtención de la última configuración de MT5 Tester.

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


Aplicando

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

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


Resultado

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

 

Foro sobre comercio, sistemas de comercio automatizados y prueba de estrategias de comercio

Guiones: Balance Graph HTML

fxsaber, 2019.09.19 09:56

Convertidor de archivos de texto a 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");
}


Permite insertar datos de texto en una fuente

#include <..\Files\Graph.mqh>
 
Características de 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 no funciona en el Probador. La alternativa está abajo.
// Сохраняет ресурс в 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);
}


Aplicación

  ResourceSave(ResourceName, "test.bmp");  
  ResourceSaveBMP(ResourceName, "test2.bmp");
Razón de la queja: