Generische Klassenbibliothek - Bugs, Beschreibung, Fragen, Nutzungsmöglichkeiten und Vorschläge - Seite 11

 

Das letzte Beispiel für heute und anscheinend auch für diese Woche: die Übereinstimmung zwischen der Geschäftsnummer und der Auftragsnummer, die das Geschäft ausgelöst hat:

//+------------------------------------------------------------------+
//|                                                     OrdersID.mq5 |
//|                        Copyright 2017, MetaQuotes Software Corp. |
//|                                              http://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2017, MetaQuotes Software Corp."
#property link      "http://www.mql5.com"
#property version   "1.00"
#include <Generic\HashMap.mqh>
input ulong FindTicketOrder = 82479995;
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
{
   ulong tiks = GetMicrosecondCount();
   HistorySelect(0, TimeCurrent());
   CHashMap<ulong, ulong> deals_orders;
   int total = HistoryDealsTotal();
   ulong deal_id = 0;
   for(int i = 0; i < total; i++)
   {
      deal_id = HistoryDealGetTicket(i);
      ulong order_id = HistoryDealGetInteger(deal_id, DEAL_ORDER);
      deals_orders.Add(deal_id, order_id);
   }
   ulong t2 = GetMicrosecondCount()-tiks;
   printf("Время заполнения коллекции: " + (string)t2 + " микросекунд");
   tiks = GetMicrosecondCount();
   ulong find_order = 0;
   if(deals_orders.TryGetValue(deal_id, find_order))
      printf("Сделке с номером " + (string)deal_id + " Соответствует ордер с номером " + (string)find_order);
   ulong delay = GetMicrosecondCount() - tiks;
   printf("Время выполнения запроса: " + (string)delay + " микросекунд");
}

In meinem Fall, in dem mehr als 10.000 Geschäfte auf dem Konto sind, sieht das Ergebnis wie folgt aus:

2017.12.08 17:56:05.184 OrdersID (SBRF Splice,M1)       Время заполнения коллекции: 145865 микросекунд
2017.12.08 17:56:05.184 OrdersID (SBRF Splice,M1)       Сделке с номером 44455231 Соответствует ордер с номером 83473421
2017.12.08 17:56:05.184 OrdersID (SBRF Splice,M1)       Время выполнения запроса: 9 микросекунд
 

Forum zum Thema Handel, automatisierte Handelssysteme und Testen von Handelsstrategien

Generische Klassenbibliothek - Bugs, Beschreibung, Fragen, Besonderheiten der Nutzung und Vorschläge

Vasiliy Sokolov, 2017.12.08 13:30

Wenn N sehr klein ist, normalisieren wir einfach die von der Hash-Funktion erhaltene Zahl, so dass sie immer in der N-Grenze liegen würde:

int index = GetHashCode(word)%ArraySize(m_array);

Ich habe bis zu diesem Punkt gelesen. Vasily, danke, alles ist klar, außer dem hervorgehobenen Punkt. Meiner Meinung nach ist es falsch, den Rückstand als Normalisierung zu betrachten. Es scheint logischer zu sein

int index = GetHashCode(word) * ArraySize(m_array) / HashSize; // Надо бы и округлять, а не отбрасывать нецелочисленную часть, но не стал усложнять
 
Vasiliy Sokolov:

Das ist das Problem: Der Umfang des Wörterbuchs ist oft unbekannt. Ein einfaches Beispiel: Nehmen wir an, wir haben einen Berater, der handelt. Sie verfolgt die ausgeführten Geschäfte. Wenn ein Handel in der Historie erscheint, müssen wir diesen Handel mit dem Medjack des Expert Advisors verbinden. Hierfür ist es logisch, das Wörterbuch zu verwenden. Dabei wird die Handelsnummer als Schlüssel (eindeutiger Bezeichner) und die magische Zahl des Expert Advisors als Wert verwendet. Das Problem ist, dass wir beim Start des EA nicht im Voraus bestimmen können, ob wir 100, 1000 oder gar keine Trades haben werden. Unabhängig davon, wie viel Speicher Sie vorher zuweisen, wird es entweder zu wenig oder zu viel sein.

Ich habe mir offensichtlich noch nicht den Kopf zerbrochen. Könnten Sie erklären, was zugewiesen wird? Ich verstehe das überhaupt nicht.

 

Es sieht aus wie eine Verhöhnung.

//+------------------------------------------------------------------+
//| Returns a hashcode for boolean.                                  |
//+------------------------------------------------------------------+
int GetHashCode(const bool value)
  {
   return((value)?true:false);
  }


HashFunction.mqh ohne ein Inlude. Das ist nicht richtig.


Wozu ist diese Funktion gut?

template<typename T>
int GetHashCode(T value)
  {
//--- try to convert to equality comparable object  
   IEqualityComparable<T>*equtable=dynamic_cast<IEqualityComparable<T>*>(value);
   if(equtable)
     {
      //--- calculate hash by specied method   
      return equtable.HashCode();
     }
   else
     {
      //--- calculate hash from name of object
      return GetHashCode(typename(value));
     }
  }
Schließlich wird es nicht nur für struct und union kompiliert.
 
fxsaber:

Ich glaube, ich habe mein Gehirn noch nicht ganz geknackt. Könnten Sie das Hervorgehobene erläutern? Ich verstehe das überhaupt nicht.

Ich persönlich habe es so verstanden, dass der EA beim Abschluss von Geschäften die Nummer einer Magie in das Wörterbuch (Array) mit der Nummer des Geschäfts schreiben soll, was in diesem Fall ein Zellindex ist.

Die Anzahl der zukünftigen Abschlüsse ist nicht im Voraus bekannt, und wir sollten bereits ein Array für das Schreiben der Majors deklariert haben. Die Aufgabe besteht darin, die erforderliche Menge an Speicher für das Array im Voraus zuzuweisen.

Es ist unmöglich, die genaue Menge an Speicher im Voraus zuzuweisen. Wir könnten also einen String mit Strings schreiben, die Anzahl der Teilstrings ermitteln, das Array initialisieren und alle Teilstrings (Waben) dort hineinschreiben.

Dann wird jeder medjack über die Handelsnummer aufgerufen.

So ungefähr sehe ich das auch.

 
Vasiliy Sokolov:

Das letzte Beispiel für heute und anscheinend auch für diese Woche: die Übereinstimmung zwischen der Geschäftsnummer und der Auftragsnummer, die das Geschäft ausgelöst hat:

In meinem Fall mit mehr als 10.000 Geschäften auf meinem Konto sieht das Ergebnis wie folgt aus:

Wie viel bringt die klassische Version in Ihrem Fall ein?

ulong GetDealOrder( const ulong Deal )
{
  return(HistoryDealSelect(Deal) ? HistoryDealGetInteger(Deal, DEAL_ORDER) : 0);
}


2017.12.08 17:56:05.184 OrdersID (SBRF Splice,M1)       Время выполнения запроса: 9 микросекунд
Dies ist die Ausführungszeit von printf.
 
fxsaber:

Wozu ist diese Funktion gut?

Wird nicht nur für struct und union kompiliert.

Eine weitere Überlast hinzugefügt

template<typename T>
int GetHashCode(T &value)
  {
    return GetHashCode(typename(value));
  }


Zusammengestoßen mit.

//+------------------------------------------------------------------+
//| Returns a hashcode for string.                                   |
//+------------------------------------------------------------------+
int GetHashCode(const string value)
  {
   int len=StringLen(value);
   int hash=0;
//--- check length of string
   if(len>0)
     {
      //--- calculate a hash as a fucntion of each char
      for(int i=0; i<len; i++)
         hash=31*hash+value[i];
     }
   return(hash);
  }
Gibt negative Zahlen zurück, was logisch aus einem solchen Code folgt. Ist das in Ordnung?
 
fxsaber:

Eine weitere Überlast hinzugefügt

template<typename T>
int GetHashCode(T &value)
  {
    return GetHashCode(typename(value));
  }

Wenn ein Objekt eine Schnittstelle oder eine Methode nicht implementiert, ist es meines Erachtens besser, explizit eine Ausnahme zu erzeugen, als es zu verschweigen und dann ohne Umschweife nach der Ursache des Problems zu suchen.


Er gibt negative Zahlen zurück, was logisch aus einem solchen Code folgt. Ist das in Ordnung?

Völlig normal.
Ein Hash garantiert Ihnen nichts, er ist nur eine Zahl, die dieses oder jenes Objekt in gewissem Maße charakterisiert.
Wenn Sie eine Ganzzahl benötigen, verwenden Sie uint.

 
Sergey Dzyublik:

Wenn ein Objekt eine Schnittstelle oder eine Methode nicht implementiert, ist es für mich besser, explizit eine Ausnahme zu erzeugen, als zu schweigen und dann für eine unbekannte Zeit nach der Ursache des Problems zu suchen.

MqlTick?

 
fxsaber:

MqlTick?


Verstehen Sie, was der Code tut, wenn es keine explizite Implementierung derGetHashCode-Template-Funktionsspezialisierung für den Typ T gibt?
template<typename T>
int GetHashCode(T &value)
  {
    return GetHashCode(typename(value));
  }
Antwort: Es ist erbärmlich, weil es den Mangel an Umsetzung beschönigt. Alle Objekte der gleichen Klasse geben den gleichen Hash-Wert zurück.
Grund der Beschwerde: