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

 

继承结构的特点

struct A
{
private: 
  int i;
};

struct B : public A
{
  int i; // A::i в private, поэтому никакого пересечения по именам
};

void OnStart()
{
  A a;
  B b;
  
  Print(sizeof(a)); // 4
  Print(sizeof(b)); // 8 - при любом наследовании размер только увеличивается
  
  // Кастинг в обе стороны без union
  a = b;
  b = a;
}
 

如果你想知道在设置-->图表-->最大条数窗口中 是否启用了 "无限 "标志,请使用这个结构

   int max_bars=TerminalInfoInteger(TERMINAL_MAXBARS);
   if(max_bars<1 e7)
     {
      Print("Макс.баров в окне должно быть Unlimited!");
      return false;
     }
 

当我不希望一个公共方法亮起来的时候(比如在对象名称后面输入一个点的时候),我把这个方法变成一个公共运算符。然而,并不总是能够使用这样的拐杖。

 
fxsaber:

当我不希望一个公共方法亮起来的时候(比如在对象名称后面输入一个点的时候),我把这个方法变成一个公共运算符。然而,并不总是能够使用这样的拐杖。

代码中是否有一个例子?请。

 
阿尔乔姆-特里什金

代码中是否有一个例子?请。

struct A
{
private:  
  int Value;
  
public:
  int GetValue( void ) const
  {
    return(this.Value);
  }
};

struct B : public A
{
private:
  // Делает доп. расчеты
  void AddCalculate( void )
  {
    Print(__FUNCSIG__);
  }
  
public:
  // Так "спрятали" метод доп. расчетов
  void operator ~( void )
  {
    this.AddCalculate();
  }
};

void OnStart()
{
  A a;
  B b;
  
  b = a; // После присвоения требуется вызвать доп. расчеты.
  
  ~b;    // Провели доп. расчеты
  
  b.GetValue(); // После точки попрежнему виден только GetValue()
}
 

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

mql5语言的特殊性、微妙性和技巧性

fxsaber, 2017.09.08 13:20

struct A
{
private:  
  int Value;
  
public:
  int GetValue( void ) const
  {
    return(this.Value);
  }
};

struct B : public A
{
private:
  // Делает доп. расчеты
  void AddCalculate( void )
  {
    Print(__FUNCSIG__);
  }
  
public:
  // Так "спрятали" метод доп. расчетов
  void operator ~( void )
  {
    this.AddCalculate();
  }
};

void OnStart()
{
  A a;
  B b;
  
  b = a; // После присвоения требуется вызвать доп. расчеты.
  
  ~b;    // Провели доп. расчеты
  
  b.GetValue(); // После точки попрежнему виден только GetValue()
}

这不就是

class A
{
 private:
 void AddCalculate(void) const
  {
   Print(__FUNCSIG__);
  }
 public:
 int GetValue(void) const
  {
   this.AddCalculate();
   return(0);
  }
 
};
这不是同样的事情吗?


 
阿列克谢-维克多罗夫

还有这个。

这不是同样的事情吗?

不,当然不是。字段Value1,Value2,......。是很多的;GetValue1()和GetValue2()是相同的。在每次GetValue时进行额外的计算是不合理的。即使在一个GetValue中多次调用,进行计算也没有意义。

 

我想不出如何能够设置一个简单结构 的数组字段的大小。所以我做了这个拐杖。

// Простая структура - не имеет сложных объектов
template <typename T>
struct STRING // : public T
{
  int i;
  uchar Array[sizeof(T) - sizeof(int)];

  void operator =( const string Str )
  {
    StringToCharArray(Str, this.Array);    
  }
  
  template <typename T1>
  void operator =( const T1 &Str )
  {
    ArrayCopy(this.Array, Str.Array);
  }
  
  string ToString( void ) const
  {
    return(CharArrayToString(this.Array));
  }

// много методов, работающих с this.Array и this.i
// ....

};

#define  SET_STRING(SIZE) \
  struct STRUCT##SIZE    \
  {                      \
    uchar Array[SIZE];   \
  };                     \
                         \
  STRING<STRUCT##SIZE>

void OnStart()
{  
  SET_STRING(20) Str[1];  // Массив "строк", каждая длиной 20 байтов
  SET_STRING(50) Str2[2]; // Массив "строк", каждая длиной 50 байтов
  
  Str[0] = "Hello World!";
  Str2[0] = Str[0];
  
  Print(sizeof(Str));
  Print(sizeof(Str2));
  
  Print(Str[0].ToString());
  Print(Str2[0].ToString());
}


简而言之,我使用了宏程序。在MQL5中,可能没有其他方法。这在C++中是一个正常的解决方案吗?像模板<typesize S>。

 

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

图书馆: MT4Orders

fxsaber, 2017.09.14 08:52

甚至在MQL5 Reason旗帜之前,SL/TP触发器就已经 在论坛上发布了。它的逻辑清楚地表明,当一个未结头寸 的SL/TP/SO水平被交易服务器接受时,相应的市场订单就会产生,并在MT5的未结订单表中,直到它执行为止。


因此,在MT5中,即使在纯粹的MQL5上,也不可能修改/删除这些订单,MT5的交易逻辑需要检查未结订单是否真的被冻结。


// Триггер SL/TP/SO
void OnTradeTransaction ( const MqlTradeTransaction &Trans, const MqlTradeRequest &Request, const MqlTradeResult &Result )
{ 
  if ((Trans.type == TRADE_TRANSACTION_ORDER_ADD) && OrderSelect(Trans.order))
  {
    const ENUM_ORDER_REASON Reason = (ENUM_ORDER_REASON)OrderGetInteger(ORDER_REASON);
    
    if (Reason == ORDER_REASON_TP)
      Print("Position #" + (string)Trans.position + " - triggered TP.");    
    else if (Reason == ORDER_REASON_SL)
      Print("Position #" + (string)Trans.position + " - triggered SL.");    
    else if (Reason == ORDER_REASON_SO)
      Print("Position #" + (string)Trans.position + " - triggered StopOut.");    
  }
}


...我们可以看到,在超过四分之一秒的时间里,TP订单被挂在开放的订单中。任何修改/删除的尝试都会引起错误。

要注意MT5的这个特点。

 
fxsaber:

当我不希望一个公共方法亮起来的时候(比如在对象名称后面输入一个点的时候),我把这个方法变成一个公共运算符。然而,并不总是能够使用这样的拐杖。

事实上,它是某种巨大的拐杖。以后你将如何解析你的代码,包含这种不知所云的运算符?

这一定是一个设计 错误。如果一个类最初不打算从外部改变,而只包含Get-methods,它应该是一样的。所有的修改都是通过从它继承的类来进行的。

另一个方便的变体是受保护的继承,当基类包含所有的方法,而继承类只显示获取方法。当需要时,你可以把它投给基类。但Metaeditor仍然没有修复这个错误,所有这些方法都会被甩到列表中,即使它们不可用。

对每个GetValue进行额外计算是不合理的。即使一个GetValue被调用一次以上,也不需要进行计算。

那么是什么阻止了你使用Recalculate()方法呢?如果这就是使类在逻辑上工作的原因,因为类本身不能定义什么时候需要重新计算,这意味着类是由用户控制的。