エラー、バグ、質問 - ページ 2822 1...281528162817281828192820282128222823282428252826282728282829...3185 新しいコメント Alexey Navoykov 2020.08.10 15:46 #28211 Nikolai Semko: 標準の round(), ceil(), floor() も double を返すので、丸めだけは行われない。しかし、これらを通じて、特に彼らは通常のものよりも速く動作します。 その方が速いかもしれないが、それは間違っている。12345.0000000000001のようなものをceilに渡すと(あなたの例と同様)、出力に12346を得ることができます。 Nikolai Semko 2020.08.10 16:05 #28212 Alexey Navoykov: その方が速いかもしれないが、それは間違っている。 12345.0000000000001のようなもの(あなたの例と同様)をceilに渡すと、出力に12346を得ることができます。 ご自身で試されたことはありますか? 試してみてください。Print(ceil( 12345.0000000000001)); Print(Ceil( 12345.0000000000001)); Print(ceil( 12345.000000000001)); Print(Ceil( 12345.000000000001));出力します。2020.08.10 12:03:23.856 ErrorNormalizeDouble (EURUSD,M1) 12345.0 2020.08.10 12:03:23.856 ErrorNormalizeDouble (EURUSD,M1) 12345 2020.08.10 12:03:23.856 ErrorNormalizeDouble (EURUSD,M1) 12346.0 2020.08.10 12:03:23.856 ErrorNormalizeDouble (EURUSD,M1) 12346 は、ceil(「上から最も近い整数の数値を返す」)なので、12346になるはずです。 最初のケースは12345です。ダブル型の有効桁数は17ですが、18を持っているからです。 fxsaber 2020.08.10 16:23 #28213 Nikolai Semko: 本当に、ダブルは比べものになりませんね。ただ、難しいルールなんです。 もちろん、ダブルス同士を直接比較することは可能であり、時には必要な場合もあります。 例えば、OnTickはOptimization中に1兆回呼ばれることもあります。保留中の指値を実行するかどうかを理解するために、内蔵のテスターは現在の対応するシンボル価格と指値価格を比較します。各オンティックコールの前に、各保留注文に対して行われます。つまり、これらのチェックは何百億回、何千億回と行われているのです。 そして、それは正規化によってその都度行われます。まあ、これは計算機資源の 無駄遣いとしか言いようがない。保留中の注文とシンボルの価格はあらかじめ正規化されているので。そのため、両者を直接比較することができますし、そうする必要があります。 MQL-customのMQL Testerは、ネイティブのビルトインテスターを性能面で容易に凌駕しています。 Nikolai Semko 2020.08.10 16:56 #28214 fxsaber:もちろん、ダブルス同士を直接比較することは可能であり、時には必要な場合もあります。例えば、OnTickはOptimizeの時に1兆回呼ばれることがあります。内蔵のテスターは、保留中の指値を実行するかどうかを理解するために、現在の対応するシンボル価格と指値価格を比較します。各オンティックコールの前に、各保留注文に対して行われます。つまり、これらのチェックは何百億回、何千億回と行われているのです。そして、それは正規化によってその都度行われます。まあ、これは計算機資源の 無駄遣いとしか言いようがない。保留中の注文とシンボルの価格はあらかじめ正規化されているので。そのため、両者を直接比較することができますし、そうする必要があります。MQL-customのMQL Testerは、ネイティブのビルトインテスターを性能面で容易に凌駕しています。NormalizeDouble()は非常に高価な関数です。ですから、忘れた方がいいんです。NormalizeDouble()とintで正規化することの違いを示すスクリプトを紹介します。#define SIZE 1000000 int Ceil (double x) {return (x-(int)x>0)?(int)x+1:(int)x;} int Round(double x) {return (x>0)?(int)(x+0.5):(int)(x-0.5);} int Floor(double x) {return (x>0)?(int)x:((int)x-x>0)?(int)x-1:(int)x;} //+------------------------------------------------------------------+ //| Script program start function | //+------------------------------------------------------------------+ void OnStart() { double a[SIZE]; double s1=0,s2=0, s3=0; for (int i=0;i<SIZE;i++) a[i]=(rand()-16384)/M_PI; ulong t1=GetMicrosecondCount(); for (int i=0;i<SIZE;i++) s1+=a[i]; t1=GetMicrosecondCount()-t1; ulong t2=GetMicrosecondCount(); for (int i=0;i<SIZE;i++) s2+=NormalizeDouble(a[i],5); t2=GetMicrosecondCount()-t2; ulong t3=GetMicrosecondCount(); for (int i=0;i<SIZE;i++) s3+=Round(a[i]*100000); s3/=100000; t3=GetMicrosecondCount()-t3; Print("простая сумма - " + string(t1)+ " микросекунд, сумма = "+ DoubleToString(s1,18)); Print("сумма с NormalizeDouble - " + string(t2)+ " микросекунд, сумма = "+ DoubleToString(s2,18)); Print("сумма, нормализированная через int - " + string(t3)+ " микросекунд, сумма = "+ DoubleToString(s3,18)); }の結果です。2020.08.10 12:55:30.766 TestSpeedNormalizeDouble (USDCAD,H4) простая сумма - 1394 микросекунд, сумма = 626010.5038610587362201 2020.08.10 12:55:30.766 TestSpeedNormalizeDouble (USDCAD,H4) сумма с NormalizeDouble - 5363 микросекунд, сумма = 626010.5046099 795727060 2020.08.10 12:55:30.766 TestSpeedNormalizeDouble (USDCAD,H4) сумма, нормализированная через int - 1733 микросекунд, сумма = 626010.5046099999 453873 SZZでは、intによる正規化もより正確です(正規化の最後の桁の後の9の数でわかります-青でハイライトされています)。 Nikolai Semko 2020.08.10 17:17 #28215 Nikolai Semko:NormalizeDouble()は非常に高価な関数です。だから、忘れたほうがいいんです。以下は、NormalizeDouble()とintによる正規化との違いを示すスクリプトです。の結果です。 SZZでは、intによる正規化がより正確です(正規化の最後の桁の後の9の数でわかります-青でハイライトされています)。 また、合計が double ではなく long である場合、int での合計(乗算と丸め、そして最終的な合計を割る)は通常の double の合計よりも高速に計算されるので、結果はさらに素晴らしいものになります。 #define SIZE 1000000 int Ceil (double x) {return (x-(int)x>0)?(int)x+1:(int)x;} int Round(double x) {return (x>0)?(int)(x+0.5):(int)(x-0.5);} int Floor(double x) {return (x>0)?(int)x:((int)x-x>0)?(int)x-1:(int)x;} //+------------------------------------------------------------------+ //| Script program start function | //+------------------------------------------------------------------+ void OnStart() { double a[SIZE]; double s1=0,s2=0, s3=0; long s=0; for (int i=0;i<SIZE;i++) a[i]=(rand()-16384)/M_PI; ulong t1=GetMicrosecondCount(); for (int i=0;i<SIZE;i++) s1+=a[i]; t1=GetMicrosecondCount()-t1; ulong t2=GetMicrosecondCount(); for (int i=0;i<SIZE;i++) s2+=NormalizeDouble(a[i],5); t2=GetMicrosecondCount()-t2; ulong t3=GetMicrosecondCount(); for (int i=0;i<SIZE;i++) s+=Round(a[i]*100000); s3=s/100000.0; t3=GetMicrosecondCount()-t3; Print("простая сумма - " + string(t1)+ " микросекунд, сумма = "+ DoubleToString(s1,18)); Print("сумма с NormalizeDouble - " + string(t2)+ " микросекунд, сумма = "+ DoubleToString(s2,18)); Print("сумма, нормализированная через int - " + string(t3)+ " микросекунд, сумма = "+ DoubleToString(s3,18)); } の結果です。 2020.08.10 13:15:58.982 TestSpeedNormalizeDouble (USDCAD,H4) простая сумма - 1408 микросекунд, сумма = 460384.3207830497995019 2020.08.10 13:15:58.982 TestSpeedNormalizeDouble (USDCAD,H4) сумма с NormalizeDouble - 6277 микросекунд, сумма = 460384.3162300114054233 2020.08.10 13:15:58.982 TestSpeedNormalizeDouble (USDCAD,H4) сумма, нормализированная через int - 964 микросекунд, сумма = 460384.3162299999967218 Rorschach 2020.08.10 17:36 #28216 Nikolai Semko:また、合計がdouble経由ではなくlong経由の場合は、int経由の合計(乗算と丸め、その後に合計の除算)の方が通常のdoubleの合計より速いので、結果はさらに素晴らしいものになります。の結果です。 比較のための10進数 加算。 リンクが違います、完全な実装ではありません。 Alexey Navoykov 2020.08.10 17:38 #28217 fxsaber:そして、それは毎回ノーマライゼーションによって行われます。まあ、これはコンピューティングリソースの 無駄遣いとしか言いようがない。 なぜわかるかというと、価格が正規化されていなくても、チェックは単純に行われるからです。 if (fabs(price-limitprice) < ticksize/2) 価格がティックサイズの倍数であることを考えると Alexey Navoykov 2020.08.10 18:07 #28218 Nikolai Semko: さらに、intによる正規化もより正確であることがわかります(正規化の最後の桁の後の9の数でわかります-青でハイライトされています)。 テストが正しくありません。 なぜ最後に一度だけ100000. 0で割るのですか? 反復ごとに実行し、合計すべきです。 これは公平な比較です。 しかし、これは全く正規化ではありません。あなたはテストアルゴリズムを最適化しただけ です。当然ながら、より速く、より正確に(累積誤差が減るので)なります。 fxsaber 2020.08.10 18:13 #28219 Alexey Navoykov:どうしてわかるんですか? なぜなら、正規化されていない価格をテスターに入力しても、同じように処理されるからです。 結局のところ、価格が正規化されていなくても、チェックは簡単にできるのです。 正規化とは、この場合、単一の標準アルゴリズムを適用した後、この標準の2倍を直接比較できるようにすることを意味します。 だから、テスターは直接ダブルを比較するわけではありません。NormalizeDoubleや ticksizeなどで行っています。しかし、確かに2倍速の直接比較ではありません。そして、それはまったく合理的ではありません。 Nikolai Semko 2020.08.10 18:23 #28220 fxsaber:もちろん、ダブルス同士を直接比較することは可能であり、時には必要な場合もあります。例えば、Optimize OnTickは1兆回呼ばれることもあります。内蔵のテスターは、保留中のリミットコールを実行するかどうかを理解するために、現在の対応するシンボル価格とリミットコール価格を比較します。各オンティックコールの前に、各保留注文に対して行われます。つまり、これらのチェックは何百億回、何千億回と行われているのです。そして、それは正規化によってその都度行われます。まあ、これは計算機資源の 無駄遣いとしか言いようがない。保留中の注文とシンボルの価格はあらかじめ正規化されているので。そのため、両者を直接比較することができますし、そうする必要があります。MQL-customのMQL Testerは、ネイティブのビルトインテスターに性能で勝ることはありません。 そこで、性能ナンセンス版を確認することにしました。 正規化前の double の比較でも、εやintへの変換で double を比較した場合よりも、平均してさらに遅くなります。 #define SIZE 1000000 int Ceil (double x) {return (x-(int)x>0)?(int)x+1:(int)x;} int Round(double x) {return (x>0)?(int)(x+0.5):(int)(x-0.5);} int Floor(double x) {return (x>0)?(int)x:((int)x-x>0)?(int)x-1:(int)x;} bool is_equal(double d1, double d2, double e=0.000000001) {return fabs(d1-d2)<e;} void OnStart() { double a[SIZE], a_norm[SIZE]; int s1=0,s2=0, s3=0; for (int i=0;i<SIZE;i++) { a[i]=(rand()-16384)/1641.1452; a_norm[i]=NormalizeDouble(a[i],2); } double test = 1.11; ulong t1=GetMicrosecondCount(); for (int i=0;i<SIZE;i++) if (a_norm[i]==test) s1++; t1=GetMicrosecondCount()-t1; ulong t2=GetMicrosecondCount(); for (int i=0;i<SIZE;i++) if (is_equal(a[i],test,0.005)) s2++; t2=GetMicrosecondCount()-t2; ulong t3=GetMicrosecondCount(); int test_int = test*100; for (int i=0;i<SIZE;i++) if (Round(a[i]*100)==test_int) s3++; t3=GetMicrosecondCount()-t3; Print("простое сравнение предварительно нормализированых double - " + string(t1)+ " микросекунд, всего совпадений = "+ string(s1)); Print("сравнение double через эпсилон - " + string(t2)+ " микросекунд, всего совпадений = "+ string(s2)); Print("сравнение double через преобразование в int - " + string(t3)+ " микросекунд, всего совпадений = "+ string(s3)); } その結果 2020.08.10 14:31:39.620 TestCompareDouble (USDCAD,H4) простое сравнение предварительно нормализированых double - 900 микросекунд, всего совпадений = 486 2020.08.10 14:31:39.620 TestCompareDouble (USDCAD,H4) сравнение double через эпсилон - 723 микросекунд, всего совпадений = 486 2020.08.10 14:31:39.620 TestCompareDouble (USDCAD,H4) сравнение double через преобразование в int - 805 микросекунд, всего совпадений = 486 2020.08.10 14:31:42.607 TestCompareDouble (USDCAD,H4) простое сравнение предварительно нормализированых double - 1533 микросекунд, всего совпадений = 488 2020.08.10 14:31:42.607 TestCompareDouble (USDCAD,H4) сравнение double через эпсилон - 758 микросекунд, всего совпадений = 488 2020.08.10 14:31:42.607 TestCompareDouble (USDCAD,H4) сравнение double через преобразование в int - 790 микросекунд, всего совпадений = 488 2020.08.10 14:31:44.638 TestCompareDouble (USDCAD,H4) простое сравнение предварительно нормализированых double - 986 микросекунд, всего совпадений = 472 2020.08.10 14:31:44.638 TestCompareDouble (USDCAD,H4) сравнение double через эпсилон - 722 микросекунд, всего совпадений = 472 2020.08.10 14:31:44.638 TestCompareDouble (USDCAD,H4) сравнение double через преобразование в int - 834 микросекунд, всего совпадений = 472 プロセッサの新規性やアーキテクチャに大きく依存することは否定できませんし、人によって結果は異なるかもしれません。 どうやら、コンパイラが乱数の和を最適化する機能がないようです。丸めを括弧の外に出してはいけない。 プロセッサの2重比較は1コマンドのようです イプシロンで比較する場合(最も高速な方法)、2つの2重の比較操作があるのは変わりませんが、それに加えて、3つのパラメータを渡す関数呼び出しと1つの引き算の操作をしているのです。 2つのダブルの比較という操作の性能は、変数の値そのものに依存するのでしょうか?そうでしょうか。 げっ、意味わかんない。私は何を考慮に入れなかったのか、どこで間違ったのか、助けてください。 1...281528162817281828192820282128222823282428252826282728282829...3185 新しいコメント 取引の機会を逃しています。 無料取引アプリ 8千を超えるシグナルをコピー 金融ニュースで金融マーケットを探索 新規登録 ログイン スペースを含まないラテン文字 このメールにパスワードが送信されます エラーが発生しました Googleでログイン WebサイトポリシーおよびMQL5.COM利用規約に同意します。 新規登録 MQL5.com WebサイトへのログインにCookieの使用を許可します。 ログインするには、ブラウザで必要な設定を有効にしてください。 ログイン/パスワードをお忘れですか? Googleでログイン
標準の round(), ceil(), floor() も double を返すので、丸めだけは行われない。
しかし、これらを通じて、特に彼らは通常のものよりも速く動作します。
その方が速いかもしれないが、それは間違っている。
ご自身で試されたことはありますか?
試してみてください。
出力します。
は、ceil(「上から最も近い整数の数値を返す」)なので、12346になるはずです。最初のケースは12345です。ダブル型の有効桁数は17ですが、18を持っているからです。
本当に、ダブルは比べものになりませんね。ただ、難しいルールなんです。
もちろん、ダブルス同士を直接比較することは可能であり、時には必要な場合もあります。
例えば、OnTickはOptimization中に1兆回呼ばれることもあります。保留中の指値を実行するかどうかを理解するために、内蔵のテスターは現在の対応するシンボル価格と指値価格を比較します。各オンティックコールの前に、各保留注文に対して行われます。つまり、これらのチェックは何百億回、何千億回と行われているのです。
そして、それは正規化によってその都度行われます。まあ、これは計算機資源の 無駄遣いとしか言いようがない。保留中の注文とシンボルの価格はあらかじめ正規化されているので。そのため、両者を直接比較することができますし、そうする必要があります。
MQL-customのMQL Testerは、ネイティブのビルトインテスターを性能面で容易に凌駕しています。
fxsaber:
もちろん、ダブルス同士を直接比較することは可能であり、時には必要な場合もあります。
例えば、OnTickはOptimizeの時に1兆回呼ばれることがあります。内蔵のテスターは、保留中の指値を実行するかどうかを理解するために、現在の対応するシンボル価格と指値価格を比較します。各オンティックコールの前に、各保留注文に対して行われます。つまり、これらのチェックは何百億回、何千億回と行われているのです。
そして、それは正規化によってその都度行われます。まあ、これは計算機資源の 無駄遣いとしか言いようがない。保留中の注文とシンボルの価格はあらかじめ正規化されているので。そのため、両者を直接比較することができますし、そうする必要があります。
MQL-customのMQL Testerは、ネイティブのビルトインテスターを性能面で容易に凌駕しています。
NormalizeDouble()は非常に高価な関数です。ですから、忘れた方がいいんです。
NormalizeDouble()とintで正規化することの違いを示すスクリプトを紹介します。
の結果です。
SZZでは、intによる正規化もより正確です(正規化の最後の桁の後の9の数でわかります-青でハイライトされています)。NormalizeDouble()は非常に高価な関数です。だから、忘れたほうがいいんです。
以下は、NormalizeDouble()とintによる正規化との違いを示すスクリプトです。
の結果です。
SZZでは、intによる正規化がより正確です(正規化の最後の桁の後の9の数でわかります-青でハイライトされています)。また、合計が double ではなく long である場合、int での合計(乗算と丸め、そして最終的な合計を割る)は通常の double の合計よりも高速に計算されるので、結果はさらに素晴らしいものになります。
の結果です。
また、合計がdouble経由ではなくlong経由の場合は、int経由の合計(乗算と丸め、その後に合計の除算)の方が通常のdoubleの合計より速いので、結果はさらに素晴らしいものになります。
の結果です。
比較のための10進数 加算。
リンクが違います、完全な実装ではありません。
そして、それは毎回ノーマライゼーションによって行われます。まあ、これはコンピューティングリソースの 無駄遣いとしか言いようがない。
なぜわかるかというと、価格が正規化されていなくても、チェックは単純に行われるからです。
価格がティックサイズの倍数であることを考えると
さらに、intによる正規化もより正確であることがわかります(正規化の最後の桁の後の9の数でわかります-青でハイライトされています)。
テストが正しくありません。 なぜ最後に一度だけ100000. 0で割るのですか? 反復ごとに実行し、合計すべきです。 これは公平な比較です。 しかし、これは全く正規化ではありません。あなたはテストアルゴリズムを最適化しただけ です。当然ながら、より速く、より正確に(累積誤差が減るので)なります。
どうしてわかるんですか?
なぜなら、正規化されていない価格をテスターに入力しても、同じように処理されるからです。
結局のところ、価格が正規化されていなくても、チェックは簡単にできるのです。
正規化とは、この場合、単一の標準アルゴリズムを適用した後、この標準の2倍を直接比較できるようにすることを意味します。
だから、テスターは直接ダブルを比較するわけではありません。NormalizeDoubleや ticksizeなどで行っています。しかし、確かに2倍速の直接比較ではありません。そして、それはまったく合理的ではありません。
もちろん、ダブルス同士を直接比較することは可能であり、時には必要な場合もあります。
例えば、Optimize OnTickは1兆回呼ばれることもあります。内蔵のテスターは、保留中のリミットコールを実行するかどうかを理解するために、現在の対応するシンボル価格とリミットコール価格を比較します。各オンティックコールの前に、各保留注文に対して行われます。つまり、これらのチェックは何百億回、何千億回と行われているのです。
そして、それは正規化によってその都度行われます。まあ、これは計算機資源の 無駄遣いとしか言いようがない。保留中の注文とシンボルの価格はあらかじめ正規化されているので。そのため、両者を直接比較することができますし、そうする必要があります。
MQL-customのMQL Testerは、ネイティブのビルトインテスターに性能で勝ることはありません。
そこで、性能ナンセンス版を確認することにしました。
正規化前の double の比較でも、εやintへの変換で double を比較した場合よりも、平均してさらに遅くなります。
その結果
プロセッサの新規性やアーキテクチャに大きく依存することは否定できませんし、人によって結果は異なるかもしれません。
どうやら、コンパイラが乱数の和を最適化する機能がないようです。丸めを括弧の外に出してはいけない。
プロセッサの2重比較は1コマンドのようです
イプシロンで比較する場合(最も高速な方法)、2つの2重の比較操作があるのは変わりませんが、それに加えて、3つのパラメータを渡す関数呼び出しと1つの引き算の操作をしているのです。
2つのダブルの比較という操作の性能は、変数の値そのものに依存するのでしょうか?そうでしょうか。
げっ、意味わかんない。私は何を考慮に入れなかったのか、どこで間違ったのか、助けてください。