Merkmale der Sprache mql5, Feinheiten und Techniken - Seite 54

 

Merkmale der vererbten Strukturen

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

Wenn Sie wissen wollen, ob das "Unbegrenzt"-Flag in Einstellungen --> Diagramme --> Maximale Balken im Fenster aktiviert ist, verwenden Sie diese Konstruktion:

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

Wenn ich nicht möchte, dass eine öffentliche Methode aufleuchtet (wenn ich zum Beispiel einen Punkt nach dem Objektnamen eingebe), mache ich diese Methode zu einem öffentlichen Operator. Es ist jedoch nicht immer möglich, eine solche Krücke zu benutzen.

 
fxsaber:

Wenn ich nicht möchte, dass eine öffentliche Methode aufleuchtet (wenn ich zum Beispiel einen Punkt nach dem Objektnamen eingebe), mache ich diese Methode zu einem öffentlichen Operator. Allerdings ist es nicht immer möglich, eine solche Krücke zu benutzen.

Gibt es ein Beispiel im Code? Ich bitte Sie.

 
Artyom Trishkin:

Gibt es ein Beispiel im Code? Ich bitte Sie.

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()
}
 

Forum zum Thema Handel, automatisierte Handelssysteme und Testen von Handelsstrategien

Eigenheiten der mql5-Sprache, Feinheiten und Tricks

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()
}

Ist das nicht

class A
{
 private:
 void AddCalculate(void) const
  {
   Print(__FUNCSIG__);
  }
 public:
 int GetValue(void) const
  {
   this.AddCalculate();
   return(0);
  }
 
};
Ist das nicht das Gleiche?


 
Alexey Viktorov:

Und dies.

Ist das nicht das Gleiche?

Nein, natürlich nicht. Die Felder Wert1, Wert2, ... sind viele; GetValue1() und GetValue2() sind dasselbe. Es ist nicht sinnvoll, bei jedem GetValue zusätzliche Berechnungen durchzuführen. Es macht keinen Sinn, Berechnungen auch nur in einem mehrfach aufgerufenen GetValue durchzuführen.

 

Ich konnte nicht herausfinden, wie man die Größe eines Array-Feldes einer einfachen Struktur festlegen kann. Also habe ich diese Krücke gebaut.

// Простая структура - не имеет сложных объектов
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());
}


Ich habe Makros verwendet, um es kurz zu machen. In MQL5 gibt es wahrscheinlich keine andere Möglichkeit. Ist dies eine normale Lösung in C++? Wie Vorlage <typesize S>.

 

Forum zum Thema Handel, automatisierte Handelssysteme und Strategietests

Bibliotheken: MT4Orders

fxsaber, 2017.09.14 08:52

Der SL/TP-Trigger wurde bereits vor den MQL5 Reason-Flags im Forum veröffentlicht. Seine Logik zeigte deutlich, dass, wenn SL/TP/SO-Niveaus einer offenen Position vom Handelsserver akzeptiert werden, ein entsprechender Marktauftrag generiert wird, der in der MT5-Tabelle der offenen Aufträge steht, bis er ausgeführt wird.


Daher ist im MT5 selbst bei reinem MQL5 die Änderung/Löschung solcher Aufträge nicht möglich, und die Handelslogik im MT5 erfordert die Überprüfung, ob ein offener Auftrag tatsächlich eingefroren ist oder nicht.


// Триггер 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.");    
  }
}


...Wir können sehen, dass der TP-Auftrag mehr als eine Viertelsekunde lang zwischen den offenen Aufträgen hing. Jeder Versuch, sie zu ändern oder zu löschen, hätte zu Fehlern geführt.

Seien Sie sich dieser Funktion des MT5 bewusst.

 
fxsaber:

Wenn ich nicht möchte, dass eine öffentliche Methode aufleuchtet (wenn ich zum Beispiel einen Punkt nach dem Objektnamen eingebe), mache ich diese Methode zu einem öffentlichen Operator. Allerdings ist es nicht immer möglich, eine solche Krücke zu benutzen.

Eigentlich ist es eine Art Mega-Krücke. Wie wollen Sie später Ihren Code analysieren, der so uninformative Operatoren enthält, dass Sie nicht verstehen, was sie tun?

Das muss ein Konstruktionsfehler sein. Wenn eine Klasse zunächst nicht von außen verändert werden soll, sondern nur Get-Methoden enthält, sollte sie gleich bleiben. Alle Änderungen werden über die von ihr geerbten Klassen durchgeführt.

Eine weitere praktische Variante wäre die geschützte Vererbung, bei der die Basisklasse alle Methoden enthält und die geerbte Klasse nur die Get-Methoden anzeigt. Und bei Bedarf können Sie sie auf die Basisklasse übertragen. Aber Metaeditor hat den Fehler immer noch nicht behoben, alle diese Methoden werden in die Liste aufgenommen, auch wenn sie nicht verfügbar sind.

Es ist nicht sinnvoll, für jeden GetValue zusätzliche Berechnungen durchzuführen. Selbst bei einem mehrmaligen Aufruf von GetValue sind die Berechnungen nutzlos.

Was hindert Sie also daran, die Methode Recalculate() zu verwenden? Wenn das der Grund ist, warum die Klasse logisch funktioniert, weil die Klasse selbst nicht definieren kann, wann eine Neuberechnung notwendig ist, bedeutet das, dass die Klasse von einem Benutzer gesteuert wird.