OnTrade

Trade事件发生时在EA中调用这个函数。这个函数旨在处理订单、持仓和交易列表的变化。

void  OnTrade(void);

返回值

无返回值

注意

OnTrade()只为EA交易调用。即使您在指标和脚本中添加了具有相同名称和类型的函数,也不能在这些指标和脚本中使用此函数。

对于任何交易操作(下达挂单、开仓/平仓、下止损单、激活挂单等),订单和交易的历史和/或持仓和当前订单的列表都被适当更改。

当处理一个订单时,交易服务器向程序端发送一条关于传入Trade事件的消息。若要从历史记录中检索订单和交易的相关数据,需要先使用HistorySelect()执行交易历史请求。

如果出现以下情况,则服务器生成交易事件:

  • 更改活跃订单,
  • 更改持仓,
  • 更改交易,
  • 更改交易历史。

 

每一个 Trade事件都可能作为一个或多个交易请求的结果出现。交易请求使用OrderSend()OrderSendAsync(),被发送到服务器。每个请求都可能导致多个交易事件。您不能依赖“一个请求,一个交易事件”的声明,因为事件的处理可能分为几个阶段执行,并且每个操作都可能更改订单的状态、持仓和交易历史记录。

 

OnTrade()处理程序在适当调用OnTradeTransaction()之后被调用。通常,在OnTrade ()和OnTradeTransaction ()调用的数量上没有确切的相关性。OnTrade()一次调用对应一次或多次的OnTradeTransaction调用。

EA样例,OnTrade()处理程序

//+------------------------------------------------------------------+
//|                                               OnTrade_Sample.mq5 |
//|                        Copyright 2018, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2000-2024, MetaQuotes Ltd."
#property link      "https://www.mql5.com"
#property version   "1.00"
 
input    int days=7;            //按天计算的交易历史深度
//--- 在全局范围内设置交易历史的界限
datetime     start;             // 缓存中交易历史的开始日期
datetime     end;               // 缓存中交易历史的结束日期
//--- 全局计数器
int          orders;            // 活跃订单数量
int          positions;         // 持仓数量
int          deals;             // 交易历史缓存中的交易数量
int          history_orders;    // 交易历史缓存中的订单数量
bool         started=false;     // 计数器相关性标识
 
//+------------------------------------------------------------------+
//| EA交易初始化函数                                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   end=TimeCurrent();
   start=end-days*PeriodSeconds(PERIOD_D1);
   PrintFormat("Limits of the history to be loaded: start - %s, end - %s",
               TimeToString(start),TimeToString(end));
   InitCounters();
//---
   return(0);
  }
//+------------------------------------------------------------------+
//|  持仓、订单和交易计数器的初始化                                       |
//+------------------------------------------------------------------+
void InitCounters()
  {
   ResetLastError();
//--- 加载历史
   bool selected=HistorySelect(start,end);
   if(!selected)
     {
      PrintFormat("%s. Failed to load history from %s to %s to cache. Error code: %d",
                  __FUNCTION__,TimeToString(start),TimeToString(end),GetLastError());
      return;
     }
//--- 获取当前值
   orders=OrdersTotal();
   positions=PositionsTotal();
   deals=HistoryDealsTotal();
   history_orders=HistoryOrdersTotal();
   started=true;
   Print("Counters of orders, positions and deals successfully initialized");
  }  
//+------------------------------------------------------------------+
//| EA报价函数                                                        |
//+------------------------------------------------------------------+
void OnTick()
  {
   if(started) SimpleTradeProcessor();
   else InitCounters();
  }
//+------------------------------------------------------------------+
//| 当Trade事件到达时被调用                                             |
//+------------------------------------------------------------------+
void OnTrade()
  {
   if(started) SimpleTradeProcessor();
   else InitCounters();
  }
//+------------------------------------------------------------------+
//| 处理交易和历史变化的示例                                            |
//+------------------------------------------------------------------+
void SimpleTradeProcessor()
  {
   end=TimeCurrent();
   ResetLastError();
//--- 从指定的时间间隔下载交易历史到程序缓存
   bool selected=HistorySelect(start,end);
   if(!selected)
     {
      PrintFormat("%s. Failed to load history from %s to %s to cache. Error code: %d",
                  __FUNCTION__,TimeToString(start),TimeToString(end),GetLastError());
      return;
     }
//--- 获取当前值
   int curr_orders=OrdersTotal();
   int curr_positions=PositionsTotal();
   int curr_deals=HistoryDealsTotal();
   int curr_history_orders=HistoryOrdersTotal();
//--- 检查活跃订单的数量是否发生变化
   if(curr_orders!=orders)
     {
      //--- 活跃订单的数量已经发生变化
      PrintFormat("Number of orders has been changed. Previous value is %d, current value is %d",
                  orders,curr_orders);
      //--- 更新值
      orders=curr_orders;
     }
//--- 持仓数量的变化
   if(curr_positions!=positions)
     {
      //--- 持仓的数量已经发生变化
      PrintFormat("Number of positions has been changed. Previous value is %d, current value is %d",
                  positions,curr_positions);
      //--- 更新值
      positions=curr_positions;
     }
//--- 交易历史缓存中的交易数量的变化
   if(curr_deals!=deals)
     {
      //--- 交易历史缓存中的交易数量已经发生变化
      PrintFormat("Number of deals has been changed. Previous value is %d, current value is %d",
                  deals,curr_deals);
      //--- 更新值
      deals=curr_deals;
     }
//--- 交易历史缓存中的历史订单数量的变化
   if(curr_history_orders!=history_orders)
     {
      //--- 交易历史缓存中的历史订单数量已经发生变化
      PrintFormat("Number of orders in history has been changed. Previous value is %d, current value is %d",
                  history_orders,curr_history_orders);
     //--- 更新值
     history_orders=curr_history_orders;
     }
//--- 检查是否有必要更改缓存中请求的交易历史的限制
   CheckStartDateInTradeHistory();
  }
//+------------------------------------------------------------------+
//|  更改请求交易历史的开始日期                                          |
//+------------------------------------------------------------------+
void CheckStartDateInTradeHistory()
  {
//--- 初始时间间隔,如果我们现在开始工作
   datetime curr_start=TimeCurrent()-days*PeriodSeconds(PERIOD_D1);
//--- 确保交易历史的开始限制没有消失
//--- 预定日期超过1天
   if(curr_start-start>PeriodSeconds(PERIOD_D1))
     {
      //--- 修正在缓存区载入历史的开始日期
      start=curr_start;
      PrintFormat("New start limit of the trade history to be loaded: start => %s",
                  TimeToString(start));
      //--- 现在重新载入更新间隔的交易历史
      HistorySelect(start,end);
      //--- 为进一步比较,修正历史中交易和订单的计数器
      history_orders=HistoryOrdersTotal();
      deals=HistoryDealsTotal();
     }
  }
//+------------------------------------------------------------------+
/* Sample output:
  Limits of the history to be loaded: start - 2018.07.16 18:11, end - 2018.07.23 18:11
  The counters of orders, positions and deals are successfully initialized
  Number of orders has been changed. Previous value 0, current value 1
  Number of orders has been changed. Previous value 1, current value 0
  Number of positions has been changed. Previous value 0, current value 1
  Number of deals has been changed. Previous value 0, current value 1
  Number of orders in the history has been changed. Previous value 0, current value 1
*/

另见

OrderSendOrderSendAsyncOnTradeTransaction客户端事件