[英]How to get MQL4 code work under an actual state of a Trade context?
在以下情况下, TradeContext()
有何关系?
同时发送交易指令时,在这些情况下, TradeContext()
返回繁忙状态?
1)当相同的EA附加到不同的十字架上时,每个在其MetaTrader Terminal 4平台的相同实例中的自己的图表上。
2)在MetaTrader Terminal 4平台的一个实例中,采用不同策略,跨不同图表,但全部使用相同FX-cross的情况。
3)当使用MetaTrader Terminal 4平台的多个实例时,请在上述两种情况下操作EA代码。
情况3)具有更好的客户端-服务器吞吐量 ,因为MT4终端平台的每个实例都包含其自己的内部引擎(“交易(管理)上下文”实例)。 从技术上讲,此内部引擎对于用户是不可见的,但是当此引擎阻止XTO指示在服务器端实现时,用户有责任检查情况。
早些年,MetaTrader Terminal 4平台经常报告案例,这是内部实施的贸易管理工厂模式的内部状态,避免了任何进一步的请求被处理。
在代码尝试检查GetLastError()
或_LastError
或通过IsTradeContextBusy()
值检查代码之后,此类指示不是异步报告的,也不与MQL4代码执行流程_LastError
,而只能间接访问:
#include <stdlib.mqh>
#include <stderror.mqh>
...
ErrorDescription( GetLastError() ); // was available for showing an Error state
并在_LastError == 146
情况下
== ERR_TRADE_CONTEXT_BUSY
报告交易上下文繁忙时的状态。
换句话说,工作流中的每个XTO操作通常都被仔细的错误状态检测分析代码包围,并且包括(以某种可行的形式,在可能的情况下)某种补救措施,从而克服了被阻止(拒绝)的问题。 )XTO操作,直到可能或有一些超时的看门狗控制的退出路径。
几年之后,也许是在Build 509之后,肯定是在Build 624+部署之后,这种常见(隐藏)的阻塞状态不再如此频繁地出现。
如果您观察到情况,当_LastError
确实再次报告ERR_TRADE_CONTEXT_BUSY
时,将需要更多注意以隔离这种状态,因此最好对代码执行流程中的所有步骤进行详细记录,以便进行映射实际平台状态。
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: { ...
}
}
如果无法解决这种情况的测试持续时间,则可以使用以下方法:
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;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.