初心者の方からの質問 MQL5 MT5 MetaTrader 5 - ページ 713

 
dimnik:
直近の1回以上のトレードの結果を知る方法を教えてください。

方法は2つあります。

Expert Advisor で直接OnTradeTransaction() を使用し、履歴に記録されたトレードをキャッチします。

//+------------------------------------------------------------------+
//| TradeTransaction function                                        |
//+------------------------------------------------------------------+
void OnTradeTransaction(const MqlTradeTransaction &trans,
                        const MqlTradeRequest &request,
                        const MqlTradeResult &result)
  {
//--- get transaction type as enumeration value
   ENUM_TRADE_TRANSACTION_TYPE type=trans.type;
//--- if transaction is result of addition of the transaction in history
   if(type==TRADE_TRANSACTION_DEAL_ADD)
     {
      long     deal_entry        =0;
      double   deal_profit       =0.0;
      double   deal_volume       =0.0;
      string   deal_symbol       ="";
      long     deal_magic        =0;
      if(HistoryDealSelect(trans.deal))
        {
         deal_entry=HistoryDealGetInteger(trans.deal,DEAL_ENTRY);
         deal_profit=HistoryDealGetDouble(trans.deal,DEAL_PROFIT);
         deal_volume=HistoryDealGetDouble(trans.deal,DEAL_VOLUME);
         deal_symbol=HistoryDealGetString(trans.deal,DEAL_SYMBOL);
         deal_magic=HistoryDealGetInteger(trans.deal,DEAL_MAGIC);
        }
      else
         return;
      if(deal_symbol==Symbol() && deal_magic==m_magic)
         if(deal_entry==DEAL_ENTRY_OUT)
           {
            // здесь ваши действия
           }
     }
  }

または、取引履歴を参照 するために、例えば次のようなものです。

//+------------------------------------------------------------------+
//|                                               HistorySelect.mq5  |
//|                              Copyright © 2016, Vladimir Karputov |
//|                                           http://wmua.ru/slesar/ |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2016, Vladimir Karputov"
#property link      "http://wmua.ru/slesar/"
#property version   "1.00"
#property description "Реверс позиции и исследование \"DEAL_POSITION_ID\" истории сделок"
#property script_show_inputs
//---
input datetime start=D'2016.08.05 09:00:00';
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
//---
   if(AccountInfoInteger(ACCOUNT_MARGIN_MODE)==ACCOUNT_MARGIN_MODE_RETAIL_HEDGING)
     {
      Print("This script cannot be run on a hedge; Этот скрипт нельзя запускать на хедж");
      return;
     }
   Print_IDs();
  }
//+------------------------------------------------------------------+
//| List all positions and deals                                     |
//+------------------------------------------------------------------+
void Print_IDs(void)
  {
//--- запрашиваем историю сделок и ордеров за указанный период серверного времени
   HistorySelect(start,TimeCurrent()+86400);
   uint     total    =HistoryDealsTotal();   // количество сделок в истории
   ulong    ticket   =0;                     // тикет сделки в истории
   long     type     =0;                     // тип сделки
   long     deal_id=0;   // идентификатор позиции, в открытии, изменении или закрытии которой участвовала эта сделка
   double   volume   =0.0;                   // объём сделки
   double   profit   =0.0;                   // финансовый результат сделки
   double   price    =0.0;                   // цена сделки
   string   symbol   =NULL;                  // имя символа, по которому произведена сделка
   long     entry    =0;                     // направление сделки – вход в рынок, выход из рынка или разворот
//--- for all deals
   for(uint i=0;i<total;i++)
     {
      //--- try to get deals ticket
      if((ticket=HistoryDealGetTicket(i))>0)
        {
         //--- get deals properties
         type     =HistoryDealGetInteger(ticket,DEAL_TYPE);
         deal_id  =HistoryDealGetInteger(ticket,DEAL_POSITION_ID);
         volume   =HistoryDealGetDouble(ticket,DEAL_VOLUME);
         profit   =HistoryDealGetDouble(ticket,DEAL_PROFIT);
         price    =HistoryDealGetDouble(ticket,DEAL_PRICE);
         symbol   =HistoryDealGetString(ticket,DEAL_SYMBOL);
         entry    =HistoryDealGetInteger(ticket,DEAL_ENTRY);
         Print(EnumToString((ENUM_DEAL_ENTRY)entry),
               ", type ",EnumToString((ENUM_DEAL_TYPE)type),
               ", price ",DoubleToString(price,Digits()),
               ", Deal ",symbol," volume ",DoubleToString(volume,2),
               ", DEAL_POSITION_ID #",deal_id,
               ", profit ",DoubleToString(profit,2));
        }
     }
   Print("");
  }
//+------------------------------------------------------------------+


どの方法を選ぶかによって、コードを少し編集する必要があります - 最後の取引に関する情報を得るために。

ファイル:
 
void OnTradeTransaction(const MqlTradeTransaction &trans,
                        const MqlTradeRequest &request,
                        const MqlTradeResult &result)
  {
   if (trans.type == TRADE_TRANSACTION_DEAL_ADD && trans.symbol == _Symbol)
     {
       if (!HistoryOrderSelect(trans.order)) printf("Ордер не найден");
       if (order.Magic() != MagicNumber) printf("Ошибка: магик неправильный %u",order.Magic());
     }  
    
  }

イベントハンドラは、EAのマジックを使ったすべてのトレードを記録しています。

しかし、なぜか最初のトレードはいつも間違ったマジック(ゼロ)が出るのに、次のトレードは問題なく出るのです。

どうすれば修正できますか?それとも、別の方法でやったほうがいいのでしょうか?

 
dimnik:
void OnTradeTransaction(const MqlTradeTransaction &trans,
                        const MqlTradeRequest &request,
                        const MqlTradeResult &result)
  {
   if (trans.type == TRADE_TRANSACTION_DEAL_ADD && trans.symbol == _Symbol)
     {
       if (!HistoryOrderSelect(trans.order)) printf("Ордер не найден");
       if (order.Magic() != MagicNumber) printf("Ошибка: магик неправильный %u",order.Magic());
     }  
    
  }

イベントハンドラでEAのマジックを使った全取引を監視する。

しかし、なぜか最初のトレードはいつも間違ったマジック(ゼロ)が出るのに、次のトレードは問題なく出るのです。

どうすれば修正できますか?それとも、別の方法でやったほうがいいのでしょうか?

命令で動くことから脱却する必要がある。これは時代遅れの古いシステム である。そうすれば、すべてがうまくいく。"TRADE_TRANSACTION_DEAL_ADD" - トランザクションを履歴に追加します。注文の執行や 口座残高の取引の結果として行われます。他に必要なものはありますか?取引は実行され、歴史に記録された。
 
dimnik:

イベントハンドラは、EAのウィザードですべてのトレードを記録します。

しかし、なぜか、最初の取引では、マジシャン(chistoriorderを通じて受信)は常に間違っている(ゼロ)、次の取引では - すべてが正常である。


このトランザクションのパラメータを表示します。

チケット/タイプ/シンボル/利益を知ることの何が問題なのでしょうか?

 
o_O:


この案件のパラメータを印刷します。

チケット、タイプ、シンボル、利益を見つけるには何が問題なのでしょうか?

出力します。

ディール2、マジック0、ボリューム0.000000

一般的にすべての取引で、正しい数が表示されますが、マグとボリュームはゼロです。


       deal.Ticket(trans.deal);
       printf("Сделка %f, Magic %u, Volume %f", trans.deal,deal.Magic(),deal.Volume());
 
dimnik:

出力します。

ディール2、マジック0、ボリューム0.000000

一般的に、すべての取引で正しい番号が表示されますが、弾倉とボリュームはゼロです。


       deal.Ticket(trans.deal);
       printf("Сделка %f, Magic %u, Volume %f", trans.deal,deal.Magic(),deal.Volume());

このコードを追加してください。

//+------------------------------------------------------------------+
//| TradeTransaction function                                        |
//+------------------------------------------------------------------+
void OnTradeTransaction(const MqlTradeTransaction &trans,
                        const MqlTradeRequest &request,
                        const MqlTradeResult &result)
  {
//--- получим тип транзакции в виде значения перечисления  
   ENUM_TRADE_TRANSACTION_TYPE type=trans.type;
   Print(EnumToString(type));
   long     deal_type         =0;
   long     deal_positions_id =0;
   long     deal_ticket       =0;
   double   deal_volume       =0;
   long     deal_entry        =0;
   long     deal_magic        =0;
   string   deal_symbol       ="";
   string   deal_comment      ="";
   if(HistoryDealSelect(trans.deal))
     {
      deal_type         =HistoryDealGetInteger(trans.deal,DEAL_TYPE);
      deal_positions_id =HistoryDealGetInteger(trans.deal,DEAL_POSITION_ID);
      deal_ticket       =HistoryDealGetInteger(trans.deal,DEAL_TICKET);
      deal_volume       =HistoryDealGetDouble(trans.deal,DEAL_VOLUME);
      deal_entry        =HistoryDealGetInteger(trans.deal,DEAL_ENTRY);
      deal_magic        =HistoryDealGetInteger(trans.deal,DEAL_MAGIC);
      deal_symbol       =HistoryDealGetString(trans.deal,DEAL_SYMBOL);
      deal_comment      =HistoryDealGetString(trans.deal,DEAL_COMMENT);
      Print("D_TYPE: ",EnumToString((ENUM_DEAL_TYPE)deal_type),", ",
            "D_POSITION_ID: ",deal_positions_id,", ",
            "D_TICKET: ",deal_ticket,", ",
            "D_VOLUME: ",DoubleToString(deal_volume,2),", ",
            "D_ENTRY: ",EnumToString((ENUM_DEAL_ENTRY)deal_entry),", ",
            "_MAGIC: ",deal_magic,", ",
            "D_SYMBOL: ",deal_symbol,", ",
            "D_COMMENT: ",deal_comment);
     }
   else
      return;
  }

をクリックすると、どのような種類の 取引が発生するのか、また「TRADE_TRANSACTION_DEAL_ADD」では、マジックとボリュームの両方が表示されることがわかります。


 
Vladimir Karputov:

このコードを追加してください。

//+------------------------------------------------------------------+
//| TradeTransaction function                                        |
//+------------------------------------------------------------------+
void OnTradeTransaction(const MqlTradeTransaction &trans,
                        const MqlTradeRequest &request,
                        const MqlTradeResult &result)
  {
//--- получим тип транзакции в виде значения перечисления  
   ENUM_TRADE_TRANSACTION_TYPE type=trans.type;
   Print(EnumToString(type));
   long     deal_type         =0;
   long     deal_positions_id =0;
   long     deal_ticket       =0;
   double   deal_volume       =0;
   long     deal_entry        =0;
   long     deal_magic        =0;
   string   deal_symbol       ="";
   string   deal_comment      ="";
   if(HistoryDealSelect(trans.deal))
     {
      deal_type         =HistoryDealGetInteger(trans.deal,DEAL_TYPE);
      deal_positions_id =HistoryDealGetInteger(trans.deal,DEAL_POSITION_ID);
      deal_ticket       =HistoryDealGetInteger(trans.deal,DEAL_TICKET);
      deal_volume       =HistoryDealGetDouble(trans.deal,DEAL_VOLUME);
      deal_entry        =HistoryDealGetInteger(trans.deal,DEAL_ENTRY);
      deal_magic        =HistoryDealGetInteger(trans.deal,DEAL_MAGIC);
      deal_symbol       =HistoryDealGetString(trans.deal,DEAL_SYMBOL);
      deal_comment      =HistoryDealGetString(trans.deal,DEAL_COMMENT);
      Print("D_TYPE: ",EnumToString((ENUM_DEAL_TYPE)deal_type),", ",
            "D_POSITION_ID: ",deal_positions_id,", ",
            "D_TICKET: ",deal_ticket,", ",
            "D_VOLUME: ",DoubleToString(deal_volume,2),", ",
            "D_ENTRY: ",EnumToString((ENUM_DEAL_ENTRY)deal_entry),", ",
            "_MAGIC: ",deal_magic,", ",
            "D_SYMBOL: ",deal_symbol,", ",
            "D_COMMENT: ",deal_comment);
     }
   else
      return;
  }

をクリックすると、どのような 取引が行われているかがわかります。また、「TRADE_TRANSACTION_DEAL_ADD」では、マジコンとボリュームの両方が表示されることも確認できます。


ありがとうございます、そのように動作します。
 
dimnik:

出力します。

ディール2、マジック0、ボリューム0.000000

一般に、すべての取引で正しい数字が出るが、魔法の数字や数量はゼロである。


       deal.Ticket(trans.deal);
       printf("Сделка %f, Magic %u, Volume %f", trans.deal,deal.Magic(),deal.Volume());

CDealInfoクラスを 使用する場合、私は独立して取引の履歴をロードする必要があることを長い間気づいていた、その後、すべてがうまく機能する

   if(trans.type==TRADE_TRANSACTION_DEAL_ADD)
     {
      HistorySelect(0,TimeCurrent());
       deal.Ticket(trans.deal);
       printf("Сделка %f, Magic %u, Volume %f", trans.deal,deal.Magic(),deal.Volume());
     }
 
dimnik:
ありがとうございます、うまくいきました。

すべての種類の取引を印刷しないようにするには、OnTradeTransaction で以下の条件を作成します。

//--- получим тип транзакции в виде значения перечисления  
   ENUM_TRADE_TRANSACTION_TYPE type=trans.type;
   if(type!=TRADE_TRANSACTION_DEAL_ADD)
      return;

   long     deal_type         =0;

つまり、トランザクションの種類が「TRADE_TRANSACTION_DEAL_ADD」でない場合、終了します。

もし、保留中の注文の発注(トリガーではなく、単に発注)をフォローする必要がある場合、OnTradeTransactionはこのような形をとります。

//+------------------------------------------------------------------+
//| TradeTransaction function                                        |
//+------------------------------------------------------------------+
void OnTradeTransaction(const MqlTradeTransaction &trans,
                        const MqlTradeRequest &request,
                        const MqlTradeResult &result)
  {
//--- get transaction type as enumeration value
   ENUM_TRADE_TRANSACTION_TYPE type=trans.type;
   Print(EnumToString(type));
//--- if transaction is result of addition of the transaction in history
   if(type==TRADE_TRANSACTION_ORDER_ADD)
     {
      long     order_type        =0;
      double   order_price       =0.0;
      double   order_volume      =0.0;
      string   order_symbol      ="";
      long     order_magic       =0;
      if(OrderSelect(trans.order)) // select pending orders
        {
         order_type=OrderGetInteger(ORDER_TYPE);
         order_price=OrderGetDouble(ORDER_PRICE_OPEN);
         order_volume=OrderGetDouble(ORDER_VOLUME_INITIAL);
         order_symbol=OrderGetString(ORDER_SYMBOL);
         order_magic=OrderGetInteger(ORDER_MAGIC);
        }
      else
         return;
      if(order_symbol==m_symbol.Name() && order_magic==m_magic)
        {
         if(order_type==ORDER_TYPE_BUY_LIMIT)
           {
            //
           }
         if(order_type==ORDER_TYPE_SELL_LIMIT)
           {
            //
           }
        }
     }
  }
 

OnTradeTransactionを使用 することで、不思議と最適化時間が変化しています。15Mのシステム、非常にシンプル、年間履歴、1回の実行は0.3〜0.4秒で発生します。

最適化スタート後、最初の200~300本は1秒以下で進み、次のものは15~20秒まで遅くなります(50回!)。

CPUのオーバーヒートや荒らしもなく、メモリも半分以上空いている(16GBから)。

OnTradeTransaction ハンドラを使用する前は、このようなことはありませんでした。小さなタイムフレームでより複雑な EA でも、毎回ほぼ同じ速度で最適化されていました。

HistoryDealSelectはそれほど速度に影響するのでしょうか?どうすればラグを解消できるのか?

void OnTradeTransaction(const MqlTradeTransaction &trans,
                        const MqlTradeRequest &request,
                        const MqlTradeResult &result)
  {
   if( trans.type != TRADE_TRANSACTION_DEAL_ADD) return;
   ENUM_TRADE_TRANSACTION_TYPE type=trans.type;
   long     deal_type         =0;
   double   deal_volume       =0;
   long     deal_magic        =0;
   if(HistoryDealSelect(trans.deal))
     {
      deal_type         =HistoryDealGetInteger(trans.deal,DEAL_TYPE);
      deal_volume       =HistoryDealGetDouble(trans.deal,DEAL_VOLUME);
      deal_magic        =HistoryDealGetInteger(trans.deal,DEAL_MAGIC);
     }
   else
      return;
   if (deal_type == DEAL_TYPE_BUY && deal_magic == MagicNumber) current_position += deal_volume;
   if (deal_type == DEAL_TYPE_SELL && deal_magic == MagicNumber) current_position -= deal_volume;
      
  }
理由: