找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
首页论坛EAHub 外汇论坛
查看: 16|回复: 0

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

[复制链接]

4万

主题

54

回帖

4万

积分

管理员

积分
45954
发表于 2026-8-23 02:52:00 | 显示全部楼层 |阅读模式
最近突然对自动化交易感兴趣,用到了一次性平仓所有订单的函数,于是从网上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);

            }

         }

}
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|EAHub外汇论坛

GMT+8, 2026-10-12 13:42 , Processed in 0.414997 second(s), 19 queries .

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表