外汇EA编写教程:MQL5食谱:处理TradeTransaction事件

介绍

在本文中,我将介绍一种使用MQL5控制事务事件的方法。我想指出的是,有一些文章专门讨论这个话题。其中之一是使用ontrade()函数处理EA事务中的事务事件。我不想复制其他作者,将使用另一个处理器OnTradeTransaction()。

我想提请读者注意以下几点。在当前版本的MQL5中,客户机终端中有14个正式的事件处理器。此外,程序员可以使用EventChartCustom()创建自定义事件,使用OnChartEvent()处理这些事件。但是,文档中没有提到“事件驱动编程”(EDP)。这很奇怪。结果表明,MQL5中的任何程序都是基于EDP原则的。例如,所有EA模板中的“EA事件处理器”步骤允许用户选择。

显然,无论如何,在MQL5中都使用了事件驱动的编程机制。语言中的程序块由两部分组成:事件选择和处理。此外,如果我们谈论的是客户机事件,程序员只控制第二部分,即事件处理程序。为了公平起见,也有一些异常事件。还包括计时器和自定义事件。对这些事件的控制权完全留给程序员。

1。TradeTransaction事件

在深入讨论我们的主题之前,让我们先参考官方资料。

根据文档,TradeTransaction事件是事务帐户确定操作的结果。操作本身包含几个确定性事务阶段。例如,当以市场价格开仓时,通过交易账户进行的最常见操作包括以下几个阶段:

  1. 提出交易请求;
  2. 验证交易请求;
  3. 向服务器发送事务请求;
  4. 接收服务器端对事务请求执行的响应。

这些序列只显示终端和服务器对之间的逻辑,这些逻辑反映在EA代码的字符串中。从贸易交易事件的角度来看,在市场中开仓的方式如下:

  1. mql5-程序从服务器端接收完成请求的结果;
  2. 在订单表单中请求唯一的订单号,包括打开的订单列表;
  3. 订单执行后从未结订单列表中删除;
  4. 之后,订单转移到账户历史记录;
  5. 帐户历史记录还包含交易数据,这是订单执行的结果。

因此,OnTradeTransaction()处理器在仓库打开时被调用五次。

稍后我们将详细讨论程序代码,现在我们将仔细查看函数头。它有三个输入参数。

void  OnTradeTransaction(
   const MqlTradeTransaction&    trans,        // structure of the trade transaction
   const MqlTradeRequest&        request,      // structure of the request
   const MqlTradeResult&         result        // structure of the response
   );

这些参数在文档中有详细描述。我想引起注意的是,事务结构的参数是一类抛出消息,在当前调用过程中由处理器接收。

关于交易我也要说几句,因为我们会遇到很多。

在mql5中,枚举交易类型是提供交易类型的特殊枚举。为了找出交易公司的类型,我们需要参考参数mqltradetransaction type常量。

struct MqlTradeTransaction
  {
   ulong                         deal;             // Ticket of the deal
   ulong                         order;            // Ticket of the order
   string                        symbol;           // Trade symbol
   ENUM_TRADE_TRANSACTION_TYPE   type;             // Type of the trade transaction
   ENUM_ORDER_TYPE               order_type;       // Type of the order
   ENUM_ORDER_STATE              order_state;      // Status of the order
   ENUM_DEAL_TYPE                deal_type;        // Type of the deal
   ENUM_ORDER_TYPE_TIME          time_type;        // Order expiration type
   datetime                      time_expiration;  // Order expiration time
   double                        price;            // Price 
   double                        price_trigger;    // Price that triggers the Stop Limit order
   double                        price_sl;         // Level of Stop Loss
   double                        price_tp;         // Level of Take Profit
   double                        volume;           // Volume in lots
  };

结构的第四个字段是我们要查找的枚举变量。

2。仓库处置

本质上,所有事务的定位都会导致对OnTradeTransaction()处理器的五次调用。其中有:

  • 露天仓库;
  • 打开位置;
  • 倒车位置;
  • 规模;
  • 部分清算。

修改仓库是唯一两次调用TradeTransaction处理器的事务操作。

由于没有与清晰事务操作对应的事务类型的信息,因此我们打算通过实验和调试来发现它。

在此之前,我们需要创建一个包含TradeTransaction事件处理程序的EA模板。我把模板命名为TradeProcessor。MQ5。我添加了一个功能来显示日志中结构字段值的信息。这些值是事件处理程序的参数。分析这些记录将非常耗时,但最终它将通过呈现事件的全景来进行补偿。

我们需要在MetaTrader 5终端的任何图表上以调试模式启动EA。

手动打开仓库并查看代码。这是第一次处理器调用的情况(图例)。1)。

图例.1. 类型字段等于 TRADE_TRANSACTION_REQUEST

传说。1。类型字段等于交易请求

日志中显示以下条目:

IO      0       17:37:53.233    TradeProcessor (EURUSD,H1)      ---===Transaction===---
NK      0       17:37:53.233    TradeProcessor (EURUSD,H1)      Ticket of the deal: 0
RR      0       17:37:53.233    TradeProcessor (EURUSD,H1)      Type of the deal: DEAL_TYPE_BUY
DE      0       17:37:53.233    TradeProcessor (EURUSD,H1)      Ticket of the order: 0
JS      0       17:37:53.233    TradeProcessor (EURUSD,H1)      Status of the order: ORDER_STATE_STARTED
JN      0       17:37:53.233    TradeProcessor (EURUSD,H1)      Type of the order: ORDER_TYPE_BUY
FD      0       17:37:53.233    TradeProcessor (EURUSD,H1)      Price: 0.0000
FN      0       17:37:53.233    TradeProcessor (EURUSD,H1)      Level of Stop Loss: 0.0000
HF      0       17:37:53.233    TradeProcessor (EURUSD,H1)      Level of Take Profit: 0.0000
FQ      0       17:37:53.233    TradeProcessor (EURUSD,H1)      Price that triggers the Stop Limit order: 0.0000
RR      0       17:37:53.233    TradeProcessor (EURUSD,H1)      Trade symbol: 
HD      0       17:37:53.233    TradeProcessor (EURUSD,H1)      Pending order expiration time: 1970.01.01 00:00
GS      0       17:37:53.233    TradeProcessor (EURUSD,H1)      Order expiration type: ORDER_TIME_GTC
DN      0       17:37:53.233    TradeProcessor (EURUSD,H1)      Type of the trade transaction TRADE_TRANSACTION_REQUEST
FK      0       17:37:53.233    TradeProcessor (EURUSD,H1)      Volume in lots: 0.00

在此块中,我们只对事务类型的记录感兴趣。如我们所见,这种类型属于(交易请求)请求。

可以在请求块中获取请求的详细信息。

QG 0贸易处理器(欧元兑美元,h1)17:37:53.233交易处理器(欧元兑美元,h1)-==请求==HL 0:17:37:53.233交易处理器(欧元兑美元,h1)交易操作的类型:交易活动交易EE:0交易处理器(欧元兑美元,h1)对订单的评论:JP:0交易EE:17:37:53.233。2 33贸易处理器(欧元兑美元,h1)与要求价格的偏差:0 GS;0 GS;17:37:53.233贸易处理器(欧元兑美元,h1)订单到期时间:1970.01.01 00:00 LF;0贸易处理器(欧元兑美元,H1)17:37:53.233交易处理器的幻数:0 fm,0 fm,17:37:53.233交易处理器(欧元兑美元,H1);N BSP订单门票:22535869 EJ:17:37:53.233 TradeProcessor(欧元兑美元,h1)价格:1.3137 qr:0:17:37:53.233;tra折旧处理器(欧元兑美元,h1)订单的止损水平:0.0000 ij;0.0000 ij;17:37:53.233贸易处理器(欧元兑美元,h1)订单的获利水平:0.0000 kksp;0:17:37:53.233 TradeProcessor(欧元兑美元,h1)订单的停止限制级别:0.0000 fs;0:17:37:53.233 TradeProcessor(欧元兑美元,h1)nbsp;trad符号:欧元兑美元Rd、Nbspsp、Nbspsp、Nbspsp、订单类型:订单类型

请求执行的结果数据可以从响应块中获得。

KG      0       17:37:53.233    TradeProcessor (EURUSD,H1)      ---===Response===---
JR      0       17:37:53.233    TradeProcessor (EURUSD,H1)      Code of the operation result: 10009
GD      0       17:37:53.233    TradeProcessor (EURUSD,H1)      Ticket of the deal: 15258202
NR      0       17:37:53.233    TradeProcessor (EURUSD,H1)      Ticket of the order: 22535869
EF      0       17:37:53.233    TradeProcessor (EURUSD,H1)      Volume of the deal: 0.11
MN      0       17:37:53.233    TradeProcessor (EURUSD,H1)      Price of the deal: 1.3137
HJ      0       17:37:53.233    TradeProcessor (EURUSD,H1)      Bid: 1.3135
PM      0       17:37:53.233    TradeProcessor (EURUSD,H1)      Ask: 1.3137
OG      0       17:37:53.233    TradeProcessor (EURUSD,H1)      Comment to the operation: 
RQ      0       17:37:53.233    TradeProcessor (EURUSD,H1)      Request ID: 1

通过分析处理器的其他参数,例如请求和响应的结构,您可以获得关于第一个请求调用的附加信息。

注意,第二个调用是将订单添加到打开的订单列表中(图。2)。

图例.2. 类型字段等于 TRADE_TRANSACTION_ORDER_ADD

传说。2。类型字段等于交易记录订单添加

“transaction”块是日志中唯一需要的东西。

MJ      0       17:41:12.280    TradeProcessor (EURUSD,H1)      ---===Transaction===---
JN      0       17:41:12.280    TradeProcessor (EURUSD,H1)      Ticket of the deal: 0
FG      0       17:41:12.280    TradeProcessor (EURUSD,H1)      Type of the deal: DEAL_TYPE_BUY
LM      0       17:41:12.280    TradeProcessor (EURUSD,H1)      Ticket of the order: 22535869
LI      0       17:41:12.280    TradeProcessor (EURUSD,H1)      Status of the order: ORDER_STATE_STARTED
LP      0       17:41:12.280    TradeProcessor (EURUSD,H1)      Type of the order: ORDER_TYPE_BUY
QN      0       17:41:12.280    TradeProcessor (EURUSD,H1)      Price: 1.3137
PD      0       17:41:12.280    TradeProcessor (EURUSD,H1)      Level of Stop Loss: 0.0000
NL      0       17:41:12.280    TradeProcessor (EURUSD,H1)      Level of Take Profit: 0.0000
PG      0       17:41:12.280    TradeProcessor (EURUSD,H1)      Price that triggers the Stop Limit order: 0.0000
DL      0       17:41:12.280    TradeProcessor (EURUSD,H1)      Trade symbol: EURUSD
JK      0       17:41:12.280    TradeProcessor (EURUSD,H1)      Pending order expiration time: 1970.01.01 00:00
QD      0       17:41:12.280    TradeProcessor (EURUSD,H1)      Order expiration type: ORDER_TIME_GTC
IQ      0       17:41:12.280    TradeProcessor (EURUSD,H1)      Type of the trade transaction: TRADE_TRANSACTION_ORDER_ADD
PL      0       17:41:12.280    TradeProcessor (EURUSD,H1)      Volume in lots: 0.11

在订单中,我们可以看到订单号和其他参数(名称、价格和数量)已收到并包含在已完成订单列表中。

对事件处理程序的第三个调用是从已经打开的订单列表中删除订单(图)。3)。

图例.3. 类型字段等于 TRADE_TRANSACTION_ORDER_DELETE

传说。三。类型字段等于交易记录订单删除

“transaction”块是日志中唯一需要的东西。

PF      0       17:52:36.722    TradeProcessor (EURUSD,H1)      ---===Transaction===---
OE      0       17:52:36.722    TradeProcessor (EURUSD,H1)      Ticket of the deal: 0
KL      0       17:52:36.722    TradeProcessor (EURUSD,H1)      Type of the deal: DEAL_TYPE_BUY
EH      0       17:52:36.722    TradeProcessor (EURUSD,H1)      Ticket of the order: 22535869
QM      0       17:52:36.722    TradeProcessor (EURUSD,H1)      Status of the order: ORDER_STATE_STARTED
QK      0       17:52:36.722    TradeProcessor (EURUSD,H1)      Type of the order: ORDER_TYPE_BUY
HS      0       17:52:36.722    TradeProcessor (EURUSD,H1)      Price: 1.3137
MH      0       17:52:36.722    TradeProcessor (EURUSD,H1)      Level of Stop Loss: 0.0000
OP      0       17:52:36.722    TradeProcessor (EURUSD,H1)      Level of Take Profit: 0.0000
EJ      0       17:52:36.722    TradeProcessor (EURUSD,H1)      Price that triggers the Stop Limit order: 0.0000
IH      0       17:52:36.722    TradeProcessor (EURUSD,H1)      Trade symbol: EURUSD
KP      0       17:52:36.722    TradeProcessor (EURUSD,H1)      Pending order expiration time: 1970.01.01 00:00
LO      0       17:52:36.722    TradeProcessor (EURUSD,H1)      Order expiration type: ORDER_TIME_GTC
HG      0       17:52:36.722    TradeProcessor (EURUSD,H1)      Type of the trade transaction: TRADE_TRANSACTION_ORDER_DELETE
CG      0       17:52:36.722    TradeProcessor (EURUSD,H1)      Volume in lots: 0.11

除交易类型外,此处没有新信息。

对处理器的第四个调用是当新的历史订单出现在历史数据中时。(传说)4)。

图例.4. 类型字段等于 TRADE_TRANSACTION_HISTORY_ADD

传说。4。类型字段等于交易记录添加

我们可以从程序块“事务”中获取相关信息。

QO      0       17:57:32.234    TradeProcessor (EURUSD,H1)      ---===Transaction==---
RJ      0       17:57:32.234    TradeProcessor (EURUSD,H1)      Ticket of the deal: 0
NS      0       17:57:32.234    TradeProcessor (EURUSD,H1)      Type of the deal: DEAL_TYPE_BUY
DQ      0       17:57:32.234    TradeProcessor (EURUSD,H1)      Ticket of the order: 22535869
EH      0       17:57:32.234    TradeProcessor (EURUSD,H1)      Status of the order: ORDER_STATE_FILLED
RL      0       17:57:32.234    TradeProcessor (EURUSD,H1)      Type of the order: ORDER_TYPE_BUY
KJ      0       17:57:32.234    TradeProcessor (EURUSD,H1)      Price: 1.3137
NO      0       17:57:32.234    TradeProcessor (EURUSD,H1)      Level of Stop Loss: 0.0000
PI      0       17:57:32.234    TradeProcessor (EURUSD,H1)      Level of Take Profit: 0.0000
FS      0       17:57:32.234    TradeProcessor (EURUSD,H1)      Price that triggers the Stop Limit order: 0.0000
JS      0       17:57:32.234    TradeProcessor (EURUSD,H1)      Trade symbol: EURUSD
LG      0       17:57:32.234    TradeProcessor (EURUSD,H1)      Pending order expiration time: 1970.01.01 00:00
KP      0       17:57:32.234    TradeProcessor (EURUSD,H1)      Order expiration type: ORDER_TIME_GTC
OL      0       17:57:32.234    TradeProcessor (EURUSD,H1)      Type of the trade transaction: TRADE_TRANSACTION_HISTORY_ADD
JH      0       17:57:32.234    TradeProcessor (EURUSD,H1)      Volume in lots: 0.00

在这个阶段,我们可以看到订单已经执行。

最后,第五个调用在事务订单添加到历史记录(图例)时发生。5)。

图例.5. 类型字段等于 TRADE_TRANSACTION_DEAL_ADD

传说。5。类型字段等于交易记录交易记录添加

在日志中,我们只对程序块中的“事务”感兴趣。

OE      0       17:59:40.718    TradeProcessor (EURUSD,H1)      ---===Transaction===---
MS      0       17:59:40.718    TradeProcessor (EURUSD,H1)      Ticket of the deal: 15258202
RJ      0       17:59:40.718    TradeProcessor (EURUSD,H1)      Type of the deal: DEAL_TYPE_BUY
HN      0       17:59:40.718    TradeProcessor (EURUSD,H1)      Ticket of the order: 22535869
LK      0       17:59:40.718    TradeProcessor (EURUSD,H1)      Status of the order: ORDER_STATE_STARTED
LE      0       17:59:40.718    TradeProcessor (EURUSD,H1)      Type of the order: ORDER_TYPE_BUY
MM      0       17:59:40.718    TradeProcessor (EURUSD,H1)      Price: 1.3137
PF      0       17:59:40.718    TradeProcessor (EURUSD,H1)      Level of Stop Loss: 0.0000
NN      0       17:59:40.718    TradeProcessor (EURUSD,H1)      Level of Take Profit: 0.0000
PI      0       17:59:40.718    TradeProcessor (EURUSD,H1)      Price that triggers the Stop Limit order: 0.0000
DJ      0       17:59:40.718    TradeProcessor (EURUSD,H1)      Trade symbol: EURUSD
JM      0       17:59:40.718    TradeProcessor (EURUSD,H1)      Pending order expiration time: 1970.01.01 00:00
QI      0       17:59:40.718    TradeProcessor (EURUSD,H1)      Order expiration type: ORDER_TIME_GTC
CK      0       17:59:40.718    TradeProcessor (EURUSD,H1)      Type of the trade transaction: TRADE_TRANSACTION_DEAL_ADD
RQ      0       17:59:40.718    TradeProcessor (EURUSD,H1)      Volume in lots: 0.11

在这个块中,最重要的字符串是事务号。

我要提出一个商业计划。对于职位,他们只有两部分。第一部分看起来像传说。6。

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

图6。第一交易流计划

仓库处理的所有交易操作均按照本计划进行。这里唯一的例外是修改位置操作。最终操作包括以下事务流(图例)。7)。

图例.7. 第二个事务流程规划

传说。7。二次交易流程规划

因此,在交易和订单历史记录中无法跟踪对头寸的修改。

几乎有所有关于职位的信息。

三。限价订单处理

对于限价订单,应注意,它们的交易量较少。同时,在订单处理中,交易类型的组合也更多。

为了修改订单,处理器被调用两次,类似于修改仓库。下单和删除需要调用三次。删除或执行订单时,将调用四次TradeTransaction事件。

现在,我们将下限价订单。我们需要在任何图表的MetaTrader 5终端上以调试模式启动EA。

对处理器的第一个调用是请求连接(图8)。

图例.8. 类型字段等于 TRADE_TRANSACTION_REQUEST

传说。8。类型字段等于交易请求

日志中将包含以下条目:

IO      0       18:13:33.195    TradeProcessor (EURUSD,H1)      ---===Transaction===---
NK      0       18:13:33.195    TradeProcessor (EURUSD,H1)      Ticket of the deal: 0
RR      0       18:13:33.195    TradeProcessor (EURUSD,H1)      Type of the deal: DEAL_TYPE_BUY
DE      0       18:13:33.195    TradeProcessor (EURUSD,H1)      Ticket of the order: 0
JS      0       18:13:33.195    TradeProcessor (EURUSD,H1)      Status of the order: ORDER_STATE_STARTED
JN      0       18:13:33.195    TradeProcessor (EURUSD,H1)      Type of the order: ORDER_TYPE_BUY
FD      0       18:13:33.195    TradeProcessor (EURUSD,H1)      Price: 0.0000
FN      0       18:13:33.195    TradeProcessor (EURUSD,H1)      Level of Stop Loss: 0.0000
HF      0       18:13:33.195    TradeProcessor (EURUSD,H1)      Level of Take Profit: 0.0000
FQ      0       18:13:33.195    TradeProcessor (EURUSD,H1)      Price that triggers the Stop Limit order: 0.0000
RR      0       18:13:33.195    TradeProcessor (EURUSD,H1)      Trade symbol: 
HD      0       18:13:33.195    TradeProcessor (EURUSD,H1)      Pending order expiration time: 1970.01.01 00:00
GS      0       18:13:33.195    TradeProcessor (EURUSD,H1)      Order expiration type: ORDER_TIME_GTC
DN      0       18:13:33.195    TradeProcessor (EURUSD,H1)      Type of the trade transaction: TRADE_TRANSACTION_REQUEST
FK      0       18:13:33.195    TradeProcessor (EURUSD,H1)      Volume in lots: 0.00
NS      0       18:13:33.195    TradeProcessor (EURUSD,H1)      

QG      0       18:13:33.195    TradeProcessor (EURUSD,H1)      ---===Request==---
IQ      0       18:13:33.195    TradeProcessor (EURUSD,H1)      Type of the trade operation: TRADE_ACTION_PENDING
OE      0       18:13:33.195    TradeProcessor (EURUSD,H1)      Order comment: 
PQ      0       18:13:33.195    TradeProcessor (EURUSD,H1)      Deviation from the requested price: 0
QS      0       18:13:33.195    TradeProcessor (EURUSD,H1)      Order expiration time: 1970.01.01 00:00
FI      0       18:13:33.195    TradeProcessor (EURUSD,H1)      Magic number of the EA: 0
CM      0       18:13:33.195    TradeProcessor (EURUSD,H1)      Ticket of the order: 22535983
PK      0       18:13:33.195    TradeProcessor (EURUSD,H1)      Price: 1.6500
KR      0       18:13:33.195    TradeProcessor (EURUSD,H1)      Stop Loss level of the order: 0.0000
OI      0       18:13:33.195    TradeProcessor (EURUSD,H1)      Take Profit level of the order: 0.0000
QK      0       18:13:33.195    TradeProcessor (EURUSD,H1)      StopLimit level of the order: 0.0000
QQ      0       18:13:33.195    TradeProcessor (EURUSD,H1)      Trade symbol: GBPUSD
RD      0       18:13:33.195    TradeProcessor (EURUSD,H1)      Type of the order: ORDER_TYPE_BUY_LIMIT
LS      0       18:13:33.195    TradeProcessor (EURUSD,H1)      Order execution type: ORDER_FILLING_RETURN
MN      0       18:13:33.195    TradeProcessor (EURUSD,H1)      Order expiration type: ORDER_TIME_GTC
IK      0       18:13:33.195    TradeProcessor (EURUSD,H1)      Volume in lots: 0.14
NS      0       18:13:33.195    TradeProcessor (EURUSD,H1)      
CD      0       18:13:33.195    TradeProcessor (EURUSD,H1)      ---===Response===---
RQ      0       18:13:33.195    TradeProcessor (EURUSD,H1)      Code of the operation result: 10009
JI      0       18:13:33.195    TradeProcessor (EURUSD,H1)      Ticket of the deal: 0
GM      0       18:13:33.195    TradeProcessor (EURUSD,H1)      Ticket of the order: 22535983
LF      0       18:13:33.195    TradeProcessor (EURUSD,H1)      Volume of the deal: 0.14
JN      0       18:13:33.195    TradeProcessor (EURUSD,H1)      Price of the deal: 0.0000
MK      0       18:13:33.195    TradeProcessor (EURUSD,H1)      Bid: 0.0000
CM      0       18:13:33.195    TradeProcessor (EURUSD,H1)      Ask: 0.0000
IG      0       18:13:33.195    TradeProcessor (EURUSD,H1)      Comment to the operation: 
DQ      0       18:13:33.195    TradeProcessor (EURUSD,H1)      Request ID: 1

处理器的第二次调用将把订单添加到打开的订单列表中(图)。9)。

图例.9. 类型字段等于 TRADE_TRANSACTION_ORDER_ADDED

传说。9。类型字段等于添加的交易记录订单

在日志中,我们只需要查看事务块。

HJ      0       18:17:02.886    TradeProcessor (EURUSD,H1)      ---===Transaction===---
GQ      0       18:17:02.886    TradeProcessor (EURUSD,H1)      Ticket of the deal: 0
CH      0       18:17:02.886    TradeProcessor (EURUSD,H1)      Type of the deal: DEAL_TYPE_BUY
RL      0       18:17:02.886    TradeProcessor (EURUSD,H1)      Ticket of the order: 22535983
II      0       18:17:02.886    TradeProcessor (EURUSD,H1)      Status of the order: ORDER_STATE_STARTED
OG      0       18:17:02.886    TradeProcessor (EURUSD,H1)      Type of the order: ORDER_TYPE_BUY_LIMIT
GL      0       18:17:02.886    TradeProcessor (EURUSD,H1)      Price: 1.6500
IE      0       18:17:02.886    TradeProcessor (EURUSD,H1)      Level of Stop Loss: 0.0000
CO      0       18:17:02.886    TradeProcessor (EURUSD,H1)      Level of Take Profit: 0.0000
IF      0       18:17:02.886    TradeProcessor (EURUSD,H1)      Price that triggers the Stop Limit order: 0.0000
PL      0       18:17:02.886    TradeProcessor (EURUSD,H1)      Trade symbol: GBPUSD
OL      0       18:17:02.886    TradeProcessor (EURUSD,H1)      Pending order expiration time: 1970.01.01 00:00
HJ      0       18:17:02.886    TradeProcessor (EURUSD,H1)      Order expiration type: ORDER_TIME_GTC
LF      0       18:17:02.886    TradeProcessor (EURUSD,H1)      Type of the trade transaction: TRADE_TRANSACTION_ORDER_ADD
FR      0       18:17:02.886    TradeProcessor (EURUSD,H1)      Volume in lots: 0.14

第三个调用处理器根据下订单(图例)刷新数据。10)。

特别是,订单状态接收订单状态的值。

图例.1. 类型字段等于 TRADE_TRANSACTION_REQUEST0

传说。10。类型字段等于交易记录订单更新

在日志中,我们只需要查看事务块中的记录。

HS      0       18:21:27.004    TradeProcessor (EURUSD,H1)      ---===Transaction==---
GF      0       18:21:27.004    TradeProcessor (EURUSD,H1)      Ticket of the deal: 0
CO      0       18:21:27.004    TradeProcessor (EURUSD,H1)      Type of the deal: DEAL_TYPE_BUY
RE      0       18:21:27.004    TradeProcessor (EURUSD,H1)      Ticket of the order: 22535983
KM      0       18:21:27.004    TradeProcessor (EURUSD,H1)      Status of the order: ORDER_STATE_PLACED
QH      0       18:21:27.004    TradeProcessor (EURUSD,H1)      Type of the order: ORDER_TYPE_BUY_LIMIT
EG      0       18:21:27.004    TradeProcessor (EURUSD,H1)      Price: 1.6500
GL      0       18:21:27.004    TradeProcessor (EURUSD,H1)      Level of Stop Loss: 0.0000
ED      0       18:21:27.004    TradeProcessor (EURUSD,H1)      Level of Take Profit: 0.0000
GO      0       18:21:27.004    TradeProcessor (EURUSD,H1)      Price that triggers the Stop Limit order: 0.0000
RE      0       18:21:27.004    TradeProcessor (EURUSD,H1)      Trade symbol: GBPUSD
QS      0       18:21:27.004    TradeProcessor (EURUSD,H1)      Pending order expiration time: 1970.01.01 00:00
JS      0       18:21:27.004    TradeProcessor (EURUSD,H1)      Order expiration type: ORDER_TIME_GTC
RD      0       18:21:27.004    TradeProcessor (EURUSD,H1)      Type of the trade transaction: TRADE_TRANSACTION_ORDER_UPDATE
JK      0       18:21:27.004    TradeProcessor (EURUSD,H1)      Volume in lots: 0.14

这里最重要的字符串是订单的状态。

与仓库处理不同,限价订单处理不能通过计划来实现。限价订单的每个操作在交易类型方面都是唯一的。

下限订单将生成三个交易(图例。11)。

图例.1. 类型字段等于 TRADE_TRANSACTION_REQUEST1

传说。11。下限订单交易流

修改限制订单将导致两个交易(图12)。

图例.1. 类型字段等于 TRADE_TRANSACTION_REQUEST2

传说。12。修改有限订单交易流程

如果删除限制顺序,将调用四次OnTradeTransaction()处理器(图例)。13)。

图例.1. 类型字段等于 TRADE_TRANSACTION_REQUEST3

传说。13。有限订单删除交易流程

删除限额订单由以下计划(图例)定义。14)。

图例.1. 类型字段等于 TRADE_TRANSACTION_REQUEST4

传说。14。有限订单删除交易流程

触发限价订单,最终交易操作将导致四个不同的交易(图例)。15)。

图例.1. 类型字段等于 TRADE_TRANSACTION_REQUEST5

传说。15。有限订单激活交易流

我不打算在这里为每个事务组合输入日志条目。如果读者愿意这样做,他们可以通过执行代码来判断。

4。通用处理器

让我们通过最终用户的眼睛来了解处理TradeTransaction事件的程序。最终用户可能需要一个与订单和仓库完美配合的程序。程序员必须对onstradeTransaction()进行编码,以便它能够识别所有事务及其组合—仓库或订单,而不管流程如何。理想情况下,程序可以指示可以执行哪些操作来完成一系列事务处理。

在下面的示例中,使用了一系列事务处理。mql5的开发人员做出以下声明:

…一个交易请求从终端手工发送或通过 OrderSend()/OrderSendAsync() 函数,可以在交易服务器上生成一些连续的事务。这些事务抵达终端的优先级是没有保证的,因此交易算法不应该基于假设:一组事务一个接一个的到来。除此之外,事务可能会在服务器到终端输送中丢失…

因此,如果要求编写一个接近理想工作的程序,您可以改进建议的样本,使事务处理独立于事务的到达顺序。

一般来说,仓库和订单可以有共同的交易类型。有11种交易类型。其中只有四个需要在来自终端的事务中处理:

  • 交易交易更新;
  • 交易交易交易删除;
  • 交易记录更新;
  • 交易记录删除。

我们不打算在本文中讨论它们。根据开发人员的不同,可以将这些类型设计为扩展事务服务器的功能。我必须承认,我以前没有处理过这些类型的问题。

这就为我们提供了七种功能齐全的类型,以便从OnTradeTransaction()中获取最常用的流程。

在处理器主体的这一部分中,定义了当前事务类型,并发挥了极其重要的作用。

//--- ========== Types of transaction [START]
   switch(trans_type)
     {
      //--- 1) if it is a request
      case TRADE_TRANSACTION_REQUEST:
        {

         //---
         break;
        }
      //--- 2) if it is an addition of a new open order
      case TRADE_TRANSACTION_ORDER_ADD:
        {

         //---
         break;
        }
      //--- 3) if it is a deletion of an order from the list of open ones
      case TRADE_TRANSACTION_ORDER_DELETE:
        {

         //---     
         break;
        }
      //--- 4) if it is an addition of a new order to the history
      case TRADE_TRANSACTION_HISTORY_ADD:
        {

         //---     
         break;
        }
      //--- 5) if it is an addition of a deal to history
      case TRADE_TRANSACTION_DEAL_ADD:
        {

         //---
         break;
        }
      //--- 6) if it is a modification of a position 
      case TRADE_TRANSACTION_POSITION:
        {

         //---
         break;
        }
      //--- 7) if it is a modification of an open order
      case TRADE_TRANSACTION_ORDER_UPDATE:
        {

         //---
         break;
        }
     }
//--- ========== Types of transactions [END]

我们将尝试定义当前事务类型可以处理哪些事务操作。为了找出我们正在做什么-职位或订单,我们将事务操作类型分配给案例模块以处理请求。

模块如下所示:

//--- 1) if it is a request
      case TRADE_TRANSACTION_REQUEST:
        {
         //---
         last_action=request.action;
         string action_str;

         //--- what is the request for?
         switch(last_action)
           {
            //--- а) on market
            case TRADE_ACTION_DEAL:
              {
               action_str="place a market order";
               trade_obj=TRADE_OBJ_POSITION;
               break;
              }
            //--- б) place a pending order
            case TRADE_ACTION_PENDING:
              {
               action_str="place a pending order";
               trade_obj=TRADE_OBJ_ORDER;
               break;
              }
            //--- в) modify position
            case TRADE_ACTION_SLTP:
              {
               trade_obj=TRADE_OBJ_POSITION;
               //---
               StringConcatenate(action_str,request.symbol,": modify the levels of Stop Loss",
                                 " and Take Profit");

               //---
               break;
              }
            //--- г) modify order
            case TRADE_ACTION_MODIFY:
              {
               action_str="modify parameters of the pending order";
               trade_obj=TRADE_OBJ_ORDER;
               break;
              }
            //--- д) delete order
            case TRADE_ACTION_REMOVE:
              {
               action_str="delete pending order";
               trade_obj=TRADE_OBJ_ORDER;
               break;
              }
           }
         //---
         if(InpIsLogging)
            Print("Request received: "+action_str);

         //---
         break;
        }

在这种情况下,改变一些变量并不困难。

static ENUM_TRADE_REQUEST_ACTIONS last_action; // market operation at the first pass

最后一个动作变量将记住事件处理程序启动的原因。

static ENUM_TRADE_OBJ trade_obj;               // specifies the trade object at the first pass

变量trade_obj保存正在处理的内容——位置或订单。要做到这一点,我们应该创建enum_trade_obj枚举。

此后,我们将继续处理贸易交易订单添加交易类型模块:

//--- 2) if it is an addition of a new open order
      case TRADE_TRANSACTION_ORDER_ADD:
        {
         if(InpIsLogging)
           {
            if(trade_obj==TRADE_OBJ_POSITION)
               Print("Open a new market order: "+
                     EnumToString(trans.order_type));
            //---
            else if(trade_obj==TRADE_OBJ_ORDER)
               Print("Place a new pending order: "+
                     EnumToString(trans.order_type));
           }
         //---
         break;
        }

这个模块非常简单。因为仓库是在第一步处理的,所以在当前位置会出现“打开一个新的市场订单”的日志条目,否则会出现“放置一个新的待处理订单”。在此块中,没有其他操作信息。

现在它是第三个处理交易订单删除类型的模块:

//--- 3) if it is a deletion of an order from the list of open ones
      case TRADE_TRANSACTION_ORDER_DELETE:
        {
         if(InpIsLogging)
            PrintFormat("Order deleted from the list of open ones: #%d, "+
                        EnumToString(trans.order_type),trans.order);
         //---     
         break;
        }

该模块也只有一个角色。

第四个案例模块处理交易记录添加类型:

//--- 4) if it is an addition of a new order to the history
      case TRADE_TRANSACTION_HISTORY_ADD:
        {
         if(InpIsLogging)
            PrintFormat("Order added to the history: #%d, "+
                        EnumToString(trans.order_type),trans.order);

         //--- if a pending order is being processed
         if(trade_obj==TRADE_OBJ_ORDER)
           {
            //--- if it is the third pass
            if(gTransCnt==2)
              {
               //--- if the order was canceled, check the deals
               datetime now=TimeCurrent();

               //--- request the history of orders and deals
               HistorySelect(now-PeriodSeconds(PERIOD_H1),now);

               //--- attempt to find a deal for the order
               CDealInfo myDealInfo;
               int all_deals=HistoryDealsTotal();
               //---
               bool is_found=false;
               for(int deal_idx=all_deals;deal_idx>=0;deal_idx--)
                  if(myDealInfo.SelectByIndex(deal_idx))
                     if(myDealInfo.Order()==trans.order)
                        is_found=true;

               //--- if the deal was not found
               if(!is_found)
                 {
                  is_to_reset_cnt=true;
                  //---
                  PrintFormat("Order canceled: #%d",trans.order);
                 }
              }
            //--- if it is the fourth pass
            if(gTransCnt==3)
              {
               is_to_reset_cnt=true;
               PrintFormat("Order deleted: #%d",trans.order);
              }
           }
         //---     
         break;
        }

此外,还将订单添加到历史记录中,此模块将检查我们是否处理限价订单。完成后,我们需要找出传递给处理器的数字。如果取消限价订单,交易类型将出现在第三次交货时。删除限价订单后,此类型将出现在第四次交货时。

模块检查第三遍的字符串,我们需要再次参考事务历史记录。如果没有发现交易,我们相信订单已经取消。

第五个案例模块处理交易交易添加类型。根据字符串的大小,这是程序的最大模块。

查看此块中的交易。根据单个数字选择事务以获得其属性是很重要的。如果职位是空缺或持平,则可以提供交易类型。在这里也可以得到极限阶的触发信息。在一种情况下,当TradeTransaction事件处理程序工作时,交易价格受限的订单。

//--- 5) if it is an addition of a deal to history
      case TRADE_TRANSACTION_DEAL_ADD:
        {
         is_to_reset_cnt=true;
         //---
         ulong deal_ticket=trans.deal;
         ENUM_DEAL_TYPE deal_type=trans.deal_type;
         //---
         if(InpIsLogging)
            PrintFormat("Deal added to history: #%d, "+EnumToString(deal_type),deal_ticket);

         if(deal_ticket>0)
           {
            datetime now=TimeCurrent();

            //--- request the history of orders and deals
            HistorySelect(now-PeriodSeconds(PERIOD_H1),now);

            //--- select a deal by the ticket
            if(HistoryDealSelect(deal_ticket))
              {
               //--- check the deal
               CDealInfo myDealInfo;
               myDealInfo.Ticket(deal_ticket);
               long order=myDealInfo.Order();

               //--- parameters of the deal
               ENUM_DEAL_ENTRY  deal_entry=myDealInfo.Entry();
               double deal_vol=0.;
               //---
               if(myDealInfo.InfoDouble(DEAL_VOLUME,deal_vol))
                  if(myDealInfo.InfoString(DEAL_SYMBOL,deal_symbol))
                    {
                     //--- position
                     CPositionInfo myPos;
                     double pos_vol=WRONG_VALUE;
                     //---
                     if(myPos.Select(deal_symbol))
                        pos_vol=myPos.Volume();

                     //--- if the market was entered
                     if(deal_entry==DEAL_ENTRY_IN)
                       {
                        //--- 1) opening of a position
                        if(deal_vol==pos_vol)
                           PrintFormat("/n%s: new position opened",deal_symbol);

                        //--- 2) addition to the open position        
                        else if(deal_vol<pos_vol)
                           PrintFormat("/n%s: addition to the current position",deal_symbol);
                       }

                     //--- if the market was exited
                     else if(deal_entry==DEAL_ENTRY_OUT)
                       {
                        if(deal_vol>0.0)
                          {
                           //--- 1) closure of a position
                           if(pos_vol==WRONG_VALUE)
                              PrintFormat("/n%s: position closed",deal_symbol);

                           //--- 2) partial closure of the open position        
                           else if(pos_vol>0.0)
                              PrintFormat("/n%s: partial closing of the current position",deal_symbol);
                          }
                       }

                     //--- if position was reversed
                     else if(deal_entry==DEAL_ENTRY_INOUT)
                       {
                        if(deal_vol>0.0)
                           if(pos_vol>0.0)
                              PrintFormat("/n%s: position reversal",deal_symbol);
                       }
                    }

               //--- order activation
               if(trade_obj==TRADE_OBJ_ORDER)
                  PrintFormat("Pending order activation: %d",order);
              }
           }

         //---
         break;
        }

交易类型trade_transaction_position是唯一的,仅在仓库修改时处理:

//--- 6) if it is a modification of a position
      case TRADE_TRANSACTION_POSITION:
        {
         is_to_reset_cnt=true;
         //---
         PrintFormat("Modification of a position: %s",deal_symbol);
         //---
         if(InpIsLogging)
           {
            PrintFormat("New price of stop loss: %0."+
                        IntegerToString(_Digits)+"f",trans.price_sl);
            PrintFormat("New price of take profit: %0."+
                        IntegerToString(_Digits)+"f",trans.price_tp);
           }

         //---
         break;
        }

最终案例模块允许处理交易订单更新类型。

此类型仅在处理限价订单时发生。当触发任何交易操作时,它就会启动,重点关注限价指令,尽管状态可能会改变。

//--- 7) if it is a modification of an open order
      case TRADE_TRANSACTION_ORDER_UPDATE:
        {

         //--- if it was the first pass
         if(gTransCnt==0)
           {
            trade_obj=TRADE_OBJ_ORDER;
            PrintFormat("Canceling the order: #%d",trans.order);
           }
         //--- if it was the second pass
         if(gTransCnt==1)
           {
            //--- if it is an order modification
            if(last_action==TRADE_ACTION_MODIFY)
              {
               PrintFormat("Pending order modified: #%d",trans.order);
               //--- clear counter
               is_to_reset_cnt=true;
              }
            //--- if it is deletion of the order
            if(last_action==TRADE_ACTION_REMOVE)
              {
               PrintFormat("Delete pending order: #%d",trans.order);

              }
           }
         //--- if it was the third pass
         if(gTransCnt==2)
           {
            PrintFormat("A new pending order was placed: #%d, "+
                        EnumToString(trans.order_type),trans.order);
            //--- clear counter
            is_to_reset_cnt=true;
           }

         //---
         break;
        }

总之,如果此类型在首次触发OnTradeTransaction()时发生,则可以取消或执行订单。

如果此类型发生在事件处理程序的第二个开头,则可以删除或修改顺序。要查找订单的确切结果,请参阅包含最后一个事务操作的静态变量last_action。

第三个引导事件处理程序是这种类型的最后一个案例。第三次开始完成下限订单的过程。

布尔变量“重置”也用于代码中。它用作清除OnTradeTransaction()处理器传输计数的标志。

这几乎与TradeTransaction事件过程有关。我还在对处理器的调用开始时添加了一个停顿。在转移到历史数据之前,它为关闭交易或订单提供了一个稍微延迟的机会。

结论

在本文中,我试图描述可以使用哪些不同的事务操作,以及如何检索有关终端中发生的事件的信息。

这种方法的最大优点是程序可以接收有关事务操作的阶段性实现的信息。在我看来,这种方法可以用于将事务从一个终端复制到另一个终端。

本文由MetaQuotes Software Corp.翻译自俄语原文
,网址为https://www.mql5.com/ru/articles/1111。

附加文件下载zip tradeprocessor.mq5(31.35 kb)

 

 


MyFxtop迈投(www.myfxtop.com)-靠谱的外汇跟单社区,免费跟随高手做交易!

 

免责声明:本文系转载自网络,如有侵犯,请联系我们立即删除,另:本文仅代表作者个人观点,与迈投财经无关。其原创性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容、文字的真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。

著作权归作者所有。
商业转载请联系作者获得授权,非商业转载请注明出处。

風險提示

MyFxtops邁投所列信息僅供參考,不構成投資建議,也不代表任何形式的推薦或者誘導行為。MyFxtops邁投非外匯經紀商,不接觸妳的任何資金。 MYFXTOPS不保證客戶盈利,不承擔任何責任。從事外彙和差價合約等金融產品的槓桿交易具有高風險,損失有可能超過本金,請量力而行,入市前需充分了解潛在的風險。過去的交易成績並不代表以後的交易成績。依據各地區法律法規,MyFxtops邁投不向中國大陸、美國、加拿大、朝鮮居民提供服務。

邁投公眾號

聯繫我們

客服QQ:981617007
Email: service@myfxtop.com

MyFxtops 邁投