[Erreur dans la récupération de l'heure du senior TF dans le chronomètre ! - page 6

 
J'aimerais beaucoup savoir ce que les développeurs pensent de tout cela.
 
 ResetLastError();
      if(iBarShift(Symbol(),PERIOD_M15,TimeCurrent(),true)==-1)
        {
         Print(__FILE__+": Данные истории по последнему часу отсутствуют! Ошибка #",GetLastError());
         return( false );
        }
      //---
      if(GetLastError()==ERR_NO_ERROR)
        {
         ResetLastError();
         //--- Запоминаем время открытия бара
         _m15OpenTime=iTime(NULL,PERIOD_M15,0);
         //---
         Print(__FILE__,": Актуальное время открытия бара М15 = "+TimeToString(_m15OpenTime)+". Ошибка #",GetLastError());
         //--- Возвращаем истину
         return( true );
        }
 
Alexey Kozitsyn:

Il semble que la solution la plus fiable soit d'attendre l'appel de OnCalculate() avec vérification obligatoire de la connexion au serveur de commerce. Si nous ne vérifions pas la connexion (IsConnected()), alors même dans OnCalculate() nous l'obtiendrons au chargement du terminal :

Toutefois, il ne supprime pas toutes les questions :

1. Pourquoi n'est-il pas indiqué dans la documentation de IsConnected() qu'il faut nécessairement l'appeler avant de recevoir des données (au moins) du senior TF dans OnCalculate() ?

2. Pourquoi IsConnected() dans OnTimer() ne fonctionne-t-il pas ? Le fait d'établir une connexion avec un serveur commercial n'est-il pas censé nous indiquer que des données peuvent être obtenues ?

3. Une fois que nous avons établi une connexion avec le serveur commercial et que nous essayons de recevoir des données dans OnTimer(), les fonctions iTime(), iBarShift(), SeriesInfoInteger() et les fonctions similaires ne devraient-elles pas renvoyer des erreurs si les données de ce serveur commercial particulier, dont elles tirent des informations, ne sont pas encore synchronisées ? Sinon, cela donne des résultats absurdes, comme le fait que nous vous renvoyons l'erreur 4066 une fois et que vous pouvez ensuite utiliser les données dont vous disposez.

J'ai parlé aux développeurs et à l'un de mes amis sur place et je leur ai dit ce qui suit : 1 Que dois-je faire ?

1 N'importe quoi, vous pouvez l'appeler à tout moment et de n'importe où.

2 IsConnected peut être appelé de n'importe où dans le code et cela fonctionne, mais c'est une fonction qui n'écrit rien sur la pile d'erreurs ; elle renvoie true/false et c'est tout. Etant donné que la procédure de connexion est assez longue (minimum 1 sec) et que IsConnected est déclenché au moment de la connexion, il est nécessaire de vérifier l'état de la connexion et d'attendre le début du flux de citations lors du démarrage du terminal.

3 Ces fonctions n'écrivent rien sur la pile d'erreurs, elles renvoient elles-mêmes le résultat.

Pourquoi avons-nous obtenu 4066 ? Cette erreur a été causée par la fonction TimeCurrent. Le terminal se connecte et demande du temps au serveur ; selon la qualité de la connexion, cela prend aussi un certain temps, c'est pourquoi nous avons un minuteur rapide. Et puis nous avons obtenu 4066 sur notre demande de TimeCurrent. Et puis nous avons obtenu l'heure et nos fonctions ont commencé à fonctionner normalement et elles ont elles-mêmes renvoyé une erreur suite à leur travail en contournant la pile d'erreurs.

Dans cette situation, il est recommandé d'utiliser une minuterie rapide et de démarrer le terminal, afin de vérifier que nous avons commencé à recevoir des données du serveur. Ma version est un peu maladroite, il serait correct de recevoir un signal de OnCalculate pour commencer à recevoir des données.

 
C'est plus simple que ça.
 
Alexey Kozitsyn:

Que suggérez-vous pour résoudre le problème (existe-t-il, à votre avis) ? Attendre que OnCalculate() soit appelé 1-2 fois ?

Oui, exactement. Dans OnInit(), appelez simplement les TF nécessaires sans vérifier le résultat (vous ne pouvez pas vous y fier), et dans OnCalculate, appelez la fonction IsTFD DataReady(). Dès que la réponse est vraie pour toutes les TFs demandées, vous pouvez commencer à exécuter l'algorithme de l'indicateur.

 
Alexey Kozitsyn:

1. Pourquoi la documentation de IsConnected() ne précise-t-elle pas qu'il faut toujours l'appeler avant de recevoir des données (au moins) du TF senior dans OnCalculate() ?

IsConnected() est une fonction assez délicate. Il renvoie l'état d'une seule connexion au serveur. Mais le terminal utilise plus d'une connexion. Il y a 8 fils commerciaux à lui seul. Ainsi, même si IsConnected() renvoie vrai, on ne sait pas très bien ce que cela signifie. Au moins, nous ne pouvons pas nous attendre à ce que les séries chronologiques soient demandées et construites. Mais si IsConnected() renvoie false, alors nous pouvons être sûrs que le terminal est toujours hors ligne.

Quelle est la tâche pour laquelle la présence de la connexion terminale est si cruciale ? D'après ce que je comprends, l'indicateur est un outil de visualisation des données. Les données qui sont disponibles. Lorsque de nouvelles données arrivent, la visualisation est mise à jour. Il ne devrait pas être nécessaire de vérifier la pertinence des données. C'est la tâche du terminal.

 
Igor Makanu:

Je suppose que nous parlons de MQL5, la préparation de l'OHLC n'est pas la même que dans MT4.

Je parle de MT4. Il y a environ 2 ou 3 ans, j'ai rencontré un problème avec Time[0]. Les développeurs semblent l'avoir corrigé, mais au fil du temps, il est réapparu. Le problème est qu'il est impossible de reproduire ce bogue sans ambiguïté.

 
Ihor Herasko:

IsConnected() est une fonction assez délicate. Elle ne renvoie que l'état d'une des connexions au serveur. Mais le terminal utilise plus d'une connexion. Il y a 8 fils de discussion sur le commerce à lui seul. Ainsi, même si IsConnected() renvoie vrai, on ne sait pas vraiment ce que cela signifie. Au moins, nous ne pouvons pas nous attendre à ce que les séries chronologiques soient demandées et construites. Mais si IsConnected() renvoie false, alors nous pouvons être sûrs que le terminal est toujours hors ligne.

Quelle est la tâche pour laquelle la présence de la connexion terminale est si cruciale ? D'après ce que je comprends, l'indicateur est un outil de visualisation des données. Les données qui sont disponibles. Lorsque de nouvelles données arrivent, la visualisation est mise à jour. Il ne devrait pas être nécessaire de vérifier la pertinence des données. C'est la tâche du terminal.

Pour les indicateurs, je ne me souviens pas de la nécessité de vérifier la connexion avec le serveur, ce que nous avons dans l'historique est dessiné, lorsque l'historique est chargé, cela signifie que tous les tampons des indicateurs sont recalculés.

J'ai développé et utilisé la fonction suivante dans mon EA, elle est généralement satisfaisante et vérifie correctement la connexion avec le serveur :

bool ServerDisable(int count=10){
   if(IsTesting()||IsOptimization())return(false);
   for(int i=0;i<count;i++){
      if(IsConnected())
         if(IsTradeAllowed())
            if(!IsTradeContextBusy()){RefreshRates(); return(false);}
      Sleep(157);
   }
   Print(__FUNCTION__," Торговый сервер не отвечает");
return(true);}

J'utilise spécifiquement Sleep() pour transmettre le contrôle au terminal et ensuite vérifier la connexion au serveur et la possibilité de négocier.

 
Ihor Herasko:

Je parle de MT4. Il y a environ 2 ou 3 ans, j'ai rencontré un problème avec Time[0]. Les développeurs semblaient l'avoir corrigé, mais au fil du temps, il est réapparu. Le problème est qu'il est impossible de reproduire ce bogue sans ambiguïté.

Si ce n'est pas trop difficile, voici le sujet du thème - téléchargement correct de l'historique à partir du TF majeur, voici l'indicateur : "J'ai besoin de dessiner la MA" du TF majeur sur les barres du TF mineur, je l'ai fait en 5 minutes, il fonctionnera pour 98% correctement, où dans ce code 2% de "pièges" qui causeront des bugs ?

Je suis intéressé par le code correct pour MT4

#property copyright "IgorM"
#property link      "https://www.mql5.com/ru/users/igorm"
#property version   "1.00"
#property strict
#property indicator_separate_window
#property indicator_buffers 1
#property indicator_plots   1
//--- plot line1
#property indicator_label1  "line1"
#property indicator_type1   DRAW_LINE
#property indicator_color1  clrRed
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1
//--- input parameters
input ENUM_TIMEFRAMES   TimeFrame   =  PERIOD_H4;
input int               MAPeriod    =  25;
//--- indicator buffers
double         BufMA[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
   double cl[];
//--- indicator buffers mapping
   SetIndexBuffer(0,BufMA);
   IndicatorDigits(Digits);
// запускаем подгрузку истории и выходим, даже не проверяя подгружена она или нет, история тут еще не нужна
   CopyClose(_Symbol,TimeFrame,0,iBars(_Symbol,TimeFrame),cl);
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
//---
   int i,limit,resultcopy;
   double closetf[];
   if(prev_calculated==0)
     {
      resultcopy=CopyClose(_Symbol,TimeFrame,0,iBars(_Symbol,TimeFrame),closetf);
      if(resultcopy<0)
        {
         Print("Подгрузка истории....");
         return(0);
        }
      if(resultcopy<MAPeriod)
        {
         Comment("Большой период МА!!!, в истории доступно ", resultcopy," баров");
         return(resultcopy);
        }
      limit=resultcopy-1;
        }else{
      resultcopy=CopyClose(_Symbol,TimeFrame,0,iBars(_Symbol,TimeFrame),closetf);
      if(resultcopy<0)
        {
         Print("Подгрузка истории....");
         return(0);
        }
      if(resultcopy<MAPeriod)
        {
         Comment("Большой период МА!!!, в истории доступно ", resultcopy," баров");
         return(resultcopy);
        }
      limit=resultcopy-prev_calculated+1;
     }
   limit = fmin(rates_total-1,limit);
// основной цикл расчета индикатора
   for(i=limit; i>=0 && !IsStopped(); i--)
     {
      BufMA[i]=iMA(_Symbol,TimeFrame,MAPeriod,0,MODE_SMA,PRICE_CLOSE,i);
     }
//---
   return(resultcopy);

  }
 
Vitaly Gorbunov:

J'ai parlé aux développeurs et à un ami que je connais là-bas, et je vais vous dire une chose à la fois.

1 N'importe quoi, vous pouvez l'appeler à tout moment et de n'importe quel endroit.

2 IsConnected peut être appelé de n'importe où dans le code et cela fonctionne, mais c'est une fonction qui ne met rien sur la pile d'erreurs, elle renvoie vrai/faux et c'est tout. Considérant que la procédure de connexion est assez longue (minimum 1 sec) et que IsConnected est déclenché au moment de la connexion, il est nécessaire de vérifier l'état de la connexion et d'attendre le début du flux de citations au démarrage du terminal.

3 Ces fonctions n'écrivent rien sur la pile d'erreurs, elles renvoient elles-mêmes le résultat.

Pourquoi avons-nous obtenu 4066 ? Cette erreur a été causée par la fonction TimeCurrent. Le terminal se connecte et demande l'heure au serveur, selon la qualité de la connexion cela prend aussi un certain temps, donc n'oubliez pas notre minuteur rapide. Et puis nous avons obtenu 4066 sur notre demande de TimeCurrent. Et puis nous avons obtenu l'heure et nos fonctions ont commencé à fonctionner normalement et elles ont elles-mêmes renvoyé une erreur suite à leur travail en contournant la pile d'erreurs.

Comme recommandation dans une telle situation, la minuterie rapide et le démarrage du terminal, assurez-vous de vérifier que nous avons commencé à recevoir des données du serveur. Ma variante est un peu maladroite, il serait correct de recevoir un signal de OnCalculate pour commencer à recevoir des données.

1. Lisez attentivement ce que j'écris. Ce n'est pas la première fois que je te le dis ! Je n'ai rien dit sur le fait de ne pas appeler quelque part !

Vous voulez dire que toutes les fonctions iBarShift(), iTime(), SeriesInfo...() demandent TimeCurrent() ?