Old Tick Value and Trade Context Busy quadrupled?

 

Can anyone explain what has been changed to cause 4X the frequency of these calls. I am testing an EA on 'real' time, not back testing, but am now 'being allowed' 1 trade in 8 (average). The EA is the same, and was making 98 out of 100 trades correctly (win 70%, lose 30%), on platform 225 with IBFX and FXDD.

I guess a secondary question would be why one has to download a 'new' copy of 'old' data (suggested to reduce old tick value trade rejects) if it is past data and not supposed to change anymore? Makes me wonder just what extra 'triggers' were included to benefit the carrier of the trades being placed.

LimeyLad51

 
LimeyLad51:

Can anyone explain what has been changed to cause 4X the frequency of these calls.

I don't have either and I doubt it has anything to do with the latest update (the forum should have been full of complaints if that was the case). Anyway, the reason for both errors is known:

  • 'Old Tick' error means there was an 'error of time synchronization between trade server and data center' (https://www.mql5.com/en/forum/103754). It's basically a tick with a bad timestamp arriving at the Terminal. This tick is filtered and the error is logged for informational purposes only (and can safely be ignored). These do not affect the platform or running EA's. From my personal experience I can tell u that these tend to happen more if your connection to the broker is bad (large latency, too many hops, internet drops, etc.).
  • 'Trade Context' errors mean u are running more than one EA and they are badly designed - they don't know how to share the trade context. There's an explanation and a proved method to deal with these errors in this article -> Error 146 ("Trade context busy") and How to Deal with It.

I am testing an EA on 'real' time, not back testing, but am now 'being allowed' 1 trade in 8 (average). The EA is the same, and was making 98 out of 100 trades correctly (win 70%, lose 30%), on platform 225 with IBFX and FXDD.

What do u mean "being allowed"? Check what errors u get and deal with them... If u are sure the problem lies with build 226, there is nothing preventing u from downgrading to check your claim.


I guess a secondary question would be why one has to download a 'new' copy of 'old' data (suggested to reduce old tick value trade rejects) if it is past data and not supposed to change anymore?

You don't need to that, it's not going to reduce 'old tick' errors and these errors do not cause 'trade rejects'.

 
gordon wrote >>

I don't have either and I doubt it has anything to do with the latest update (the forum should have been full of complaints if that was the case). Anyway, the reason for both errors is known:

  • 'Old Tick' error means there was an 'error of time synchronization between trade server and data center' (https://www.mql5.com/en/forum/103754). It's basically a tick with a bad timestamp arriving at the Terminal. This tick is filtered and the error is logged for informational purposes only (and can safely be ignored). These do not affect the platform or running EA's. From my personal experience I can tell u that these tend to happen more if your connection to the broker is bad (large latency, too many hops, internet drops, etc.).
  • 'Trade Context' errors mean u are running more than one EA and they are badly designed - they don't know how to share the trade context. There's an explanation and a proved method to deal with these errors in this article -> Error 146 ("Trade context busy") and How to Deal with It.

What do u mean "being allowed"? Check what errors u get and deal with them... If u are sure the problem lies with build 226, there is nothing preventing u from downgrading to check your claim.


You don't need to that, it's not going to reduce 'old tick' errors and these errors do not cause 'trade rejects'.


I appreciate the explanation - the clearest I've seen yet for those two problems. I would assume my phraseology is incorect but it seems that way (being allowed) when 225 gave none in 3 years, running the same EA on 6 charts for performance under different price movements, and 226 has given pages of them in the platform history.

You're right about badly written - but taking the bull by the horns is usually the way to get things right and never forget why. I appreciate the return and will try to sort out my inaccuracies with the trade and setup commands.

LimeyLad51

 
gordon:
  • 'Old Tick' ... These do not affect the platform or running EA's.

One thing I'd like to add to this. In most cases, Gordon, this is absolutely correct.

However, consider the following scenario - which actually happened to us whilst live-trading a considerable amount of money on behalf of clients:

The broker changed the date/time on their servers to the correct time but 3 days in the future.

One of our strategies (which was running on a number of accounts) understandably generated inappropriate order closes and opens.

When the broker set their clocks back to the correct date, the MT4 platforms (with perfect logic) started complaining about every valid tick being an old tick. This would have happened for 3 days until ticks dated later than the time that had been incorrectly set, started to arrive.

So in order to restore live trading, I reinstalled ALL of our MT4 trading instances in our hosting site which were talking to that particular broker.

And although the broker rectified the situation financially, the whole thing generated a lot of work for us.

CB

 

That's quite amazing... I wonder what happens if u accidentally setup the local computer time a few days in the past/future (as it's Saturday, I can't test this now). In this specific case 'old tick' was a symptom and not the problem itself, but I doubt that's what LimeyLad is having as I understand that in this case ALL ticks were filtered as 'old ticks'...


Although this seems to be an extremely rare case, perhaps adding code like this is a good idea:

if (MathAbs(TimeLocal()-TimeCurrent()) > 24*60*60) Alert("Critical error!");  //and send email/sms/etc. to alert the user

Not sure this would work though, cause maybe TimeCurrent() won't be updated since the ticks are filtered...?

 
That logic would never get run since start() isn't triggered due to Old Ticks (ie. every tick) being discarded. CB
 
cloudbreaker:
That logic would never get run since start() isn't triggered due to Old Ticks (ie. every tick) being discarded. CB
Yap. Silly me :)
 
cloudbreaker:

... However, consider the following scenario - which actually happened to us whilst live-trading a considerable amount of money on behalf of clients: ....

This is an invaluable information to share CB & all thank you.... Automated trading presently needs a lot of unnecessary precautions & anticipations IMHO (by individual customized programming). If this is not to be dealt with by Metaquotes I'm afraid It's gonna be like the idea of 'Automated Car Driving' a while back, which didn't get received well in our daily realms. MQ need to seriously listen/remedy this.
 
cloudbreaker:
That logic would never get run since start() isn't triggered due to Old Ticks (ie. every tick) being discarded. CB

I have an EA running on a seperate chart specifically to manage my connection issues. It calls start() inside init(). Start is nothing but sleeps and loops to to test connection and if there is no connection for 5 mins restarts terminal. Because of the endless loop in init, init never finishes loading so whether the terminal recieves a tick or not makes no difference to the running of this EA. It would seem to me that this set up would run Gordon's code..

Sadly, my connection problem isn't completely solved because on restart, if connection is not established, init() is not run and my method stalls.

Brazen advertising of my issue in a hope of finding a solution :)

https://www.mql5.com/en/forum/126166

V
 

The sad reality is that vast majority of old tick and context busy is almost always on the brokers' server side. As you all know, FXCM is notorious for this.

Are you saying, FXCM traders all write crappy EAs? No, some people needlessly stress over their codes when they get these messages when in

most likely case, it is your brokers' doing. If it is all working great and then complete stop due to these errors, assume that it is the brokers' side.

 

Old ticks, is a broker problem.

Trade context busy should only occur with multiple EAs (multiple charts) and usually when the server starts taking longer. Do your EA's have a semaphore to prevent this?

//+------------------------------------------------------------------+
//| Trade context semaphore.                                         |
//+------------------------------------------------------------------+
void    RelTradeContext(){      // Set global variable for GetTradeContext = 0
/*bool  need2refresh;           // Export=T to GetTradeContext=R|T|F,
                                // SetDIR=R|F, start=F, ModifyStops=R|F */
    need2refresh = true;        // Assume caller did a OrderSend/Modify/Close.
    while( !(IsTesting() || IsStopped()) ){
        GlobalVariableSet(TC.GV.Name, 0.0); // Unlock the trade context.
        int _GetLastError = GetLastError();
        if (_GetLastError == 0) break;
        Comment("RelTradeContext: GlobalVariableSet('",
                TC.GV.Name,"',0.0)-Error #", _GetLastError );   Sleep(1000);
    }
}   // void RelTradeContext()
int  Random(int min, int max){  return( MathRand()/32768.0*(max-min+1)+min );  }
#define ERR_146_MIN_WAIT_MSEC    1000   // Trade context busy random delay min
#define ERR_146_MAX_WAIT_MSEC    5000   // Trade context busy random delay max
void RandomSleep(){ Sleep(Random(ERR_146_MIN_WAIT_MSEC,ERR_146_MAX_WAIT_MSEC));}
#define ERR_146_TIMEOUT_MSEC    60000   // Trade context busy maximum delay
#include <stderror.mqh>                 // ERR_GLOBAL_VARIABLE_NOT_FOUND
int     GetTradeContext(int maxWaitMsec = ERR_146_TIMEOUT_MSEC){
//  bool    need2refresh;               // Import from RelTradeContext
    /*Return codes:*/{
        #define TC_LOCKED        0  //  Success. The global variable TC.GV.Name
    //                                  was set to 1, locking out others.
        #define TC_REFRESH      +1  //  Success. The trade context was initially
    //                                  busy, but became free. The market info
    //                                  needed to be refreshed. Recompute trade
    //                                  values if necessary.
        #define TC_ERROR        -1  //  Error, interrupted by the user. The
    //                                  expert was removed from the chart, the
    //                                  terminal was closed, the chart period
    //                                  and/or symbol was changed, etc.)
        #define TC_TIMEOUT      -2  //  Error, the wait limit was exceeded.
    /*************************************************************************/}
    if ( IsTesting() ){                     // Only one EA runs under the tester
        if (need2refresh)   Refresh();
        return(TC_LOCKED);                  // Context always available.
    }
    /* If there is no global variable, create it. If the variable == 1 wait
     * until another thread sets it back to 0. Set it to 1. */
    int     startWaitingTime    = GetTickCount(),   // Remember start time.
            GTCreturn           = TC_LOCKED;        // Assume an idle context.
    bool    TC_locked           = false;            // Not yet.
    while(true){
        if ( IsStopped() ){     // The expert was terminated by the user, abort.
            Print("GTC: The expert was terminated by the user!");
            if (TC_locked)  RelTradeContext();
            return(TC_ERROR);
        }
        if (!TC_locked) {                           // Set the semaphore.
            if (GlobalVariableSetOnCondition( TC.GV.Name, 1.0, 0.0 )){
                TC_locked=true;                     // Semaphore now set.
                continue;                           // Check for non-sema EAs.
            }
            int _GetLastError   = GetLastError();   switch(_GetLastError){
            case 0:                             // Variable exists but is
                break;                          // already set. Need to wait.
            case ERR_GLOBAL_VARIABLE_NOT_FOUND:
                GlobalVariableSet(TC.GV.Name, 0.0); // Create it.
                _GetLastError   = GetLastError();
                if (_GetLastError == 0) continue;
                Print(  "GetTradeContext: GlobalVariableSet(", TC.GV.Name,
                            ", 0.0) Failed: ",  _GetLastError );    // Error
                return(TC_ERROR);
            default:
                Print(  "GetTradeContext:GlobalVariableSetOnCondition('",
                        TC.GV.Name, "',1.0,0.0)-Error #", _GetLastError);
                break;                      // Exit switch, wait and retry.
            }   // switch(_GetLastError)
        }   // Set the semaphore.
        else if (!IsTradeContextBusy()){            // Cleanup and return.
            if (GTCreturn == TC_REFRESH){           // Clear the Wait comment
                Comment(WindowExpertName(),": ", VERSION);
                need2refresh=true;
            }
            if (need2refresh)   Refresh();
            return(GTCreturn);
        }
        int delay = GetTickCount() - startWaitingTime ;
        if (delay > maxWaitMsec){                   // Abort.
            Print("Waiting time (", maxWaitMsec/1000, " sec) exceeded!");
            if (TC_locked)  RelTradeContext();
            return(TC_TIMEOUT);
        }
        Comment("Wait until another expert finishes trading... ", delay/1000.);
        RandomSleep();
        GTCreturn = TC_REFRESH;                     // Will need to refresh.
    }   // while
    /*NOTREACHED*/
}   // GetTradeContext
Reason: