Some background on short circuit evaluation (skip this if you already know what it is):
Examine this if statement with a logical OR operator:
int A=1; int B=2; if(A=1 || B=6){ do stuff; }
If there is short circuit evaluation(“SCE”), as long as the leftmost condition fulfills, the entire if OR statement fulfills and passes control to the next line.
If there is no SCE, even though A may be true, the code will still check what B is.
Similarly for an if statement with a logical AND operator:
int A=1; int B=2; if(A!=1 && B=2){ do stuff; }
With SCE, A!=1 returns FALSE hence does not proceed to check what B is, resulting in a correct FALSE output for the whole if statement.
Without SCE, even though A!=1 returns FALSE, B is still checked even though we already know the if statement will output FALSE regardless of what the value of B is.
How can mql4’s AND and OR operators be checked for short circuit evaluation?
As a breakpoint can’t be placed within an if statement in C much less mql4 (I’m sure someone will be able to point out otherwise), a workaround is to make the 2nd operand an illegal operation and the 1st operand not lead up to it.
A simple EA to test the OR operator:
mql4 OR Short Circuit Evaluation Test.mq4
extern double numerator = 1; extern double denominator = 0; int init(){ if(1>0 || numerator/denominator)Print("numerator/denominator = ", numerator/denominator); return(0); } int start(){ return(0); }
Since the left operand, 1 > 0, returns TRUE, we can expect the whole if statement to return TRUE.
With SCE, the 2nd operand, numerator/denominator, is not performed.
Without SCE, the 2nd operand will execute regardless that the 1st operand already returned TRUE, and thereby giving a zero divide error for denominator with value of 0.
Notes:
1. Added the numerator and denominator as external variables to play around with, the statement could simple be written as if(1>0 || 1/0).
2. Initially wrote it as a script but the zero divide prevented any printing in the Journal tab, hence it’s an EA to be run in the Strategy Tester.
With denominator=2, we see:
When run in the Strategy Tester, with denominator=0, we see:
Hence, mql4’s OR operator does not have SCE.
Similarly for the AND operator:
mql4 AND Short Circuit Evaluation Test.mq4
extern double numerator = 1; extern double denominator = 0; int init(){ if(denominator!=0 && numerator/denominator)Print("numerator/denominator = ", numerator/denominator); return(0); } int start(){ return(0); }
Since the left operand, denominator!=0, returns FALSE, we expect that the whole if statement will return FALSE.
With SCE, the 2nd operand, numerator/denominator, is not performed.
Without SCE, the 2nd operand will execute even though the 1st operand already returned FALSE, and thereby giving a zero divide error for denominator with value of 0.
With denominator=2, we see:
When run in the Strategy Tester, with denominator=0, we see:
Ergo, mql4’s AND operator does not have SCE too.
Unlike ANSI-standard C/C++, mql4’s AND and OR operators do not perform SCE.
What’s the big hairy point?
1. SCE makes code run faster, particularly for multiple AND or OR operations. Two things that trading algorithms are particularly fond of.
2. While improvements will be in the sub-ms range per pass, backtesting should be sped up for large histories.
For mql4, you can work around this by cascading your if statements for AND operations, and duplicating results for OR operations.
Couple that with efficient function calling (more on that in a future post), I’ve shaved about 30% off my backtesting time, which is insanely time consuming.
Update 2013-04-03:
A good way to avoid || or && is to convert the multiple || or && statement into a single arithmetic to be assigned to a variable to be polled.
It’s not correct that MQL4 dosen’t evaluate short-circuit AND and OR.
Instead the test code is not correct:
if(1>0 || numerator/denominator) Print(“numerator/denominator = “, numerator/denominator);
In this code, 1>0 is evaluated to true and the expression numerator/denominator is not evaluated (short-circuit). But since the if-condition is true, the Print-expression is executed, and there is a division by zero that causes the EA to stop with the error. If one replaces the Print-expression e.g. by Print(“Hallo world”), one sees that the if-condition is evaluated without division by zero.
Thanks for the input. I’ve only just gotten round to reviewing comments. >.<
The post was done in 2013, and since MT4 build 600 onwards (2014.02.04), Metaquotes added short circuit evaluation to MQL.
See: https://www.mql5.com/en/forum/149271
"Shortened conditions check is now used in logical operations, unlike the old MQL4 version where all expressions have been calculated and the check has been performed afterwards."
As an addendum, there's simpler ways to check for evaluation and that would be to simply assign a variable and print it after the check is made. No need to muck around with zero divide.