价格!=价格? - 页 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位),虽然还没有经过严格的测试。

//+------------------------------------------------------------------+
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就是这样。

经纪人的双倍值可以从1.23457500000000到1.234584999999999的任何地方,仍然被认为是同一个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函数

例如,双倍数x= (MathRound( 1.37883 * 100000) )/ 100000 ;

所以我们可以用函数

double round ( double value )

{ int D= MathPow(10,Digits);

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

return(x);

} 
 
*只在涉及双倍值的计算中使用normalize double,而不是在有双倍值的地方使用。
 
tonny:
*只在涉及双倍值的计算中使用normalize double,而不是在有双倍值的地方使用。
或者根本就不要使用NormalizeDouble(),大多数时候,当它被使用时,完全 没有必要使用它......错误4107可以通过使用NormalizeDouble()来解决,但还有其他方法。任何来自预定义变量时间序列函数 的价格都不需要被规范化,整数乘以点的结果也不需要。
 
WDholic:

我们应该避免使用normalisedouble吗?

或者是......我有个想法,我们可以使用MathRound函数

例如,双倍数x= (MathRound( 1.37883 * 100000) )/ 100000 ;


你仍然会得到一个双数,并且仍然有可能出现价格 != 价格。

我找到了这个解决方案,它将双倍数变成了整数,用于比较双倍数.. .

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)

永远不会成真。

 
大量的计算,而不是简单的解决方案