Erreurs, bugs, questions - page 3028

 
Andrey Dik:

réfléchissez encore.

Tu dois réfléchir, Andrei. C'est dans votre code que les cafards sont là.

Eh bien, je suis si enclin aujourd'hui... Je vais essayer de pousser dans la bonne direction :

Une nouvelle barre s'est ouverte... iBars() a augmenté de un...... Mais le nombre de barres comptées n'a pas changé. Et il ne changera pas tant qu'il n'aura pas recalculé cette nouvelle barre...

Quelle est la prochaine étape ?

 
Igor Makanu:

cela ne devrait pas fonctionner correctement dans les indicateurs :

si je ne me trompe pas, dans l'aide il y a une décomposition du script pour paginer les données pour tous les TFs et il devrait y avoir un avertissement que les données historiques ne peuvent pas être demandées à l'indicateur de cette façon, parce que l'indicateur fonctionne de manière asynchrone.

et il est recommandé d'utiliser BarsCalculated() une fois après avoir lié le handle


UPD : script pour la pagination de l'historique et explication pourquoi il ne fonctionne pas dans les indicateurs: https://www.mql5.com/ru/docs/series/timeseries_access

Vous êtes sûr de comprendre la signification du code ?

 
Alexey Viktorov:

Tu dois réfléchir, Andrei. C'est dans votre code qu'il y a des cafards.

Eh bien, je suis si enclin aujourd'hui... Je vais essayer de pousser dans la bonne direction :

Une nouvelle barre s'est ouverte... iBars() a augmenté de un...... Mais le nombre de barres comptées n'a pas changé. Et il ne changera pas tant qu'il n'aura pas recalculé cette nouvelle barre...

Quelle est la prochaine étape ?

mon bon monsieur, ne m'écrivez pas, vous n'êtes pas dans le coup.

Ou prouvez-le avec un code.

 
Andrey Dik:

Vous êtes sûr de comprendre la signification du code ?

Avec une forte probabilité - sûr et compris

Vous voulez que l'indicateur synchronise le "TF supérieur" avant d'appeler un autre indicateur.

mon indicateur fonctionne, n'est-ce pas ? - vous pouvez lui ajouter BarsCalculated() - mais comme dans les exemples d'indicateurs de la livraison, par exemple MACD.mql5


HH : il y a beaucoup d'indicateurs multitime dans QB. Si j'ai besoin de me rappeler ce qu'il faut faire et comment le faire, je recherche habituellement les indicateurs de Mladen Rakic et je regarde les siens, le style de codage est particulier (plus exactement le formatage), mais ils sont 100% fonctionnels.

https://www.mql5.com/ru/users/mladen

 
Andrey Dik:

Chérie, ne m'écris pas, tu n'es pas dans le coup.

Ou prouvez-le avec un code.

Eh bien alors, phew sur vous...

Les développeurs ne répondent pas à de telles inepties, Igor va bientôt se lasser... Et reste à parler tout seul...

Demandez simplement à Drummer de déplacer vos épanchements dans un fil séparé ... pour éviter d'encombrer le fil approprié ...

 

Forum sur le trading, les systèmes de trading automatisé et les tests de stratégies de trading

Bugs, bugs, questions

Andrey Dik, 2021.05.28 05:16

J'essaie de vérifier la synchronisation des données sur la période demandée (M5) et la disponibilité de l'indicateur sur celle-ci, si elle n'est pas prête, je vais quitter.

Par conséquent, l'indicateur ne fonctionne qu'une fois à l'ouverture de la barre M1, et non à chaque tick :


//проверка готовности данных и индикатора на другом TF
if (SeriesInfoInteger (Symbol (), tf, SERIES_SYNCHRONIZED))
{
  if (iBars (Symbol (), tf) != BarsCalculated (handleFr)) return 0;
}
else return 0;

//проверка на наличие нового бара
if (rates_total == prev_calculated) return rates_total;

J'espère que les développeurs écouteront mes supplications.

Je ne comprends pas bien votre code. Que doit-il se passer après "return 0 ;" lors du prochain appel à OnCalculate ?
 
Alexey Viktorov:

Igor va bientôt se lasser aussi...

J'ai juste le désir de comprendre

dans MT5 il y a beaucoup de pièges avec la synchronisation, maintenant la question est à ce sujet aussi.

imho, si l'indicateur utilise des constructions sur chaque barre (lignes, pas flèches)

ce cycle est suffisant pour un calcul économique :

for(int i = prev_calculated; i < rates_total; i++)
   {
      Buffer[i] = close[i];
   }

s'il s'agit du premier appel, alors prev_calculated sera = 0, lors des appels suivants, les nouvelles barres seront recalculées.


et si les deux indicateurs sont écrits correctement, vous n'avez pas besoin de synchroniser quoi que ce soit en plus, tout fonctionnera, la seule chose qui reste est de comparer CopyBuffer() avec le nombre requis de valeurs de l'indicateur appelé

 
Igor Makanu:

Je veux juste trouver une solution.

dans MT5 il y a beaucoup de pièges avec la synchronisation, maintenant la question est à propos de cela aussi.

imho, si l'indicateur utilise une construction sur chaque barre (des lignes, pas des flèches)

ce cycle est suffisant pour un calcul économique :

s'il s'agit du premier appel, alors prev_calculated sera = 0, lors des appels suivants, les nouvelles barres seront recalculées.


et si les deux indicateurs sont écrits correctement, vous n'avez pas besoin de synchroniser quoi que ce soit en plus, tout fonctionnera, la seule chose qui reste est de comparer CopyBuffer() avec le nombre requis de valeurs de l'indicateur appelé

C'est ce que je veux dire. Il serait correct d'essayer de synchroniser avant la première exécution, mais de cette façon.............

 
Igor Makanu:

Je veux juste trouver une solution.

dans MT5 il y a beaucoup de pièges avec la synchronisation, maintenant la question est à propos de cela aussi.

imho, si l'indicateur utilise une construction sur chaque barre (des lignes, pas des flèches)

ce cycle est suffisant pour un calcul économique :

s'il s'agit du premier appel, alors prev_calculated sera = 0, lors des appels suivants, les nouvelles barres seront recalculées.


et si les deux indicateurs sont écrits correctement, vous n'avez pas besoin de synchroniser quoi que ce soit en plus, tout fonctionnera, la seule chose qui reste est de comparer CopyBuffer() avec le nombre requis de valeurs de l'indicateur appelé

si vous voulez comprendre et ne pas vous opposer, vous devriez écrire quelque chose comme le code ci-dessous :

#property indicator_chart_window
#property indicator_buffers 1
#property indicator_plots   1

#property indicator_label1  "I"
#property indicator_type1   DRAW_LINE
#property indicator_color1  clrRed
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1

double         IBuffer[];

int OnInit()
{
   SetIndexBuffer   (0,IBuffer,INDICATOR_DATA);
   ArraySetAsSeries (IBuffer, true);

   return(INIT_SUCCEEDED);
}

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[])
{
   if (rates_total == prev_calculated) return rates_total;
   
   ulong t = GetMicrosecondCount ();
   
   ArraySetAsSeries (high,        true);

   int limit = rates_total - prev_calculated - 1;

   for (int i = limit; i >= 0; i--)
   {
      IBuffer [i] = high [i];
   }

   //----------------------------------------------------------------
   double e = (GetMicrosecondCount () - t) / 1000000.0;
   Print (DoubleToString (e, 6), " sec, рассчитано ", rates_total - prev_calculated, " баров, всего баров ", rates_total);
   return(rates_total);
}
#property indicator_chart_window
#property indicator_buffers 1
#property indicator_plots   1

//--- plot I
#property indicator_label1  "I"
#property indicator_type1   DRAW_LINE
#property indicator_color1  clrRed
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1

input ENUM_TIMEFRAMES  OldTF = PERIOD_M5;

double IBuffer[];
int    Handle = 0;

int OnInit()
{
   SetIndexBuffer   (0,IBuffer,INDICATOR_DATA);
   ArraySetAsSeries (IBuffer, true);

   Handle = iCustom (Symbol (), OldTF, "OldTF.ex5");
   if (Handle == INVALID_HANDLE)
   {
      Print ("Не удалось получить хендл индикатора OldTF.ex5");
      return INIT_FAILED;
   }

   return INIT_SUCCEEDED;
}

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[])
{
   if (rates_total == prev_calculated) return rates_total;

   if (SeriesInfoInteger (Symbol (), OldTF, SERIES_SYNCHRONIZED))
   {
      if (iBars (Symbol (), OldTF) != BarsCalculated (Handle))
      {
        Print ("Индикатор на периоде ", OldTF, " ещё не рассчитан");
        return 0;
      }
   }
   else 
   {
     Print ("Период ", OldTF, " не синхронизирован.");
     return 0;
   }

   ulong t = GetMicrosecondCount ();

   ArraySetAsSeries (high, true);
   ArraySetAsSeries (time, true);

   int limit = rates_total - prev_calculated - 1;

   double buff [];
   int ind = 0;
   for (int i = limit; i >= 0; i--)
   {
      ind = iBarShift (Symbol (), OldTF, time [i], false);
      if (CopyBuffer (Handle, 0, ind, 1, buff) != -1)
      {
        IBuffer [i] = buff [0];
      }
      else
      {
        Print ("Ошибка копирования буфера ", GetLastError ());
        return 0;
      }
   }

   //----------------------------------------------------------------
   double e = (GetMicrosecondCount () - t) / 1000000.0;
   Print (DoubleToString (e, 6), " sec, расcчитано ", rates_total - prev_calculated, " баров, всего баров ", rates_total);
   return(rates_total);
}

compilez les deux codes et exécutez le second. obtenez quelque chose comme ceci dans les logs lors de l'exécution sur M1 et M3 de l'indicateur senior :

2021.05.28 19:05:01.408 OldTF (EURUSD,M3) 0.000234 sec, 50000 barres calculées, 50000 barres totales

2021.05.28 19:05:03.860 LitTF (EURUSD,M1) 0.007452 sec, 50023 barres calculées, 50023 barres totales

2021.05.28 19:06:00.670 OldTF (EURUSD,M3) 0.000001 sec, calculé 1 barre, total barres 50001

2021.05.28 19:06:02.211 LitTF (EURUSD,M1) 0.008180 sec, 50024 barres calculées, 50024 barres au total

2021.05.28 19:07:00.780 LitTF (EURUSD,M1) 0.000004 sec, calculé 1 barre, total barres 50025

2021.05.28 19:08:01.246 LitTF (EURUSD,M1) 0.000014 sec, réglé 1 barre, total barres 50026

2021.05.28 19:09:00.959 OldTF (EURUSD,M3) 0.00000014 sec, calculé 1 barres, total barres 50002

2021.05.28 19:09:01.775 LitTF (EURUSD,M1) 0.006898 sec, 50027 barres calculées, 50027 barres totales

2021.05.28 19:10:00.830 LitTF (EURUSD,M1) 0.000004 sec, calculé 1 barre, total barres 50028

même à l'œil nu, vous pouvez voir, premièrement, que c'est le moyen le plus rapide de construire des indicateurs rapides et, deuxièmement, que le pré-calcul est mis à zéro.

Dans cet exemple, l'indicateur doit être entièrement recalculé à chaque nouvelle barre M3.

Alexey Viktorov:

Tu n'es pas obligé de le faire.

Les développeurs ne répondent pas à de telles inepties, Igor va vite se lasser aussi... Et reste à parler tout seul...

Il faut juste demander à drubashka de déplacer vos épanchements dans un fil séparé pour ne pas encombrer le bon....

Regardez le code ci-dessus, mangez votre passeport, saupoudrez des cendres sur votre tête et mettez votre orgueil là où personne ne peut le voir.

 
Igor Makanu:

cela ne devrait pas fonctionner correctement dans les indicateurs :

si je ne me trompe pas, dans l'aide il y a une décomposition du script pour paginer les données pour tous les TFs et il devrait y avoir un avertissement que les données historiques ne peuvent pas être demandées à l'indicateur de cette façon, parce que l'indicateur fonctionne de manière asynchrone.

et il est recommandé d'utiliser BarsCalculated() une fois après avoir lié le handle


UPD : script pour la pagination de l'historique et explication pourquoi il ne fonctionne pas dans les indicateurs: https://www.mql5.com/ru/docs/series/timeseries_access

Dans cet article, il est seulement écrit qu'il n'est pas souhaitable de demander des données à partir de timeseries (ou de demander SeriesInfoInteger dans une boucle) dans une indica


"Rappelons que l'envoi d'une demande de mise à jour d'une série temporelle avec la même période quel'indicateur appelant la mise à jour est hautement indésirable. Le caractère indésirable de la requête utilisant la même période de symbole que celle de l'indicateur est dû au fait que la mise à jour des données historiques est effectuée dans le même thread, dans lequel l'indicateur travaille. Par conséquent, il y a une forte probabilité de coincement."


Si nous demandons simplement SeriesInfoInteger et, en cas de faux, sortons de OnCalculate, comment le wedge peut-il se produire ?

Raison: