Erreurs, bugs, questions - page 3147

 
SuhanovDM94 #:
Bonne journée à tous. Pourriez-vous m'indiquer si la fonction Sleep() est exécutée dans le mode de test de l'Expert Advisor (test sur des ticks réels, bien sûr) ?

En cours - le temps du Testeur est modifié d'une quantité appropriée.

 
fxsaber #:

Exécuté - le temps du Testeur est modifié d'une quantité appropriée.

Merci beaucoup !

 
Wizard #:
Est-il possible de trouver la taille du tick même dans mql5, après lequel une position a été ouverte?

Il s'avère que vous le pouvez. La boucle for est insérée dans une fonction distincte, dans la fonction OnTick() ou à votre guise. Je suis intéressé par l'opinion des autres. Par exemple, j'en ai besoin pour créer un système ultra-précis. Par conséquent, j'écris sans bibliothèques, y compris les fonctions d'ouverture et de fermeture des positions. Qui que ce soit, les bibliothèques mqh ralentissent le travail, par exemple la compilation prend 1,5 fois plus de temps. Il est préférable de tout écrire dans un seul fichier. Le style, OOP ou procédural, n'a pas d'importance. MQL5 ne deviendra jamais un langage du niveau de C++, il est limité. Le point est dans les bibliothèques.

#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);
      }
   }
}

 

J'en ai marre de ce bug - il y a un indicateur, il y a un expert qui travaille dessus. Je modifie l'indicateur et le recompile. Les modifications de l'indicateur sont clairement visibles sur le graphique - le conseiller expert est exécuté dans le testeur - mais c'est comme s'il n'avait rien changé. Le même résultat.

Si je redémarre le terminal et passe le testeur après cela, il générera un nouveau code.

Qu'est-ce que c'est que ce piratage, je ne comprends pas.

J'ai supprimé l'indicateur ex5. Le testeur continue à fonctionner comme si rien ne s'était passé. Où trouve-t-on le fichier à exécuter ? ? ???

 
Roman #:

3184
Comportement étrange de l'indicateur.
La boucle for entre dans le corps, non pas à chaque tick, mais une seule fois à chaque nouvelle bougie.

Mais i == 0 et la condition donnée permet i>=0

sur le tick de la même barre limite = 0
donc la première valeur de i = -1 et la condition i>=0
c'est pourquoi il ne va pas dans la boucle.

 
Nikolai Semko #:

au tick sur la même barre limite = 0
donc la première valeur i = -1 et la condition i>=0
c'est pourquoi il ne va pas dans la boucle.

Merci, j'ai raté celui-là.

Mais maintenant, le tampon indicateur IndBuff[i] fait des siennes, le tableau étant hors de portée.
De quoi a-t-il besoin ? Pourquoi n'alloue-t-il pas à l'initiale i=limite ?


//+------------------------------------------------------------------+
//|                                                       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 #:

Merci, j'ai raté celui-là.

Mais maintenant le tampon indicateur IndBuff[i] fait le cerveau, array out of range.
De quoi a-t-il besoin ? Pourquoi n'alloue-t-il pas à l'initial i=limite ?

   //Проверка и расчёт количества просчитываемых баров
   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 #:

Ainsi, à chaque barre, il entre dans une boucle, alors qu'il doit entrer dans une boucle à chaque tick.

Cela fonctionnait comme suit

pour les ticks i>=0,

pour les barres i>0

Maintenant, je ne sais pas comment travailler avec le tampon.

 

C'est parce que IndBuff n'est pas alloué à rates_total + 1
Et ArrayResize ne lui est pas applicable.
Ils ont cassé la pour construire. Maintenant on doit tout faire par des "si" ?

//+------------------------------------------------------------------+
//| 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)
 
Roman #:

C'est parce que IndBuff n'est pas alloué à rates_total + 1
Et ArrayResize ne lui est pas applicable.
Ils ont cassé la pour construire. Devons-nous utiliser des if-arses maintenant ?

for(int i=limit - 1;....

au moins...