You are depending on the host chart receiving a quote from your broker if you run an EA with your code in the OnTick() event. Masses of stuff can be happening to the other pairs and your bot will not pick them up.
The solution is the OnTimer() function. You have to add this yourself:
Code: Select all
void OnTimer()
{
//Call all your functions that were previously called from OnTick().
//OnTick() will be empty.
}//End void OnTimer()
Code: Select all
extern int EventTimerIntervalSeconds=1;
Code: Select all
//create timer
//EventSetTimer(EventTimerIntervalSeconds);
secureSetTimer(EventTimerIntervalSeconds);//Explanation at the top of the function
Code: Select all
bool secureSetTimer(int seconds)
{
//This is another brilliant idea by tomele. Many thanks Thomas. Here is the explanation:
/*
I am testing something René has developed on Eaymon's VPS as well as on Google's VPS. I ran into a problem with EventSetTimer().
This problem was reported by other users before and apparently occurs only on VPS's, not on desktop machines. The problem is that
calls to EventSetTimer() eventually fail with different error codes returned. The EA stays on the chart with a smiley (it
is not removed), but no timer events are sent to OnTimer() and the EA doesn't act anymore.
The problem might be caused by the VPS running out of handles. A limited number of these handles is shared as a pool
between all virtual machines running on the same host machine. The problem occurs randomly when all handles are in use
and can be cured by repeatedly trying to set a timer until you get no error code.
I have implemented a function secureSetTimer() that does this. If you replace EventSetTimer() calls with secureSetTimer()
calls in the EA code, this VPS problem will not affect you anymore:
*/
int error=-1;
int counter=1;
do
{
EventKillTimer();
ResetLastError();
EventSetTimer(seconds);
error=GetLastError();
Print("secureSetTimer, attempt=",counter,", error=",error);
if(error!=0) Sleep(1000);
counter++;
}
while(error!=0 && !IsStopped() && counter<100);
return(error==0);
}
In the rational world, the result of dividing 1 by 2 is 0.5, even if the result is held in a double so,
double someNumber = 1 /2;
results in someNumber being zero, not 0.5
The second concerns comparing doubles. Suppose you declare two doubles i.e.
Code: Select all
double num1 = 0, num2 = 0;
Code: Select all
if (num1 == num2)
{
//Do something
}
Variable declared as 'double' have 8 decimal points, so the equation should be comparing two values of 25.00000000 each. The compiler sometimes adds an extra 1 to the final decimal point, so one of the numbers might contain 25.00000001. They are unequal so the equation fails. Sane programming languages have the fix for this installed. CrapQl4 doesn't, or at least did not, so we have a function provided by garyfritz a long time ago:
Code: Select all
bool closeEnough(double num1,double num2)
{
/*
This function addresses the problem of the way in which mql4 compares doubles. It often messes up the 8th
decimal point.
For example, if A = 1.5 and B = 1.5, then these numbers are clearly equal. Unseen by the coder, mql4 may
actually be giving B the value of 1.50000001, and so the variable are not equal, even though they are.
This nice little quirk explains some of the problems I have endured in the past when comparing doubles. This
is common to a lot of program languages, so watch out for it if you program elsewhere.
Gary (garyfritz) offered this solution, so our thanks to him.
*/
if(num1==0 && num2==0) return(true); //0==0
if(MathAbs(num1 - num2) / (MathAbs(num1) + MathAbs(num2)) < 0.00000001) return(true);
//Doubles are unequal
return(false);
}//End bool closeEnough(double num1, double num2)
Code: Select all
if (closeEnough(num1, num2) )
{
//Do something
}