[MT4-EA]错误146 ("交易作业忙") 和如何处理
1.MetaTrader 4客户端中 "交易运作" 的概念
[backcolor=rgb(251, 251, 252)]来自MetaEditor参考文档的一段话:[/backcolor]
[backcolor=rgb(251, 251, 252)]来自智能交易和脚本的交易,只能够提供一个并在交易作业中开启 (来自智能交易和脚本的自动交易作业)。这就是为什么如果智能交易业务作业忙,其他的智能交易或脚本在此刻不能调用函数生成错误146 (ERR_TRADE_CONTEXT_BUSY)。[/backcolor]
[backcolor=rgb(251, 251, 252)]换句话说,只有一个智能交易(脚本)可以准时交易。所以其他智能交易尝试开始交易将被错误 146停止。文章将会找到问题的解决方案。[/backcolor]
2. 函数 IsTradeAllowed()[backcolor=rgb(251, 251, 252)]这是最简单的方法是使用名称为IsTradeAllowed()的函数找出交易作业忙。[/backcolor]
[backcolor=rgb(251, 251, 252)]来自 MetaEditor参考文档的一段话:[/backcolor]
[backcolor=rgb(251, 251, 252)]"bool IsTradeAllowed()如果智能交易允许交易,返回TRUE 。否则,返回FALSE。[/backcolor]
[backcolor=rgb(251, 251, 252)]这就意味着如果函数 IsTradeAllowed()返回TRUE只有一个可以尝试交易。[/backcolor]
[backcolor=rgb(251, 251, 252)]在交易业务之前必须检测完成。[/backcolor]
[backcolor=rgb(251, 251, 252)]函数错误使用范例:[/backcolor]
int
start
()
{
// 检测交易作业
if
(
!
IsTradeAllowed
()
)
{
// 如果函数IsTradeAllowed() 返回FALSE, 通知用户
Print
(
"交易作业忙。智能交易不能开仓
!
"
)
;
// 并且中止交易业务。当下一个替克进入将重新开始 // 进入
return
(
-
1
)
;
}
else
{
// 如果函数IsTradeAllowed()返回TRUE,通知用户 // 并继续运行
Print
(
"
交易作业空闲!开始运作...
"
)
;
}
// 现在检测市场
...
// 计算止损和赢利水平和标准手
...
// 开仓
if
(
OrderSend
(
...
)
<
0
)
Alert
(
"
开仓错误 #
"
,
GetLastError
()
)
;
return
(
0
)
;
}
[backcolor=rgb(251, 251, 252)]在这个范例中,在start() 函数开始时检测交易运作状态。这是个错误想法: 在我们的智能交易计算的时间内交易作业会被其他智能交易占据(需要进入市场,止损和赢利,标准手等等)。这些情况,接受开仓将失败。[/backcolor]
[backcolor=rgb(251, 251, 252)] 函数适当应用范例:[/backcolor]
int
start
()
{
// 现在检测市场
...
// 计算止损和赢利水平,标准手数
...
// 现在检测交易作业
if
(
!
IsTradeAllowed
()
)
{
Print
(
"交易作业忙
! 智能交易不能开仓!
"
)
;
return
(
-
1
)
;
}
else
Print
(
"
交易作业正常! 尝试开仓...
"
)
;
//如果检测正常,开仓
if
(
OrderSend
(
...
)
<
0
)
Alert
(
"
错误开仓 #
"
,
GetLastError
()
)
;
return
(
0
)
;
}
[backcolor=rgb(251, 251, 252)]在开仓之前立即检测交易作业状态,并且可能在两种动作行为之间插入其他的智能交易 .[/backcolor]
[backcolor=rgb(251, 251, 252)]这种方法存在两点不足:[/backcolor]
[list] [*]智能交易在接收到明确结果检测状态的同时,将尝试开始交易. [*]如果检测失败,智能交易将尝试使用下一个替克交易; 将会延误. [/list][backcolor=rgb(251, 251, 252)]解决第二种不足很简单:等待交易作业空闲即可.随后,在其他智能交易结束后,智能交易将立即开始交易.[/backcolor]
[backcolor=rgb(251, 251, 252)]范例如下:[/backcolor]
int
start
()
{
// 现在检测是否进入市场
...
// 计算赢利/止损水平和标准手数
...
// 检测交易作业是否空闲
if
(
!
IsTradeAllowed
()
)
{
Print
(
"
交易作业忙!等待空闲...
"
)
;
// 无限循环
while
(
true
)
{
// 如果智能交易被用户停止,停止业务
if
(
IsStopped
()
)
{
Print
(
"智能交易被用停止
!
"
)
;
return
(
-
1
)
;
}
// 如果交易作业空闲,开始交易
if
(
IsTradeAllowed
()
)
{
Print
(
"交易作业空闲
!
"
)
;
break
;
}
// 如果没有条件设置循环, "等待" 0.1秒 // 并且检测重新开始
Sleep
(
100
)
;
}
}
else
Print
(
"
交易作业空闲!尝试开仓...
"
)
;
// 尝试开仓 if(OrderSend(...) < 0) Alert("错误开仓 # ", GetLastError()); return(0); }
[backcolor=rgb(251, 251, 252)]这种情况出现,我们可以指出以下错误:[/backcolor]
[list] [*] 函数 IsTradeAllowed()不仅仅能够显现交易作业的状态,同样可以在无限循环中以“隐藏”开启/关闭;如果从图表中手动移除,将停止运作。 [*]如果智能交易等待交易作业空闲,在这个时间里,价格会改变并且可能用这个价格交易 - 数据需要刷新开仓重新计算。 [/list][backcolor=rgb(251, 251, 252)]纠正的错误代码将会是以下:[/backcolor]
// 智能交易等待交易的时间time (in seconds) whithin which the expert will wait until the trade // 交易作业空闲(如果忙)
int
MaxWaiting_sec
=
30
;
int
start
()
{
// 现在检验是否进入市场
...
// 计算止损,赢利和标准手数
...
// 检测交易作业是否空闲
if
(
!
IsTradeAllowed
()
)
{
int
StartWaitingTime
=
GetTickCount
()
;
Print
(
"交易作业忙
!等待空闲...
"
)
;
// 无限循环
while
(
true
)
{
// 如过用户中止智能交易,停止业务
if
(
IsStopped
()
)
{
Print
(
"
智能交易被用户中止!
"
)
;
return
(
-
1
)
;
}
// 如果等待时间超过命名变量 // MaxWaiting_sec, 停止业务
if
(
GetTickCount
()
-
StartWaitingTime
>
MaxWaiting_sec
*
1000
)
{
Print
(
"
标准限定(
"
+
MaxWaiting_sec
+
"
sec)超过
!
"
)
;
return
(
-
2
)
;
}
// 如果交易作业空闲,
if
(
IsTradeAllowed
()
)
{
Print
(
"
交易作业空闲!
"
)
;
// 刷新市场信息
RefreshRates
()
;
// 重新计算止损和赢利水平
...
// 离开循环状态并开始交易
break
;
}
// 如过没有条件离开
,请 "等待" 0.1秒
// 并且重新开始检测
Sleep
(
100
)
;
}
}
else
Print
(
"交易作业空闲
!尝试开仓...
"
)
;
// 尝试开仓
if
(
OrderSend
(
...
)
<
0
)
Alert
(
"错误开仓 #
"
,
GetLastError
()
)
;
return
(
0
)
;
}
[backcolor=rgb(251, 251, 252)]来自智能交易和脚本的交易,只能够提供一个并在交易作业中开启 (来自智能交易和脚本的自动交易作业)。这就是为什么如果智能交易业务作业忙,其他的智能交易或脚本在此刻不能调用函数生成错误146 (ERR_TRADE_CONTEXT_BUSY)。[/backcolor]
[backcolor=rgb(251, 251, 252)]换句话说,只有一个智能交易(脚本)可以准时交易。所以其他智能交易尝试开始交易将被错误 146停止。文章将会找到问题的解决方案。[/backcolor]
2. 函数 IsTradeAllowed()[backcolor=rgb(251, 251, 252)]这是最简单的方法是使用名称为IsTradeAllowed()的函数找出交易作业忙。[/backcolor]
[backcolor=rgb(251, 251, 252)]来自 MetaEditor参考文档的一段话:[/backcolor]
[backcolor=rgb(251, 251, 252)]"bool IsTradeAllowed()如果智能交易允许交易,返回TRUE 。否则,返回FALSE。[/backcolor]
[backcolor=rgb(251, 251, 252)]这就意味着如果函数 IsTradeAllowed()返回TRUE只有一个可以尝试交易。[/backcolor]
[backcolor=rgb(251, 251, 252)]在交易业务之前必须检测完成。[/backcolor]
[backcolor=rgb(251, 251, 252)]函数错误使用范例:[/backcolor]
int
start
()
{
// 检测交易作业
if
(
!
IsTradeAllowed
()
)
{
// 如果函数IsTradeAllowed() 返回FALSE, 通知用户
(
"交易作业忙。智能交易不能开仓
!
"
)
;
// 并且中止交易业务。当下一个替克进入将重新开始 // 进入
return
(
-
1
)
;
}
else
{
// 如果函数IsTradeAllowed()返回TRUE,通知用户 // 并继续运行
(
"
交易作业空闲!开始运作...
"
)
;
}
// 现在检测市场
...
// 计算止损和赢利水平和标准手
...
// 开仓
if
(
OrderSend
(
...
)
<
0
)
Alert
(
"
开仓错误 #
"
,
GetLastError
()
)
;
return
(
0
)
;
}
[backcolor=rgb(251, 251, 252)]在这个范例中,在start() 函数开始时检测交易运作状态。这是个错误想法: 在我们的智能交易计算的时间内交易作业会被其他智能交易占据(需要进入市场,止损和赢利,标准手等等)。这些情况,接受开仓将失败。[/backcolor]
[backcolor=rgb(251, 251, 252)] 函数适当应用范例:[/backcolor]
int
start
()
{
// 现在检测市场
...
// 计算止损和赢利水平,标准手数
...
// 现在检测交易作业
if
(
!
IsTradeAllowed
()
)
{
(
"交易作业忙
! 智能交易不能开仓!
"
)
;
return
(
-
1
)
;
}
else
(
"
交易作业正常! 尝试开仓...
"
)
;
//如果检测正常,开仓
if
(
OrderSend
(
...
)
<
0
)
Alert
(
"
错误开仓 #
"
,
GetLastError
()
)
;
return
(
0
)
;
}
[backcolor=rgb(251, 251, 252)]在开仓之前立即检测交易作业状态,并且可能在两种动作行为之间插入其他的智能交易 .[/backcolor]
[backcolor=rgb(251, 251, 252)]这种方法存在两点不足:[/backcolor]
[list] [*]智能交易在接收到明确结果检测状态的同时,将尝试开始交易. [*]如果检测失败,智能交易将尝试使用下一个替克交易; 将会延误. [/list][backcolor=rgb(251, 251, 252)]解决第二种不足很简单:等待交易作业空闲即可.随后,在其他智能交易结束后,智能交易将立即开始交易.[/backcolor]
[backcolor=rgb(251, 251, 252)]范例如下:[/backcolor]
int
start
()
{
// 现在检测是否进入市场
...
// 计算赢利/止损水平和标准手数
...
// 检测交易作业是否空闲
if
(
!
IsTradeAllowed
()
)
{
(
"
交易作业忙!等待空闲...
"
)
;
// 无限循环
while
(
true
)
{
// 如果智能交易被用户停止,停止业务
if
(
IsStopped
()
)
{
(
"智能交易被用停止
!
"
)
;
return
(
-
1
)
;
}
// 如果交易作业空闲,开始交易
if
(
IsTradeAllowed
()
)
{
(
"交易作业空闲
!
"
)
;
break
;
}
// 如果没有条件设置循环, "等待" 0.1秒 // 并且检测重新开始
Sleep
(
100
)
;
}
}
else
(
"
交易作业空闲!尝试开仓...
"
)
;
// 尝试开仓 if(OrderSend(...) < 0) Alert("错误开仓 # ", GetLastError()); return(0); }
[backcolor=rgb(251, 251, 252)]这种情况出现,我们可以指出以下错误:[/backcolor]
[list] [*] 函数 IsTradeAllowed()不仅仅能够显现交易作业的状态,同样可以在无限循环中以“隐藏”开启/关闭;如果从图表中手动移除,将停止运作。 [*]如果智能交易等待交易作业空闲,在这个时间里,价格会改变并且可能用这个价格交易 - 数据需要刷新开仓重新计算。 [/list][backcolor=rgb(251, 251, 252)]纠正的错误代码将会是以下:[/backcolor]
// 智能交易等待交易的时间time (in seconds) whithin which the expert will wait until the trade // 交易作业空闲(如果忙)
int
MaxWaiting_sec
=
30
;
int
start
()
{
// 现在检验是否进入市场
...
// 计算止损,赢利和标准手数
...
// 检测交易作业是否空闲
if
(
!
IsTradeAllowed
()
)
{
int
StartWaitingTime
=
GetTickCount
()
;
(
"交易作业忙
!等待空闲...
"
)
;
// 无限循环
while
(
true
)
{
// 如过用户中止智能交易,停止业务
if
(
IsStopped
()
)
{
(
"
智能交易被用户中止!
"
)
;
return
(
-
1
)
;
}
// 如果等待时间超过命名变量 // MaxWaiting_sec, 停止业务
if
(
GetTickCount
()
-
StartWaitingTime
>
MaxWaiting_sec
*
1000
)
{
(
"
标准限定(
"
+
MaxWaiting_sec
+
"
sec)超过
!
"
)
;
return
(
-
2
)
;
}
// 如果交易作业空闲,
if
(
IsTradeAllowed
()
)
{
(
"
交易作业空闲!
"
)
;
// 刷新市场信息
RefreshRates
()
;
// 重新计算止损和赢利水平
...
// 离开循环状态并开始交易
break
;
}
// 如过没有条件离开
,请 "等待" 0.1秒
// 并且重新开始检测
Sleep
(
100
)
;
}
}
else
(
"交易作业空闲
!尝试开仓...
"
)
;
// 尝试开仓
if
(
OrderSend
(
...
)
<
0
)
Alert
(
"错误开仓 #
"
,
GetLastError
()
)
;
return
(
0
)
;
}
遇到矛盾 先站在对方的立场上想想问题,先试着去理解别人
● 如何使用WinMTR查询平台连接流畅度