Diskussion zum Artikel "Bibliothek für ein leichtes und schnelles Entwickeln vom Programmen für den MetaTrader (Teil I). Konzept, Datenverwaltung und erste Ergebnisse" - Seite 4

 
fxsaber:

Vielen Dank, es ist klar erklärt. Aber immer noch gibt es eine Frage - es ist klar, dass es schneller in MT4 ist, aber wenn wir über 5 sprechen - ist es schneller, alle Methoden separat auszuführen, als eine CopyRates aufrufen? Wenn ja, dann macht es Sinn, anstelle von MQLRates eine Balkenstruktur/Klasse zu erstellen, die nicht alle Felder, sondern nur die in unserem Fall notwendigen, z.B. per Maske, schreiben würde.

 
alex_all:

Vielen Dank, es ist klar erklärt. Aber immer noch gibt es eine Frage - es ist klar, dass es schneller in MT4 ist, aber wenn wir über 5 sprechen - ist es schneller, alle Methoden separat auszuführen, als eine CopyRates aufrufen? Wenn ja, macht es Sinn, anstelle von MQLRates eine eigene Balkenstruktur/Klasse zu erstellen, die nicht alle Felder, sondern nur die in unserem Fall notwendigen, z.B. per Maske, schreiben würde.

Versuchen Sie dies.

 
Keine Aktualisierung?
 
soldadoraso21:
Willst du nicht aktualisieren?

Не понял вопроса.

Ich verstehe die Frage nicht.

 

Da es sich um eine in Entwicklung befindliche Bibliothek handelt, werde ich weitere Artikel abwarten, bevor ich eine globale Bemerkung mache.

Allerdings sind mir in diesem ersten Teil 2 potentielle Problemfälle aufgefallen:

Erstens.

Sometimes, you may want to get the number of decimal places in a symbol lot. Let's enter this function to our file of service functions:

//+------------------------------------------------------------------+
//| Rückgabe der Anzahl der Nachkommastellen in einer Symbolmenge |
//+------------------------------------------------------------------+
uint DigitsLots(conststring symbol_name) 
  { 
   return (int)ceil(fabs(log(SymbolInfoDouble(symbol_name,SYMBOL_VOLUME_STEP))/log(10)));
  }

1.a Die vorgeschlagene Lösung mit log ist nicht universell. Bei einigen Symbolen kann man durchaus einen Volumenschritt von z.B. 0,25 haben und die Funktion DigitsLots() wird in diesem Fall eine falsche Antwort liefern.

1.b Warum wollen Sie die "Anzahl der Dezimalstellen in einem Symbol-Lot"? Ich sehe keinen wirklichen Anwendungsfall dafür.

1.c Wenn Sie wirklich die log-Funktion verwenden wollen und sich mit Sonderfällen an anderer Stelle befassen, sollten Sie log10 anstelle des natürlichen Logarithmus verwenden.

return (int)ceil(fabs(log10(SymbolInfoDouble(symbol_name,SYMBOL_VOLUME_STEP))));

1.d Die Bereitstellung einer solchen Funktion in der öffentlichen Schnittstelle könnte zu ineffizienten Ergebnissen führen, da sie 5 Funktionsaufrufe verwendet und bei jedem Tick mehrmals aufgerufen werden könnte.


Zweitens.

intOnInit()
  {
//---
   list_all_orders.Sort();
   list_all_orders.Clear();
   if(!HistorySelect(0,TimeCurrent()))
     {
      Print(DFUN,TextByLanguage(": Не удалось получить историю сделок и ордеров",": Failed to get history of deals and orders"));
      returnINIT_FAILED;
     }
   ...

2.a Dies ist kein korrekter Weg, um HistorySelect() aufzurufen, da man einige historische Informationen verpassen könnte, da TimeCurrent() das letzte bekannte Tickdatum vom Broker-Server zurückgibt. Argumentation von hier und aus Erfahrung.

2.b Es ist ein schlechtes Beispiel, TimeCurrent() in der OnInit()-Funktion zu verwenden, wenn man keine Garantie hat, dass eine Broker-Verbindung besteht. Im Allgemeinen ist es eine schlechte Idee, Daten in OnInit() abzufragen.

 

Danke für die Kommentare, aber dies ist nur ein Test.

  1. Ich werde die Möglichkeit in Betracht ziehen, die Funktion in eine andere - völlig universelle - zu ändern
  2. die Anzahl der Nachkommastellen für das Lot jedes einzelnen Symbols ist für die eindeutige Übermittlung von Handelsaufträgen notwendig
  3. Ihre Funktion mit log10 hat kein von Ihnen geäußertes Problem mit einem Lotschritt von 0,25?
  4. Die Angaben über die Anzahl der Nachkommastellen werden einmalig in das Objekt der Klasse Symbol geschrieben. Dies wird - in späteren Artikeln - weiter ausgeführt.

Eine Prüfung in OnInit () ist nur zur Kontrolle nötig. Und nur dort erhalte ich auf diese Weise die Historie der Orders. In Sammlungen von Aufträgen, Geschäften und Positionen - sonst.

All dies in späteren Artikeln.

-------------

Спасибо за комментарии, но это всего лишь тест.

  1. я рассмотрю возможность изменения функции на иную - полностью универсальную
  2. количество знаков после запятой для лота каждого отдельного символа нужно для безошибочной отправки торговых приказов
  3. ваша функция с log10 не имеет озвученной вами проблемы с шагом лота 0.25 ?
  4. данные о количестве знаков после запятой записываются единожды в объект класса-символ. Это будет далеее - в последующих статьях

Тестовая проверка в OnInit() нужна всего лишь именно для проверки. И только там историю ордеров получаю таким образом. В коллекциях ордеров, сделок и позиций - иначе.

Всё это в последующих статьях.
 
Artyom Trishkin:

Danke für die Kommentare, aber dies ist nur ein Test.

  1. Ich werde die Möglichkeit in Betracht ziehen, die Funktion in eine andere - völlig universelle - zu ändern
  2. die Anzahl der Nachkommastellen für das Lot jedes einzelnen Symbols ist für die eindeutige Übermittlung von Handelsaufträgen notwendig
  3. Ihre Funktion mit log10 hat kein von Ihnen geäußertes Problem mit einem Lotschritt von 0,25?
  4. Die Angaben über die Anzahl der Nachkommastellen werden einmalig in das Objekt der Klasse Symbol geschrieben. Dies wird - in späteren Artikeln - weiter ausgeführt.

Eine Prüfung in OnInit () ist nur zur Kontrolle nötig. Und nur dort erhalte ich auf diese Weise die Historie der Orders. In Sammlungen von Aufträgen, Geschäften und Positionen - sonst.

All dies in späteren Artikeln.


1. Gut.

2. Es ist nicht notwendig, wenn Sie Ihr Lot richtig normalisieren, etwa wie :

 double lotStep=SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_STEP);
 lots=MathRound(lots/lotStep)*lotStep;

Die Verwendung von Losziffern kann nur zu Problemen führen.

3. log10 hat das gleiche Problem, es ist nicht universell. Es war nur, um den nutzlosen Aufruf von log(10) zu vermeiden.

4. Gut.

Ich weiß, dass es nur zur Überprüfung ist, aber selbst wenn der Testcode öffentlich zugänglich ist, denke ich, dass wir eine Verantwortung haben, gute Praktiken zu zeigen und zu verwenden.

Ich werde andere Artikel lesen.

 
Alain Verleyen:

1. Gut.

2. Es ist nicht erforderlich, wenn Sie Ihre Partie richtig normalisieren, etwa so:

Die Verwendung von Losziffern kann nur zu Problemen führen.

3. log10 hat das gleiche Problem, es ist nicht universell. Es ging nur darum, den nutzlosen Aufruf von log(10) zu vermeiden.

4. Gut.

Ich weiß, dass es nur zur Überprüfung ist, aber selbst wenn der Testcode öffentlich zugänglich ist, denke ich, dass wir eine Verantwortung haben, gute Praktiken zu zeigen und anzuwenden.

Ich werde andere Artikel lesen.

GUT. Danke
 

Hallo

Sie können mich sozusagen als Ihren Einsteiger oder Studenten betrachten.

Ich habe beschlossen, Ihre Bibliothek zu studieren, aber es ist schwierig für mich, obwohl ich etwas in MQL wissen, aber ich stolperte auf den ersten Schritt.

Ich kam zu dem Punkt Implementierung der Methode des Vergleichs von zwei Aufträgen mit einander durch eine bestimmte Eigenschaft:

//+------------------------------------------------------------------+
//|| Vergleicht COrder-Objekte miteinander auf alle möglichen Eigenschaften.
//+------------------------------------------------------------------+
int COrder::Compare(const CObject *node,const int mode=0) const
  {
   const COrder *order_compared=node;
//--- Vergleich der ganzzahligen Eigenschaften von zwei Ordnungen
   if(mode<ORDER_PROP_INTEGER_TOTAL)
     {
      long value_compared=order_compared.GetProperty((ENUM_ORDER_PROP_INTEGER)mode);
      long value_current=this.GetProperty((ENUM_ORDER_PROP_INTEGER)mode);
      return(value_current>value_compared ? 1 : value_current<value_compared ? -1 : 0);
     }
//--- Vergleich der realen Eigenschaften von zwei Ordnungen
   else if(mode<ORDER_PROP_DOUBLE_TOTAL+ORDER_PROP_INTEGER_TOTAL)
     {
      double value_compared=order_compared.GetProperty((ENUM_ORDER_PROP_DOUBLE)mode);
      double value_current=this.GetProperty((ENUM_ORDER_PROP_DOUBLE)mode);
      return(value_current>value_compared ? 1 : value_current<value_compared ? -1 : 0);
     }
//--- Vergleich der Zeichenketteneigenschaften von zwei Aufträgen
   else if(mode<ORDER_PROP_DOUBLE_TOTAL+ORDER_PROP_INTEGER_TOTAL+ORDER_PROP_STRING_TOTAL)
     {
      string value_compared=order_compared.GetProperty((ENUM_ORDER_PROP_STRING)mode);
      string value_current=this.GetProperty((ENUM_ORDER_PROP_STRING)mode);
      return(value_current>value_compared ? 1 : value_current<value_compared ? -1 : 0);
     }
   return 0;
  }
//+------------------------------------------------------------------+

Dies ist der Code in der Bibliothek, wo ich ihn schreiben muss

nach

   //--- Vergleicht COrder-Objekte anhand aller möglichen Eigenschaften miteinander
   virtual int       Compare(const CObject *node,const int mode=0) const;

oder in der geschützten Klasse der abstrakten Ordnung.

protected:
   //--- Geschützter parametrischer Konstruktor
                     COrder(ENUM_ORDER_STATUS order_status,const ulong ticket);
                     
   //--- Ruft die ganzzahligen Eigenschaften des ausgewählten Auftrags ab und gibt sie aus seinen Parametern zurück
   long              OrderMagicNumber(void)        const;
   long              OrderTicket(void)             const;
   long              OrderTicketFrom(void)         const;
   long              OrderTicketTo(void)           const;
   long              OrderPositionID(void)         const;
   long              OrderPositionByID(void)       const;
   long              OrderOpenTimeMSC(void)        const;
   long              OrderCloseTimeMSC(void)       const;
   long              OrderType(void)               const;
   long              OrderTypeByDirection(void)    const;
   long              OrderTypeFilling(void)        const;
   long              OrderTypeTime(void)           const;
   long              OrderReason(void)             const;
   long              DealOrder(void)               const;
   long              DealEntry(void)               const;
   bool              OrderCloseByStopLoss(void)    const;
   bool              OrderCloseByTakeProfit(void)  const;
   datetime          OrderOpenTime(void)           const;
   datetime          OrderCloseTime(void)          const;
   datetime          OrderExpiration(void)         const;
   datetime          PositionTimeUpdate(void)      const;
   datetime          PositionTimeUpdateMSC(void)   const;
   
   //--- Ruft die realen Eigenschaften des ausgewählten Auftrags ab und gibt sie anhand seiner Parameter zurück: (1) Eröffnungskurs, (2) Schlusskurs, (3) Gewinn,
   //--- (4) Kommission, (5) Swap, (6) Volumen, (7) ausstehendes Volumen (8) StopLoss-Preis, (9) TakeProfit-Preis (10) StopLimit-Ordersetzungspreis
   double            OrderOpenPrice(void)          const;
   double            OrderClosePrice(void)         const;
   double            OrderProfit(void)             const;
   double            OrderCommission(void)         const;
   double            OrderSwap(void)               const;
   double            OrderVolume(void)             const;
   double            OrderVolumeCurrent(void)      const;
   double            OrderStopLoss(void)           const;
   double            OrderTakeProfit(void)         const;
   double            OrderPriceStopLimit(void)     const;
   
   //--- Abrufen und Zurückgeben von String-Eigenschaften des ausgewählten Auftrags aus seinen Parametern: (1) Symbol, (2) Kommentar, (3) Börsenkennzeichen
   string            OrderSymbol(void)             const;
   string            OrderComment(void)            const;
   string            OrderExternalID(void)         const;
   
public:
   //--- Gibt die (1) Integer-, (2) Real- und (3) String-Eigenschaft der Bestellung aus dem Property-Array zurück
   long              GetProperty(ENUM_ORDER_PROP_INTEGER property)      const { return m_long_prop[property];                    }
   double            GetProperty(ENUM_ORDER_PROP_DOUBLE property)       const { return m_double_prop[this.IndexProp(property)];  }
   string            GetProperty(ENUM_ORDER_PROP_STRING property)       const { return m_string_prop[this.IndexProp(property)];  }
   
   //--- Gibt das Kennzeichen zurück, dass der Auftrag die angegebene Eigenschaft beibehält
   virtual bool      SupportProperty(ENUM_ORDER_PROP_INTEGER property)        { return true; }
   virtual bool      SupportProperty(ENUM_ORDER_PROP_DOUBLE property)         { return true; }
   virtual bool      SupportProperty(ENUM_ORDER_PROP_STRING property)         { return true; }

Bitte haben Sie Verständnis dafür, dass ich nicht mehr jung bin, junge Leute können das im Handumdrehen begreifen.

Und auch ich habe ein Thema auf dem Forum in Artikel und technische Bibliothek auf automatisierten Handel (12560) Ich bin ein Student dort werde ich dieses Thema duplizieren Ich möchte eine Antwort von Ihnen im Detail über die Struktur,

arbeiten Schritt für Schritt nach dem Artikel . Sie können falsch sein und nicht verstehen.

Форум трейдеров - MQL5.community: Статьи и техническая библиотека по автоматическому трейдингу
Форум трейдеров - MQL5.community: Статьи и техническая библиотека по автоматическому трейдингу
  • www.mql5.com
Обсуждение статей по трейдингу и примеров на языках MQL4/MQL5
 
Vladimir Andreev:

Hallo

Sie können mich sozusagen als Ihren Bewerber oder Studenten betrachten.

Ich habe beschlossen, Ihre Bibliothek zu studieren, aber es ist schwierig für mich, obwohl ich etwas in MQL wissen, aber ich stolperte beim ersten Schritt.

Ich habe den Punkt Verwirklichung der Methode des Vergleichs von zwei Aufträgen mit einander durch eine bestimmte Eigenschaft erreicht :

Dies ist der Code in der Bibliothek, wo ich ihn schreiben muss

nach

oder in der geschützten Klasse des abstrakten Befehls

Bitte haben Sie Verständnis dafür, dass ich nicht mehr jung bin, aber junge Leute können das im Handumdrehen begreifen.

Und auch ich eröffnete ein Thema auf dem Forum in Artikel und technische Bibliothek auf automatisierten Handel (12560) Ich bin ein Student dort werde ich dieses Thema zu duplizieren Ich möchte eine detaillierte Antwort von Ihnen über die Struktur,

arbeiten Schritt für Schritt nach dem Artikel . Sie können falsch sein und nicht verstehen.

Es gibt zwei Möglichkeiten, eine Klassenmethode zu erstellen - direkt im Klassenkörper:

class CMyClass
  {
   bool Flag(void) { return false; }
  }

und außerhalb des Klassenkörpers:

class CMyClass
  {
   bool Flag(void);
  }
//--- Methode außerhalb des Klassenkörpers implementiert
bool CMyClass::Flag(void) { return false; }

Im ersten Fall wird die Methode direkt im Klassenkörper definiert und implementiert - das ist praktisch für kurze Methoden, die nicht viele Zeilen beanspruchen. Wenn die Methode jedoch umfangreich ist, ist es bequemer, sie im Klassenkörper zu deklarieren und die Implementierung außerhalb des Klassenkörpers zu platzieren - wie im zweiten Beispiel.

Es ist klar, dass es bequemer ist, die Methode innerhalb des Klassenkörpers zu schreiben. Aber die Methode, nach der Sie fragen, sollte besser getrennt vom Klassenkörper geschrieben werden.

Sie können jedoch alle Dateien, die dem Artikel beigefügt sind, herunterladen - sie enthalten bereits alles, sie sind einsatzbereit - und sie verwenden, um zu studieren, was in dem Artikel beschrieben wird.