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

 
レナト・ファットフーリン

HistorySelect(puts access range in tester) と、実際に特定のチケットを検索してキャッシュする HistoryDealSelect(ticket) を比較することはできません。

それを理解した上で、Clear-variantはすぐに作られたのです。クリアとフルを同時に比較できるようにすること。

 
fxsaber
この方法では、(特にテスターでの)履歴は補足されるだけで、古い記録は変更されない。クリアのバリエーションということです。


リアルでは、注文が一部約定して何度か売買が発生しても、完全に埋まるかキャンセルされるまで履歴に残らないようです。つまり、歴史の凍結というルールが守られるのです。

もし、チェックなしでソフトを書いたら、とっくにすべてが崩壊していたでしょう。

金融ソフトは「手抜き」モードでは書けません。あるところで切って、また別のところで切って、そうすると開発者はハードチェックを省略する権利を信じるようになり、失敗は必至です。

テスターではまだチェックを減らすことができますが、実際のEAでは、あなたのEAの動作と同時に、市場全体の環境が常に変化する中で、多くの非同期プロセスが動作しています。MQL5の呼び出しの間に何かが保存されるなんてことは考えられません。

 
レナト・ファットフーリン

もし、チェックなしでソフトを書いたら、とっくにすべてが崩壊していたでしょう。

金融ソフトは「手抜き」モードでは書けません。あるところで切って、また別のところで切って、そうすると開発者はハードチェックを省略する権利を信じるようになり、失敗は必至です。

テスターではまだチェックを緩めることができますが、現実の世界ではEAの動作と並行して、常に市場全体の環境を変化させる非同期のプロセスがたくさん動いています。MQL5の呼び出しの間に何かが保存されると思うと怖いですね。

分かりやすい説明ありがとうございましたテスターで少しは引き締まるといいのですが。

 
fxsaber:

このような理解から、「クリア」バリエーションはすぐに作られました。だから、クリアとフルを同時に比較することができるのです。

テスト対象を誤解している。これは決してClear variantではなく、元々記載されているHistorySelectの 参照とは関係がない。

あなたのフルバリアントは、本質的にダブルコール(チケットルックアップ)を意味し、そのうちの1つはキャッシュにトレードを選択し、2番目はキャッシュされた結果にアクセスします。特定のタスクにおいて、トレードが存在することが分かっている場合、最初のセレクトコールは冗長となる。Getメソッドは、影響を受けるレコードを暗黙のうちにキャッシュする。



そのため、詳細なラストエラーコードを内部で公開し(GetLastError()呼び出しで)、開発者が失敗の根本的な理由を把握できるようにする必要があります。通常、このようなチェックは、プラットフォームの奥深くにある呼び出しごとに数回行われます。
 
レナト・ファットフーリン

テスト対象を誤解している。決してClearオプションではありませんし、元々記載されているHistorySelectの参照とは関係がありません。

気づいていないようです。

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

汎用クラスライブラリ - バグ、説明、問題、使用例、提案

fxsaber さん 2017.12.08 22:46

  BENCH(HistorySelect(0, INT_MAX));
  BENCH(Print(SumProfit(Deals, GetDealProfitClear))); // Реализация с предварительно загруженной историей
それとも、違うことを話しているのでしょうか。
 
fxsaber

気づいてないようですが。

それとも、違うことを話しているのでしょうか。

気づいたこと

プリロードされた履歴とは?テスターの HistorySelectは偽物で、クエリで指定した履歴を全てキャッシュに転送するのではなく、既存の取引データベースの中から位置をマークするだけだと指摘しました。したがって、コストはゼロである。

GetDealProfitClearでは、HistoryDealGetDouble(Deal,DEAL_PROFIT)を使って、誤解されているGetDealProfitFullメソッドと同じ場所に正確にリクエストを行い、その物理的本質が全く同じである2つのメソッドを使用しています。

return(HistoryDealSelect(Deal) ? HistoryDealGetDouble(Deal, DEAL_PROFIT) : 0)

つまり、テスターでの履歴へのアクセスは非常に最適化されており、Expert Advisor以外では誰も取引履歴を変更できない(チェックも残っている)ことに本当に重点を置いているのです。

実際の端末ではすべてが異なり、HistorySelectは高価です。

 
レナト・ファットフーリン

なるほど、そういうことだったんですね。詳しい説明ありがとうございましたどうなるんでしょうね。

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

Generic クラスライブラリ - エラー、説明、質問、使用上の特殊性、提案

レナート・ファットフーリン さん 2017.12.08 23:19

私たちのコードを見ました。トレード ベースへの呼び出しを最適化することは可能です。来週のリリースまでに実装するようにします。

そして、ジェネリックの話題はとても便利ですが興味深く見守っていきたいと思います。
 

CHashMapの 実装を確認
素直に気に入りました。

//+------------------------------------------------------------------+
//| Class CHashMap<TKey, TValue>.                                    |
//| Usage: Represents a collection of keys and values.               |
//+------------------------------------------------------------------+
template<typename TKey,typename TValue>
class CHashMap: public IMap<TKey,TValue>
  {
protected:
   int               m_buckets[];                        
   Entry<TKey,TValue>m_entries[];
   int               m_count;
   int               m_free_list;
   int               m_free_count;
   IEqualityComparer<TKey>*m_comparer;
   bool              m_delete_comparer;

public:
                     CHashMap(void);
                     CHashMap(const int capacity);
                     CHashMap(IEqualityComparer<TKey>*comparer);
                     CHashMap(const int capacity,IEqualityComparer<TKey>*comparer);
                     CHashMap(IMap<TKey,TValue>*map);
                     CHashMap(IMap<TKey,TValue>*map,IEqualityComparer<TKey>*comparer);
                    ~CHashMap(void);
   //--- methods of filling data 
   bool              Add(CKeyValuePair<TKey,TValue>*pair);
   bool              Add(TKey key,TValue value);
   //--- methods of access to protected data
   int               Count(void)                                       { return(m_count-m_free_count); }
   IEqualityComparer<TKey>*Comparer(void)                        const { return(m_comparer);           }
   bool              Contains(CKeyValuePair<TKey,TValue>*item);
   bool              Contains(TKey key,TValue value);
   bool              ContainsKey(TKey key);
   bool              ContainsValue(TValue value);
   //--- methods of copy data from collection   
   int               CopyTo(CKeyValuePair<TKey,TValue>*&dst_array[],const int dst_start=0);
   int               CopyTo(TKey &dst_keys[],TValue &dst_values[],const int dst_start=0);
   //--- methods of cleaning and deleting
   void              Clear(void);
   bool              Remove(CKeyValuePair<TKey,TValue>*item);
   bool              Remove(TKey key);
   //--- method of access to the data
   bool              TryGetValue(TKey key,TValue &value);
   bool              TrySetValue(TKey key,TValue value);

private:
   void              Initialize(const int capacity);
   void              Resize(int new_size,bool new_hash_codes);
   int               FindEntry(TKey key);
   bool              Insert(TKey key,TValue value,const bool add);
  };


改善可能な提案もいくつかあります。

1) 私の率直な意見ですが、この実装は、初期サイズ3と、ハッシュテーブルを再構築する際の後続の容量の選択が、かなり正しくありません。
そうですね、分布の均一化のために素数を選ぶというのは正しいです。
しかし、CPrimeGeneratorの実装は期待に沿うものではなく、素数の抜けがある。
このような「ジェネレータ」の目的は明確で、素数の自動生成で1.2桁の増加率を提供することである。
しかし、これでは係数が小さすぎるのでは?C++でベクトルを扱う場合、この係数はライブラリにもよりますが、通常1.5〜2.0です(演算の平均的な複雑さに強く影響するため)。
この場合、定数係数の後、素数リストの2進法検索で素数に丸めるという 方法が考えられます。
それに初期サイズが3というのは小さすぎる、前世紀に生きているわけではないのだから。

2) 現在、ハッシュテーブルの再構築(Resize)は、容量が100%になったとき(m_entries[]がすべて埋まったとき)にのみ行われています。
このため、あまり均等に配置されていない鍵の衝突が多発する可能性があります。
オプションとして、ハッシュテーブルの再構築を行うために必要な上限を100%削減するフィルファクターの導入を検討する。

 
fxsaber

そして、あなたの場合、どのくらい返ってくるのか、というクラシックバージョン。

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の実行時間です。

なんだか、私の例を変に理解しているようですね。MetaTraderの標準的な機能と何かを比較する目的はありません。あくまでも、自分のユーザーレベルで、何でもかんでも連想してサンプリングする効率的なアルゴリズムをアレンジするということです。案件番号と注文番号の関連付けの例は、HistoryDealGetInteger(Deal, DEAL_ORDER) というシステムがあるため、実用的価値の低い例と考えるべきでしょう。

 
fxsaber

さて、ここで注目の2つの指標を比較してみましょう。HashMapのアクセスは開発者の4倍速いことが判明しました。でも、開発者はすでに履歴を含めて持っているわけで...。

同じ理由で、この比較も正しくありません。カスタムCHashMapとシステム機能との連携で取引環境を手に入れることを比較すると?