设为首页 收藏本站 切换语言

MT4一键全部平仓函数无法一次平掉所有订单的原因及解决方法

| 发表于 2023-1-4 16:15:51 | 显示全部楼层 |复制链接
最近突然对自动化交易感兴趣,用到了一次性平仓所有订单的函数,于是从网上copy了一段代码,稍微精简了一下,就有了以下问题代码:
void ClosePosition()
{
for(int i=0; i<OrdersTotal(); i++)
         {
            OrderSelect(i, SELECT_BY_POS);
            if(OrderType()==OP_BUY)
            {
               OrderClose(OrderTicket(),OrderLots(),MarketInfo(OrderSymbol(), MODE_BID),3);
            }
            else if(OrderType()==OP_SELL)
            {
               OrderClose(OrderTicket(),OrderLots(),MarketInfo(OrderSymbol(), MODE_ASK),3);
            }
         }
}


在实际调用时,发现只能平掉部分仓,只有多次调用才能完全平仓。


参考了别人程序中的代码,以及经过调试之后,找到了问题所在:
当OrderSelect函数通过SELECT_BY_POS方式获取订单时,每次执行都是从当前的持仓列表中按时间先后顺序获取订单。如果在获取订单之后持仓列表发生变动,下次获取时是从发生变动之后的新列表中获取。
所以如果按以上代码,从0号订单开始循环,获取0号订单并关闭之后,持仓列表就被更新重新排序,那么下次循环时通过OrderSelect获取到的1号订单实际对应的是未关闭0号时列表中的2号订单。
这也是为什么这段代码只能按间隔顺序关闭一半的订单。


所以解决方法就很简单了,就是在持仓列表中从尾部开始向前获取订单,这样每次关闭一个订单之后都不会影响前面的订单顺序:
void ClosePosition()
{
for(int i=OrdersTotal()-1; i>=0; i--)  //从尾部开始循环
         {
            OrderSelect(i, SELECT_BY_POS);
            if(OrderType()==OP_BUY)
            {
               OrderClose(OrderTicket(),OrderLots(),MarketInfo(OrderSymbol(), MODE_BID),3);
            }
            else if(OrderType()==OP_SELL)
            {
               OrderClose(OrderTicket(),OrderLots(),MarketInfo(OrderSymbol(), MODE_ASK),3);
            }
         }
}

如果有帮助,就支持一下我呗
举报

评论 使用道具

精彩评论3

pxyhub
C
| 发表于 2023-1-4 18:01:41 | 显示全部楼层
倒序平,来个顺序平...
举报

点赞 评论 使用道具

whmm
C
| 发表于 2023-1-4 19:16:54 | 显示全部楼层
不错支持一下,在上面加个while循环也可以
举报

点赞 评论 使用道具

xinhua123
DDD
| 发表于 2023-1-5 00:43:53 | 显示全部楼层
来学习了,谢谢楼主
举报

点赞 评论 使用道具

发新帖
EA交易
您需要登录后才可以评论 登录 | 立即注册

简体中文
繁體中文
English(英语)
日本語(日语)
Deutsch(德语)
Русский язык(俄语)
بالعربية(阿拉伯语)
Türkçe(土耳其语)
Português(葡萄牙语)
ภาษาไทย(泰国语)
한어(朝鲜语/韩语)
Français(法语)