MT5でOrderSendを正しく動作させる方法 - ページ 11

 
prostotrader:

2つではなく、1つです :)

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

TRADE_TRANSACTION_REQUESTは、OrderSendAsymcを 使用してオーダーチケットを受け取る際に必要です。

そこで、何が問題なのか?具体的にOrderSendAsync()を使っているかどうかは、どのように判断するのですか?
また、例えばトレードリクエストを送ってきたExpert Advisorのスタンプを確認するような使い方はできないのでしょうか?あるいは、例えば、最後の取引が行われたポジションのチケットを確認するには?

最後に、このイベントを使って、取引が行われた価格をチェックすることができます(ただし、このイベントで価格をチェックするのは、非同期取引を使用する場合にのみ意味があると思います)。

では、非同期注文送信を使用すれば、コードは正しいのでしょうか?

 
Oleg Shenker:

では、何がいけないのでしょうか?多分OrderSendAsync()を使っていると思うのですが、どうなんでしょう?
また、例えばトレードリクエストを送信したExpert Advisorのスタンプを確認するような使い方はできないのでしょうか。あるいは、例えば、最後の取引が行われたポジションのチケットを確認するには?

最後に、このイベントを使って、取引が行われた価格をチェックすることができます(ただし、このイベントで価格をチェックするのは、非同期取引を使用する場合にのみ意味があると思います)。

では、非同期注文送信を使用すれば、コードは正しいのでしょうか?

というトピックがあります。

"OrderSend "で正しく動作させる方法

この機能は(開発者が考えているように)完全に同期的であるべきで、つまり、注文を送ったら、チケットをもらったら、である。

は、すべて注文に問題ありません。しかし、現在この機能はかなり正しく動作していないため、注文のチケットを受け取った後に

OnTradeTransactionで、すべてがOKであることの確認を得る。

すなわち、この注文のデータは、端末内で完全に同期している。

//+------------------------------------------------------------------+
// 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で、すべてがOKであることの確認を得る。

つまり、この注文のデータは、端末内で完全に同期されているのです。

//+------------------------------------------------------------------+
// 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イベント(取引合計の確定を意味する)が2回発生するのですが、別の問題があります。
 
Oleg Shenker:
素晴らしいその仕組みはわかっている。ただ、私は非同期の注文送信を使用しています。同じトランザクションのREQUESTイベント(トランザクションの合計を確定する意味)が2回発生しました。

OrderSEndAsync を配置する際にOnTradeTransaction メッセージがどのように処理されるべきかをよく理解していないだけです。

このEAを記録し、どのように動作するかを確認する

ファイル:
TestOrders.mq5  25 kb
 
prostotrader:

OrderSEndAsync を配置する際にOnTradeTransaction メッセージがどのように処理されるべきかをよく理解していないだけです。

Expert Advisorを録画して、その動作を確認する。

それが、TradeTransactionをどのように正しく扱うべきかということです。

 
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.成行注文や指値注文(保留でないもの)、つまり即時に執行される注文を使用する場合

または拒否された場合、いずれの場合も3.のTRADE_TRANSACTION_HISTORY_ADDを監視する必要があります。

このような注文は履歴に追加されます。

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の3つのイベントがあります。

TRADE_TRANSACTION_ORDER_UPDATE - 注文が設定(変更)されたことを取得するために使用されます。

TRADE_TRANSACTION_DEAL_ADD - 取引が実行されたという情報を取得する

TRADE_TRANSACTION_HISTORY_ADD - この注文は取引システムに存在しません。

以上、"知恵 "でした。

追加

OrderSendAsyncとOnTradeTransactionの 相互作用は問題なく 動作します。

とか、FX(リアル)で

 
prostotrader:

追加

OrderSendAsyncとOnTradeTransactionはFOREX(デモ)で確認 したところ、問題なく 動作しています。

ともに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

Expert Advisorのログです。

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


2017.01.05 11:46:01.673に 送信されました。

サーバーから1秒以上応答がない、注文が確認された。

通常モードでは7〜10msecで応答します。

 

"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;
    }  
  }