MQL5: 通过反向持仓来平仓

MQL5: 通过反向持仓来平仓


EA交易中最常见的操作,下单和平仓。
在脚本程序中写。
首先要了解发送下单需要的函数 OrderSend
同样,先放上官方给的函数参考链接 OrderSend

OrderSend函数的参数列表
MQL5: 通过反向持仓来平仓_第1张图片
MqlTradeRequest 交易请求结构,该结构的属性如下图所示
MQL5: 通过反向持仓来平仓_第2张图片

MqlTradeResult 交易请求结果结构,该结构的属性如下图所示
MQL5: 通过反向持仓来平仓_第3张图片
然后通过代码来看如何去使用这两个结构去实例化OrderSend函数

//+------------------------------------------------------------------+
//|                                                        order.mq5 |
//|                        Copyright 2019, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2019, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
   setorder();   
  }
//+------------------------------------------------------------------+
void setorder()
  {
//--- 准备请求
   MqlTradeRequest req={0};
   req.action      =TRADE_ACTION_DEAL;                      //立即处理
   req.symbol      =_Symbol;                                //当前图表的交易品种名称
   req.magic       =02;
   req.volume      =0.01;                                   //手数
   req.type        =ORDER_TYPE_BUY;                         //订单类型
   req.price       =SymbolInfoDouble(_Symbol,SYMBOL_ASK);//报价
   req.deviation   =10;
   req.comment     ="Buy using OrderSendAsync()";           //订单注释
   MqlTradeResult  res={0};                                             
   if(!OrderSendAsync(req,res))
     {
      Print(__FUNCTION__,": error ",GetLastError(),", retcode = ",res.retcode);
     }
  }

注意到这里给了一个交易的幻数 ,即req.magic = 02。给订单指定的交易幻数意味着可以在平仓时指定需要平掉的订单。当然也可以根据指定报价去平仓,这里不做讨论。

以下给出 遍历持仓来找到幻数为02的订单,且为做多单,然后通过反向持仓来平仓 的脚本程序

void OnStart()
  {
//--- 声明并初始化交易请求和交易请求结果
   MqlTradeRequest request;
   MqlTradeResult  result;
   int total=PositionsTotal(); // 持仓数   
//--- 重做所有持仓
   for(int i=total-1; i>=0; i--)
     {
      //--- 订单的参数
      ulong  position_ticket=PositionGetTicket(i);                                                           // 持仓价格
      string position_symbol=PositionGetString(POSITION_SYMBOL);                        // 交易品种 
      int    digits=(int)SymbolInfoInteger(position_symbol,SYMBOL_DIGITS);              // 小数位数
      ulong  magic=PositionGetInteger(POSITION_MAGIC);                                        // 持仓的幻数
      double volume=PositionGetDouble(POSITION_VOLUME);                                 // 持仓交易量
      ENUM_POSITION_TYPE type=(ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);    // 持仓类型
      //--- 如果幻数匹配
      if(magic == 02 && type == POSITION_TYPE_BUY )
        {
         //--- 归零请求和结果值
         ZeroMemory(request);
         ZeroMemory(result);
         //--- 设置操作参数
         request.action   =TRADE_ACTION_DEAL;        // 交易操作类型
         request.position =position_ticket;          // 持仓价格
         request.symbol   =position_symbol;          // 交易品种 
         request.volume   =volume;                   // 持仓交易量
         request.deviation=5;                        // 允许价格偏差
         request.magic    =EXPERT_MAGIC;             // 持仓幻数
         //--- 根据持仓类型设置价格和订单类型 
         request.price=SymbolInfoDouble(position_symbol,SYMBOL_BID);
         request.type =ORDER_TYPE_SELL;
         //--- 输出关闭信息
         PrintFormat("Close #%I64d %s %s",position_ticket,position_symbol,EnumToString(type));
         //--- 发送请求
         if(!OrderSend(request,result))
            PrintFormat("OrderSend error %d",GetLastError());  // 如果不能发送请求,输出错误代码
         //--- 操作信息   
         PrintFormat("retcode=%u  deal=%I64u  order=%I64u",result.retcode,result.deal,result.order);
         //---
        }
     }
  }
//+------------------------------------------------------------------+

以上程序均可运行。
如有表达错误,还请指正。

你可能感兴趣的:(MT5,下单,平仓)