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<br / translate="no">2019.08.19 21:28:14.364 lrp_last_7 (m_GBPCHF,M1) 在'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++中工作吗?有一个专门的专题 来讨论此类问题

 

关于交易、自动交易系统和测试交易策略的论坛

图书馆:专家

fxsaber, 2019.09.12 06:17

与MT4不同的是,MT5在运行或改变EA时不会记录其输入参数。因此,没有办法从日志中看出终端中运行的是什么。

这个功能可以补救这种情况。

#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则不显示。

 
 

关于交易、自动交易系统和交易策略测试的论坛

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

 

关于交易、自动交易系统和测试交易策略的论坛

脚本:平衡图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
 
资源保存 在测试器中不起作用。下面是备选方案。
// Сохраняет ресурс в 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");