ライブラリ: CDouble & CDoubleVector - ページ 2

 
Alain Verleyen:
よくやった。しかし、取引の観点からは、1.70060か1.70061のどちらかが必要であり、どちらも正しい。そのため、数学的な丸め方式に頼るのではなく、取引操作に応じて 最適な方を選択したいと思うかもしれません。

このシナリオでは、ステップ・サイズ==0.00001の場合、結果として1.70061が得られるだけで、1.70060の値は近いが正しくない。

 
nicholishen:

このシナリオでは、ステップサイズ==0.00001の場合、結果として1.70061しか得られないはずであり、1.70060という値は近いが正しくない。

申し訳ありませんが、あなたの推論が理解できません。ステップ・サイズ」とは何ですか?

 
Alain Verleyen:

申し訳ないが、あなたの推論が理解できない。ステップ・サイズ」とは何ですか?

例えば、lot_step = 0.01(2桁)、tick_size = 0.00005...などです。


この例では、ティックサイズ== 0.00001の5桁の記号を扱っています。

 
nicholishen:

step-size は、四捨五入するステップの値です。例えば、lot_step = 0.01(2桁)、tick_size = 0.00005...など。


この例では、ティックサイズ==0.00001の5桁の記号を扱っています。

ステップ・サイズがティック・サイズということですね。それでもまだ、取引の観点から、 1.700605のような計算された価格を1.70060に「丸め」(数学的/コーディング的な方法が何であれ)ることができない理由がわかりません。
削除済み  
Alain Verleyen: ステップサイズはティックサイズなのですね。それでもまだ、取引の観点から、 1.700605のような計算された価格を1.70060に「丸め」(数学的/コーディング的な方法が何であれ)られない理由がわかりません。

トレーディングの観点」はここでは関係ないことをご理解ください。これは純粋に数学的な問題であり、 @amrali 氏が解決策を提示している。

トレーディングの視点」についてここで議論する必要はありません。このスレッドの テーマから外れて おり、最終的に誰かが再びBANされることになる、別の激しい議論にエスカレートするからです。ですから、そのようなことはなるべく避けてください!

 
Fernando Carreiro:

トレーディングの視点」はここでは関係ないことをご理解ください。これは純粋に数学的な問題であり、 @amraliが 解決策を提供している。

トレーディングの視点」についてここで議論する必要はありません。このスレッドの テーマから外れて いますし、最終的にはまた誰かが追放されるような激論に発展するでしょう。ですから、そうならないようにしてください!

私はただ@nicholishenが 言ったことを理解しようとしているだけです。白熱した議論などする必要はありません。ここは取引に関するフォーラムですよね?

計算価格1.700605から実際の価格1.70060がなぜ「正しくない」のか説明してください。もし私が何かを見落としているのであれば、それを理解したいと思います。

 
Alain Verleyen:

私はただ@nicholishenが 言ったことを理解しようとしているだけだ。白熱した議論などする必要はない。ここはトレードに関するフォーラムでしょう?

計算価格1.700605から実際の価格1.70060がなぜ「正しくない」のか説明してください。もし私が何かを見逃しているのであれば、それを理解したいと思います。

フェルナンドが言ったように、"これは純粋に数学的な問題 "であり、数学的な意味で期待される結果は、5が切り捨てられるのではなく、最も近い桁に切り上げられることです。MathRound関数は一貫性のない結果を出しており、もし一貫性のない結果を避けたいのであれば、@amraliが 賢明な提案をしてくれたように、代わりにNDを使うことをお勧めする。本題に戻りますが、CDoubleライブラリはより一貫性のある結果を得るためにMathRound関数を使用しなくなりました。

 
Alain Verleyen:

私はただ@nicholishenが 言ったことを理解しようとしているだけだ。白熱した議論などする必要はない。ここはトレードに関するフォーラムでしょう?

計算価格1.700605から実際の価格1.70060がなぜ「正しくない」のか説明してください。もし私が何かを見逃しているのであれば、それを理解したいと思います。

Alain Verleyenさん ご指摘の通りです。1回の計算では、それほど大きな違いはないかもしれません。しかし、各段階で四捨五入するような計算を重ねると、最終的な誤差は大きくなります。マーチンゲール戦略を考えてみましょう。計算されたロットサイズは、それぞれ前のロットサイズ(丸められた値として取引サーバーに送信されたもの)から導き出されます。ここで考える問題は「誤差の伝播」と呼ばれるものです。ですから、中間誤差をできるだけ少なくするためには、NormalizeDouble()を使用する方が安全だと思います。

第二に、ここにはより技術的な点も存在する。 MathRound(number * power) / power 関数を エッジの数値で使用すると 、入力によって 、あるときは上の丸め値が、あるときは下の丸め値が得られます。 この丸め方の不統一は、あなたがコメントで述べているように、最終的に丸められた値(上か下か)を得る限り、取引の観点からは問題ではないかもしれません。しかし、 マーク・ワトキンが述べて いるように このような丸め方の不一致は、「CDouble」ライブラリを使用するクライアントコードに検出しにくいバグをもたらす可能性があります。

ところで、 MathRound(number / point) * point のような 上記の関数の別の変種を エッジ数で使用すると 丸められた数(上か下か)が得られます!(結果は期待値と1イプシロン異なるが、取引関数としては問題ない)

以下のスクリプトは、これらの問題をより明確に示すのに役立ちます:

#property strict

#define  PRINT(A) Print(#A + " = ", (A))

//+------------------------------------------------------------------+
//||
//+------------------------------------------------------------------+
// MathRound()の結果とエッジ番号の不一致

void OnStart()
{
    // 小数点以下5桁に半値切りする。

    PRINT(MathRound(1.248825 * 100000) / 100000 == 1.24883);    // trueの場合、その価格は切り上げられる(予想通り)。
    PRINT(MathRound(1.248835 * 100000) / 100000 == 1.24883);    // trueの場合、今回は切り捨てられる
    PRINT(MathRound(1.248845 * 100000) / 100000 == 1.24885);    // trueの場合、その価格は再び切り上げられる

    // MathRound() の 2 番目のバリエーション

    PRINT(MathRound(1.248825 / 0.00001) * 0.00001 == 1.24883);   // trueの場合、価格は切り上げられる(予想通り)
    PRINT(MathRound(1.248835 / 0.00001) * 0.00001 == 1.24883);   // 今回は切り捨てられる。
    PRINT(MathRound(1.248845 / 0.00001) * 0.00001 == 1.24885);   // 偽の場合、価格は正確に切り上げられない!
    PRINT(MathRound(1.248845 / 0.00001) * 0.00001 == 1.24884);   // falseの場合、同じ価格は正確に切り捨てられない!
    PRINT(MathRound(1.248845 / 0.00001) * 0.00001 == 1.2488400000000001);   // しかし、取引機能については問題ない。 
}

したがって、 算術(中点)丸めが指示されたときに一貫性のない結果にならないように、MathRound(number)NormalizeDouble(number, 0) に置き換える方が良いでしょう

中点丸めのための他の良い選択肢:MathRound()を使用し、ハーフイプシロン補正を適用する。

(これは 以前掲載したMathRoundCorrect()関数で 実装されている )。

double MathRoundCorrect(double num, int precision) {
        double c = 0.5 * DBL_EPSILON * num;
// double p = MathPow(10, precision); //遅い
        double p = 1; while (precision--> 0) p *= 10;
        if (num < 0)
                p *= -1;
        return MathRound((num + c) * p) / p;
}

wikipediaの記事によると、他にも様々な丸めモードがあるようです。あなたの要求に合うものを自由に選んでください。よろしくお願いします。

https://en.wikipedia.org/wiki/Rounding

Rounding - Wikipedia
Rounding - Wikipedia
  • en.wikipedia.org
Graphs of the result, y, of rounding x using different methods. For clarity, the graphs are shown displaced from integer y values. In the SVG file, hover over a method to highlight it and, in SMIL-enabled browsers, click to select or deselect it. Rounding a numerical value means replacing it by another value that is approximately equal but has...