価格 != 価格 ? - ページ 2

 

比較のためであれば、自分で簡単に関数を 作ることができます。

bool checkDoubles(double a, double b, string check)
{
if(check==">"){
if (a - b > Point / 2)return(1);else return (0);
}else if(check=="<"){
if (b - a > Point / 2)return(1);else return (0);
}else if(check==">="){
if (a - b > -Point)return(1);else return (0);
}if(check=="<="){
if (b - a > -Point)return(1);else return (0);
}else if(check=="!="){
if (MathAbs(a - b) > Point / 2)return(1);else return (0);
}else {
Print("Sorry you've entered a wrong check value");
}
return (0);
}

これは単なる思いつきです。

 
heelflip43:

比較のためであれば、自分で簡単に関数を作ることができます。

これは単なる思いつきです。


いい考えですね、ありがとうございます :-)
 

Point" や "Point/2.0" の使用は、差分値としてはあまり良いものではありません、IMO。 NormalizeDoubleで発生する丸め誤差は、8桁よりずっと小さく、15桁の可能性が高いです。

このルーチンは、まだ厳密なテストはしていませんが、(小数点以下15桁まで "diff "を使っても)うまく動作するように思われます。

//+------------------------------------------------------------------+
bool AvsB(double A, string checkStr, double B)
{
   //checkStr = StringTrimLeft(StringTrimRight(checkStr));
   double diff = 0.000000000000001; // 15 decimal places
   //double diff = 0.000000005;
   //double diff = 0.00000001;
   if     (checkStr == ">" ){if (A - B >  diff)return(true);else return(false);}
   else if(checkStr == "<" ){if (B - A >  diff)return(true);else return(false);}
   else if(checkStr == ">="){if (A - B > -diff)return(true);else return(false);}
   else if(checkStr == "<="){if (B - A > -diff)return(true);else return(false);}
   else if(checkStr == "!="){if (MathAbs(A - B) >  diff)return(true);else return(false);}
   else if(checkStr == "=" || checkStr == "=="){if (MathAbs(A - B) <  diff)return(true);else return(false);}
   else {Print("Sorry, bad usage: AvsB(A, checkStr, B).  Wrong checkStr value: ",checkStr);}
   return(false);
} // end of AvsB
//+------------------------------------------------------------------+

Here is a check of the obvious:

   if (1.34929 == NormalizeDouble(1.34929 , 5))  Alert("MT4 Pass");
   else Alert("MT4 FAIL.  ROUNDOFF BUG");    // Yes, this is what MT4 does, a fail.

   if (AvsB(1.34929 ,"==", NormalizeDouble(1.34929 , 5)))  Alert("AvsB Pass");  // It does pass using the AvsB routine!
   else Alert("AvsB FAIL.  ROUNDOFF BUG"); 
 

比較することができるが、内部的に A や B を正規化することができ、また比較の差(A-B や B-A の)を「桁」に基づいてより大きな数に緩和することができる、さらに別の可能なルーチンがここにあります。 このルーチンが上記の単純な「AvsB」と比べて必要であるかどうかは疑問ですが、希望に応じて使用できるように提供します。

//+------------------------------------------------------------------+
bool AvsB_nA_nB_digits(double A, string checkStr, double B, bool normalizeA, bool normalizeB, int digits)
{
   //checkStr = StringTrimLeft(StringTrimRight(checkStr));
   if (normalizeA) A = NormalizeDouble(A,MathMin(8,digits));
   if (normalizeB) B = NormalizeDouble(B,MathMin(8,digits));
   
   double diff;
   switch(digits)
   {
      case 0  : diff = 0.5; break; // Or 1.0 ??
      case 1  : diff = 0.1; break;
      case 2  : diff = 0.01; break;
      case 3  : diff = 0.001; break;
      case 4  : diff = 0.0001; break;
      case 5  : diff = 0.00001; break;
      case 6  : diff = 0.000001; break;
      case 7  : diff = 0.0000001; break;
      case 8  : diff = 0.00000001; break;
      case 9  : diff = 0.000000001; break;
      case 10 : diff = 0.0000000001; break;
      case 11 : diff = 0.00000000001; break;
      case 12 : diff = 0.000000000001; break;
      case 13 : diff = 0.0000000000001; break;
      case 14 : diff = 0.00000000000001; break;
      default : diff = 0.000000000000001; break; // 15 decimal places max (I think)
   }
   
   if     (checkStr == ">" ){if (A - B >  diff)return(true);else return(false);}
   else if(checkStr == "<" ){if (B - A >  diff)return(true);else return(false);}
   else if(checkStr == ">="){if (A - B > -diff)return(true);else return(false);}
   else if(checkStr == "<="){if (B - A > -diff)return(true);else return(false);}
   else if(checkStr == "!="){if (MathAbs(A - B) >  diff)return(true);else return(false);}
   else if(checkStr == "=" || checkStr == "=="){if (MathAbs(A - B) <  diff)return(true);else return(false);}
   else {Print("Sorry, bad usage: AvsB(A, checkStr, B).  Wrong checkStr value: ",checkStr);}
   return(false);
} // end of AvsB_nA_nB_digits
//+------------------------------------------------------------------+
 
pips4life:

Point" や "Point/2.0" の使用は、差分値としてはあまり良いものではありません、IMO。NormalizeDoubleで発生する丸め誤差は、8桁よりはるかに小さく、15桁の可能性が高いです。

丸め誤差とみなされない最大の値、あるいは同等に、価格変化 とみなされない最小の値が欲しいところです。価格はポイントの倍数でしか変化しないので、ポイント/2はまさにそれである。

ブローカーからの2倍の値は、1.23457500000000から1.23458499999999のどこにあっても、同じ1.23458の価格とみなされるのです。

これを利用していれば、問題は起きなかったはずです。

if (a > b)
if (a - b > Point / 2.)
if (a >= b)
if (a - b > -Point/2.)
if (a != b)
if (MathAbs(a - b) > Point / 2.)
 

normalisedoubleの使用を避けるべきでしょうか?

それともMathRound 関数 で対応できるのでしょうか?

例: double x= (MathRound( 1.37883 * 100000))/ 100000 ;

ということで、関数

double round ( double value )

{ int D= MathPow(10,Digits);

double x =  ( MathRound (value * D)) / D ;

return(x);

} 
 
*2本の指でネクタイを所定の位置に振ってください。2倍の値を含む計算で正規化2倍を使用するだけで、2倍の値があるところすべてに使用するわけではありません。
 
tonny:
*ダブルの値を含む計算で正規化ダブルを使用するだけでなく、ちょうどどこでもダブルがあります。
エラー4107はNormalizeDouble()を使用することによって対処することができますが、他の方法があります。定義済み変数や 時系列関数から 得られる価格は、決して正規化する必要はありませんし、整数にPointを掛けた結果も同様です。
 
WDholic:

normalisedoubleの使用を避けるべきでしょうか?

それとも MathRound 関数で対応できるのでしょうか?

例: double x= (MathRound( 1.37883 * 100000))/ 100000 ;


あなたはまだdoubleで終わるし、まだ価格の可能性がある!

そこで、doubleをint型に変換してdoubleを比較するという解決策にたどり着きました。. .

int Flat(double ValueToFlatten)
   {
   double Power = MathPow(10, Digits);
   int ReturnValue;
   
   ReturnValue = MathRound(Power * (ValueToFlatten + (4.9/ (Power*10) ) ) ) ;
   return (ReturnValue);
   
   }

そうすれば,....

Flat(price) != Flat(price)

は決して真にはならない。

 
シンプルな解決 策ではなく、多くの計算が必要な場合