Can price != price ? - page 2

 

Si c'est pour la comparaison, vous pourriez facilement créer votre propre fonction :

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);
}

C'est juste une idée.

 
heelflip43:

Si c'est pour la comparaison, vous pourriez facilement créer votre propre fonction :

C'est juste une idée.


C'est une bonne idée, je vous en remercie :-)
 

L'utilisation de "Point" ou "Point/2.0" n'est pas une très bonne valeur de différence, IMO. L'erreur d'arrondi introduite par NormalizeDouble (qui m'a brûlé aujourd'hui), est certainement beaucoup plus petite que 8 chiffres, plus probablement 15 chiffres.

Compte tenu des conseils précédents, j'ai apporté quelques modifications et mis au point la routine suivante qui semble fonctionner correctement (même en utilisant la "différence" à 15 décimales), bien qu'elle n'ait pas encore été rigoureusement testée :

//+------------------------------------------------------------------+
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"); 
 

Voici encore une autre routine possible qui peut comparer, mais qui peut aussi normaliser en interne soit A et/ou B, et qui va aussi relaxer la différence de comparaison (de A-B ou B-A) à un nombre plus grand basé sur les "chiffres". Je doute que cette routine soit nécessaire par rapport à la simple "AvsB" ci-dessus, mais elle est proposée à votre usage si vous le souhaitez :

//+------------------------------------------------------------------+
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:

L'utilisation de "Point" ou "Point/2.0" n'est pas une très bonne valeur de différence, IMO. L'erreur d'arrondi introduite par NormalizeDouble (qui m'a brûlé aujourd'hui), est certainement beaucoup plus petite que 8 chiffres, plus probablement 15 chiffres.

Vous voulez la plus grande valeur qui ne peut pas être considérée comme une erreur d'arrondi ou, de manière équivalente, la plus petite valeur qui ne peut pas être considérée comme un changement de prix. Puisque les prix ne peuvent changer que d'un multiple de point, point/2 est exactement cela.

La valeur double du courtier pourrait être n'importe où entre 1,23457500000000 et 1,23458499999999999 et être toujours considérée comme le même prix de 1,23458.

Si vous aviez utilisé cette méthode, vous n'auriez pas eu ce problème :

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.)
 

Devons-nous éviter d'utiliser la fonction normalisedouble ?

ou peut-être... j'ai pensé que nous pouvons utiliser lafonction MathRound

ex . double x= (MathRound( 1.37883 * 100000)) / 100000 ;

Ainsi, nous pouvons créer la fonction

double round ( double value )

{ int D= MathPow(10,Digits);

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

return(x);

} 
 
*Il secoue sa cravate en position avec deux doigts* N'utilisez normalize double que dans les calculs impliquant une valeur double et pas seulement partout où il y a un double.
 
tonny:
*N'utilisez NormalizeDouble que dans les calculs impliquant une valeur double et non pas partout où il y a un double.
Ou bien n'utilisez pas du tout NormalizeDouble(), la plupart du temps, lorsqu'il est utilisé, il n'est absolument pas nécessaire de l'utiliser... L'erreur 4107 peut être résolue en utilisant NormalizeDouble(), mais il existe d'autres moyens. Tout prix provenant de variables prédéfinies ou de fonctions de séries chronologiques n'aura jamais besoin d'être normalisé, pas plus que le résultat d'un nombre entier multiplié par Point.
 
WDholic:

Devons-nous éviter d'utiliser la fonction normalisedouble ?

ou peut-être... j'ai pensé que nous pourrions utiliser la fonction MathRound

ex . double x= (MathRound( 1.37883 * 100000)) / 100000 ;


Vous vous retrouvez quand même avec un double et toujours la possibilité de prix != prix

Je suis arrivé à cette solution qui transforme les doubles en ints dans le but de comparer les doubles . . .

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

de sorte que...

Flat(price) != Flat(price)

ne sera jamais vrai.

 
Beaucoup de calculs au lieu d'une solution simple.