其他分享
首页 > 其他分享> > 持仓单一键平仓脚本

持仓单一键平仓脚本

作者:互联网

转载原文:http://www.popoding.club/post/31/

在手动或自动化交易中,一键平仓功能都是比较常用的,特别是在涉及风控管理的时候,能够快速止损,有效控制风险。这个脚本功能实现起来并不难,但在程序化实现的过程中,会有一些不同的应用场景。

遍历持仓订单

在执行平仓指令前,需要先遍历所有持仓单,找到具体的订单后,根据持仓订单订单号来进行平仓功能实现,需要用到的函数是PositionsTotal(),得到持仓订单总数,再用for循环就可以实现遍历功能。

for(int i = 0; i < PositionsTotal(); i++)
     {
         //循环体
     }

获取订单属性

在循环体内,需要根据订单序列获取订单号,用到的函数是PositionGetTicket(),这个函数可以得到订单号,同时也定位到当前订单,之后才能获取到相关订单属性信息。

ulong pos_ticket = PositionGetTicket(i);                        //订单号
ulong pos_magic = PositionGetInteger(POSITION_MAGIC);           		//订单幻数
string pos_symbol = PositionGetString(POSITION_SYMBOL);         		//订单品种
double pos_profit = PositionGetDouble(POSITION_PROFIT);        		//订单盈利

平仓条件

这里可以获取MT5平台中显示的所有订单属性信息,比较常用的有订单号、幻数、品种、盈利额、类型等。这些属性都会涉及到不同的应用场景,比如平仓某一品种的所有订单,平仓所有盈利单,平仓所有买入单等等,都是在取到了对应的属性后通过条件判断来实现。

在多品种多模式复杂交易系统中,需要根据不同模式类别将订单进行分类,以便进行适配性更强、更复杂的仓位管理,这里就需要用到订单幻数,可以在开仓时,通过指定幻数编码规则来进行实现,比如11010001,“11”代表品种EURUSD,“01”代表模式1,“0001”代表当前品种当前模式下的第1单。这里只是举个例子,编码规则可以根据需要来制定,那么有了这个幻数编号,就可以通过截取指定的内容,来进行更复杂要求的平仓实现,比如平仓所有EURUSD模式1的亏损订单。

平仓功能

MT5的平仓功能是通过反向订单请求来实现的,也就是说如果持仓单是买入单,通过发送一个卖出单指令,指定相同的订单号、品种、交易量等请求信息,就可以实现平仓;卖出单平仓则是发送一个买入单指令。

request.position = pos_ticket;	//指定平仓订单号

需要提及的是,有的平台经纪商会有请求模式上的区别,若是模式不正确,将导致请求失败,模式有ORDER_FILLING_FOK、ORDER_FILLING_IOC、ORDER_FILLING_RETURN三种类型,区别是针对部分成交量的处理方式不同,通过SymbolInfoInteger()函数,SYMBOL_FILLING_MODE属性值获取,就可以进行不同方式的适配。

int filling=(int)SymbolInfoInteger(Symbol(),SYMBOL_FILLING_MODE);
if(filling == 1)
{
    request.type_filling = ORDER_FILLING_FOK; //全部成交模式
}
else
     if(filling == 2)
{
            request.type_filling = ORDER_FILLING_IOC; //部分成交模式
       }
      else
         if(filling == 3)
          {
            request.type_filling == ORDER_FILLING_RETURN;  //限价单执行模式
          }

实现源码

#property copyright "公众号 Luyuanmw 微信 wentxiong"
#property link      "http://www.popoding.club/"
#property version   "1.00"
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
//---
//遍历持仓单
   for(int i = 0; i < PositionsTotal(); i++)
     {
      //循环体
      ulong pos_ticket = PositionGetTicket(i);                        //订单号
      ulong pos_magic = PositionGetInteger(POSITION_MAGIC);           //订单幻数
      string pos_symbol = PositionGetString(POSITION_SYMBOL);         //订单品种
      double pos_profit = PositionGetDouble(POSITION_PROFIT);         //订单盈利
      double pos_volume = PositionGetDouble(POSITION_VOLUME);         //交易量
      ENUM_POSITION_TYPE pos_type = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);//订单类型

      //平仓
      MqlTradeRequest request = {0};
      MqlTradeResult result = {0};
      double ask = SymbolInfoDouble(Symbol(),SYMBOL_ASK);
      double bid = SymbolInfoDouble(Symbol(),SYMBOL_BID);

      //请求结构体
      request.action = TRADE_ACTION_DEAL;
      request.position = pos_ticket;
      request.symbol = pos_symbol;
      request.volume = pos_volume;
      request.deviation = 50;
      request.magic = pos_magic;

      //指定订单成交模式
      int filling=(int)SymbolInfoInteger(Symbol(),SYMBOL_FILLING_MODE);
      if(filling == 1)
        {
         request.type_filling = ORDER_FILLING_FOK; //全部成交模式
        }
      else
         if(filling == 2)
           {
            request.type_filling = ORDER_FILLING_IOC; //部分成交模式
           }
         else
            if(filling == 3)
              {
               request.type_filling = ORDER_FILLING_RETURN;  //限价单执行模式
              }

      //指定幻数、品种条件
      if(pos_magic == 0 && pos_symbol == Symbol())
        {
         if(pos_type == POSITION_TYPE_SELL)
           {
            request.type = ORDER_TYPE_BUY;
            request.price = ask;
           }
         else
            if(pos_type == POSITION_TYPE_BUY)
              {
               request.type = ORDER_TYPE_SELL;
               request.price = bid;
              }

         //发送请求命令
         if(!OrderSend(request,result))
           {
            printf("Ordersend Error : %d",GetLastError());
           }
        }
     }
  }
//+------------------------------------------------------------------+

 

标签:平仓,request,持仓,pos,订单,filling,FILLING,单一
来源: https://blog.csdn.net/wentxiong/article/details/118058255