mql5语言的特点、微妙之处以及技巧 - 页 229

 

英语(原文):我想提出一个 MQL 语言功能请求。如果这不是正确的主题,请告诉我。原始请求在英语论坛 ...

俄语(Google 翻译):我想申请 MQL 语言功能。 如果这不是正确的主题,请告诉我。 原始请求在英文论坛 ...

 

如何 一行填充数组

struct clr_struct{
   color uncheck;
};
clr_struct clr[];

//clr[0].uncheck=0x999999;
//clr[1].uncheck=0x999999;

clr[].uncheck={0x999999,0x999999};//как правильно?
 
Pavel Kolchin 用 一行填充数组
clr_struct clr[] = {{0x999999}, {0x999999}};
 

还有一个关于访问权限的生活小窍门:如果你有一个不可抗拒的愿望,想让一个类的私有字段/函数的访问权限给另一个类,你可以使用标准的 MQL 工具做以下事情:

我们需要:从 B 访问 A::f1()

//--------- как было
class   A
  {
   int               m;
   int               f1() {return m;}                       // нужно дать к нему доступ классу B
public:
                     A(int a): m(a) {}
  };

class B {};

让我们这样重写:

class A;
class B
  {
private:
   class AB
     {
   public:
      virtual int    CallAf1(A&) const  = 0;
                     AB() {ABptr = &this;}
     } static *ABptr;

   // внутри B используем  этот метод для получения доступа к A::f1()
   static int        CallAf1(A & obj)
     {
      return ABptr.CallAf1(obj);
     }

public:
   class AB2: AB {};

   // вспомогательный метод - только для проверки
   static void       _f1_test(A & obj)
     {
      Print("test ", CallAf1(obj));
     }
  };
B::AB *B::ABptr = NULL;

class   A
  {
   int               m;
   int               f1() {return m;}
public:
                     A(int a): m(a) {}

   //--  добавлено
private:
   class AB3: B::AB2
     {
      int            CallAf1(A &obj) const {return obj.f1();}
     }   static  const     ABlink;
  };
const A::AB3 A::ABlink;

要在 B 中调用 (A)a.f1(),请调用 CallAf1(a)。如果 f1() 有参数,我们将其添加到 CallAf1()。

测试:

void OnStart()
  {
    A f(2);
    B::_f1_test(f);
  }

您可以将 CallAf1() 设置为受保护的,但这会在访问权限方面造成很大的漏洞--您可以在代码的任何地方创建类 B 的后代,并在其中创建一个公共方法来调用 CallAf1() --也就是说,每个人都可以访问 A::f1()。


附注:这种结构非常繁琐(如果您愿意,可以将其塞入宏中),但它比 friend C++ 有一个优点:它不提供对所有类成员 的访问权限,而只提供对选定成员 的访问权限。

 
mktr8591 #:

还有一个关于访问权限的生活小窍门:如果您迫切希望将一个类的私有字段/函数的访问权限授予另一个类,您可以使用标准的 MQL 工具来实现这一目的

我花了很长时间才学会...虚拟化是个好主意,谢谢!
 
fxsaber #:
花了很长时间才进入状态...虚拟化做得不错,谢谢!
我在开头唯一没写的是,你不能再创建任何 B::AB2(及其后代)类的对象,否则一切都会崩溃 :-)
 
在测试器中以所有符号模式运行此智能交易系统
input int inTmp = 0; // https://www.mql5.com/ru/forum/321656/page90#comment_44727856

bool Res = true;

// Проверяет, нормализована ли цена по алгоритму NormalizeDouble.
bool IsNDPrice( const double &Price )
{
  return(Price == NormalizeDouble(Price, 5));
}

// Проверяет, нормализована ли цена, как при парсинге или ручном вводе.
bool IsNDPrice2( const double &Price )
{
  return(Price == (double)DoubleToString(Price, 5));
}

void OnTick()
{
  MqlTick Tick;
  
  if (SymbolInfoTick(_Symbol, Tick))
//    Res &= IsNDPrice(Tick.bid) && IsNDPrice(Tick.ask); // OnTester == 1.
    Res &= IsNDPrice2(Tick.bid) && IsNDPrice2(Tick.ask); // OnTester == 0.
}

double OnTester()
{
  return(Res);
}
显示所有价格都使用 NormalizeDouble 算法进行了归一化处理。如果您使用的价格不是从终端获得的,而是通过解析或手动输入获得的,则需要进行归一化处理才能正确运行。没有必要弄错
 

REASON_ACCOUNT(即使账户没有更改,只是重新登录) 时,Expert Advisor 将完全卸载并加载新的副本。

因此,OnDeinit 中的 ExpertRemove 不会影响新的副本,因为它会触及未加载的副本。

void OnInit() { Print(__FUNCSIG__); }

void OnDeinit( const int ) { Print(__FUNCSIG__); }


重新登录后的结果。

2023.02.07 11:33:12.717 Test5-3 (EURUSD,M1)     void OnDeinit(const int)
2023.02.07 11:33:13.926 Test5-3 (EURUSD,M1)     void OnInit()


退出后,新的 EA 副本等待超过一秒(最长两秒)才能启动。等待时间如此之长的原因是什么?

 

SymbolInfoTick 每次都会返回最新的刻度线。也就是说,不跳过指标的所谓刻度线收集,说得难听点,是有问题的。


证明不可能通过指标收集刻度线(不跳转)。

// Аналог Sleep для индикатора.
void Sleep2( const uint Pause )
{
  const uint StartTime = GetTickCount();
  
  while (!IsStopped() && (GetTickCount() - StartTime) < Pause)
    ;
}

#define  TOSTRING(A) #A + " = " + (string)(A) + " "

int OnCalculate( const int rates_total,
                 const int,
                 const datetime &time[],
                 const double &open[],
                 const double &high[],
                 const double &low[],
                 const double &close[],
                 const long &tick_volume[],
                 const long &volume[],
                 const int &spread[] )
{  
  static const int period = PeriodSeconds();
  
  Sleep2(1000); // Расчеты.
  
  MqlTick Tick[1];
  
  if (SymbolInfoTick(_Symbol, Tick[0]) &&
      ((Tick[0].bid != close[rates_total - 1]) || // Свежий бар не соответсвует последнему тику.
       Tick[0].time / period > time[rates_total - 1] / period))
  {
    ArrayPrint(Tick);
    Print(TOSTRING(time[rates_total - 1]) + TOSTRING(close[rates_total - 1]));
  }

  return(rates_total);
}


结果。

                 [time]   [bid]   [ask] [last] [volume]    [time_msc] [flags] [volume_real]
[0] 2023.02.07 16:28:39 1.54951 1.54959 0.0000        0 1675787319322      98       0.00000
time[rates_total-1] = 2023.02.07 16:28:00 close[rates_total-1] = 1.5495 

                 [time]   [bid]   [ask] [last] [volume]    [time_msc] [flags] [volume_real]
[0] 2023.02.07 16:28:40 1.54948 1.54959 0.0000        0 1675787320719      98       0.00000
time[rates_total-1] = 2023.02.07 16:28:00 close[rates_total-1] = 1.5495 

                 [time]   [bid]   [ask] [last] [volume]    [time_msc] [flags] [volume_real]
[0] 2023.02.07 16:28:41 1.54952 1.54960 0.0000        0 1675787321823     100       0.00000
time[rates_total-1] = 2023.02.07 16:28:00 close[rates_total-1] = 1.54954 

                 [time]   [bid]   [ask] [last] [volume]    [time_msc] [flags] [volume_real]
[0] 2023.02.07 16:28:42 1.54954 1.54961 0.0000        0 1675787322223     102       0.00000
time[rates_total-1] = 2023.02.07 16:28:00 close[rates_total-1] = 1.54951 00000000002 

                 [time]   [bid]   [ask] [last] [volume]    [time_msc] [flags] [volume_real]
[0] 2023.02.07 16:28:43 1.54955 1.54964 0.0000        0 1675787323721     100       0.00000
time[rates_total-1] = 2023.02.07 16:28:00 close[rates_total-1] = 1.54948 

                 [time]   [bid]   [ask] [last] [volume]    [time_msc] [flags] [volume_real]
[0] 2023.02.07 16:28:44 1.54954 1.54962 0.0000        0 1675787324323     100       0.00000
time[rates_total-1] = 2023.02.07 16:28:00 close[rates_total-1] = 1.54952 

                 [time]   [bid]   [ask] [last] [volume]    [time_msc] [flags] [volume_real]
[0] 2023.02.07 16:28:45 1.54956 1.54962 0.0000        0 1675787325421     102       0.00000
time[rates_total-1] = 2023.02.07 16:28:00 close[rates_total-1] = 1.54952
 
可能的 MQL5 语言结构之一。

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

错误、错误、问题

fxsaber, 2023.02.14 13:11

input string inStr = "B2";

class A {};

class B1 : public A {};
class B2 : public A {};
// .....
class B100 : public A {};

void OnStart()
{
  A* a = New2(inStr); // создает объект, который прописан в inStr.
}

// Решение.
template <typename T>
A* New( const string &ClassName ) { return((typename(T) == ClassName) ? new T : NULL); }

typedef A* (*TNew)( const string& );
static const TNew FuncNew[] = {New<B1>, New<B2>, /*....,*/ New<B100>};

A* New2( string ClassName )
{  
  A* Res = NULL;
  
  ClassName = "class " + ClassName;
  
  for (int i = ArraySize(FuncNew) - 1; !Res && (i >= 0); i--)
    Res = FuncNew[i](ClassName);  
    
  return(Res);
}

不幸的是,MQL4 还不能完成这种工作。