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

OnTradeTransaction函数介绍

[复制链接]

4万

主题

54

回帖

4万

积分

管理员

积分
45954
发表于 2026-8-23 06:49:00 | 显示全部楼层 |阅读模式
EA调用TradeTransaction事件发生的OnTradeTransaction()函数较少在本网站述及,在此记录学习过程。


void  OnTradeTransaction()

   const MqlTradeTransaction&    trans,     // trade transaction structure

   const MqlTradeRequest&        request,   // request structure

   const MqlTradeResult&         result     // response structure

   );

该函数有三个参数:

1.  trans[in]  MqlTradeTransaction 类型变量,它主要用来描述交易类型。

2. request[in]  MqlTradeRequest  类型变量 ,描述启动一个交易的请求,它包含TRADE_TRANSACTION_REQUEST 类型的值。它是个ENUM_TRADE_REQUEST_ACTIONS 枚举变量,主要描述请求动作:deal,pending,sltp,modify,remove,closeby.

3. result[in]  MqlTradeResult 类型变量,包含了发出请求交易的执行结果。它包含TRADE_TRANSACTION_RESULT类型的值,描述服务器对应收到的交易请求的返回结果:return code,deal ticket,order ticket(针对pending order),volume,deal price,bid,ask,comment(经纪商对操作的注释),request ID(发出交易请求时终端设定),code of error(外部交易系统返回的)

OnTradeTransaction() 在如下4种情况下被调用(总记录最近的),用来处理交易服务器发给终端的 TradeTransaction 事件:1. 从MQL5程序使用OrderSend()或OrderSendAsync()函数发出的交易请求和随后的执行;

2. 人工通过GUI发出的交易请求和随后的执行;

3. 在服务器上激活挂单;

4. 在服务器上执行操作;

MqlTradeTransaction 类型变量包括嗯呢trans变量,交易类型有枚举变量ENUM_TRADE_TRANSACTION_TYPE 描述,主要是Order_Add,Order_update(变更一个现存的order),Order_delete,deal_add(增加一个deal进入历史),deal_update,deal_delete,history_add(由于执行或取消而在交易历史中增加订单order),history_update(order历史中改变一个order),history_delete,position(与交易执行无关的开仓变化),request (服务器发出的交易请求已经被处理的通知以及处理结果已收到)。

在分析TradeTransaction时,为了收集必要的信息是有必要分析第二、三个参数(request和result)。例如:发出开仓请求将导致:1. 请求已被服务去收到进行处理;2. 开仓订单在账户里创建;3. 订单被执行;4. 执行的订单将被从活动状态移除;5.到订单历史中 ;6. 随后的交易将被增加的历史中;7. 在账户中新的仓位被创建。 所有这些过程都是 TradeTransaction 事件。

EA的OnTradeTransaction函数句柄将用来处理交易。终端不断处理进来的交易,所以交易账户状态也会随着OnTradeTransaction函数的运行而不断变化,程序会被通知所有这些交易事件。

交易队列长度了1024个单元,OnTradeTransaction会由于队列过长,新的交易会取代在队列中前面的交易。

不要与OnTrade函数混淆,OnTrade是用来处理订单、仓位和交易清单的改变,它只能由EA调用。OnTrade()函数句柄是在适当的 OnTradeTransaction() 函数调用后才被调用。一般来说, 函数OnTrade () 和 OnTradeTransaction () 调用数目并无精确的相关性。一个OnTrade() 调用对应了一个或几个OnTradeTransaction的调用.

以下是一个官网给出的例子:

//+------------------------------------------------------------------+
//| TradeTransaction function                                        |
//+------------------------------------------------------------------+
void OnTradeTransaction(const MqlTradeTransaction &trans,
                        const MqlTradeRequest &request,
                        const MqlTradeResult &result)
  {
//---
   static int counter=0;   // counter of OnTradeTransaction() calls
   static uint lasttime=0; // time of the OnTradeTransaction() last call
//---
   uint time=GetTickCount(); //自从系统开始所过去多少milliseconds,不关机会overfilled49.7天后
//--- if the last transaction was performed more than 1 second ago,
   if(time-lasttime>1000)
     {
      counter=0; // then this is a new trade operation, an the counter can be reset
      if(IS_DEBUG_MODE)
         Print(" New trade operation");
     }
   lasttime=time;
   counter++;
   Print(counter,". ",__FUNCTION__);
//--- result of trade request execution
   ulong            lastOrderID   =trans.order;
   ENUM_ORDER_TYPE  lastOrderType =trans.order_type;
   ENUM_ORDER_STATE lastOrderState=trans.order_state;
//--- the name of the symbol, for which a transaction was performed
   string trans_symbol=trans.symbol;
//--- type of transaction   这个是比较经典的使用方法从type入手
   ENUM_TRADE_TRANSACTION_TYPE  trans_type=trans.type;
   switch(trans.type)
     {
      case  TRADE_TRANSACTION_POSITION:   // position modification
        {
         ulong pos_ID=trans.position;
         PrintFormat("MqlTradeTransaction: Position  #%d %s modified: SL=%.5f TP=%.5f",
                     pos_ID,trans_symbol,trans.price_sl,trans.price_tp);
        }
      break;
      case TRADE_TRANSACTION_REQUEST:     // sending a trade request
         PrintFormat("MqlTradeTransaction: TRADE_TRANSACTION_REQUEST");
         break;
      case TRADE_TRANSACTION_DEAL_ADD:    // adding a trade
        {
         ulong          lastDealID   =trans.deal;
         ENUM_DEAL_TYPE lastDealType =trans.deal_type;
         double        lastDealVolume=trans.volume;
         //--- Trade ID in an external system - a ticket assigned by an exchange
         string Exchange_ticket="";
         if(HistoryDealSelect(lastDealID))
            Exchange_ticket=HistoryDealGetString(lastDealID,DEAL_EXTERNAL_ID);
         if(Exchange_ticket!="")
            Exchange_ticket=StringFormat("(Exchange deal=%s)",Exchange_ticket);
  
         PrintFormat("MqlTradeTransaction: %s deal #%d %s %s %.2f lot   %s",EnumToString(trans_type),
                     lastDealID,EnumToString(lastDealType),trans_symbol,lastDealVolume,Exchange_ticket);
        }
      break;
      case TRADE_TRANSACTION_HISTORY_ADD: // adding an order to the history
        {
         //--- order ID in an external system - a ticket assigned by an Exchange
         string Exchange_ticket="";
         if(lastOrderState==ORDER_STATE_FILLED)
           {
            if(HistoryOrderSelect(lastOrderID))
               Exchange_ticket=HistoryOrderGetString(lastOrderID,ORDER_EXTERNAL_ID);
            if(Exchange_ticket!="")
               Exchange_ticket=StringFormat("(Exchange ticket=%s)",Exchange_ticket);
           }
         PrintFormat("MqlTradeTransaction: %s order #%d %s %s %s   %s",EnumToString(trans_type),
                     lastOrderID,EnumToString(lastOrderType),trans_symbol,EnumToString(lastOrderState),Exchange_ticket);
        }
      break;
      default: // other transactions   
        {
         //--- order ID in an external system - a ticket assigned by Exchange
         string Exchange_ticket="";
         if(lastOrderState==ORDER_STATE_PLACED)
           {
            if(OrderSelect(lastOrderID))
               Exchange_ticket=OrderGetString(ORDER_EXTERNAL_ID);
            if(Exchange_ticket!="")
               Exchange_ticket=StringFormat("Exchange ticket=%s",Exchange_ticket);
           }
         PrintFormat("MqlTradeTransaction: %s order #%d %s %s   %s",EnumToString(trans_type),
                     lastOrderID,EnumToString(lastOrderType),EnumToString(lastOrderState),Exchange_ticket);
        }
      break;
     }
//--- order ticket     
   ulong orderID_result=result.order;
   string retcode_result=GetRetcodeID(result.retcode);
   if(orderID_result!=0)
      PrintFormat("MqlTradeResult: order #%d retcode=%s ",orderID_result,retcode_result);
//---   
  } 复制代码

以下是在N根K线后开单的使用OnTransactionTrade的虚拟程序的例子:-------One deal in N bars---------
#property version   "1.00"
//--- input parameters
input uchar    InpBars              = 10;     //   10根K线后下单
input ulong    InpDeviation     = 1000; // 偏差点数, in points (1.09123-1.08123=1000 points)
input ulong    InpMagic           = 2;      // 幻数
//---
datetime m_last_deal_IN = 0;              // "0" -> D'1970.01.01 00:00';
  
void OnTick()
  {
//--- 在这写的入场或其他信号
   if(PositionsTotal()==0)
     {
      datetime time[];
      ArraySetAsSeries(time,true);
      int start_pos=0;           // 拷贝时间的开始位置
      int count=InpBars+1;  // 拷贝多少根K线
      if(CopyTime(Symbol(),Period(),start_pos,count,time)!=count)
         return;
      //--- check
      if(time[InpBars]>m_last_deal_IN)// 前第10根K线的开始时间已经大于最近一次开仓时间
        {
         //--- 开仓
        }
     }
  }  
  
void OnTradeTransaction(const MqlTradeTransaction &trans,
                        const MqlTradeRequest &request,
                        const MqlTradeResult &result)
  {
   ENUM_TRADE_TRANSACTION_TYPE type=trans.type;
   if(type==TRADE_TRANSACTION_DEAL_ADD)  
     {
      long     deal_ticket       =0;
      long     deal_order        =0;
      long     deal_time         =0;
      long     deal_time_msc     =0;
      long     deal_type         =-1;
      long     deal_entry        =-1;
      long     deal_magic        =0;
      long     deal_reason       =-1;
      long     deal_position_id  =0;
      double   deal_volume       =0.0;
      double   deal_price        =0.0;
      double   deal_commission   =0.0;
      double   deal_swap         =0.0;
      double   deal_profit       =0.0;
      string   deal_symbol       ="";
      string   deal_comment      ="";
      string   deal_external_id  ="";
      if(HistoryDealSelect(trans.deal))
        {
         deal_ticket         =HistoryDealGetInteger(trans.deal,DEAL_TICKET);
         deal_order         =HistoryDealGetInteger(trans.deal,DEAL_ORDER);
         deal_time           =HistoryDealGetInteger(trans.deal,DEAL_TIME);
         deal_time_msc   =HistoryDealGetInteger(trans.deal,DEAL_TIME_MSC);
         deal_type           =HistoryDealGetInteger(trans.deal,DEAL_TYPE);
         deal_entry          =HistoryDealGetInteger(trans.deal,DEAL_ENTRY);
         deal_magic         =HistoryDealGetInteger(trans.deal,DEAL_MAGIC);
         deal_reason        =HistoryDealGetInteger(trans.deal,DEAL_REASON);
         deal_position_id  =HistoryDealGetInteger(trans.deal,DEAL_POSITION_ID);

         deal_volume           =HistoryDealGetDouble(trans.deal,DEAL_VOLUME);
         deal_price               =HistoryDealGetDouble(trans.deal,DEAL_PRICE);
         deal_commission    =HistoryDealGetDouble(trans.deal,DEAL_COMMISSION);
         deal_swap               =HistoryDealGetDouble(trans.deal,DEAL_SWAP);
         deal_profit               =HistoryDealGetDouble(trans.deal,DEAL_PROFIT);

         deal_symbol            =HistoryDealGetString(trans.deal,DEAL_SYMBOL);
         deal_comment        =HistoryDealGetString(trans.deal,DEAL_COMMENT);
         deal_external_id      =HistoryDealGetString(trans.deal,DEAL_EXTERNAL_ID);
        }
      else
         return;
      ENUM_DEAL_ENTRY enum_deal_entry=(ENUM_DEAL_ENTRY)deal_entry;
      if(deal_symbol==Symbol() && deal_magic==InpMagic)
        {
         if(deal_type==DEAL_TYPE_BUY || deal_type==DEAL_TYPE_SELL)
           {
            if(deal_entry==DEAL_ENTRY_IN)
              {
               m_last_deal_IN=iTime(Symbol(),Period(),0);
              }
           }
        }
     }
  }复制代码
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

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

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

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