OrderSend

通过向服务器发送请求,OrderSend()函数用来执行交易操作操作。

bool  OrderSend(
   MqlTradeRequest&  request,      // query structure
   MqlTradeResult&   result        // structure of the answer
   );

参量

request

[in] 指针指向 MqlTradeRequest 结构类型操作,描述成客户的交易活动。

result

[in,out]指针指向MqlTradeResult结构类型操作,描述成功完成后的交易操作结构(如果真值可以返回)。

返回值

成功检测基础结构(索引检测)返回真值-这并不是交易操作成功执行的标志。更多函数执行结果的细节描述,都分析在result结构域中。

注释

交易需要通过多个步骤检测交易服务器,第一,检测是否所有要求操作request参量都正确填满,如果没有错误,服务器接收下一步订单,如果命令通过服务器成功接收,OrderSend()函数返回真值。

在向服务器发送请求之前推荐检验请求,为了检验请求,使用OrderCheck()函数。检验是否有足够的资金来执行交易操作,并在交易请求检测结果中返回许多有用的参量:

  • 返回码 在检测请求中包括错误信息;
  • 在交易操作执行后显示账户余额;
  • 在交易操作执行后显示产权值;
  • 在交易操作执行后显示浮点类型值;
  • 交易操作所需保证金;
  • 在交易操作执行后可用产权数量;
  • 在交易操作执行后建立的保证金水平;
  • 注释回应代码,错误描述。

When sending a market order (MqlTradeRequest.action=TRADE_ACTION_DEAL), the successful result of the OrderSend() function does not mean that the order has been executed (appropriate trades have been performed). In this case, 'true' means only that the order has been successfully placed in the trading system for further execution. The trade server can fill in the deal or order field values in the returned result tructure, if it is aware of these data when forming a response to an OrderSend() call. Generally, event(s) of executing trades corresponding to an order may happen after sending a response to the OrderSend() call. Therefore, for any type of a trade request, when receiving the OrderSend() execution result, we should first check the retcode trade server response code and the retcode_external external system response code (if necessary) available in the obtained result tructure.

每个接收到的订单存储在交易服务器中排队处理,直到可以执行的条件发生:

  • 临界期,
  • 反面要求的外观,
  • 当执行价格出现时命令执行,
  • 收到的取消订单的命令。

订单执行时,交易服务器向客户端发送关于交易事件程序发生的信息,可以通过OnTrade() 函数执行。

在通过OrderSend()函数发送的服务器上执行交易请求的结果可以通过OnTradeTransaction 处理程序跟踪。应该注意,当执行交易请求时,将会多次调用OnTradeTransaction处理程序。

例如,当发送市场买入订单时,它会被处理,为账户创建一个适当的买入订单,然后执行订单并从持仓订单列表中移除,然后它被添加到订单历史记录,相应的交易也被添加到历史记录并创建新持仓。OnTradeTransaction函数将会为这里每个事件进行调用。

示例:

//--- ORDER_MAGIC值
input long order_magic=55555;
//+------------------------------------------------------------------+
//| 启动函数的脚本程序                                                  |
//+------------------------------------------------------------------+
void OnStart()
  {
//--- 确保账户是样本
   if(AccountInfoInteger(ACCOUNT_TRADE_MODE)==ACCOUNT_TRADE_MODE_REAL)
     {
      Alert("Script operation is not allowed on a live account!");
      return;
     }
//--- 下订单或者删除订单
   if(GetOrdersTotalByMagic(order_magic)==0) 
     {
      //--- 无当前订单 - 下订单
      uint res=SendRandomPendingOrder(order_magic);
      Print("Return code of the trade server ",res);
     }
   else // 有订单 - 删除订单
     {
      DeleteAllOrdersByMagic(order_magic);
     }
//---
  }
//+------------------------------------------------------------------+
//| 接收当前带有指定的ORDER_MAGIC的订单号                                |
//+------------------------------------------------------------------+
int GetOrdersTotalByMagic(long const magic_number)
  {
   ulong order_ticket;
   int total=0;
//--- 检查通过所有挂单
   for(int i=0;i<OrdersTotal();i++)
      if((order_ticket=OrderGetTicket(i))>0)
         if(magic_number==OrderGetInteger(ORDER_MAGIC)) total++;
//---
   return(total);
  }
//+------------------------------------------------------------------+
//| 删除所有带有指定ORDER_MAGIC的挂单                                   |
//+------------------------------------------------------------------+
void DeleteAllOrdersByMagic(long const magic_number)
  {
   ulong order_ticket;
//--- 检查所有挂单
   for(int i=OrdersTotal()-1;i>=0;i--)
      if((order_ticket=OrderGetTicket(i))>0)
         //--- 带有恰当ORDER_MAGIC的订单 
         if(magic_number==OrderGetInteger(ORDER_MAGIC))
           {
            MqlTradeResult result={};
            MqlTradeRequest request={};
            request.order=order_ticket;
            request.action=TRADE_ACTION_REMOVE;
            OrderSend(request,result);
            //--- 编写服务器回复到日志
            Print(__FUNCTION__,": ",result.comment," reply code ",result.retcode);
           }
//---
  }
//+------------------------------------------------------------------+
//| 随机设置挂单                                                       |
//+------------------------------------------------------------------+
uint SendRandomPendingOrder(long const magic_number)
  {
//--- 准备请求
   MqlTradeRequest request={};
   request.action=TRADE_ACTION_PENDING;         // 设置挂单
   request.magic=magic_number;                  // ORDER_MAGIC
   request.symbol=_Symbol;                      // 交易品种
   request.volume=0.1;                          // 0.1为单位的交易量
   request.sl=0;                                // 没有指定止损价位
   request.tp=0;                                // 没有指定盈利价位
//--- 形成订单类型
   request.type=GetRandomType();                // 订单类型
//--- 形成挂单价格
   request.price=GetRandomPrice(request.type);  // 开盘价
//--- 发送交易请求
   MqlTradeResult result={};
   OrderSend(request,result);
//--- 编写服务器回复到日志 
   Print(__FUNCTION__,":",result.comment);
   if(result.retcode==10016) Print(result.bid,result.ask,result.price);
//--- 返回交易服务器回复的代码
   return result.retcode;
  }
//+------------------------------------------------------------------+
//| 返回随机挂单类型                                                   |
//+------------------------------------------------------------------+
ENUM_ORDER_TYPE GetRandomType()
  {
   int t=MathRand()%4;
//---   0<=t<4
   switch(t)
     {
      case(0):return(ORDER_TYPE_BUY_LIMIT);
      case(1):return(ORDER_TYPE_SELL_LIMIT);
      case(2):return(ORDER_TYPE_BUY_STOP);
      case(3):return(ORDER_TYPE_SELL_STOP);
     }
//--- 不正确值
   return(WRONG_VALUE);
  }
//+------------------------------------------------------------------+
//| 返回随机价格                                                       |
//+------------------------------------------------------------------+
double GetRandomPrice(ENUM_ORDER_TYPE type)
  {
   int t=(int)type;
//--- 交易品种止损水平
   int distance=(int)SymbolInfoInteger(_Symbol,SYMBOL_TRADE_STOPS_LEVEL);
//--- 接收上一个订单号数据
   MqlTick last_tick={};
   SymbolInfoTick(_Symbol,last_tick);
//--- 按照类型计算价格
   double price;
   if(t==2 || t==5) // ORDER_TYPE_BUY_LIMIT or ORDER_TYPE_SELL_STOP
     {
      price=last_tick.bid; // 不同于卖价
      price=price-(distance+(MathRand()%10)*5)*_Point;
     }
   else             // ORDER_TYPE_SELL_LIMIT or ORDER_TYPE_BUY_STOP
     {
      price=last_tick.ask; // 不同于买价
      price=price+(distance+(MathRand()%10)*5)*_Point;
     }
//---
   return(price);
  }

另见

交易操作类型交易请求结构请求检测结果结构交易请求结果结构