Erreurs, bugs, questions - page 3027

 
Andrey Dik:
Le compteur est remis à zéro pour des raisons indépendantes de la volonté du programmeur, comme si l'indicateur fonctionnait pour la première fois !

Je ne voulais pas que mon message se perde dans les applaudissements incompréhensibles, mais il est parvenu aux estimés développeurs.

Est-ce que c'est comme ça sur chaque nouveau bar ? Ils sont rassurés, n'est-ce pas ?

Si ce n'est pas à chaque barre, il y a différentes raisons pour réinitialiser le pre_kalc.

 

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.27 13:53

c'est-à-dire que le compteur pré_calculé est remis à zéro dès que la nouvelle barre de temps apparaît. cela signifie que l'indicateur est recalculé à nouveau comme s'il avait été lancé la première fois.

Cette construction vous est-elle familière ?

if (rates_total == prev_calculated) return rates_total;
  
int startInd = rates_total - prev_calculated;

for (int i = startInd; i >= 0; i--)
{
  //тут считаем индикатор, который обращается к другому индикатору на старшем ТФ
}

le problème n'est pas dans la logique de l'EA (redessiner, ne pas redessiner, sous-dessiner ou autre) mais dans le fait que prev_calculated est remis à zéro alors que personne ne lui a demandé de le faire !

Je pense que le problème est :

if (rates_total == prev_calculated) return rates_total;

Vous ne laissez pas l'indicateur appelé sur un autre TF calculer chaque tick, et ensuite vous l'appelez et l'historique est synchronisé et le calcul à partir de zéro de cet indicateur.


j'ai créé un test. l'indicateur appelé compte tout et ne se réinitialise pas à prev_calculated == 0

J'ai dessiné la fermeture dans l'indicateur et déroulé l'événement avec une nouvelle barre et prev_calculated == 0 :

// tst.mq5

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 start;
   static datetime t = 0;
   if(t != time[rates_total-1])
   {
      t = time[rates_total-1];
      Print(MQLInfoString(MQL_PROGRAM_NAME), " New bar ", t);
   }
   
   if(prev_calculated == 0)
   {
      start = 0;
      ArrayInitialize(Buffer, EMPTY_VALUE);
      Print(MQLInfoString(MQL_PROGRAM_NAME), " prev_calculated == 0");
   }
   else start = prev_calculated - 1;


   for(int i = start; i < rates_total; i++)
   {
      Buffer[i] = close[i];
   }
//--- return value of prev_calculated for next call
   return(rates_total);
}

appelez cet indicateur (obtenez les 2 dernières valeurs du tampon) et dessinez également la fermeture sur votre TF :

input ENUM_TIMEFRAMES TF = PERIOD_M5;
int OnInit()
{
//--- indicator buffers mapping
   SetIndexBuffer(0, Buffer, INDICATOR_DATA);
   ind_handle = iCustom(NULL, TF, "NewFolder\\tst");
//---
   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 start;
   static datetime t = 0;
   if(t != time[rates_total-1])
   {
      t = time[rates_total-1];
      Print(MQLInfoString(MQL_PROGRAM_NAME), " New bar ", t);
   }

   if(prev_calculated == 0)
   {
      start = 0;
      ArrayInitialize(Buffer, EMPTY_VALUE);
      Print(MQLInfoString(MQL_PROGRAM_NAME), " prev_calculated == 0");
   }
   else start = prev_calculated - 1;


   for(int i = start; i < rates_total; i++)
   {
      Buffer[i] = close[i];
   }
   double buf[];
   if(CopyBuffer(ind_handle, 0, 0, 2, buf) < 0) Print("Error CopyBuffer # ",GetLastError());
//--- return value of prev_calculated for next call
   return(rates_total);
}


a exécuté le dernier indicateur sur M1 , log :

2021.05.27 21:48:34.196 tst_tf (EURUSD,M1) tst_tf Nouvelle barre 2021.05.27 21:48:00

2021.05.27 21:48:34.197 tst_tf (EURUSD,M1) tst_tf prev_calculated == 0

2021.05.27 21:48:34.197 tst_tf (EURUSD,M1) Erreur CopyBuffer # 4806

2021.05.27 21:48:34.197 tst (EURUSD,M5) tst Nouvelle barre 2021.05.27 21:45:00

2021.05.27 21:48:34.197 tst (EURUSD,M5) tst prev_calculated == 0

2021.05.27 21:49:01.636 tst_tf (EURUSD,M1) tst_tf nouvelle barre 2021.05.27 21:49:00

2021.05.27 21:50:00.149 tst_tf (EURUSD,M1) tst_tf Nouvelle barre 2021.05.27 21:50:00

2021.05.27 21:50:00.149 tst_tf (EURUSD,M5) tst Nouvelle barre 2021.05.27 21:50:00

2021.05.27 21:51:01.789 tst_tf (EURUSD,M1) tst_tf Nouvelle barre 2021.05.27 21:51:00

2021.05.27 21:52:02.832 tst_tf (EURUSD,M1) tst_tf Nouvelle barre 2021.05.27 21:52:00

2021.05.27 21:53:00.920 tst_tf (EURUSD,M1) tst_tf Nouvelle barre 2021.05.27 21:53:00

2021.05.27 21:54:02.778 tst_tf (EURUSD,M1) tst_tf Nouvelle barre 2021.05.27 21:54:00

2021.05.27 21:55:00.308 tst_tf (EURUSD,M1) tst_tf Nouvelle barre 2021.05.27 21:55:00

2021.05.27 21:55:00.308 tst_tf (EURUSD,M5) tst Nouvelle barre 2021.05.27 21:55:00

2021.05.27 21:56:00.118 tst_tf (EURUSD,M1) tst_tf Nouvelle barre 2021.05.27 21:56:00

2021.05.27 21:57:00.419 tst_tf (EURUSD,M1) tst_tf Nouvelle barre 2021.05.27 21:57:00

 
Andrey Khatimlianskii:

C'est comme ça à chaque nouveau bar ? Ils sont sur-assurés ou quelque chose comme ça...

Si ce n'est pas sur chaque barre, il y a différentes raisons pour réinitialiser pre_calc.

exactement sur chaque nouvelle mesure de la majeure TF.

Par exemple, si l'indicateur fonctionne sur M1 et accède à l'indicateur sur M5, alors toutes les 5 minutes l'indicateur sera complètement recalculé.

 
Igor Makanu:

Je pense que le problème est :

Vous ne laissez pas l'indicateur appelé sur un autre TF calculer chaque tick, puis vous l'appelez et il y a une synchronisation de l'historique et un calcul à partir de zéro de cet indicateur.


j'ai créé un test. l'indicateur appelé compte tout et ne se réinitialise pas à prev_calculated == 0

J'ai dessiné la fermeture dans l'indicateur et déroulé l'événement avec une nouvelle barre et prev_calculated == 0 :

appelez cet indicateur (obtenez les 2 dernières valeurs du tampon) et dessinez également la fermeture sur votre TF :

Je vérifie la synchronisation des données sur le TF supérieur demandé (M5) et la disponibilité de l'indicateur sur celui-ci, s'il n'est pas prêt, alors je quitte.

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.

 
Andrey Dik:

Je vérifie la synchronisation des données sur le TF supérieur demandé (M5) et la disponibilité de l'indicateur sur celui-ci, s'il n'est pas prêt, alors je quitte.

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


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

cela ne devrait pas fonctionner correctement dans les indicateurs :

if (SeriesInfoInteger (Symbol (), tf, SERIES_SYNCHRONIZED))

si je ne me trompe pas, dans l'aide, il y a une description 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 en raison du fait que l'indicateur fonctionne de manière asynchrone.

et il est recommandé d'utiliser BarsCalculated() une fois après avoir lié l'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

 
Andrey Dik:

Je vérifie la synchronisation des données sur le TF supérieur demandé (M5) et la disponibilité de l'indicateur sur celui-ci, s'il n'est pas prêt, alors je quitte.

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


Dois-je vraiment utiliser ma pré-calculation personnalisée ? J'espère que les développeurs écouteront mes supplications.

A quoi sert un tel chèque ?

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

Il serait beaucoup plus simple d'écrire return 0 ; sans condition et c'est tout.

A chaque nouvelle barre, la condition sera remplie et toutes les barres seront recalculées sans tenir compte de la synchronisation. Vous avez écrit un code irréfléchi et vous prétendez que c'est un bug terminal...

 
Une erreur de compilation :
union X1 { //(1) нормально
        char x11[INT_MAX/2+1];
};
union X2 { //(2) Error: 'X2' - struct is too large
        char x21[INT_MAX/2+1];
        char x22[INT_MAX/2+1];
};
Quelle est la différence fondamentale entre (1) et (2) ?
 
L'union avec un seul champ est une chose étrange.
 
Alexey Viktorov:

Quel est l'intérêt d'un tel contrôle ?

Il serait plus facile d'écrire return 0 ; sans condition et c'est tout...

La condition sera remplie à chaque nouvelle barre et toutes les barres seront recalculées indépendamment de la synchronisation. Vous avez écrit un code irréfléchi et l'avez fait passer pour un bug terminal...

réfléchissez encore.

 
fxsaber:
Une union avec un seul champ est une chose étrange.

C'est la même chose que pour la structure, mais l'erreur est plus évidente. Il est même écrit dans la documentation à ce sujet :"Otherwise union behaves as structure".

Union\char\char est également étrange, et aussi pour plus de clarté, mais il peut être réécrit :

union X3 { //(3) Error: 'X2' - struct is too large
        char x31[INT_MAX/2+1];
        int  x32[INT_MAX/8+1];
};
Donc, cela ne semble étrange à personne, non plus.