如何在MT5中正确使用OrderSend? - 页 11

 
prostotrader:

不是两个,是一个 :)

if(transaction.type == TRADE_TRANSACTION_REQUEST && request.action == TRADE_ACTION_DEAL)

当你使用OrderSendAsymc 来接收订单时,需要TRADE_TRANSACTION_REQUEST。

那么,那里出了什么问题?你怎么知道我是否具体使用了OrderSendAsync()?
我不能用它来检查,比如说,向我发出交易请求的专家顾问的印章?或者,举例来说,查看最后一笔交易执行的仓单?

最后,我可以用这个事件来检查交易的价格(尽管我同意,在这个事件中检查价格只有在使用异步交易时才有意义)。

那么,如果我使用异步订单发送,代码是否正确?

 
Oleg Shenker:

那么它有什么问题呢?你怎么知道,也许我使用了OrderSendAsync()?
我不能用它来检查,例如,发送交易请求的专家顾问的印章?或者,举例来说,查看最后一笔交易执行的仓单?

最后,我可以用这个事件来检查交易的价格(尽管我同意,在这个事件中检查价格只有在使用异步交易时才有意义)。

所以如果我使用异步订单发送,代码是正确的?

该主题名为

"如何正确使用OrderSend"。

这个功能(按照开发者的设想)应该是完全同步的,即如果你发送一个订单,如果你得到一张票。

订单一切正常。但现在这个功能不能很好地工作,所以在收到一个订单的票据后,你

OnTradeTransaction 中得到一个确认,即一切正常。

也就是说,这个订单的数据在终端是完全同步的。

//+------------------------------------------------------------------+
// Expert TradeTransaction function                                  |
//+------------------------------------------------------------------+
void OnTradeTransaction(const MqlTradeTransaction &trans,
                        const MqlTradeRequest &request,
                        const MqlTradeResult &result)
  {
   switch(trans.type)
     {
      case TRADE_TRANSACTION_ORDER_UPDATE:
           switch(trans.order_state)
           {
            case ORDER_STATE_PLACED:
               if(order_ticket==trans.order)
                 {
                  Print(__FUNCTION__," Order plased done. Ticket = ",trans.order);
                  if(order_ticket>0)
                    {
                     if(OrderSelect(order_ticket))
                       {
                        //Данные по ордеру синхронизированы
                       }
                     else
                       {
                        Print(__FUNCTION__," Order not select! Ticket = ",trans.order);
                       }
                    }
                  else
                    {
                     Print(__FUNCTION__," Wrong order ticket = ",trans.order);
                    }
                 }
               break;
           }
         break;
     }
  }
 
prostotrader:

该主题名为

"如何正确使用OrderSend"。

这个功能(按照开发者的设想)应该是完全同步的,即如果你发送一个订单,如果你得到一张票。

订单一切正常。但现在这个功能不能很好地工作,所以在收到一个订单的票据后,你

OnTradeTransaction 中得到一个确认,即一切正常。

也就是说,这个订单的数据在终端是完全同步的。

//+------------------------------------------------------------------+
// Expert TradeTransaction function                                  |
//+------------------------------------------------------------------+
void OnTradeTransaction(const MqlTradeTransaction &trans,
                        const MqlTradeRequest &request,
                        const MqlTradeResult &result)
  {
   switch(trans.type)
     {
      case TRADE_TRANSACTION_ORDER_UPDATE:
           switch(trans.order_state)
           {
            case ORDER_STATE_PLACED:
               if(order_ticket==trans.order)
                 {
                  Print(__FUNCTION__," Order plased done. Ticket = ",trans.order);
                  if(order_ticket>0)
                    {
                     if(OrderSelect(order_ticket))
                       {
                        //Данные по ордеру синхронизированы
                       }
                     else
                       {
                        Print(__FUNCTION__," Order not select! Ticket = ",trans.order);
                       }
                    }
                  else
                    {
                     Print(__FUNCTION__," Wrong order ticket = ",trans.order);
                    }
                 }
               break;
           }
         break;
     }
  }


很好!我知道它。只是我使用的是异步订单发送。我有一个不同的问题,同一个交易的REQUEST事件(指最终确定交易总额)出现了两次。
 
Oleg Shenker:
很好!我知道它是如何运作的。只是我使用的是异步订单发送。我有一个不同的问题,同一个交易的REQUEST事件(在最终确定交易总额的意义上)出现了两次。

你只是不太理解在放置OrderSEndAsync时,应该如何处理OnTradeTransaction 消息。

记录这个EA,看看它是如何工作的

附加的文件:
TestOrders.mq5  25 kb
 
prostotrader:

你只是不太理解在放置OrderSEndAsync时,应该如何处理OnTradeTransaction 消息。

记录专家顾问,看看它是如何工作的

这就是我想问你的,应该如何正确处理TradeTransactions。

 
Oleg Shenker:

所以我问你应该如何正确处理TradeTransactions。

OrderSendAsync的顺序如下。

当你用OrderSendAsync命令发送订单时,如果订单被成功发送,你将收到order_id

bool SendOrderAsyncMode()
  {
   double price=SymbolInfoDouble(Symbol(),SYMBOL_SESSION_PRICE_LIMIT_MAX);
   MqlTradeRequest request={0};
   MqlTradeResult  result={0};
   order_ticket=0;
   order_id=0;
   request.action = TRADE_ACTION_PENDING;
   request.magic  = 9876543210;
   request.symbol = Symbol();
   request.volume = 1;
   request.price  = price;
   request.type=ORDER_TYPE_SELL_LIMIT;
   request.comment="Async mode";
   request.type_filling=ORDER_FILLING_RETURN;
   request.type_time=ORDER_TIME_DAY;
   if(OrderSendAsync(request,result))
     {
      if((result.retcode==TRADE_RETCODE_PLACED) || (result.retcode==TRADE_RETCODE_DONE))
        {
         if(result.request_id>0)
           {
            order_id=result.request_id;
            Print(__FUNCTION__," Order sent in async mode");
            return(true);
           }
         else
           {
            Print(__FUNCTION__," Error order sent in async mode! Retcode = ",result.retcode);
           }
        }
      else
        {
         Print(__FUNCTION__," Error order sent in async mode! Retcode = ",result.retcode);
        }
     }
   else
     {
      Print(__FUNCTION__," Order not sent in async mode.");
     }
   return(false);
  }

然后我们在OnTradeTransactions 中获得所有其他数据

1.收到订货单

void OnTradeTransaction(const MqlTradeTransaction &trans,
                        const MqlTradeRequest &request,
                        const MqlTradeResult &result)
  {
   switch(trans.type)
     {
      case TRADE_TRANSACTION_REQUEST:
         if((order_id>0) && (order_id==result.request_id))
           {
            order_id=0;
            order_ticket=result.order;
            Print(__FUNCTION__," Order get ticket done. Ticket = ",result.order);
           }
         break;
     }
}

2.如果你使用市场或限价(非挂单)订单,即那些立即执行的订单

或被拒绝,有必要监控TRADE_TRANSACTION_HISTORY_ADD,因为在任何情况下3.

这种命令被添加到历史中。

void OnTradeTransaction(const MqlTradeTransaction &trans,
                        const MqlTradeRequest &request,
                        const MqlTradeResult &result)
  {
   switch(trans.type)
     {
      case TRADE_TRANSACTION_HISTORY_ADD:
         if(order_ticket==trans.order)
           {
             //Берем данные из истории
           }
         break;
    }
  }


如果你使用挂单(可以分批执行),那么你应该监控

有三个事件TRADE_TRANSACTION_ORDER_UPDATE, TRADE_TRANSACTION_HISTORY_ADD, TRADE_TRANSACTION_DEAL_ADD。

TRADE_TRANSACTION_ORDER_UPDATE - 用于获取订单已被设置(修改)的信息。

TRADE_TRANSACTION_DEAL_ADD - 获得一个交易已经执行的信息

TRADE_TRANSACTION_HISTORY_ADD - 该订单不存在于贸易系统中;我们可以查看该订单的数据。

这就是所有的 "智慧"

添加

OrderSendAsync和OnTradeTransaction 的互动工作没有问题

和外汇(真实)上

 
prostotrader:

添加

OrderSendAsync和OnTradeTransaction工作正常,我在FOREX(演示)上检查过。

都是在外汇市场上(真实)。

谢谢你!现在我知道如何使用OnTradeTransaction()函数了,还是有其他的秘诀?

如果TradeTransaction()事件会丢失,我怎样才能做到没有任何注意事项?

 
Oleg Shenker:

谢谢你!现在我知道如何使用OnTradeTransaction()了,还是有其他的秘诀?

如果TradeTransaction()事件会丢失,怎么可能没有注意事项?

没有什么秘密了。

它可能会丢失(但它在4-5个月内发生了3-4次,而且是在市场活动强劲的时刻)。

所以保险并不是一件坏事。

 

而这里是一个订单检查的具体例子

终端日志。

2017.01.05 11:46:01.673 Trades  'xxxxx': buy limit 1.00 PLT-6.17 at 952.3
2017.01.05 11:46:02.895 Trades  'xxxxx': accepted buy limit 1.00 PLT-6.17 at 952.3
2017.01.05 11:46:02.896 Trades  'xxxxx': buy limit 1.00 PLT-6.17 at 952.3 placed for execution in 1223.187 ms

专家顾问日志。

2017.01.05 11:46:02.829 trader (PLT-3.17,H1)      CheckOrders: Задержка ответа сервера. Ожидание продолжается...


该订单已于2017.01.05 11:46:01.673 发送。

服务器超过1秒没有回复,订单已被检查。

在正常模式下,响应时间为7-10毫秒。

 

回答"如何在MT5中正确使用OrderSend"的问题

有一个简单的答案。

直到开发人员解决了这个问题,那么

ulong pre_ticket; //Предварительный тикет
ulong order_ticket; //Тикет ордера
//---
if(OrderSend(request,result))
  {
    if(result.retcode==TRADE_RETCODE_DONE)
    {
      pre_ticket=result.order;
    }  
  }
//----------------------------------------------------------------+
//| TradeTransaction function                                        |
//+------------------------------------------------------------------+
void OnTradeTransaction(const MqlTradeTransaction &trans,
                        const MqlTradeRequest &request,
                        const MqlTradeResult &result)
{
   switch(trans.type)
   {
     case TRADE_TRANSACTION_ORDER_UPDATE:
       if((pre_ticket>0) && (trans.order==pre_ticket))
       {
         switch(trans.order_state)
         {
           case ORDER_STATE_PLACED:
             order_ticket = pre_ticket;
           break;
         }
       }
     break;
   }
}

当他们这样做时,那么

ulong order_ticket; //Тикет ордера
//---
if(OrderSend(request,result))
  {
    if(result.retcode==TRADE_RETCODE_DONE)
    {
      order_ticket=result.order;
    }  
  }
原因: