汎用クラスライブラリ - バグ、説明、質問、使用上の特徴、提案 - ページ 11

 

今日と今週の最後の例は、取引番号とその取引を開始した注文番号の対応です。

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

口座内の取引件数が1万件以上ある私の場合、結果は以下のようになります。

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 микросекунд
 

トレーディング、自動売買システム、トレーディング戦略のテストに関するフォーラム

汎用クラスライブラリ - バグ、説明、質問、使用上の特殊性、提案

ヴァシリー・ソコロフ さん 2017.12.08 13:30

Nが非常に小さい場合は、ハッシュ関数が得る数を単純に正規化し、常にNの極限になるようにする。

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

これまで読んできたのは、この辺りまで。Vasily、ありがとう、ハイライトされたものを除いて、すべてが明確です。私の考えでは、残滓を正規化するのは間違っています。より論理的であると思われる

int index = GetHashCode(word) * ArraySize(m_array) / HashSize; // Надо бы и округлять, а не отбрасывать нецелочисленную часть, но не стал усложнять
 
ワシリー・ソコロフ

それは、辞書のサイズが不明であることが多いということです。簡単な例ですが、アドバイザーが取引をしているとします。実行された取引を追跡します。履歴に取引が表示されたら、この取引とExpert AdvisorのMedjackを紐づける必要があります。そのためには、辞書を使うのが筋である。こ こで、取引番号はキー(一意の識別子)として使用され、Expert Advisorのマジックナンバーは値として使用されます。問題は、EAの開始時に、100回取引するのか、1000回取引するのか、それとも取引しないのか、事前に決定できないことです。事前にいくらメモリを確保しても、少なすぎるか多すぎるかのどちらかです。

明らかにまだ頭を働かせていない。何が割り当てられているのか説明してください。まったく理解できない。

 

あざとく見える。

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


HashFunction.mqhはinludeなし。こんなのおかしいよ。


この機能は何に使うのですか?

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));
     }
  }
結局、構造体やユニオンだけではコンパイルされないのです。
 
fxsaber

完全に脳みそが割れていないんでしょうね。ハイライトされた部分を明確にしてください。まったく理解できない。

個人的には、トレードが行われたときに、EAが辞書(配列)にマジックの番号(この場合はセルインデックス)を書き込むという意味だと理解しました。

将来の取引数は事前に分からないので、メジャーを書くための配列は すでに宣言して あるはずです。課題は、あらかじめ配列に必要な量のメモリを確保することです。

あらかじめ正確な量のメモリを割り当てることは不可能です。つまり、文字列で文字列を書き、部分文字列の数を取得し、配列を初期化し、そこにすべての部分文字列(ハニカム)を書き込むことができるのです。

そして、各メダルジャックは、取引番号でアクセスすることになります。

だいたいそんな感じです。

 
Vasiliy Sokolov:

今日と今週の最後の例は、取引番号とその取引を開始した注文番号の対応です。

私の場合、アカウントに10,000以上の取引がある場合、結果は以下のようになります。

あなたの場合、クラシック版のリターンはどれくらいですか?

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 микросекунд
これはprintfの 実行時間です。
 
fxsaber

この機能は何に使うのですか?

構造体やユニオンのコンパイルだけではありません。

別のオーバーロードを追加

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


ぶつかる。

//+------------------------------------------------------------------+
//| 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);
  }
このようなコードから論理的に導かれる負の数を返します。大丈夫でしょうか?
 
fxsaber

別のオーバーロードを追加

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

オブジェクトがあるインターフェースやメソッドを実装していない場合、黙っているよりも明示的に例外を発生させてから、問題の原因を明確に探した方が良いように思います。


負の数を返すので、このようなコードから論理的に導かれる。大丈夫でしょうか?

絶対に普通です。
ハッシュは何かを保証するものではなく、このオブジェクト、このオブジェクトをある程度特徴づける数字に過ぎません。
整数が必要な場合は、uintを使用します。

 
セルゲイ・デジュブリク

私としては、あるオブジェクトが何らかのインターフェースやメソッドを実装していない場合、黙っておいて未知の時間をかけて問題の原因を探すよりも、明示的に例外を発生させた方が良いと考えています。

MqlTick?

 
fxsaber

MqlTick?


T型のGetHashCode テンプレート関数の特殊化の明示的な実装が ない場合、コードがどうなるのか理解できていますか?
template<typename T>
int GetHashCode(T &value)
  {
    return GetHashCode(typename(value));
  }
答え:実装されていないことをごまかすから情けないんだよ。同じクラスのオブジェクトはすべて同じハッシュ値を返します。