简体   繁体   中英

How to get MQL4 code work under an actual state of a Trade context?

How is a TradeContext() relevant in the following scenarios?

Will a TradeContext() return busy in these situations() when sending trade instructions at the same time?

1) When the same EA, attached to different crosses, each on its own chart in the same instance of the MetaTrader Terminal 4 platform.

2) When different strategies, across different charts, but all using the same FX-cross, in one instance of the MetaTrader Terminal 4 platform.

3) When using multiple instances of the MetaTrader Terminal 4 platform, operating EA-code in either of the situations mentioned above.

The case 3) has better client-server throughput , as each instance of MT4 Terminal platform contains it's own internal engine ( a Trade (management) Context instance ). This internal engine is technically invisible to user, but user has a responsibility to check the cases, when this engine is blocking the XTO's instructed to be fulfilled on the Server-side.


Fact #1: The platform evolves.

In early years, the MetaTrader Terminal 4 platform was quite often reporting cases, when it's internal implementation of a trade-management factory-pattern, dwelt in a state, which avoided any further request(s) from being processed.

Such indications were not asynchronously reported / did not interface with the flow of the MQL4-code execution, but was just indirectly accessible, after the code tried to inspect the GetLastError() or _LastError or via the IsTradeContextBusy() value:

#include <stdlib.mqh>
#include <stderror.mqh>
...
ErrorDescription( GetLastError() ); // was available for showing an Error state

and in cases, where _LastError == 146
== ERR_TRADE_CONTEXT_BUSY reports a state, when a Trade context was busy.

In other words, each XTO-operation in the workflow was thus typically surrounded by a careful Error-State-detection analysis code and included ( in some feasible form, where possible ) some sort of remedy actions, so as to overcome the blocked ( refused ) XTO-operation, until possible or having some time-out watchdog-controlled exit path.

After some years, maybe after Build 509, definitely after a Build 624+ came into deployment, this so far common ( hidden ) blocking-state ceased to appear so often.

If you observe cases, when a _LastError indeed reports the ERR_TRADE_CONTEXT_BUSY again, there will be more care needed so as to isolate such state, so best use a detailed logging of all the steps in the flow of the code-execution, so as to map the actual platform state.

switch( Error )
{  case ...

   case ERR_TRADE_CONTEXT_BUSY:    {  // ERR_TRADE_CONTEXT_BUSY
                                         aLogSTRING     = StringConcatenate( msLIB.anElapsedTimeSTRING(), "[ ", DoubleToStr( GetTickCount(), 0 ), " ] Trying to OrderModify() aPendingOrderOBJECT for this SONAR_BEEP Monitor at MT4Server side. <localhost>MT4Terminal reports: [ERR_TRADE_CONTEXT_BUSY] <state>. Will Sleep() here a bit more." );
                                         aComment.ADD(            aLogSTRING );
                                         aMXact.aDeferredLOGGER(  aLogSTRING, TRUE );
                                         Sleep( 60 * 1000 );
                                         break;
                                      }
   ...
   default:                        {    ...
                                      }
   }

If testing durations, for which the situation gets not resolved, may use something like this:

  while (  !IsStopped() )  {                   // LOOP FOREVER, UNTIL IsStopped()
           tix.START = GetTickCount();         // STO()_______pre-STORE()_________________________ .START
           if (  IsTradeContextBusy() ) {      // if BUSY().......MEASURE......................... .START inner-LOOP
                 while (  IsTradeContextBusy() && !IsStopped() )  {       // LOOP @BUSY()_________________________________________________________________________ tix
                          Sleep( msLIB.RT.LOOP_inMeasureSleep.ms );       //             Sleep(*)
                       }  // .............................................// LOOP .or. !BUSY()--------------------------------------------------------<_LOOP_>----     .or. { !IsTradeContextBusy() | IsStopped() }
                 tix.END    = GetTickCount();  //  STO()__________________ .END   inner-LOOP _____________________________________________________________________ tix
                 tix.BUSY   = tix.END - tix.START;
              // aString2LOG= StringConcatenate(   TimeToStr( TimeCurrent(), _time2str.MASK ),";", DoubleToStr( tix.START, 0 ), ";",  DoubleToStr( tix.BUSY, 0 ) );
                 aString2LOG= StringConcatenate(   TimeToStr( TimeLocal(),   _time2str.MASK ),";", DoubleToStr( tix.START, 0 ), ";",  DoubleToStr( tix.BUSY, 0 ) );        // TimeLocal() works either before/after Market Closes and no quotes arrive ( thus avoiding the hanging at TimeCurrent() at the time of the last known Quote.... )
              // LOG.append
              // LOG ------------------------|||||||||||||||--------------------------   
                                      aMXact.aDeferredLOGGER( aString2LOG, ( IsStopped() ) );
                 aComment.ADD( StringConcatenate(    msLIB.anElapsedTimeSTRING(),
                                                     " <localhost>.<aTradingCONTEXT>.BUSY was <OBSERVED> at ",
                                                     DoubleToStr( aLoopCOUNTER.RollOVER * msLIB.RT.LOOP_nLoops2ShowGuiMSG + aLoopCOUNTER, 0 ),
                                                     " loop, < cpuClockTIXs.START | cpuClockTIXs.DURATION> ",
                                                     aString2LOG
                                                  )
                             );
                 aLoopCOUNTER.RollOVER = 0;
                 aLoopCOUNTER = 0;
              }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM