交易事务结构 (MqlTradeTransaction)

当在交易账户上执行一些明确活动时,它的状态会发生变化。这种活动包括:

  • 使用 OrderSendOrderSendAsync 函数在客户端从任何MQL5应用发送交易请求及其进一步执行:
  • 通过程序端图形界面发送交易请求及其进一步执行;
  • 在服务器上激活挂单和止损订单;
  • 在交易服务器上执行操作。

这些操作的结果会执行以下交易事务:

  • 处理交易请求;
  • 改变持仓订单;
  • 改变订单历史记录;
  • 改变交易历史记录;
  • 改变持仓。

例如,当发送市场买入订单时,它会被处理,为账户创建相应的买入订单,然后执行订单并从持仓列表中移除,添加到历史订单,而相应的交易也会添加到历史记录并创建新的持仓。所有这些操作都是交易事务

OnTradeTransaction()的特别句柄在MQL5提供,以获得用于账户的交易。句柄的第一个参数获得描述交易事务的MqlTradeTransaction结构。

struct MqlTradeTransaction
  {
   ulong                         deal;             // 交易单
   ulong                         order;            // 订单标签
   string                        symbol;           // 交易品种
   ENUM_TRADE_TRANSACTION_TYPE   type;             // 交易事务类型
   ENUM_ORDER_TYPE               order_type;       // 订单类型
   ENUM_ORDER_STATE              order_state;      // 订单状态
   ENUM_DEAL_TYPE                deal_type;        // 成交类型
   ENUM_ORDER_TYPE_TIME          time_type;        // 操作期的订单类型
   datetime                      time_expiration;  // 订单到期时间
   double                        price;            // 价格 
   double                        price_trigger;    // 限价止损订单激活价格
   double                        price_sl;         // 止损水平
   double                        price_tp;         // 获利水平
   double                        volume;           // 交易量手数
   ulong                         position;         // 持仓价格
   ulong                         position_by;      // 反向持仓价格
  };

字段描述

字段

描述

deal

交易单。

order

订单标签。

symbol

执行交易事务的交易品种的名称。

type

交易事务类型。该值可以是一个ENUM_TRADE_TRANSACTION_TYPE 枚举值。

order_type

交易订单类型。该值可以是一个ENUM_ORDER_TYPE 枚举值。

order_state

交易订单状态。该值可以是一个 ENUM_ORDER_STATE 枚举值。

deal_type

成交类型。该值可以是一个 ENUM_DEAL_TYPE 枚举值。

time_type

接近期限的订单类型。该值可以是一个ENUM_ORDER_TYPE_TIME枚举值。

time_expiration

挂单到期期限 (用于 ORDER_TIME_SPECIFIEDORDER_TIME_SPECIFIED_DAY订单类型)。

price

价格。根据交易事务类型,它可能是订单价,成交价或持仓价。

price_trigger

限价止损订单,止损(激活)价格 (ORDER_TYPE_BUY_STOP_LIMITORDER_TYPE_SELL_STOP_LIMIT)。

price_sl

止损价。根据交易事务类型,它可能涉及订单,交易或持仓。

price_tp

获利价。根据交易事务类型,它可能涉及订单,交易或持仓。

volume

交易量手数。根据交易事务类型,它可能表明订单,交易或持仓的当前交易量。

收到的交易分析基本参数就是type 字段中指定其类型。例如,如果TRADE_TRANSACTION_REQUEST 类型的交易 (已经收到通过服务器处理交易请求的结果),该结构只有一个字段被完整填写 - type。其他字段不分析。这样,我们可以分析两个额外的 requestresult 参数提交到 OnTradeTransaction() 句柄,显示如下。

拥有交易操作类型的数据,您可以决定在交易账户上分析订单,持仓和交易的当前状态。记住从程序端发送至服务器的交易请求可以生成多个新的交易事务。程序端优先到达不保证。

MqlTradeTransaction 结构根据交易事务类型以不同的方式填写 (ENUM_TRADE_TRANSACTION_TYPE):

TRADE_TRANSACTION_ORDER_* and TRADE_TRANSACTION_HISTORY_*

填充MqlTradeTransaction 结构的以下字段,用于有关持仓的相关订单,处理 (TRADE_TRANSACTION_ORDER_ADD, TRADE_TRANSACTION_ORDER_UPDATE 和 TRADE_TRANSACTION_ORDER_DELETE) 和历史订单 (TRADE_TRANSACTION_HISTORY_ADD, TRADE_TRANSACTION_HISTORY_UPDATE, TRADE_TRANSACTION_HISTORY_DELETE):

  • order - 订单;
  • symbol - 订单交易品种名称;
  • type - 交易事务类型;
  • order_type - 订单类型;
  • orders_state - 订单当前状态;
  • time_type - 订单过期类型;
  • time_expiration - 订单过期时间 (用于拥有 ORDER_TIME_SPECIFIEDORDER_TIME_SPECIFIED_DAY 过期类型的订单)
  • price - 客户指定的订单价格;
  • price_trigger - 限价止损订单止损价格(仅用于 ORDER_TYPE_BUY_STOP_LIMITORDER_TYPE_SELL_STOP_LIMIT)
  • price_sl - 止损订单价(已执行,如果订单指明);
  • price_tp - 获利订单价(已执行,如果订单指明);
  • volume - 订单当前交易量(未执行)。初始订单交易量可以使用 HistoryOrders* 函数在历史订单中找到。

TRADE_TRANSACTION_DEAL_*

填充MqlTradeTransaction结构的以下字段用于交易相关的交易事务,处理 (TRADE_TRANSACTION_DEAL_ADD, TRADE_TRANSACTION_DEAL_UPDATE 和 TRADE_TRANSACTION_DEAL_DELETE):

  • deal - 交易单;
  • order - 订单标签,基于已执行的交易;
  • symbol - 交易品种名称;
  • type - 交易事务类型;
  • deal_type - 交易类型;
  • price - 交易价格;
  • price_sl - 止损价格(已执行,如果执行交易的订单指明);
  • price_tp - 获利价(已执行,如果执行交易的订单指明);
  • volume - 交易量手数。

TRADE_TRANSACTION_POSITION

填充 MqlTradeTransaction 结构的以下字段用于改变与执行交易 (TRADE_TRANSACTION_POSITION) 无关联的持仓的相关交易事务:

  • symbol - 持仓交易品种名称;
  • type - 交易事务类型;
  • deal_type - 持仓类型(DEAL_TYPE_BUYDEAL_TYPE_SELL)
  • price - 加权平均持仓价;
  • price_sl - 止损价;
  • price_tp - 获利价;
  • volume - 持仓交易量手数,如果已经改变。

持仓改变(添加,改变或关闭),执行交易的结果,不会导致发生TRADE_TRANSACTION_POSITION 事务。

TRADE_TRANSACTION_REQUEST

只填充MqlTradeTransaction结构的一个字段,用于描述已被服务器处理的交易请求的交易事务,并且处理结果已经接收(TRADE_TRANSACTION_REQUEST):

  • type - 交易事务类型;

只有 type 字段(交易事务类型)必须分析这种事务。 OnTradeTransaction 函数 (请求和结果) 的第二和第三参数必须分析额外的数据。

例如:

input int MagicNumber=1234567;
 
//--- 启用CTrade 交易类并声明这种类的变量
#include <Trade\Trade.mqh>
CTrade trade;
//--- 安装和删除挂单的标识
bool pending_done=false;
bool pending_deleted=false;
//--- 挂单将被存储在这里
ulong order_ticket;
//+------------------------------------------------------------------+
//| 专家初始化函数                                                     |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- 设置MagicNumber 标记我们所有订单
   trade.SetExpertMagicNumber(MagicNumber);
//--- 交易请求将通过OrderSendAsync() 函数以非同步的模式发送
   trade.SetAsyncMode(true);
//--- 初始化变量为零
   order_ticket=0;
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| 专家订单函数                                                       |
//+------------------------------------------------------------------+
void OnTick()
  {
//---安装挂单
   if(!pending_done)
     {
      double ask=SymbolInfoDouble(_Symbol,SYMBOL_ASK);
      double buy_stop_price=NormalizeDouble(ask+1000*_Point,(int)SymbolInfoInteger(_Symbol,SYMBOL_DIGITS));
      bool res=trade.BuyStop(0.1,buy_stop_price,_Symbol);
      //--- 如果BuyStop()函数成功执行 
      if(res)
        {
         pending_done=true;
         //--- 获取从ctrade发送的请求的结果
         MqlTradeResult trade_result;
         trade.Result(trade_result);
         //--- 获得发送请求的request_id
         uint request_id=trade_result.request_id;
         Print("Request has been sent to set a pending order. Request_ID=",request_id);
         //--- 存储订单 (如果使用非同步模式发送到CTrade,则将为零) 
         order_ticket=trade_result.order;
         //--- 全部完成后,提前从OnTick() 处理程序退出
         return;
        }
     }
//--- 删除挂单
   if(!pending_deleted)
      //--- 附加检查
      if(pending_done && (order_ticket!=0))
        {
         //--- 尝试删除挂单
         bool res=trade.OrderDelete(order_ticket);
         Print("OrderDelete=",res);
         //--- 删除请求发送成功
         if(res)
           {
            pending_deleted=true;
            //--- 得到请求执行结果
            MqlTradeResult trade_result;
            trade.Result(trade_result);
            //--- 获得来自结果的 request ID
            uint request_id=trade_result.request_id;
            //--- 在日志中显示
            Print("The request has been sent to delete a pending order #",order_ticket,
                  ". Request_ID=",request_id,
                  "\r\n");
            //--- 修正来自请求结果的订单
            order_ticket=trade_result.order;
           }
        }
//---        
  }
//+------------------------------------------------------------------+
//| TradeTransaction 函数                                            |
//+------------------------------------------------------------------+
void OnTradeTransaction(const MqlTradeTransaction &trans,
                        const MqlTradeRequest &request,
                        const MqlTradeResult &result)
  {
//--- 获取事务类型作为枚举值 
   ENUM_TRADE_TRANSACTION_TYPE type=(ENUM_TRADE_TRANSACTION_TYPE)trans.type;
//--- 如果事务是请求处理结果,那么只显示它的名称
   if(type==TRADE_TRANSACTION_REQUEST)
     {
      Print(EnumToString(type));
      //--- 显示已处理的 request 字符串名称
      Print("------------RequestDescription\r\n",RequestDescription(request));
      //--- 显示request 结果描述
      Print("------------ResultDescription\r\n",TradeResultDescription(result));
      //--- 存储用于下一个OnTick()处理的删除的订单
      if(result.order!=0)
        {
         //--- 通过在next OnTick() 调用的标识删除该订单
         order_ticket=result.order;
         Print(" Pending order ticket ",order_ticket,"\r\n");
        }
     }
   else // 显示另一事务类型的完整描述
//--- 在日志中显示已接收事务的描述
      Print("------------TransactionDescription\r\n",TransactionDescription(trans));
 
//---     
  }
//+------------------------------------------------------------------+
//| 返回事务文本描述                                                   |
//+------------------------------------------------------------------+
string TransactionDescription(const MqlTradeTransaction &trans)
  {
//--- 
   string desc=EnumToString(trans.type)+"\r\n";
   desc+="Symbol: "+trans.symbol+"\r\n";
   desc+="Deal ticket: "+(string)trans.deal+"\r\n";
   desc+="Deal type: "+EnumToString(trans.deal_type)+"\r\n";
   desc+="Order ticket: "+(string)trans.order+"\r\n";
   desc+="Order type: "+EnumToString(trans.order_type)+"\r\n";
   desc+="Order state: "+EnumToString(trans.order_state)+"\r\n";
   desc+="Order time type: "+EnumToString(trans.time_type)+"\r\n";
   desc+="Order expiration: "+TimeToString(trans.time_expiration)+"\r\n";
   desc+="Price: "+StringFormat("%G",trans.price)+"\r\n";
   desc+="Price trigger: "+StringFormat("%G",trans.price_trigger)+"\r\n";
   desc+="Stop Loss: "+StringFormat("%G",trans.price_sl)+"\r\n";
   desc+="Take Profit: "+StringFormat("%G",trans.price_tp)+"\r\n";
   desc+="Volume: "+StringFormat("%G",trans.volume)+"\r\n";
//--- 返回获得的字符串
   return desc;
  }
//+------------------------------------------------------------------+
//| 返回交易请求文本描述                                                |
//+------------------------------------------------------------------+
string RequestDescription(const MqlTradeRequest &request)
  {
//---
   string desc=EnumToString(request.action)+"\r\n";
   desc+="Symbol: "+request.symbol+"\r\n";
   desc+="Magic Number: "+StringFormat("%d",request.magic)+"\r\n";
   desc+="Order ticket: "+(string)request.order+"\r\n";
   desc+="Order type: "+EnumToString(request.type)+"\r\n";
   desc+="Order filling: "+EnumToString(request.type_filling)+"\r\n";
   desc+="Order time type: "+EnumToString(request.type_time)+"\r\n";
   desc+="Order expiration: "+TimeToString(request.expiration)+"\r\n";
   desc+="Price: "+StringFormat("%G",request.price)+"\r\n";
   desc+="Deviation points: "+StringFormat("%G",request.deviation)+"\r\n";
   desc+="Stop Loss: "+StringFormat("%G",request.sl)+"\r\n";
   desc+="Take Profit: "+StringFormat("%G",request.tp)+"\r\n";
   desc+="Stop Limit: "+StringFormat("%G",request.stoplimit)+"\r\n";
   desc+="Volume: "+StringFormat("%G",request.volume)+"\r\n";
   desc+="Comment: "+request.comment+"\r\n";
//--- 返回获得的字符串
   return desc;
  }
//+------------------------------------------------------------------+
//| 返回请求处理结果的文本描述                                           |
//+------------------------------------------------------------------+
string TradeResultDescription(const MqlTradeResult &result)
  {
//---
   string desc="Retcode "+(string)result.retcode+"\r\n";
   desc+="Request ID: "+StringFormat("%d",result.request_id)+"\r\n";
   desc+="Order ticket: "+(string)result.order+"\r\n";
   desc+="Deal ticket: "+(string)result.deal+"\r\n";
   desc+="Volume: "+StringFormat("%G",result.volume)+"\r\n";
   desc+="Price: "+StringFormat("%G",result.price)+"\r\n";
   desc+="Ask: "+StringFormat("%G",result.ask)+"\r\n";
   desc+="Bid: "+StringFormat("%G",result.bid)+"\r\n";
   desc+="Comment: "+result.comment+"\r\n";
//--- 返回获得的字符串
   return desc;
  }

另见

交易事务类型OnTradeTransaction()