エラー、バグ、質問 - ページ 3147

 
皆さん、ごきげんよう。Expert Advisorのテスト モード(もちろん実ティックのテスト)でSleep()関数が実行されるかどうか、アドバイスをお願いします。
 
SuhanovDM94 #:
皆さん、ごきげんよう。Expert Advisorのテスト モード(もちろん実際のティックでテスト)でSleep()が実行されるかどうか、アドバイスをお願いします。

進行中 - テスターの時間が適切な量だけ変更されます。

 
fxsaber #:

実行された - テスターの時間が適切な量だけ変更されます。

ありがとうございました。

 
Wizard #:
mql5で、ポジションを建 てた後の、まさにティックの大きさを知ることは可能ですか?

できることがわかりました。forループは別関数、OnTick()関数内、または任意に挿入します。他の人の意見に興味がある。例えば、超精密なシステムを作るために必要なんです。そのため、ポジションを開く、閉じるなどの関数を含め、ライブラリを使わずに書いています。誰がなんと言おうと、mqhライブラリはコンパイルに1.5倍の時間がかかるなど、作業を遅くします。 すべてを1つのファイルに書く方がよいでしょう。MQL5は、C++のような言語にはなり得ないでしょう。ポイントは図書館にあります。

#define  EXPERT_MAGIC 261              // MagicNumber эксперта
input string Symbol_T  = "XAUUSD";    // глобальная переменная для задаваемого символа

..............

for(int i = PositionsTotal()-1; i >= 0; i--)
{
   if(PositionGetTicket(i) > 0 && PositionGetString(POSITION_SYMBOL) == Symbol_T && PositionGetInteger(POSITION_MAGIC) == EXPERT_MAGIC)
   {
      int attempts = 0;       // счетчик попыток
      bool success = false;   // флаг успешного выполнения копирования тиков
      MqlTick tick_array[];   // массив для приема тиков
         
      //--- сделаем 3 попытки получить тики
      while(attempts < 3)
      {
         //--- замерим время старта перед получением тиков
         uint start = GetTickCount();
         //--- дата, по которую запрашиваются тики (время открытия позиции)
         datetime Time_Open = (datetime)PositionGetInteger(POSITION_TIME);
         //--- дата, с которой запрашиваются тики (достаточно взять на 30 секунд раньше открытия позиции)
         datetime Time_Start = (datetime)(Time_Open-30);
         //--- запросим тиковую историю с момента Time_Start до момента Time_Open
         int received = CopyTicksRange(Symbol_T, tick_array, COPY_TICKS_ALL, Time_Start*1000, Time_Open*1000);
         if(received != -1)
         { 
            //--- выведем информацию о количестве тиков и затраченном времени
            PrintFormat("%s: received %d ticks in %d ms", Symbol_T, received, GetTickCount()-start);  
            //--- если тиковая история синхронизирована, то код ошибки равен нулю
            if(GetLastError()==0)
            {
               success = true;
               break;
            }
            else
               PrintFormat("%s: Ticks are not synchronized yet, %d ticks received for %d ms. Error=%d", Symbol_T, received, GetTickCount()-start, _LastError);
         }
         //--- считаем попытки
         attempts++;
         //--- пауза в 1 секунду в ожидании завершения синхронизации тиковой базы
         Sleep(1000);
      }
      //--- не удалось получить запрошенные тики от самого начала истории с трех попыток 
      if(!success)
      {
         PrintFormat("Ошибка! Не удалось получить %d тиков по %s с трех попыток", Symbol_T);
	 //return; (вставить, если цикл находится внутри функции типа void)
      }

      //--- узнаем количесто элементов в массиве
      int ticks = ArraySize(tick_array);

      //--- выведем bid последнего тика в массиве перед самым открытием позиции
      double last_bid_before_priceopen = tick_array[ticks-1].bid;
      Print("BID последнего тика: ", tick_array[ticks-1].bid);
      //--- выведем ask последнего тика в массиве перед самым открытием позиции
      double last_ask_before_priceopen = tick_array[ticks-1].ask;
      Print("ASK последнего тика: ", tick_array[ticks-1].ask);

      //--- узнаем цену, по которой была открыта позиция
      double Position_PriceOpen = PositionGetDouble(POSITION_PRICE_OPEN);

      if((ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY)
      {
         //--- вычислим размер последнего тика, на котором была открыта позиция (для BUY позиции открытие было по цене ASK)
         double size_last_tick_ASK = NormalizeDouble(fabs(Position_PriceOpen - last_ask_before_priceopen), _Digits);
      }
      else if((ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL)
      {
         //--- вычислим размер последнего тика, на котором была открыта позиция (для SELL позиции открытие было по цене BID)
         double size_last_tick_BID = NormalizeDouble(fabs(last_bid_before_priceopen - Position_PriceOpen), _Digits);
      }
   }
}

 

このバグにはうんざりしています。インジケータがあり、専門家が作業しています。インジケータを変更して再コンパイルすると、インジケータの変更はチャート上ではっきりと確認できます。 テスターでExpert Advisorを実行すると、何も変更されていないかのようになります。同じ結果です。

端末を再起動し、その後テスターを通すと、新しいコードが生成されます。

このハッキングは何なのか、私には理解できません。

インジケータex5を削除しました。テスターは何事もなかったかのように走り続けています。どこで実行するファイルを取得するのでしょうか?

 
Roman #:

3184
インジケーターの挙動がおかしい。
forループは、すべてのティックではなく、新しいローソク足で一度だけ、ボディに入ります。

しかし、i==0であり、与えられた条件ではi>=0が 許される

同じバーのティックでは limit = 0
なので、最初の値 i = -1 と条件 i>=0
がループに入らない理由です。

 
Nikolai Semko #:

at the tick on the same bar limit = 0
so the first value i = -1 and the condition i>=0
that's why it doesn't go into the loop.これは、ループに入らない理由です。

ありがとうございます、見逃してました。

しかし、現在、インジケータバッファIndBuff[i]は、その頭で、範囲外の配列をやっています。
何が必要なのか?なぜ、初期値i=limitに割り当てないのですか?


//+------------------------------------------------------------------+
//|                                                       Simple.mq5 |
//|                                  Copyright 2021, MetaQuotes Ltd. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2021, MetaQuotes Ltd."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property indicator_chart_window

#property indicator_buffers      1
#property indicator_plots        1


//indicator buffers
double IndBuff[];

double c = 0;

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
{
   SetIndexBuffer(0, IndBuff, INDICATOR_DATA);
   PlotIndexSetInteger(0, PLOT_DRAW_TYPE,  DRAW_LINE);   //тип отрисовки
   PlotIndexSetInteger(0, PLOT_LINE_STYLE, STYLE_SOLID); //стиль отрисовки
   PlotIndexSetInteger(0, PLOT_LINE_COLOR, clrAqua);     //цвет отрисовки
   PlotIndexSetInteger(0, PLOT_LINE_WIDTH, 1);           //толщина отрисовки
   PlotIndexSetString(0,  PLOT_LABEL,"K");               //метка
   PlotIndexSetDouble(0,  PLOT_EMPTY_VALUE, 0.0);        //нулевые значения считать пустыми
   
   return(INIT_SUCCEEDED);
}


//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate (const int rates_total,       
                 const int prev_calculated,   
                 const int begin,             
                 const double& price[])      
{

   ArraySetAsSeries(IndBuff, true);
   
   //-------------------------------------------------------------------------
   //Проверка и расчёт количества просчитываемых баров
   int limit = rates_total-prev_calculated;

   
   //-------------------------------------------------------------------------
   //Расчёт индикатора
   for(int i=limit; i>=0; i--)
   {
      c = iClose(_Symbol,PERIOD_CURRENT,i);      
      
      IndBuff[i] = c;  //на этой строке array out of range

   }
   

   return(rates_total);
}


 
Roman #:

ありがとうございます、見逃してました。

しかし、今、インジケータバッファIndBuff[i]は、脳、配列の範囲外をやっています。
何が必要なのか?なぜ初期値i=limitに割り当てないのか?

   //Проверка и расчёт количества просчитываемых баров
   int limit = rates_total-prev_calculated;

   if(limit==1)
     limit=2;
   //-------------------------------------------------------------------------
   //Расчёт индикатора
   for(int i=limit-1; i>=0; i--)
   {
      c = iClose(_Symbol,PERIOD_CURRENT,i);      
      
      IndBuff[i] = c;  //на этой строке array out of range

   }
 
Vitaly Muzichenko #:

そのため、すべてのバーでループに入り、一方、すべてのティックでループに入る必要があります。

以前はこのように動作していました。

をi>=0の刻みで表示する。

バーi>0に対して

今、私はバッファをどのように操作していいかわかりません。

 

それは、IndBuffがrates_total + 1
に割り当てられていないためで、ArrayResizeは 適用できない。
彼らは構築のために壊したのです。今度は、すべてをif-arsesでやらなければならないのか?

//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate (const int rates_total,       
                 const int prev_calculated,   
                 const int begin,             
                 const double& price[])      
{

   ArraySetAsSeries(IndBuff, true);
   
   //-------------------------------------------------------------------------
   //Проверка и расчёт количества просчитываемых баров
   int limit = rates_total-prev_calculated;
   
   if(limit > 1)
   {
      
      Print(rates_total,": rates_total");
      Print(limit,": limit");   
      Print(ArraySize(IndBuff),": IndBuff");
   }   
   
   //-------------------------------------------------------------------------
   //Расчёт индикатора
   for(int i=limit; i>=0; i--)
   {
      c = iClose(_Symbol,PERIOD_CURRENT,i);    

      IndBuff[i] = c;  //array out of range

   }
   

   return(rates_total);
}
100686: rates_total
100686: limit
100686: IndBuff
array out of range in 'Simple.mq5' (82,15)
理由: