OnTradeTransaction
OnTradeTransaction
当TradeTransaction事件发生时在EA中调用这个函数。这个函数旨在处理交易请求执行结果。
void OnTradeTransaction()
const MqlTradeTransaction& trans, // 交易事务结构
const MqlTradeRequest& request, // 请求结构
const MqlTradeResult& result // 回应结构
);参数
- trans
[in] MqlTradeTransaction类型变量描述了在交易账户上进行的交易。
- request
[in] MqlTradeRequest类型变量描述了导致交易的交易请求。它只包含TRADE_TRANSACTION_REQUEST类型交易的值。
- result
[in] MqlTradeResult类型变量描述了导致交易的交易请求的执行结果。它只包含TRADE_TRANSACTION_REQUEST类型交易的值。
返回值
无返回值
注意
调用OnTradeTransaction()来处理在下列情况下由交易服务器发送至程序端的TradeTransaction事件:
- 使用OrderSend()/OrderSendAsync()函数,从MQL5程序发送交易请求及其后续执行;
- 通过GUI手动发送交易请求及其后续执行;
- 激活服务器上的挂单和止损单;
- 在交易服务器端执行操作。
关于交易类型的数据包含在trans变量的类型字段中。交易事务类型在ENUM_TRADE_TRANSACTION_TYPE枚举中描述:
- TRADE_TRANSACTION_ORDER_ADD 添加一个新的活跃订单
- TRADE_TRANSACTION_ORDER_UPDATE 更改现有订单
- TRADE_TRANSACTION_ORDER_DELETE 从活跃订单列表删除一个订单
- TRADE_TRANSACTION_DEAL_ADD 在历史中添加一笔交易
- TRADE_TRANSACTION_DEAL_UPDATE 在历史中改变一笔交易
- TRADE_TRANSACTION_DEAL_DELETE 从历史删除一笔交易
- TRADE_TRANSACTION_HISTORY_ADD 在历史中添加一个订单作为执行或取消的结果
- TRADE_TRANSACTION_HISTORY_UPDATE 在订单历史中更改一个订单
- TRADE_TRANSACTION_HISTORY_DELETE 从订单历史中删除一个订单
- TRADE_TRANSACTION_POSITION 与交易执行无关的持仓变化
- TRADE_TRANSACTION_REQUEST 已收到服务器处理交易请求的通知和处理结果。
当处理TRADE_TRANSACTION_REQUEST类型交易时,需要分析OnTradeTransaction()函数的第二和第三个参数 request和result 来获取额外信息。
发送买入交易请求会导致交易账户上的一系列交易:1) 请求被接受进行处理,2) 为该账户创建了一个适当的购买订单,3) 然后执行订单,4) 已执行订单从活跃订单列表中移除,5) 添加到订单历史中,6) 随后事务被添加到历史中以及 7) 创建新持仓。所有这些阶段都是交易事务过程。每一个这类交易事务到达程序端就是TradeTransaction事件。不保证这些交易到达程序端的优先级。因此,在开发您的EA交易时,您不应该期望一组交易将在另一组之后到达。
当交易由EA的OnTradeTransaction()处理程序进行处理时,程序端将继续处理传入的交易事务。因此,在OnTradeTransaction()操作过程中,交易账户状态可能会发生变化。例如,当MQL5程序处理添加新订单时,它可以被执行,被从已开设订单的列表中删除以及被移动到历史中。所有这些事件的消息都将通知该程序。
交易事务队列长度由1024个要素组成。如果OnTradeTransaction()处理另一个事务时间太长,那么之前的事务就可能被队列中的新事物所取代。
适当调用OnTradeTransaction()之后调用OnTrade()处理程序。通常,在OnTrade ()和OnTradeTransaction ()调用的数量上没有确切的相关性。OnTrade()一次调用对应一次或多次的OnTradeTransaction调用。
每一个Trade事件都可能作为一个或多个交易请求的结果出现。交易请求使用OrderSend()或OrderSendAsync(),被发送到服务器。每个请求都可能导致多个交易事件。您不能依赖“一个请求,一个交易事件”的声明,因为事件的处理可能分为几个阶段执行,并且每个操作都可能更改订单的状态、持仓和交易历史记录。
EA样例,OnTradeTransaction()处理程序
//+------------------------------------------------------------------+
//| OnTradeTransaction_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"
#property description "Sample listener of TradeTransaction events"
//+------------------------------------------------------------------+
//| EA交易初始化函数 |
//+------------------------------------------------------------------+
int OnInit()
{
//---
PrintFormat("LAST PING=%.f ms",
TerminalInfoInteger(TERMINAL_PING_LAST)/1000.);
//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| EA报价函数 |
//+------------------------------------------------------------------+
void OnTick()
{
//---
}
//+------------------------------------------------------------------+
//| TradeTransaction函数 |
//+------------------------------------------------------------------+
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();
//--- 如果最后一个交易事务在1秒之前执行,
if(time-lasttime>1000)
{
counter=0; // 那么这是一个新交易操作,计数器可被重置
if(IS_DEBUG_MODE)
Print(" New trade operation");
}
lasttime=time;
counter++;
Print(counter,". ",__FUNCTION__);
//--- 交易请求执行的结果
ulong lastOrderID =trans.order;
ENUM_ORDER_TYPE lastOrderType =trans.order_type;
ENUM_ORDER_STATE lastOrderState=trans.order_state;
//--- 执行交易的交易品种名称
string trans_symbol=trans.symbol;
//--- 交易事务类型
ENUM_TRADE_TRANSACTION_TYPE trans_type=trans.type;
switch(trans.type)
{
case TRADE_TRANSACTION_POSITION: //持仓变化
{
ulong pos_ID=trans.position;
PrintFormat("MqlTradeTransaction: Position #%I64u %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: // 添加一个交易
{
ulong lastDealID =trans.deal;
ENUM_DEAL_TYPE lastDealType =trans.deal_type;
double lastDealVolume=trans.volume;
//--- 内部系统中的交易ID(Trade ID) - 由交易所分配的单号
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 #%I64u %s %s %.2f lot %s",EnumToString(trans_type),
lastDealID,EnumToString(lastDealType),trans_symbol,lastDealVolume,Exchange_ticket);
}
break;
case TRADE_TRANSACTION_HISTORY_ADD: // 在历史中添加一个订单
{
//--- 内部系统中的订单ID - 由交易所分配的单号
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 #%I64u %s %s %s %s",EnumToString(trans_type),
lastOrderID,EnumToString(lastOrderType),trans_symbol,EnumToString(lastOrderState),Exchange_ticket);
}
break;
default: // 其他交易事务
{
//--- 内部系统中的订单ID - 由莫斯科交易所(Moscow 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 #%I64u %s %s %s",EnumToString(trans_type),
lastOrderID,EnumToString(lastOrderType),EnumToString(lastOrderState),Exchange_ticket);
}
break;
}
//--- 订单单号
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);
//---
}
//+------------------------------------------------------------------+
//| 将数字响应代码转换为字符串记忆 |
//+------------------------------------------------------------------+
string GetRetcodeID(int retcode)
{
switch(retcode)
{
case 10004: return("TRADE_RETCODE_REQUOTE"); break;
case 10006: return("TRADE_RETCODE_REJECT"); break;
case 10007: return("TRADE_RETCODE_CANCEL"); break;
case 10008: return("TRADE_RETCODE_PLACED"); break;
case 10009: return("TRADE_RETCODE_DONE"); break;
case 10010: return("TRADE_RETCODE_DONE_PARTIAL"); break;
case 10011: return("TRADE_RETCODE_ERROR"); break;
case 10012: return("TRADE_RETCODE_TIMEOUT"); break;
case 10013: return("TRADE_RETCODE_INVALID"); break;
case 10014: return("TRADE_RETCODE_INVALID_VOLUME"); break;
case 10015: return("TRADE_RETCODE_INVALID_PRICE"); break;
case 10016: return("TRADE_RETCODE_INVALID_STOPS"); break;
case 10017: return("TRADE_RETCODE_TRADE_DISABLED"); break;
case 10018: return("TRADE_RETCODE_MARKET_CLOSED"); break;
case 10019: return("TRADE_RETCODE_NO_MONEY"); break;
case 10020: return("TRADE_RETCODE_PRICE_CHANGED"); break;
case 10021: return("TRADE_RETCODE_PRICE_OFF"); break;
case 10022: return("TRADE_RETCODE_INVALID_EXPIRATION"); break;
case 10023: return("TRADE_RETCODE_ORDER_CHANGED"); break;
case 10024: return("TRADE_RETCODE_TOO_MANY_REQUESTS"); break;
case 10025: return("TRADE_RETCODE_NO_CHANGES"); break;
case 10026: return("TRADE_RETCODE_SERVER_DISABLES_AT"); break;
case 10027: return("TRADE_RETCODE_CLIENT_DISABLES_AT"); break;
case 10028: return("TRADE_RETCODE_LOCKED"); break;
case 10029: return("TRADE_RETCODE_FROZEN"); break;
case 10030: return("TRADE_RETCODE_INVALID_FILL"); break;
case 10031: return("TRADE_RETCODE_CONNECTION"); break;
case 10032: return("TRADE_RETCODE_ONLY_REAL"); break;
case 10033: return("TRADE_RETCODE_LIMIT_ORDERS"); break;
case 10034: return("TRADE_RETCODE_LIMIT_VOLUME"); break;
case 10035: return("TRADE_RETCODE_INVALID_ORDER"); break;
case 10036: return("TRADE_RETCODE_POSITION_CLOSED"); break;
default:
return("TRADE_RETCODE_UNKNOWN="+IntegerToString(retcode));
break;
}
//---
}另见
OrderSend、OrderSendAsync、OnTradeTransaction、交易请求结构、交易事务结构、交易事务类型、交易操作类型、 客户端事件