Bibliotheken: CDictionary

 

CDictionary:

Eine Implementierung der Datenstruktur eines "Wörterbuchs" (assoziatives Array) in MQL5, basierend auf CArrayObj und CList.

Autor: Enrico Lambino

 
Automated-Trading:

CDictionary Klasse:

Autor: Enrico Lambino

Hallo Enrico,

Sehr gute Arbeit.

Danke!

Shep

 
Shephard Mukachi:

Hallo Enrico,

sehr schöne Arbeit.

Danke!

Shep

Gern geschehen. Ich habe es wie versprochen hochgeladen :)

Du hattest auch recht mit dem Serialisierungsteil. Ich habe die CreateElement()-Methode in CArrayObj übersehen. Es ist nur möglich, Objekte zu speichern und zu laden, wenn man im Voraus weiß, welche Art von Objekten zu speichern und zu laden sind, oder wenn MQ eine neue Funktion einführt, die Strings in generische Typen umwandelt. Aus diesem Grund habe ich keine Save()- und Load()-Methoden in das Programm geladen.

 

Sehr clevere Umsetzung. Gute Arbeit! Ich habe einige Änderungen vorgenommen, um die Arbeit damit (für meine Bedürfnisse) zu erleichtern. Anstatt mehrere Datentypen zu halten, hält diese optimierte Version nur einen, aber erfordert nicht die Angabe des Datentyps beim Aufruf der Get-Methode, und es erfordert auch keine String-Schlüssel-Eingabe, da der Schlüssel ist templated und casts zu String innerhalb der Dictionary-Klasse. Beispiel:


   CDictionary<double> dict;
   for(int i=0;i<Bars;i++)
      dict.Add(Time[i],Close[i]);
   for(int i=0;i<Bars;i++)
      if(dict[Time[i]] != Close[i])
         Print("Collision Error ",++cnt); 
Dateien:
Dictionary.mqh  16 kb
 
nicholishen:

Sehr clevere Umsetzung. Gute Arbeit! Ich habe einige Änderungen vorgenommen, um die Arbeit damit (für meine Bedürfnisse) zu erleichtern. Anstatt mehrere Datentypen zu halten, hält diese optimierte Version nur einen, aber erfordert nicht die Angabe des Datentyps beim Aufruf der Get-Methode, und es erfordert auch keine String-Schlüsseleingabe, da der Schlüssel schablonenhaft ist und innerhalb der Wörterbuchklasse in String umgewandelt wird. Beispiel:


Interessante Version. Vielen Dank für die Mitteilung Ihrer Ideen.

Die früheren Versionen dieser Klasse hatten Dictionary<T>. Aber später habe ich es geändert. Für meine eigenen Bedürfnisse brauchte ich etwas, wo ich verschiedene Datentypen gleichzeitig speichern kann, aber ich kann mir auch einige Anwendungen vorstellen, wo Ihre Version besser für die Aufgabe geeignet ist (und weniger umständlich, da stimme ich zu).

 

Als Ergänzung verwende ich die gleichnamige Klasse von @Vasiliy Sokolov, funktioniert super. Ich habe gerade diese Klasse gesehen, ich lade sie jetzt herunter

https://www.mql5.com/de/articles/1334

Рецепты MQL5 - Реализуем ассоциативный массив или словарь для быстрого доступа к данным
Рецепты MQL5 - Реализуем ассоциативный массив или словарь для быстрого доступа к данным
  • 2015.03.23
  • Vasiliy Sokolov
  • www.mql5.com
Эта статья описывает удобный класс для хранения информации - ассоциативный массив или словарь. Благодаря этому классу можно получать доступ к информации по ее ключу. Ассоциативный массив напоминает обычный массив, однако вместо индекса он использует некий уникальный ключ, например, перечисление ENUM_TIMEFRAMES или какой-либо текст. Что...
 

Sehr gute Arbeit.

Ich verstehe nur nicht den Nutzen der Erweiterung von CArrayObj, da die meisten Dinge, die mit CArrayObj zu tun haben, in CDictionary verboten sind (wie Sort() usw.) und bei falscher Verwendung zu Problemen führen können.
Eigentlich ist CDictionary kein CArrayObj (widerspricht dem Liskov-Prinzip der Vererbung). Es gibt also keine wirkliche Verwendung für das CArrayObj.
Ich würde stattdessen CObject erweitern und m_data[] darin haben.

*-Neue Version von DictionarySingle: Serielle Iteration und Speicherverwaltung hinzugefügt, einige kleinere Umstrukturierungen
Dateien:
 
Amir Yacoby:

Sehr gute Arbeit.

Ich verstehe nur nicht den Nutzen der Erweiterung von CArrayObj, da die meisten Dinge, die mit CArrayObj zu tun haben, in CDictionary verboten sind (wie Sort() usw.) und bei falscher Verwendung zu Problemen führen können.
Eigentlich ist CDictionary kein CArrayObj (widerspricht dem Liskov-Prinzip der Vererbung). Es gibt also keine wirkliche Verwendung für das CArrayObj.
Ich würde stattdessen CObject erweitern und m_data[] darin haben.

Ich nehme an, das ist, weil MQL nicht erlaubt

class SubClass : private SuperClass


Aber kein Grund, das Kind mit dem Bade auszuschütten. Sie könnten einfach ein CArrayObj-Objekt wickeln, anstatt es durch Ableitung zu implementieren.
 
nicholishen:

Ich nehme an, das liegt daran, dass MQL es nicht erlaubt

class SubClass : private SuperClass


Aber kein Grund, das Kind mit dem Bade auszuschütten. Man könnte ein CArrayObj-Objekt einfach einwickeln, anstatt es durch Ableitung zu implementieren.

Wrapping war meine erste Wahl.
Aber dann habe ich bemerkt, dass es nicht so trivial ist, da m_data_max und m_data_total beide in CArrayObj geschützt sind und nur einen Getter haben, und der Algorithmus einen Setter braucht.
Das m_data_max wird auch ein wenig anders in CArrayObj verwendet.

Aber egal,

class SubClass : private SuperClass

ist in MQL5 erlaubt, was eine Lösung sein kann.
Der einzige Grund, den ich sehe, um CArrayObj zu verwenden, ist das Freigeben von Speicher, was ziemlich einfach zu machen ist.
Weil ich nicht sehe, dass CArrayObj sonst nichts verwendet wird.

Es wird meistens als CObject *m_data[] verwendet - und das ist meiner Meinung nach kein ausreichender Grund, es zu erweitern.

 
Amir Yacoby:

Wrapping war meine erste Wahl.
Aber dann habe ich bemerkt, dass es nicht so trivial ist, da m_data_max und m_data_total beide in CArrayObj geschützt sind und nur einen Getter haben, und der Algorithmus braucht einen Setter.
Der m_data_max wird auch ein wenig anders in CArrayObj verwendet.

Aber trotzdem,

ist in MQL5 erlaubt, was eine Lösung sein kann.
Der einzige Grund, den ich sehe, um CArrayObj zu verwenden, ist, um Speicher freizugeben, was ziemlich einfach zu machen ist.
Weil ich nicht sehe, dass CArrayObj sonst nichts verwendet wird.

Es wird meistens als CObject *m_data[] verwendet - und das ist meiner Meinung nach kein ausreichender Grund, es zu erweitern.

Ich schätze Ihre Beiträge. Ich stimme zu. Die Verwendung von CArrayObj ist in diesem Fall eher optional.
Es gibt viele Alternativen. Sie können die Superklasse privat machen, wie Sie gesagt haben, oder direkt von CObject erben (Ihr Beispielcode), oder sich auf halbem Weg treffen: Erweitern Sie CArray anstelle von CArrayObj, damit es sicher gegen versehentlichen Missbrauch ist (es wird keine tatsächliche Sortierung durchgeführt).
Die meisten der benötigten Methoden von CArrayObj sind nicht so schwierig zu re-implementieren. Meine Lösung ist etwas eigenwillig (ich habe mich entschieden, so viel Code wie möglich für diese Klasse wiederzuverwenden).
Sie können den Code nach eigenem Ermessen ändern.

 
aktualisierte DictionarySingle Version - fügte serielle Iteration in der Reihenfolge des Hinzufügens von Objekten hinzu, fügte automatische Speicherverwaltung und ein wenig Refactoring hinzu.
Beispiel für Iteration:
   CDictionary<double> dict;
    datetime time[];
   double close[];
   ulong bars=Bars(_Symbol,_Period);
   ArraySetAsSeries(time,true);
   ArraySetAsSeries(close,true);
   CopyTime(_Symbol,_Period,0,Bars(_Symbol,_Period),time);
   CopyClose(_Symbol,_Period,0,Bars(_Symbol,_Period),close);
   for(int i=0;i<20;i++) //Bars(_Symbol,_Period);i++)
     {
      dict.Add(time[i],close[i]);
      //dict.Add(time[i],close[i]*100);
     }

   //--- vorwärts
   CDictionaryEntry<string> *node=dict.GetFirstNode();
   for(int i=0; node!=NULL; i++)
     {
      printf((string)i+":\t"+node.Value());
      node=dict.GetNextNode();
     }
   //--- rückwärts
   node=dict.GetLastNode();
   for(int i=0; node!=NULL; i++)
     {
      printf((string)i+":\t"+node.Value());
      node=dict.GetPrevNode();
     }
Dateien: