汎用クラスライブラリ - バグ、説明、質問、使用上の特徴、提案 - ページ 12 1...5678910111213141516171819...38 新しいコメント fxsaber 2017.12.08 21:29 #111 セルゲイ・デジュブリク T型に対するGetHashCode 関数の明示的な実装がない場合、コードがどうなるか理解できていますか? 答え:実装が足りないという問題が黙殺されてしまうので、興ざめです。同じクラスのオブジェクトはすべて同じハッシュ値を返します。実装(ボディ)は関係あるのか!これを追加しました。int GetHashCode(T & value)ボールから本体を挿入しました。 Sergey Dzyublik 2017.12.08 21:33 #112 fxsaber実装(ボディ)は関係あるのか!これを追加しました。ボディを一から入れました。ハエについて言われ(そんなことしたらダメだよ、コードで将来病気になるよと)、カツについて語られる。 よし、腹ごしらえだ。 fxsaber 2017.12.08 21:46 #113 提案するソリューションの速度特性を見ることにした。テスター用Expert Advisor#include <MT4Orders.mqh> #include <Generic\HashMap.mqh> CHashMap<ulong, double> DealsProfit; // Создаем историю из Amount сделок в тестере void CreateHistory( const int Amount, const double Lots = 0.1 ) { MqlTick Tick; if (SymbolInfoTick(_Symbol, Tick) && Tick.ask && Tick.bid) for (int i = (Amount >> 1) - 1; i >= 0; i--) OrderClose(OrderSend(_Symbol, OP_BUY, Lots, Tick.ask, 0, 0, 0), Lots, Tick.bid, 0); } // Заполняем массив случайно выбранными сделками void GetDeals( const int Amount, const int MaxDealTicket, ulong &Deals[] ) { for (int i = ArrayResize(Deals, Amount) - 1; i >= 0; i--) Deals[i] = MathRand() * MaxDealTicket / SHORT_MAX; } // Заполнили HashMap void SetHashMap() { if (HistorySelect(0, INT_MAX)) for (int i = HistoryDealsTotal() - 1; i >= 0; i--) { const ulong DealTicket = HistoryDealGetTicket(i); DealsProfit.Add(DealTicket, HistoryDealGetDouble(DealTicket, DEAL_PROFIT)); } } double GetDealProfitHashClear( const ulong Deal ) { static double Profit = 0; return(DealsProfit.TryGetValue(Deal, Profit) ? Profit : 0); } double GetDealProfitFull( const ulong Deal ) { return(HistoryDealSelect(Deal) ? HistoryDealGetDouble(Deal, DEAL_PROFIT) : 0); } double GetDealProfitClear( const ulong Deal ) { return(HistoryDealGetDouble(Deal, DEAL_PROFIT)); } typedef double (*GetDealProfit)( const ulong ); // Находим суммарный профит сделок из массива double SumProfit( const ulong &Deals[], GetDealProfit DealProfit ) { double Profit = 0; for (int i = ArraySize(Deals) - 1; i >= 0; i--) Profit += DealProfit(Deals[i]); return(Profit); } #define BENCH(A) \ { \ const ulong StartTime = GetMicrosecondCount(); \ A; \ Print("Time[" + #A + "] = " + (string)(GetMicrosecondCount() - StartTime)); \ } int OnInit() { const int Amount = 100000; CreateHistory(Amount); // Создаем историю из Amount сделок в тестере ulong Deals[]; GetDeals(Amount, Amount, Deals); // Заполняем массив случайно выбранными сделками // Находим суммарный профит сделок из массива BENCH(Print(SumProfit(Deals, GetDealProfitFull))); // Полноценная классическая реализация BENCH(SetHashMap()); // Заполнили HashMap BENCH(Print(SumProfit(Deals, GetDealProfitHashClear))); // Реализация через HashMap BENCH(HistorySelect(0, INT_MAX)); BENCH(Print(SumProfit(Deals, GetDealProfitClear))); // Реализация с предварительно загруженной историей return(INIT_FAILED); }Expert Advisorは10万トレードを開き、様々な方法(コメント参照)でランダムなトレードの総利益を検索します。その結果2017.12.05 00:00:00 -13133.19999999244 2017.12.05 00:00:00 Time[Print(SumProfit(Deals,GetDealProfitFull))] = 38082 2017.12.05 00:00:00 Time[SetHashMap()] = 57849 2017.12.05 00:00:00 -13133.19999999244 2017.12.05 00:00:00 Time[Print(SumProfit(Deals,GetDealProfitHashClear))] = 7437 2017.12.05 00:00:00 Time[HistorySelect(0,INT_MAX)] = 1 2017.12.05 00:00:00 -13133.19999999244 2017.12.05 00:00:00 Time[Print(SumProfit(Deals,GetDealProfitClear))] = 31669ここでは、2つの強調表示された値を比較しています。HashMapのアクセスは開発者の4倍速いことが判明した。でも、開発者ではすでに歴史も含めて...。この状況で4倍速は十分なのか、それとも不十分なのか?ここでは24ミリ秒です。履歴によくアクセスする人は、かなり節約できるのではないでしょうか。でも、どうなんだろう。より現実的なテストケース(2000トレード、1,000 000シングルヒストリーアクセス)では、以下のような結果になります。2017.12.05 00:00:00 Time[Print(SumProfit(Deals,GetDealProfitFull))] = 122969 2017.12.05 00:00:00 Time[SetHashMap()] = 816 2017.12.05 00:00:00 4829800340.792288 2017.12.05 00:00:00 Time[Print(SumProfit(Deals,GetDealProfitHashClear))] = 23852 2017.12.05 00:00:00 Time[HistorySelect(0,INT_MAX)] = 1 2017.12.05 00:00:00 4829800340.792288 2017.12.05 00:00:00 Time[Print(SumProfit(Deals,GetDealProfitClear))] = 1144271パスあたり約100msecの短縮を実現例えば、10,000回のフルパスでOptimizeを実行した場合、Hashバリアントは15分早く終わります。開発者に「History」の「A」をつけるのは時期尚早です。MQLソリューションですら高速化しているのだから、高速化できるのは明らかだ。 Renat Fatkhullin 2017.12.08 21:57 #114 fxsaber提案するソリューションの速度特性を見ることにした。テスター用Expert AdvisorExpert Advisorは10万トレードを開き、様々な方法(コメント参照)でランダムなトレードの総利益を検索します。その結果ここでは、2つの強調表示された値を比較しています。HashMapのアクセスは開発者の4倍速いことが判明した。でも、開発者ではすでに歴史も含めて...。この状況で4倍速は十分なのか、それとも不十分なのか?ここでは24ミリ秒です。履歴にアクセスする回数が非常に多ければ、かなりの節約になるのではないでしょうか。でも、どうなんだろう。プラットフォームを介した呼び出しでは、GetDealProfitFullで2回、GetDealProfitClearで1回の同期オブジェクトを通過し、各反復で多くの必須チェックが行われます。 そのため、あらかじめ用意されたローカルハッシュマップ上で動作するインレイの束で最適化されたクリーンな状態よりも、速度が遅くなるのは有名な話です。 fxsaber 2017.12.08 22:00 #115 Renat Fatkhullin: プラットフォーム経由で呼び出す場合、GetDealProfitFullで2回、GetDealProfitClearで1回、同期オブジェクトを通過させ、各反復で多くの必須チェックが行われます。 そのため、インレイの束をあらかじめ用意したローカルハッシュマップに基づくクリーンで最適化された作業と比べると、本質的に速度が遅くなる。前回の投稿を修正しました。そのため、ダブルチェックはFullと呼ばれています。HistoryDealGetDoubleの Strategy Testerの高価な同期オブジェクトと多くのチェックの話がよくわからないのですが? Renat Fatkhullin 2017.12.08 22:19 #116 fxsaber前回の投稿を修正しました。ダブルチェックがあるからこそ、Fullと呼ばれるのです。 HistoryDealGetDoubleについて、高価な同期オブジェクトや大量のチェックについて、Testerがどのように話しているのか、よくわかりません。何が違うのか。ハッシュマップテストでは、高速な非同期アクセスでローカルストレージにデータを事前投入していますが、プラットフォームコールでは、ストレージの内部に落ちる必要がありますプラットフォームでは、ストレージはハッシュマップではなく、別の種類のものです。プラットフォーム上で単一の値を取得する場合、「初めて」のようにリクエストを処理する必要があり、すべてのデータが正しく、存在していることを再確認する必要があります。 コードを見てみると、トレード・ ベースの呼び出しを最適化する方法がありました。来週のリリースまでに実装するようにします。 fxsaber 2017.12.08 22:27 #117 レナト・ファットフーリン プラットフォームでは、単一の値を抽出する場合、クエリーを「初めて扱うように」扱い、すべてのデータの正しさと存在を再確認する必要があります。しかし、TryGetValueは正しさをチェックすることなく呼び出されるのでは?ログによると、テスターのHistorySelectは 無料であることがわかります。理解できないのは、取引に関するすべてのデータを取得するために、なぜ高価なHistoryDealGet*関数を何度も呼び出す必要があるのか、ということです。MqlDeal-structureを埋めるための呼び出しは1回だけです。当然ながら、HashMapを通して履歴を扱う場合、ユーザーはCHashMap<ulong, MqlDeal>を記入することになります。MqlDealInteger, MqlDealDouble, MqlDealString または同様のものを作成し、高価なユニットコールを増やさないようにする必要があるかもしれません。また、DealTicketの正誤チェックは、毎回ではなく、一回で十分です。 Renat Fatkhullin 2017.12.08 22:34 #118 fxsaberTryGetValueの呼び出しは、正しさを確認するために行うのではないでしょうか?ログによると、テスターではHistorySelectは無料であることがわかります。 どうして無料なの?全然タダじゃないんです。理解できないのは、取引に関するすべてのデータを取得するために、なぜ高価なHistoryDealGet*関数を何度も呼び出す必要があるのか、ということです。MqlDeal-structureを埋めるための呼び出しは1回だけです。もちろん、HashMapで履歴を扱う場合は、CHashMap<ulong, MqlDeal>と記入します。取引記録形式がフローティングで定期的に拡張されるため、MqlDeal構造体は持っていないのです。これなくして、プラットフォームの機能を拡張することはできません。そのため、Get機能でアクセスするしかない。また、以前にアクセスしたレコードの他のフィールドへのアクセスは、レコードがキャッシュされているため、最初のアクセスよりも何倍も速くなります。また、DealTicketの正誤チェックは、毎回でなく、1回で十分です。上記のテストでは、毎回案件の数が新しくなるため、以前に選択した案件の キャッシュが常に乱される。また、通話と通話の間に何かが変わっていない保証はありません。履歴のリクエスト間交換は今まで通り可能です。 fxsaber 2017.12.08 22:39 #119 レナト・ファットフーリン どうして無料なの?全く無料ではありません。 トレーディング、自動売買システム、トレーディング戦略のテストに関するフォーラム 汎用クラスライブラリ - バグ、説明、問題、使用例、提案 fxsaber さん 2017.12.08 22:46 アドバイザーが10万件の取引を開始し、さまざまな方法(コメント参照)を使ってランダムな取引の総利益を調べます。結果2017.12.05 00:00:00 Time[HistorySelect(0,INT_MAX)] = 1 10万トレード(注文数も同じ)あたり、1マイクロ秒が無料になります。テスターが大事なんです。上記のテストでは、案件の数が毎回新しくなるため、以前に選択された案件の キャッシュが常に途切れることになる。また、通話と通話の間に何かが変わっていない 保証はありません。履歴のリクエスト間の交換が可能です。だから、(特にテスターでの)履歴は補足されるだけで、古い記録は変更されない。クリアバリエーションについてです。実際の市場では、注文が部分的に成立して複数の取引が発生しても、完全に埋まるかキャンセルされるまで履歴に残らないようです。つまり、凍結された歴史のルールが維持されているのです。 Renat Fatkhullin 2017.12.08 22:45 #120 fxsaber 10万トレード(注文数も同じ)の場合、1マイクロ秒は無料です。ずっとテスターが中心なんです。テスターのHistorySelectは、パラメータ0,INT_MAXで、絶対的に仮想・機能的です。これはずいぶん前に最適化されたものです。HistorySelect(puts access range in tester) と、実際に特定のチケットを探しキャッシュする HistoryDealSelect(ticket) を比較することはできません。 1...5678910111213141516171819...38 新しいコメント 取引の機会を逃しています。 無料取引アプリ 8千を超えるシグナルをコピー 金融ニュースで金融マーケットを探索 新規登録 ログイン スペースを含まないラテン文字 このメールにパスワードが送信されます エラーが発生しました Googleでログイン WebサイトポリシーおよびMQL5.COM利用規約に同意します。 新規登録 MQL5.com WebサイトへのログインにCookieの使用を許可します。 ログインするには、ブラウザで必要な設定を有効にしてください。 ログイン/パスワードをお忘れですか? Googleでログイン
T型に対するGetHashCode 関数の明示的な実装がない場合、コードがどうなるか理解できていますか?
答え:実装が足りないという問題が黙殺されてしまうので、興ざめです。同じクラスのオブジェクトはすべて同じハッシュ値を返します。
実装(ボディ)は関係あるのか!これを追加しました。
ボールから本体を挿入しました。
実装(ボディ)は関係あるのか!これを追加しました。
ボディを一から入れました。
ハエについて言われ(そんなことしたらダメだよ、コードで将来病気になるよと)、カツについて語られる。
よし、腹ごしらえだ。
提案するソリューションの速度特性を見ることにした。テスター用Expert Advisor
Expert Advisorは10万トレードを開き、様々な方法(コメント参照)でランダムなトレードの総利益を検索します。その結果
ここでは、2つの強調表示された値を比較しています。HashMapのアクセスは開発者の4倍速いことが判明した。でも、開発者ではすでに歴史も含めて...。
この状況で4倍速は十分なのか、それとも不十分なのか?ここでは24ミリ秒です。履歴によくアクセスする人は、かなり節約できるのではないでしょうか。でも、どうなんだろう。
より現実的なテストケース(2000トレード、1,000 000シングルヒストリーアクセス)では、以下のような結果になります。
1パスあたり約100msecの短縮を実現例えば、10,000回のフルパスでOptimizeを実行した場合、Hashバリアントは15分早く終わります。
開発者に「History」の「A」をつけるのは時期尚早です。MQLソリューションですら高速化しているのだから、高速化できるのは明らかだ。
提案するソリューションの速度特性を見ることにした。テスター用Expert Advisor
Expert Advisorは10万トレードを開き、様々な方法(コメント参照)でランダムなトレードの総利益を検索します。その結果
ここでは、2つの強調表示された値を比較しています。HashMapのアクセスは開発者の4倍速いことが判明した。でも、開発者ではすでに歴史も含めて...。
この状況で4倍速は十分なのか、それとも不十分なのか?ここでは24ミリ秒です。履歴にアクセスする回数が非常に多ければ、かなりの節約になるのではないでしょうか。でも、どうなんだろう。
プラットフォームを介した呼び出しでは、GetDealProfitFullで2回、GetDealProfitClearで1回の同期オブジェクトを通過し、各反復で多くの必須チェックが行われます。
そのため、あらかじめ用意されたローカルハッシュマップ上で動作するインレイの束で最適化されたクリーンな状態よりも、速度が遅くなるのは有名な話です。
プラットフォーム経由で呼び出す場合、GetDealProfitFullで2回、GetDealProfitClearで1回、同期オブジェクトを通過させ、各反復で多くの必須チェックが行われます。
そのため、インレイの束をあらかじめ用意したローカルハッシュマップに基づくクリーンで最適化された作業と比べると、本質的に速度が遅くなる。
前回の投稿を修正しました。そのため、ダブルチェックはFullと呼ばれています。
HistoryDealGetDoubleの Strategy Testerの高価な同期オブジェクトと多くのチェックの話がよくわからないのですが?前回の投稿を修正しました。ダブルチェックがあるからこそ、Fullと呼ばれるのです。
HistoryDealGetDoubleについて、高価な同期オブジェクトや大量のチェックについて、Testerがどのように話しているのか、よくわかりません。何が違うのか。
コードを見てみると、トレード・ ベースの呼び出しを最適化する方法がありました。来週のリリースまでに実装するようにします。
レナト・ファットフーリン
プラットフォームでは、単一の値を抽出する場合、クエリーを「初めて扱うように」扱い、すべてのデータの正しさと存在を再確認する必要があります。
しかし、TryGetValueは正しさをチェックすることなく呼び出されるのでは?ログによると、テスターのHistorySelectは 無料であることがわかります。
理解できないのは、取引に関するすべてのデータを取得するために、なぜ高価なHistoryDealGet*関数を何度も呼び出す必要があるのか、ということです。MqlDeal-structureを埋めるための呼び出しは1回だけです。
当然ながら、HashMapを通して履歴を扱う場合、ユーザーはCHashMap<ulong, MqlDeal>を記入することになります。
MqlDealInteger, MqlDealDouble, MqlDealString または同様のものを作成し、高価なユニットコールを増やさないようにする必要があるかもしれません。また、DealTicketの正誤チェックは、毎回ではなく、一回で十分です。
TryGetValueの呼び出しは、正しさを確認するために行うのではないでしょうか?ログによると、テスターではHistorySelectは無料であることがわかります。
理解できないのは、取引に関するすべてのデータを取得するために、なぜ高価なHistoryDealGet*関数を何度も呼び出す必要があるのか、ということです。MqlDeal-structureを埋めるための呼び出しは1回だけです。
もちろん、HashMapで履歴を扱う場合は、CHashMap<ulong, MqlDeal>と記入します。
取引記録形式がフローティングで定期的に拡張されるため、MqlDeal構造体は持っていないのです。これなくして、プラットフォームの機能を拡張することはできません。
そのため、Get機能でアクセスするしかない。また、以前にアクセスしたレコードの他のフィールドへのアクセスは、レコードがキャッシュされているため、最初のアクセスよりも何倍も速くなります。
また、DealTicketの正誤チェックは、毎回でなく、1回で十分です。
上記のテストでは、毎回案件の数が新しくなるため、以前に選択した案件の キャッシュが常に乱される。また、通話と通話の間に何かが変わっていない保証はありません。履歴のリクエスト間交換は今まで通り可能です。
どうして無料なの?全く無料ではありません。
トレーディング、自動売買システム、トレーディング戦略のテストに関するフォーラム
汎用クラスライブラリ - バグ、説明、問題、使用例、提案
fxsaber さん 2017.12.08 22:46
アドバイザーが10万件の取引を開始し、さまざまな方法(コメント参照)を使ってランダムな取引の総利益を調べます。結果
10万トレード(注文数も同じ)あたり、1マイクロ秒が無料になります。テスターが大事なんです。
上記のテストでは、案件の数が毎回新しくなるため、以前に選択された案件の キャッシュが常に途切れることになる。また、通話と通話の間に何かが変わっていない 保証はありません。履歴のリクエスト間の交換が可能です。
だから、(特にテスターでの)履歴は補足されるだけで、古い記録は変更されない。クリアバリエーションについてです。
実際の市場では、注文が部分的に成立して複数の取引が発生しても、完全に埋まるかキャンセルされるまで履歴に残らないようです。つまり、凍結された歴史のルールが維持されているのです。
10万トレード(注文数も同じ)の場合、1マイクロ秒は無料です。ずっとテスターが中心なんです。
テスターのHistorySelectは、パラメータ0,INT_MAXで、絶対的に仮想・機能的です。これはずいぶん前に最適化されたものです。
HistorySelect(puts access range in tester) と、実際に特定のチケットを探しキャッシュする HistoryDealSelect(ticket) を比較することはできません。