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 2018, MetaQuotes Software Corp."

#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客户端事件