Bibliothèque de classes génériques - bogues, description, questions, caractéristiques d'utilisation et suggestions - page 11

 

Dernier exemple pour aujourd'hui et apparemment pour cette semaine : la correspondance entre le numéro de la transaction et le numéro de l'ordre qui l'a initiée :

//+------------------------------------------------------------------+
//|                                                     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 + " микросекунд");
}

Dans mon cas, où il y a plus de 10 000 transactions sur le compte, le résultat est le suivant :

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 sur le trading, les systèmes de trading automatisé et les tests de stratégies de trading

Bibliothèque de classes génériques - bugs, description, questions, particularités d'utilisation et suggestions

Vasiliy Sokolov, 2017.12.08 13:30

Si N est très petit, il suffit de normaliser le nombre obtenu par la fonction de hachage, afin qu'il soit toujours dans la limite de N :

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

que j'ai lu jusqu'à présent. Vasily, merci, tout est clair, sauf pour la partie surlignée. À mon avis, prendre le résidu comme une normalisation est une erreur. Il semble plus logique

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

C'est là le problème : la taille du dictionnaire est souvent inconnue. Un exemple simple, disons que nous avons un conseiller qui négocie. Il assure le suivi des transactions effectuées. Lorsqu'une transaction apparaît dans l'historique, nous devons connecter cette transaction avec le Medjack du conseiller expert. Pour cela, il est logique d'utiliser le dictionnaire. Le numéro de transaction est utilisé comme clé (identifiant unique), et le numéro magique du conseiller expert est utilisé comme valeur. Le problème est qu'au début de l'EA, nous ne pouvons pas déterminer à l'avance si nous aurons 100 transactions, 1000 ou aucune transaction. Quelle que soit la quantité de mémoire que vous allouez au préalable, elle sera toujours insuffisante ou excessive.

Je n'ai manifestement pas encore réfléchi à la question. Pouvez-vous expliquer ce qui est alloué ? Je ne le comprends pas du tout.

 

Ça ressemble à une moquerie.

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


HashFunction.mqh sans inlude. Ce n'est pas bien.


Quelle est l'utilité de cette fonction ?

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));
     }
  }
Après tout, il ne compilera pas seulement pour struct et union.
 
fxsaber:

Je suppose que je n'ai pas complètement craqué mon cerveau. Pourriez-vous préciser ce qui est mis en évidence ? Je ne le comprends pas du tout.

Personnellement, j'ai compris que cela signifie que lorsque des transactions sont effectuées, l'EA doit écrire le numéro d'une magik dans le dictionnaire (tableau) par le numéro de la transaction, qui dans ce cas est un indice de cellule.

Le nombre de transactions futures n'est pas connu à l'avance, et nous devrions déjà avoir un tableau déclaré pour écrire les majors. La tâche consiste à allouer à l'avance la quantité nécessaire de mémoire pour le tableau.

Il est impossible d'allouer la quantité exacte de mémoire à l'avance. Ainsi, nous pourrions écrire une chaîne avec des chaînes, obtenir le nombre de sous-chaînes, initialiser le tableau et y écrire toutes les sous-chaînes (nids d'abeille).

Ensuite, chaque medjack sera accessible par son numéro de métier.

C'est à peu près comme ça que je vois les choses.

 
Vasiliy Sokolov:

Dernier exemple pour aujourd'hui et apparemment pour cette semaine : la correspondance entre le numéro de la transaction et le numéro de l'ordre qui l'a initiée :

Dans mon cas, où il y a plus de 10 000 transactions sur mon compte, le résultat est le suivant :

Combien la version classique rapporte-t-elle dans votre cas ?

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 микросекунд
C'est le temps d'exécution de printf.
 
fxsaber:

Quelle est l'utilité de cette fonction ?

Ne compile pas seulement pour les structures et les unions.

Ajout d'une autre surcharge

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


Bumped into.

//+------------------------------------------------------------------+
//| 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);
  }
Renvoie des nombres négatifs, ce qui découle logiquement de ce code. C'est bon ?
 
fxsaber:

Ajout d'une autre surcharge

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

Il me semble que si un objet n'implémente pas une interface ou une méthode, il est préférable de générer explicitement une exception plutôt que de ne rien dire et de chercher ensuite la source du problème en toute clarté.


Il renvoie des nombres négatifs, ce qui découle logiquement d'un tel code. C'est bon ?

Tout à fait normal.
Le hachage ne vous garantit rien, c'est juste un nombre qui caractérise dans une certaine mesure tel ou tel objet.
Si vous avez besoin d'un nombre entier, utilisez uint.

 
Sergey Dzyublik:

En ce qui me concerne, si un objet n'implémente pas une interface ou une méthode, il vaut mieux générer explicitement une exception que de garder le silence et de chercher ensuite la source du problème pendant un temps inconnu.

MqlTick?

 
fxsaber:

MqlTick?


Comprenez-vous ce que fait le code s'il n'y a pas d'implémentation explicite de la spécialisation de la fonction templateGetHashCode pour le type T ?
template<typename T>
int GetHashCode(T &value)
  {
    return GetHashCode(typename(value));
  }
Réponse : c'est pathétique parce que cela dissimule le manque de mise en œuvre. Tous les objets de la même classe renverront la même valeur de hachage.