Download MetaTrader 5

Can price != price ? - page 7

To add comments, please log in or register
Roel
490
Roel  

WHRoeder: this code good (especially check "added" and "default")? It may also serve as an easy final-reference for those who visit this thread and just go the last page (as I did)

#define LT    0
#define GT    1
#define GTE   2
#define LTE   3
#define EQ    4
#define NEQ   5

bool doublecomp(double a,int type,double b){
  // See https://forum.mql4.com/45053/page4
  // 0 compare doesn't need this function
  switch(type){
    case LT: return(b-a>Point/2.);
    case GT: return(a-b>Point/2.);
    case GTE: return(a-b>-Point); // Added
    case LTE: return(b-a>-Point); // Added
    case EQ: return(!(MathAbs(a-b)>Point/2.));
    case NEQ: return(MathAbs(a-b)>Point/2.);
    default: return(-1); // Added - needed to avoid compile error about not all control paths returning a value
  }
}
Ian Venner
2584
Ian Venner  

That code is not accurate.

How can if( !MathAbs( a - b ) > Point/2) be used to compare for equality? That would tell you 1.4999 == 1.5000

whroeder1
16086
whroeder1  
SDC: How can if( !MathAbs( a - b ) > Point/2) be used to compare for equality? That would tell you 1.4999 == 1.5000
  1. It doesn't
    if( ! (MathAbs( a     -  b    ) > Point/2) ) be used to compare for equality? That would tell you 1.4999 == 1.5000
    if( ! (MathAbs(1.4999 - 1.5000  > 0.00005  )
    if( ! (0.0001                   > 0.00005  )
    if( ! (true                                )
    if( false                                  ) 1.4999 is NOT equal to 1.5000
  2. And I had pointed out to Roel13 in a PM that the GEQ/LEQ must be -Point/2 but he didn't edit the post
  3. And as I previous posted, you only have to worry about such nonsense if the equality/non-equality is important. If you want to open above the high of a candle, does it matter if (because of rounding) that it might trigger at exactly the high? If no just use bid > high[].
Ian Venner
2584
Ian Venner  

I use

if(NormalizeDouble(price1-price2,Digits)==0)


or for doubles that arn't actual prices, a higher precision

if(NormalizeDouble(value1-value2,8)==0)
whroeder1
16086
whroeder1  
SDC: I use
if(NormalizeDouble(price1-price2,Digits)==0)
Read the very first post and you'll learn why that isn't a good idea.
Ian Venner
2584
Ian Venner  

Raptors post about this code

double TestValue = iClose(NULL, 0, 0);
   
if(TestValue != NormalizeDouble(TestValue, Digits) ) //not equal

 

So if you use,

double TestValue = iClose(NULL, 0, 0);

if(NormalizeDouble(TestValue - iClose(NULL,0,0),Digits)==0) // they are considered equal

 I have tested that method in a variety of ways I have not found a scenario where it would not return the expected or desired result.
Roel
490
Roel  

Final code... Thanks WHRoeder

#define LT    0
#define GT    1
#define GTE   2
#define LTE   3
#define EQ    4
#define NEQ   5

bool ComparePrice(double a,int type,double b){
  // See https://forum.mql4.com/45053/page4
  // 0 compare doesn't need this function
  switch(type){
    case LT: return(b-a>Point/2.);
    case GT: return(a-b>Point/2.);
    case GTE: return(a-b>-Point/2.);
    case LTE: return(b-a>-Point/2.);
    case EQ: return(!(MathAbs(a-b)>Point/2.));
    case NEQ: return(MathAbs(a-b)>Point/2.);
  }
  return(-1);
}


And, maybe a secondary function for comparing all other doubles that are not prices...

bool CompareNormal(double a,int type,double b){
  // With thanks https://forum.mql4.com/45053/page4
  // 0 compare doesn't need this function
  switch(type){
    case LT: return(b-a>0.0000000000000000000000000000001);
    case GT: return(a-b>0.0000000000000000000000000000001);
    case LTE: return(b-a>-0.0000000000000000000000000000001);
    case GTE: return(a-b>-0.0000000000000000000000000000001);
    case EQ: return(!(MathAbs(a-b)>0.0000000000000000000000000000001));
    case NEQ: return(MathAbs(a-b)>0.0000000000000000000000000000001);
  }
  return(-1);
}


See also 'MQL4 Reference > Language Basics > Data Types > Real Types (double, float)' in regards using small number for comparision.

Maybe someone knows how to write 0.00...1 better in expon

whroeder1
16086
whroeder1  
Roel13: Maybe someone knows how to write 0.00...1 better in expon
// case LT: return(b-a>0.0000000000000000000000000000001);
// case LT: return(b-a>1.0e-30);
See Real Types (double, float) - MQL4 Documentation
Noted that the value of epsilon in the above example can not be less than the predefined constant DBL_EPSILON. The value of this constant is 2.2204460492503131e-016.
Again, none of this is necessary, except in the case where the equals/not equals is important. E.g. open above the previous high, you don't want to open at the high due to round off.
Roel
490
Roel  

So there is something else interesting I found, potentially in connection with "// 0 compare doesn't need this function".

Maybe a bug only in the latest versions, not sure. Comparing with 0 no longer functions correctly. I had to resort to something unfriendly like;

outcome=(int(outcome*100)/100.0);    // Resolution 2 digits

Just to ensure that 0 values actually ended up as 0 values.

WHRoeder, thanks. More study needed :)

To add comments, please log in or register