© 本贴为 xxtz 原创/首发,严禁抄袭!
EA调用TradeTransaction事件发生的OnTradeTransaction()函数较少在本网站述及,在此记录学习过程。
void OnTradeTransaction()
const MqlTradeTransaction& trans, // trade transaction structure
const MqlTradeRequest& request, // request structure
const MqlTradeResult& result // response structure
);
该函数有三个参数:
1. trans 2. request 3. result [in] MqlTradeResult 类型变量,包含了发出请求交易的执行结果。它包含 TRADE_TRANSACTION_RESULT类型的值,描述服务器对应收到的交易请求的返回结果:return code,deal ticket,order ticket(针对pending order),volume,deal price,bid,ask,comment(经纪商对操作的注释),request ID(发出交易请求时终端设定),code of error(外部交易系统返回的)
1. 从MQL5程序使用OrderSend()或OrderSendAsync()函数发出的交易请求和随后的执行;
2. 人工通过GUI发出的交易请求和随后的执行;
3. 在服务器上激活挂单;
4. 在服务器上执行操作;
MqlTradeTransaction 类型变量包括嗯呢trans变量,交易类型有枚举变量 ENUM_TRADE_TRANSACTION_TYPE 描述,主要是Order_Add,Order_update(变更一个现存的order),Order_delete,deal_add(增加一个deal进入历史),deal_update,deal_delete,history_add(由于执行或取消而在交易历史中增加订单order),history_update(order历史中改变一个order),history_delete,position(与交易执行无关的开仓变化),request (服务器发出的交易请求已经被处理的通知以及处理结果已收到)。
例如:发出开仓请求将导致:1. 请求已被服务去收到进行处理;2. 开仓订单在账户里创建;3. 订单被执行;4. 执行的订单将被从活动状态移除;5.到订单历史中 ;6. 随后的交易将被增加的历史中;7. 在账户中新的仓位被创建。 所有这些过程都是 TradeTransaction 事件。
EA的OnTradeTransaction函数句柄将用来处理交易。终端不断处理进来的交易,所以交易账户状态也会随着OnTradeTransaction函数的运行而不断变化,程序会被通知所有这些交易事件。
交易队列长度了1024个单元,OnTradeTransaction会由于队列过长,新的交易会取代在队列中前面的交易。
不要与OnTrade函数混淆,OnTrade是用来处理订单、仓位和交易清单的改变,它只能由EA调用。 OnTrade()函数句柄是在适当的 OnTradeTransaction() 函数调用后才被调用。一般来说, 函数OnTrade () 和 OnTradeTransaction () 调用数目并无精确的相关性。一个OnTrade() 调用对应了一个或几个OnTradeTransaction的调用.
以下是一个官网给出的例子:
- //+------------------------------------------------------------------+
- //| TradeTransaction function |
- //+------------------------------------------------------------------+
- 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(); //自从系统开始所过去多少milliseconds,不关机会overfilled49.7天后
- //--- if the last transaction was performed more than 1 second ago,
- if(time-lasttime>1000)
- {
- counter=0; // then this is a new trade operation, an the counter can be reset
- if(IS_DEBUG_MODE)
- Print(" New trade operation");
- }
- lasttime=time;
- counter++;
- Print(counter,". ",__FUNCTION__);
- //--- result of trade request execution
- ulong lastOrderID =trans.order;
- ENUM_ORDER_TYPE lastOrderType =trans.order_type;
- ENUM_ORDER_STATE lastOrderState=trans.order_state;
- //--- the name of the symbol, for which a transaction was performed
- string trans_symbol=trans.symbol;
- //--- type of transaction 这个是比较经典的使用方法从type入手
- ENUM_TRADE_TRANSACTION_TYPE trans_type=trans.type;
- switch(trans.type)
- {
- case TRADE_TRANSACTION_POSITION: // position modification
- {
- ulong pos_ID=trans.position;
- PrintFormat("MqlTradeTransaction: Position #%d %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: // adding a trade
- {
- ulong lastDealID =trans.deal;
- ENUM_DEAL_TYPE lastDealType =trans.deal_type;
- double lastDealVolume=trans.volume;
- //--- Trade ID in an external system - a ticket assigned by an exchange
- 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 #%d %s %s %.2f lot %s",EnumToString(trans_type),
- lastDealID,EnumToString(lastDealType),trans_symbol,lastDealVolume,Exchange_ticket);
- }
- break;
- case TRADE_TRANSACTION_HISTORY_ADD: // adding an order to the history
- {
- //--- order ID in an external system - a ticket assigned by an Exchange
- 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 #%d %s %s %s %s",EnumToString(trans_type),
- lastOrderID,EnumToString(lastOrderType),trans_symbol,EnumToString(lastOrderState),Exchange_ticket);
- }
- break;
- default: // other transactions
- {
- //--- order ID in an external system - a ticket assigned by 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 #%d %s %s %s",EnumToString(trans_type),
- lastOrderID,EnumToString(lastOrderType),EnumToString(lastOrderState),Exchange_ticket);
- }
- break;
- }
- //--- order ticket
- 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);
- //---
- }
复制代码
以下是在N根K线后开单的使用OnTransactionTrade的虚拟程序的例子:- -------One deal in N bars---------
- #property version "1.00"
- //--- input parameters
- input uchar InpBars = 10; // 10根K线后下单
- input ulong InpDeviation = 1000; // 偏差点数, in points (1.09123-1.08123=1000 points)
- input ulong InpMagic = 2; // 幻数
- //---
- datetime m_last_deal_IN = 0; // "0" -> D'1970.01.01 00:00';
-
- void OnTick()
- {
- //--- 在这写的入场或其他信号
- if(PositionsTotal()==0)
- {
- datetime time[];
- ArraySetAsSeries(time,true);
- int start_pos=0; // 拷贝时间的开始位置
- int count=InpBars+1; // 拷贝多少根K线
- if(CopyTime(Symbol(),Period(),start_pos,count,time)!=count)
- return;
- //--- check
- if(time[InpBars]>m_last_deal_IN)// 前第10根K线的开始时间已经大于最近一次开仓时间
- {
- //--- 开仓
- }
- }
- }
-
- void OnTradeTransaction(const MqlTradeTransaction &trans,
- const MqlTradeRequest &request,
- const MqlTradeResult &result)
- {
- ENUM_TRADE_TRANSACTION_TYPE type=trans.type;
- if(type==TRADE_TRANSACTION_DEAL_ADD)
- {
- long deal_ticket =0;
- long deal_order =0;
- long deal_time =0;
- long deal_time_msc =0;
- long deal_type =-1;
- long deal_entry =-1;
- long deal_magic =0;
- long deal_reason =-1;
- long deal_position_id =0;
- double deal_volume =0.0;
- double deal_price =0.0;
- double deal_commission =0.0;
- double deal_swap =0.0;
- double deal_profit =0.0;
- string deal_symbol ="";
- string deal_comment ="";
- string deal_external_id ="";
- if(HistoryDealSelect(trans.deal))
- {
- deal_ticket =HistoryDealGetInteger(trans.deal,DEAL_TICKET);
- deal_order =HistoryDealGetInteger(trans.deal,DEAL_ORDER);
- deal_time =HistoryDealGetInteger(trans.deal,DEAL_TIME);
- deal_time_msc =HistoryDealGetInteger(trans.deal,DEAL_TIME_MSC);
- deal_type =HistoryDealGetInteger(trans.deal,DEAL_TYPE);
- deal_entry =HistoryDealGetInteger(trans.deal,DEAL_ENTRY);
- deal_magic =HistoryDealGetInteger(trans.deal,DEAL_MAGIC);
- deal_reason =HistoryDealGetInteger(trans.deal,DEAL_REASON);
- deal_position_id =HistoryDealGetInteger(trans.deal,DEAL_POSITION_ID);
-
- deal_volume =HistoryDealGetDouble(trans.deal,DEAL_VOLUME);
- deal_price =HistoryDealGetDouble(trans.deal,DEAL_PRICE);
- deal_commission =HistoryDealGetDouble(trans.deal,DEAL_COMMISSION);
- deal_swap =HistoryDealGetDouble(trans.deal,DEAL_SWAP);
- deal_profit =HistoryDealGetDouble(trans.deal,DEAL_PROFIT);
-
- deal_symbol =HistoryDealGetString(trans.deal,DEAL_SYMBOL);
- deal_comment =HistoryDealGetString(trans.deal,DEAL_COMMENT);
- deal_external_id =HistoryDealGetString(trans.deal,DEAL_EXTERNAL_ID);
- }
- else
- return;
- ENUM_DEAL_ENTRY enum_deal_entry=(ENUM_DEAL_ENTRY)deal_entry;
- if(deal_symbol==Symbol() && deal_magic==InpMagic)
- {
- if(deal_type==DEAL_TYPE_BUY || deal_type==DEAL_TYPE_SELL)
- {
- if(deal_entry==DEAL_ENTRY_IN)
- {
- m_last_deal_IN=iTime(Symbol(),Period(),0);
- }
- }
- }
- }
- }
复制代码
|