文章 "MQL5 Cookbook: 处理 TradeTransaction 事件"

 

新文章 MQL5 Cookbook: 处理 TradeTransaction 事件已发布:

在本文中,我打算介绍一种使用 MQL5 的手段来控制交易事件的方法。我要指出的是,有些文章已经专门讨论过这个话题。"EA 交易中采用 OnTrade() 函数处理交易事件" 即是其一。我不想重复其他作者,并将使用另一个处理器 - OnTradeTransaction()。

我想提请读者注意以下几点。在 MQL5 语言的当前版本,客户终端里包含 14 个正式的事件处理器。此外,程序员有可能利用 EventChartCustom() 创建自定义事件,并利用 OnChartEvent() 来处理它们。然而,术语“事件驱动编程”(EDP)在文档中并未提及。这很奇怪,事实表明,MQL5 的任何程序,都基于 EDP 原则创建。例如,在所有 EA 模板的“EA 事件处理器”步骤,可让用户进行选择。

很明显,不管怎样,事件驱动编程机制在 MQL5 中都被使用。该语言包含的程序块由两部分组成:事件选择和处理。此外,如果我们谈论的是客户端的事件,程序员只控制第二部分,即事件处理器。为了公平起 见,也有一些事件异常。定时器和自定义事件也在其中。这些事件的控制权,则完全留给了程序员。

图例.6. 第一个事务流程规划

图例.6. 第一个事务流程规划

作者:Dennis Kirichenko

 

根据我的经验,在异步模式下编程时,才真正需要使用 TradeTransaction。遗憾的是,文章对这种模式只字未提。

s.s. 我还以为 "什么是 MQL 配方"。- 是Anatoly 文章的商标标题。但现在事实证明并非如此(

 

C-4,谢谢你的意见。

C-4:

根据我的经验,在异步模式下编程时,才真正需要使用 TradeTransaction。遗憾的是,文章对这种模式只字未提......

使用 TradeTransaction 处理程序有不同的需求和要求。这是一个有趣的话题,我希望有经验的同行也能对此发表评论...

s.s. 我还以为 "MQL recipes"。- 是Anatoly 文章的品牌名称。现在事实证明并非如此(......)。

是的,我承认阿纳托利 是这一系列文章的发明者。我喜欢它,所以谦虚地加入了这个循环 :-))))

希望阿纳托利不要介意....

 
我还没有时间在本文中讨论部分订单执行(ORDER_STATE_PARTIAL)的问题。请问您,TradeTransaction 处理程序会被调用多少次?
 
denkir:
我还没有时间在本文中讨论部分订单执行(ORDER_STATE_PARTIAL)的问题。请问您,TradeTransaction 处理程序会被调用多少次?

我不知道。从逻辑上讲,处理程序的触发次数应该与完全执行时一样多。因为订单执行不是一个离散事件,MT 不知道订单是部分执行还是全部执行。

s.s. 遗憾的是,事件的传送没有保证,而且事件本身只能实时工作,这就限制了它们的应用。但对于基于状态跟踪的系统,如异步系统或交易复印机,它们却非常有用。有了事件,我们就可以构建一种算法,而无需循环,也不会因为等待 OnTimer 事件而产生额外的制动。

 
denkir:

...

我希望阿纳托利不会介意...

不,他当然不会介意。尤其是...

C-4:

...

s.s. 我还以为 "MQL 食谱"。- 是阿纳托利 文章的品牌名称。现在事实证明它不是(......

...... "MQL5 食谱 "是由 MQ 编辑人员建议的,因此任何人都可以使用。最重要的是要有更多不同的文章。

 
参考手册明确指出,一致性是无法保证的!如果查看历史数据,一致性则大相径庭。
 
感谢您撰写这篇文章。它非常有用。
 
如何让系统正常工作?
 
精彩的文章!我在这里学到了很多,祝贺你
 
VikMorroHun #:
感谢您撰写这篇文章。它非常有用。

你好、

我的情况似乎很简单:我下了一个挂单 (Sell_Stop),我想在以下情况下做出反应:a) 挂单成交,b) 未结头寸被止损或盈利目标平仓。

我的理解是否正确?

  1. 当挂单成交时,尽管 OnTradeTransaction() 的参数 "request"(请求)拥有 "magic"(魔法)字段,但我只能通过 从头寸列表中请求得到魔法数字,例如:
             if(!PositionSelectByTicket(trans.position)) {Print(__LINE__," PositionSelectByTicket FAILED ",err());}
             else {      
                OpnPos[sz].mag  = PositionGetInteger(POSITION_MAGIC);
             }   
    

  2. 我无法知道卖出头寸是开仓还是平仓的各种交易类型:
    void OnTradeTransaction(const MqlTradeTransaction& trans,
                            const MqlTradeRequest& request,
                            const MqlTradeResult& result)
      {
    //---
    
    //--- 
       static int counter=0;   // 调用 OnTradeTransaction() 的计数器 
       static uint lasttime=0; // 最后一次调用 OnTradeTransaction() 的时间 
    //--- 
       uint time=GetTickCount(); 
    //--- 如果最后一笔交易是在 1 秒钟之前执行的、 
       if(time-lasttime>1000) 
         { 
          counter=0; // 那么这是一个新的交易操作,可以重置计数器 
          if(IS_DEBUG_MODE) 
             Print(__LINE__," "," New trade operation dTime",time-lasttime); 
         } 
       Print(__LINE__," ",counter," ",DoubleToString((double(lasttime=time)/1000.0,2)
                ," Tr.Type: ",EnumToString(trans.type)," DL.Type: ",EnumToString(trans.deal_type)
                ," RQ.Type: ",EnumToString(request.type)," RQ.Fill: ",EnumToString(request.type_filling)
             ); 
    在 01:00:40 开仓并在 10:04:40 平仓的情况下,该 Print 将生成:
    01:00:40   322 0 81952.76 Tr.Type: TRADE_TRANSACTION_DEAL_ADD DL.Type: DEAL_TYPE_SELL RQ.Type: ORDER_TYPE_BUY RQ.Fill: ORDER_FILLING_FOK // open sell position
    10:04:40   322 0 81970.73 Tr.Type: TRADE_TRANSACTION_DEAL_ADD DL.Type: DEAL_TYPE_BUY  RQ.Type: ORDER_TYPE_BUY RQ.Fill: ORDER_FILLING_FOK // close sell position
    
    01:00:40   322 0 81955.30 Tr.Type: TRADE_TRANSACTION_ORDER_DELETE DL.Type: DEAL_TYPE_BUY RQ.Type: ORDER_TYPE_BUY RQ.Fill: ORDER_FILLING_FOK // open sell position
    10:04:40   322 0 81980.91 Tr.Type: TRADE_TRANSACTION_ORDER_DELETE DL.Type: DEAL_TYPE_BUY RQ.Type: ORDER_TYPE_BUY RQ.Fill: ORDER_FILLING_FOK // close sell position
    
    01:00:40   322 0 81965.14 Tr.Type: TRADE_TRANSACTION_HISTORY_ADD DL.Type: DEAL_TYPE_BUY RQ.Type: ORDER_TYPE_BUY RQ.Fill: ORDER_FILLING_FOK // open sell position
    10:04:40   322 0 81982.69 Tr.Type: TRADE_TRANSACTION_HISTORY_ADD DL.Type: DEAL_TYPE_BUY RQ.Type: ORDER_TYPE_BUY DL.Type: ORDER_FILLING_FOK // close sell position
    
    01:00:59   322 0 81968.50 Tr.Type: TRADE_TRANSACTION_REQUEST     DL.Type: DEAL_TYPE_BUY RQ.Type: ORDER_TYPE_SELL RQ.Fill: ORDER_FILLING_FOK // open sell position
    
    看涨期权看起来几乎一样--这是怎么回事?
    在卖出止损被触发并变成卖出(头寸)的情况下,request.type = ORDER_TYPE_BUY 的含义是什么?_BUY 来自何处?
您知道用 OnTradeTransaction() 的手段(参数)确定仓位已被止损或盈利目标平仓而不知道是卖出还是买入仓位被平仓的有效方法吗?