¿Puede el precio != el precio ? - página 2

 

Si es para comparar, entonces podrías crear fácilmente tu propia función:

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

Es sólo una idea.

 
heelflip43:

Si es para comparar, entonces podrías crear fácilmente tu propia función:

Es sólo una idea.


Es una buena idea, gracias por ella :-)
 

El uso de "Punto" o "Punto/2.0" no es un valor de diferencia muy bueno, IMO. El error de redondeo introducido por NormalizeDouble (que me quemó hoy), es sin duda mucho menor que 8 dígitos, más bien 15 dígitos.

Teniendo en cuenta los consejos anteriores, y hecho algunos cambios y poner juntos la siguiente rutina que parece funcionar bien (incluso utilizando el "diff" a 15 decimales), aunque no ha sido rigurosamente probado todavía:

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

Aquí hay otra posible rutina que puede comparar, pero también puede normalizar internamente A y/o B, y también relajará la diferencia de comparación (de A-B o B-A) a un número mayor basado en "dígitos". Dudo que esta rutina sea necesaria en comparación con la simple "AvsB" de arriba, pero se ofrece para su uso como se desee:

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

El uso de "Punto" o "Punto/2.0" no es un valor de diferencia muy bueno, IMO. El error de redondeo introducido por NormalizeDouble (que me quemó hoy), es sin duda mucho menor que 8 dígitos, más bien 15 dígitos.

Usted quiere el valor más grande que no puede ser considerado como un error de redondeo o, equivalentemente, el valor más pequeño que no puede ser considerado como un cambio de precio. Dado que los precios sólo pueden cambiar por un múltiplo de punto, punto/2 es justo eso.

El valor doble del corredor podría estar en cualquier lugar desde 1,23457500000000 hasta 1,234584999999999 y seguir considerándose el mismo precio de 1,23458.

Si hubieras utilizado esto, no habrías tenido el problema:

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

¿debemos evitar el uso de normalisedouble?

o tal vez... se me ocurre que podemos usarla función Math Round

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

así podemos hacer la función

double round ( double value )

{ int D= MathPow(10,Digits);

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

return(x);

} 
 
*Agita su corbata en posición con dos dedos* Sólo utiliza normalizar doble en los cálculos que implican un valor doble, no sólo en todos los casos en que hay un doble.
 
tonny:
*Agita su corbata en posición con dos dedos* Sólo usa normalizeDouble en cálculos que involucren un valor doble, no en cualquier lugar donde haya un doble.
O simplemente no use NormalizeDouble() en absoluto, la mayoría de las veces cuando se usa no hay absolutamente ninguna necesidad de usarlo... el error 4107 puede ser resuelto usando NormalizeDouble(), pero hay otras maneras. Cualquier precio que provenga de Variables Predefinidas o funciones de series de tiempo nunca necesitará ser Normalizado, tampoco el resultado de un entero multiplicado por Punto.
 
WDholic:

¿debemos evitar el uso de normalisedouble?

o tal vez... se me ocurre que podemos usar la función MathRound

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


Usted todavía termina con un doble y todavía la posibilidad de precio != precio

He llegado a esta solución que convierte los dobles en ints para poder comparar los dobles . . .

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

de modo que . . .

Flat(price) != Flat(price)

nunca sea cierto.

 
A mucho cálculo en lugar de la solución simple