== operation - page 2

Tjipke de Vries
6875
Tjipke de Vries  
Ovo:

Not sure why you are quoting me. The thread is about comparison of double precision numbers.


Why didn't you give example with

For example, the average value (Moving Average) and the Open value of the Bar.

like the OP posted ??

Your example is something different with that example

the first tick of each new bar start with High[0] == Open[0] && Close[0] == Open[0] ....

Ex Ovo Omnia
3118
Ex Ovo Omnia  
deVries:


Why didn't you give example with

For example, the average value (Moving Average) and the Open value of the Bar.

like the OP posted ??

Your example is something different with that example

the first tick of each new bar start with High[0] == Open[0] && Close[0] == Open[0] ....


What example did you mean? I do not care if moving average could ever match whatever. I stated that comparing doubles worked with quotes from broker, but might fail if calculation was involved. I am not gonna provide any example nor prove.
[Deleted]  
RaptorUK:
Yes there is . . . read and understand this ? Can price != price ?


First, thanks guy. A newbie like me really appreciated your help. yes I did read it Raptor ^^. But you said it yourself: "Any price that comes from Predefined Variables or timeseries functions will never need to be Normalized, neither will the result of an integer multiplied by Point." In this case, those High[], Low[], Open[] are all predefined variables, are they not? They should be already at the correct precision. We only need to normalize a double when we do some messy calculation like " High[1] * 0.919193 - Open[1]". I think the reason is like GumRai said,
GumRai:

If the last tick of the old bar comes in and the next tick comes very quickly, your expert may miss the first tick of the new bar and only calculate on the second. Especially if latency is poor. That is why indicators usually recount 2 bars.
It appears that this is not sensitive enough T_T to catch all the prices when new ticks come.
if(High[0] == Open[0] && Close[0] == Open[0]){
Alert("Message");
}
Simon Gniadkowski
17410
nguye235:

First, thanks guy. A newbie like me really appreciated your help. yes I did read it Raptor ^^. But you said it yourself: "Any price that comes from Predefined Variables or timeseries functions will never need to be Normalized, neither will the result of an integer multiplied by Point." In this case, those High[], Low[], Open[] are all predefined variables, are they not? They should be already at the correct precision. We only need to normalize a double when we do some messy calculation like " High[1] * 0.919193 - Open[1]". I think the reason is like GumRai said,
They are the correct precision to use with a trading function, but they are still a double value and 1.22334 may actually be 1.223340000000001 comparing doubles is not straightforward, you need to understand the issues and do it properly.
Ian Venner
2400
Ian Venner  

if you do it like this, it will work every time open is supposed to equal close unless a tick is missed.

   int open = Open[0]/Point;
   int close = Close[0]/Point;
  
   if(open == close)
   Alert("open = ",open*Point,"  close = ",close*Point);
Simon Gniadkowski
17410
SDC:

if you do it like this, it will work every time open is supposed to equal close unless a tick is missed.

Is that guaranteed ? isn't it possible that Open[0] might be 0.000000000001 under the displayed value while Close[0] is 0.00000000001 over the displayed value, one will be rounded up the other down.
[Deleted]  

can we just round the price to eight decimal place by

int a = (int) (Open[0] * 100000000);
int b = (int) (Close[0] * 100000000);
if(a == b)
Alert("....");

The number after the 8th decimal place is very small anyway. They don't matter much, so can we just ignore them?

Ian Venner
2400
Ian Venner  
RaptorUK:
Is that guaranteed ? isn't it possible that Open[0] might be 0.000000000001 under the displayed value while Close[0] is 0.00000000001 over the displayed value, one will be rounded up the other down.

Your scenario requires Open[0] = 1.2344999999999999 while the displayed value is 1.2345 I didnt think that was even possible have you ever heard of that happening ?

Ian Venner
2400
Ian Venner  

I decided this is time for a scientific test :)

We know if a price is 1.2344999999999999 and we convert it to integer ( int = price/Point) the integer value would be 12344

if we NormalizeDouble() that same price it would be 1.2345 convert that Normalized double to integer ( int = price/Point) is integer value 12345

that allows for a direct if int == int comparison test, if there really are price doubles that would give an incorrect integer value by direct conversion because they are so slightly under the actual price, this indicator will find them.

Script to test all the prices on the chart.

int start()
  {
   int iHighPrice,iLowPrice,iOpenPrice,iClosePrice;
   int iRoundedHigh,iRoundedLow,iRoundedOpen,iRoundedClose;
   double RoundedHigh,RoundedLow,RoundedOpen,RoundedClose;
   static int pass,fail,sum;
//----
   int i=Bars-1;
   while(i>=0)
   {
//---- convert price doubles directly to integers
    iHighPrice = High[i]/Point;
    iLowPrice  = Low[i]/Point;
    iOpenPrice = Open[i]/Point;
    iClosePrice = Close[i]/Point;  
//---- round price doubles
    RoundedHigh = NormalizeDouble(High[i],Digits);
    RoundedLow = NormalizeDouble(Low[i],Digits);
    RoundedOpen = NormalizeDouble(Open[i],Digits);
    RoundedClose = NormalizeDouble(Close[i],Digits);
//---- convert rounded price doubles to integers
    iRoundedHigh = RoundedHigh/Point;
    iRoundedLow = RoundedLow/Point;
    iRoundedOpen = RoundedOpen/Point;
    iRoundedClose = RoundedClose/Point;
//---- compare the two integer values
    if(iHighPrice == iRoundedHigh)
    pass++;
    else fail++;
    if(iLowPrice == iRoundedLow)
    pass++;
    else fail++;
    if(iOpenPrice == iRoundedOpen)
    pass++;
    else fail++;
    if(iClosePrice == iRoundedClose)
    pass++;
    else fail++;    
//----
    sum+=4;
    i--;
   }
   Alert(sum," prices checked");
   Alert(pass," prices passed test");
   Alert(fail," prices failed test");
//----
   return(0);
  }

Output:

EURUSD,M1: Alert: 263452 prices checked

EURUSD,M1: Alert: 228388 prices passed test

EURUSD,M1: Alert: 35064 prices failed test


So Raptor is right, the scenario where a price double can be slightly less than the displayed price does happen, and it happens a lot. Converting them directly to integers would round them down to the wrong value. I didn't think that would actually happen at all, I'm suprised how often that happened.

Ian Venner
2400
Ian Venner  

I decided to mathround the prices to round out those offending decimal places so I modified the test script:

int start()
  {
   int iHighPrice,iLowPrice,iOpenPrice,iClosePrice;
   int iRoundedHigh,iRoundedLow,iRoundedOpen,iRoundedClose;
   double RoundedHigh,RoundedLow,RoundedOpen,RoundedClose;
   static int pass,fail,sum;
//----
   int i=Bars-1;
   while(i>=0)
   {
//---- round double prices and convert to integers
    iHighPrice = MathRound(High[i]/Point);
    iLowPrice  = MathRound(Low[i]/Point);
    iOpenPrice = MathRound(Open[i]/Point);
    iClosePrice = MathRound(Close[i]/Point);  
//---- normalize price doubles and convert to integer
    iRoundedHigh = NormalizeDouble(High[i]/Point,Digits);
    iRoundedLow = NormalizeDouble(Low[i]/Point,Digits);
    iRoundedOpen = NormalizeDouble(Open[i]/Point,Digits);
    iRoundedClose = NormalizeDouble(Close[i]/Point,Digits);
//---- compare the two integer values
    if(iHighPrice == iRoundedHigh)
    pass++;
    else fail++;
    if(iLowPrice == iRoundedLow)
    pass++;
    else fail++;
    if(iOpenPrice == iRoundedOpen)
    pass++;
    else fail++;
    if(iClosePrice == iRoundedClose)
    pass++;
    else fail++;    
//----
    sum+=4;
    i--;
   }
   Alert(sum," prices checked");
   Alert(pass," prices passed test");
   Alert(fail," prices failed test");
//----
   return(0);
  }

output:

EURUSD,M1: Alert: 263452 prices checked

EURUSD,M1: Alert: 263452 prices passed test

EURUSD,M1: Alert: 0 prices failed test

so it appears it is accurate to do

int open = mathround(Open[0]/Point);

int high = mathround(High[0]/Point);

if(open == high)