Ошибки, баги, вопросы - страница 3147

 
Всем доброго времени суток. Подскажите, пожалуйста, выполняется ли функция Sleep() в режиме тестирования эксперта (тестировании на реальных тиках, естественно)?
 
SuhanovDM94 #:
Всем доброго времени суток. Подскажите, пожалуйста, выполняется ли функция Sleep() в режиме тестирования эксперта (тестировании на реальных тиках, естественно)?

Выполняется - время Тестера изменяется на соответствующую величину.

 
fxsaber #:

Выполняется - время Тестера изменяется на соответствующую величину.

Большое спасибо!

 
Wizard #:
Можно как то узнать размер того самого тика в mql5, после которого (на котором) была открыта позиция?

Оказывается, что можно. Цикл for вставляется в отдельную функцию, в функцию OnTick() или на свое усмотрение. Интересно мнение других. Например мне то нужно для создания сверхточной системы. Поэтому пишу без библиотек, включая функции для открытия, закрытия позиций. Кто бы что не говорил, библиотеки mqh замедляют работу, например, компиляция происходит в 1,5 раза дольше. Лучше писать в одном файле все. А стиль, ООП или процедурное, тут не играет роли. 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);
      }
   }
}

 

Как достал этот баг - есть индикатор, есть эскперт работающий от него. Меняется индикатор . перекомпилируется.  Изменения индикатора наглядно видны на графике Эксперт прогоняется в тестере-  но как будто ничего и не менял. Тот же самый результат.

Вот если перезаггрузить терминал и прогнать  тестер после этого, то он уже увидит новый код.

Что за шаманство - не понятно

Удалил ex5 индикатора. Тестер продолжает прогоняться как ни в чём не бывало. Ну откуда он берет файл для исполнения????

 
Roman #:

3184
Странное поведение в индикаторе.
Цикл for заходит в тело, не на каждом тике, а только один раз на новой свече.

Но i == 0  и заданное условие это позволяет i>=0  

при тике на том же баре limit = 0
значит первое значение i = -1, а условие i>=0
поэтому и не заходит в цикл.

 
Nikolai Semko #:

при тике на том же баре limit = 0
значит первое значение i = -1, а условие i>=0
поэтому и не заходит в цикл.

Спасибо, проглядел единичку.

Но теперь индикаторный буфер IndBuff[i] мозги делает, array out of range.
Что ему надо? Почему он не аллоцируется под начальный 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] мозги делает, array out of range.
Что ему надо? Почему он не аллоцируется под начальный 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 к нему не применим.
Сломали for конструкцию. Теперь через if-ы всё городить?

//+------------------------------------------------------------------+
//| 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)
Причина обращения: