Conditional Statement failure... [At wits end] if ( 1.4225 > 1.4225) is NOT TRUE!!!!!! - page 2

 
Hi John McGlaughlin,


Of course, normalization before doubles comparison is implied.
In any way, sign is more reliable part of floating-point number than mantissa.

For example, following code of AIS2 Trading Robot works perfectly:

...

//< 7.6.2. Trailing Logic 18 >                                                                                //< 464>
         //<  Buy Orders Trailing Rules >                                                                     //< 465>
         if ( OrderType       () == OP_BUY                                                                  ) //< 466>
         if ( OrderProfit     ()  > 0                                                                       ) //< 467>
         if ( NormalizeDouble ( avd.QuoteTrail     - avd.QuoteStops                      , avi.Digits ) > 0 ) //< 468>
         if ( NormalizeDouble ( avd.QuoteTrail     - avd.QuoteFreeze                     , avi.Digits ) > 0 ) //< 469>
         if ( NormalizeDouble ( OrderTakeProfit () - avd.QuoteBid       - avd.QuoteStops                      //< 470>
                                                                                         , avi.Digits ) > 0 ) //< 471>
         if ( NormalizeDouble ( avd.QuoteBid       - OrderStopLoss ()   - avd.TrailStep  - avd.QuoteTrail     //< 472>
                                                                                         , avi.Digits ) > 0 ) //< 473>
              avd.Stop        = NormalizeDouble (    avd.QuoteBid       - avd.QuoteTrail , avi.Digits     ) ; //< 474>
         //</ Buy Orders Trailing Rules >                                                                     //< 475>
                                                                                                              //< 476>
         //<  Sell Orders Trailing Rules >                                                                    //< 477>
         if ( OrderType       () == OP_SELL                                                                 ) //< 478>
         if ( OrderProfit     ()  > 0                                                                       ) //< 479>
         if ( NormalizeDouble ( avd.QuoteTrail     - avd.QuoteStops                      , avi.Digits ) > 0 ) //< 480>
         if ( NormalizeDouble ( avd.QuoteTrail     - avd.QuoteFreeze                     , avi.Digits ) > 0 ) //< 481>
         if ( NormalizeDouble ( avd.QuoteAsk       - OrderTakeProfit () - avd.QuoteStops                      //< 482>
                                                                                         , avi.Digits ) > 0 ) //< 483>
         if ( NormalizeDouble ( OrderStopLoss   () - avd.QuoteAsk       - avd.TrailStep  - avd.QuoteTrail     //< 484>
                                                                                         , avi.Digits ) > 0 ) //< 485>
              avd.Stop        = NormalizeDouble (    avd.QuoteAsk       + avd.QuoteTrail , avi.Digits     ) ; //< 486>
         //</ Sell Orders Trailing Rules >                                                                    //< 487>
//</7.6.2. Trailing Logic 18 >                                                                                //< 488>

... 

Best regards,

Airat Safin

 
Ais:
Hi John McGlaughlin,


Of course, normalization before doubles comparison is implied.
In any way, sign is more reliable part of floating-point number than mantissa.

For example, following code of AIS2 Trading Robot works perfectly:

Best regards,

Airat Safin

Ah, this helps.

I still have to wrap my mind around many of the MQL quirks.

I did not grok to normalize the test as well.


Don't you agree though,

that for the language to generate a -0 resultant is a BUG that should be fixed?

see https://forum.mql4.com/21244


Thanks for this help

John

 
cloudbreaker:

Its in the stdlib.mq4 library.

Thanks for the clarification.

the CompareDoubles(d1, d2) returns a bool which I presume is true or false for ==.

My problem only occurs when d1==d2 for the relation < or > in which case the language intermittently responds with a "-0" negative 0


I have somewhat tracked this to the USE of the NormalizeDouble(d,p) funciton but have not found a repeatable solution for proving it's existence beyond the log snippets I have provided. At any rate this will have to wait as I have to complete this EA for customers before I continue to look for bugs in MQL4.


Thanks to everyone for getting me back with workarounds.


John

 
johnmcglaughlin:

Ah, this helps.

I still have to wrap my mind around many of the MQL quirks.

I did not grok to normalize the test as well.


Don't you agree though,

that for the language to generate a -0 resultant is a BUG that should be fixed?

see https://forum.mql4.com/21244


Thanks for this help

John

John regarding the use of CompareDoubles(), did you see my reply that its in the stdlib.mq4 library?

Its not an MQL quirk, but is common in precision maths across programming languages.

 

Hi Friends,


Zero with sign is a well known feature of IA-32.
There are great lot of coprocessor's commands and situations that generate this valid result.
MQL4 just transmits the result to us.


Best regards,

Ais

 
Ais wrote >>

Hi Friends,


Zero with sign is a well known feature of IA-32.
There are great lot of coprocessor's commands and situations that generate this valid result.
MQL4 just transmits the result to us.


Best regards,

Ais

Hi AIS,

I'm afraid I will have to respectfully disagree with you on this.

In math a zero is a zero, no matter what sign is attached to it. Just because the hardware presents a fault like that doesn't mean that the programmer is absolved of the responsibility to fix it. Let me give an example:

If you look at the resource manager in Windows Vista you will likely see a bunch of memory faults in the statistics. Now, Microsoft could just say "that's a hardware problem", and not do anything about it. But we all know that wouldn't go over very well. So instead, they have written some complex algorithms to constantly check the integrity of data stored in memory and fix problems as they arise - due to smaller and smaller die fab processes that drive up volatile memory errors. As a result, we have an operating system that keeps working (most of the time).

So, it is my position that if two doubles are normalized to a specific number of digits and compared, there is no excuse for a failure to see that they are actually equal - in a command that claims to do this. In my opinion, this is an MQL bug.

That's my position. Anyone who has chimed in on this or other similar topics is certainly free to disagree, but I can't think of a good argument for not fixing this problem.

- Tovan

 

I'm comnig in late to this thread, but just for grins (humor me here...)

Try calling the 2 variables something entirely different... instead of:

"trigger" and "triggerAnchor"....

Call them "trigger" and "myAnchor"

See if that resolves it...

(25 yrs programming here... just have a hunch - may be nothing)

 
tovan:

Hi AIS,

I'm afraid I will have to respectfully disagree with you on this.

In math a zero is a zero, no matter what sign is attached to it. Just because the hardware presents a fault like that doesn't mean that the programmer is absolved of the responsibility to fix it. [...] In my opinion, this is an MQL bug.

Er, everyone's right, but it's a question of practicalities rather than principles?


There is indeed no reason, in principle, why a high-level language such as MQL should pass on the quirks of the floating point unit deep down in the hardware. Equally, there's no intrinsic reason why an int in MQL should be 32 bits long rather than, say, 57 bits long, or even for there to be an int data type as well as a double data type. More realistically, there's no reason in principle why MQL shouldn't provide the equivalent of something like the Decimal data type in .NET, either as well as or instead of the double data type.


But surely the reason why MQL does these things is speed? Code runs a lot faster if data types and operations map directly onto the artefacts of the underlying processor. MQL/MetaTrader would be significantly slower either if it used the equivalent of a Decimal internally throughout, or if it used doubles internally but had to translate to and from doubles when interpreting MQL code.


If you've got a copy of Visual Studio, try out the following C# and see how long it takes to execute:


double X = 0.3333;

for (int i = 0; i < 10000000; i++)

{

X *= 10;

        X /= 10;

        X += 10;

        X -= 10;

}


And then try declaring X as a decimal rather than a double. It's about 10 times slower.


 

Hi Friends,


It is a little fun that processor developers generate quirks.
But:
1. I agree that modern hardware is far a well from absolute perfection;
2. my choice of priority between hardware and software is hardware;
3. hardware is primary, software is secondary;
4. in this case any change of hardware response is a great liability;
5. MQL4 and MQL5 are positioned as superpowerful environments for advanced programmers;
6. every advanced programmer must know hardware as deep inside as possible;
7. example: every pilot must know his plane as deep inside as possible.


Best regards,
Ais

 
Ais:

Hi Friends,


It is a little fun that processor developers generate quirks.
But:

o

o

o

Best regards,
Ais

So then,


I have to agree with Ais to use the silly work around of ( D1 - D2 <relation> 0 ) because it is a magnitude faster. Indeed I want to be able to process another order if possible either to get into one more profitable trade or exit a head fake one PIP early.


HOWEVER; A VERY CLEAR article should be written on double arithmatic to address relationships such as a<b where a=b is false and not true.


BTW

I have just run into another little gem

when calculating take profit micro mini lots. The following MathCeil() is intermittently failing


NOTE: that as I was looking at all profitable trades I notice that the -0 is intermittently showing itself.

//+------------------------------------------------------------------+
//|                                                  PercentLots.mq4 |
//|                  Copyright © 2009, Vampire Trading Network, Inc. |
//|                                 http://VampireTradingNetwork.com |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2009, Vampire Trading Network, Inc."
#property link      "http://VampireTradingNetwork.com"

//+------------------------------------------------------------------+
//| PercentLots (double percent)
//|   Compute lots based on normalized percent
//--------------------------------------------------------------------
//| percent    Normalized percent 1 == 100 .5 = 50
//| Lots       pre calculation lots on OrderClose
//| _lots      percent lots to Close
//| lotStep    MathInfo(Symbol, MODE_LOTSTEP)
//| 
//| lots       Global lots to remain on trade
//| 
//| return     percent _lots to close
//+------------------------------------------------------------------+
double PercentLots(double percent) {
   // normalize the lots
   double   Lots  = lots,
            _lots = lots / lotStep;
   
   // calculate the percent lots and remainder
   _lots = MathCeil(_lots * percent) * lotStep;

   // update global lots left to trade
   lots  = lots - _lots;
   Log (DEBUG_ORDERS, StringConcatenate("PercentLots(): percent: ", percent, " Lots: ", Lots, " _lots: ", _lots, " lots: ", lots));
   // return the ceiling lots
   return(_lots);
}
21:56:37 2008.09.15 12:32  VTN Expert Advisor I EURUSD,H1: DEBUG_ORDERS: PercentLots(): percent: 1 Lots: 0.56 _lots: 0.57 lots: -0.01
21:56:37 2008.09.15 12:32  VTN Expert Advisor I EURUSD,H1: OrderClose error 131

21:56:39 2008.09.15 21:35  VTN Expert Advisor I EURUSD,H1: DEBUG_ORDERS: PercentLots(): percent: 1 Lots: 1.12 _lots: 1.13 lots: -0.01
21:56:39 2008.09.15 21:35  VTN Expert Advisor I EURUSD,H1: OrderClose error 131

21:57:51 2008.10.08 08:01  VTN Expert Advisor I EURUSD,H1: DEBUG_ORDERS: PercentLots(): percent: 1 Lots: 2.49 _lots: 2.5 lots: -0.01
21:57:51 2008.10.08 08:01  VTN Expert Advisor I EURUSD,H1: OrderClose error 131

I am getting told text is too long I will put it in another topic

Reason: