Erreurs, bugs, questions - page 3148

 
Roman #:

Cela est dû au fait que l'IndBuff n'est pas alloué à rates_total + 1
et que ArrayResize ne lui est pas applicable.


C'est là que vous avez besoin du moins 1 :))
L'impression montre que les dimensions sont correctes.
Utilisez la logique :
Si la limite = 0, alors il s'agit d'un nouveau tick.
Si la limite = 1, cela signifie une nouvelle barre (le dernier élément du tampon rates_total est -1 et vous avez rates_total - d'où le débordement)
Si la limite > 1, il est préférable de recalculer l'ensemble de l'indicateur.
 
Maxim Kuznetsov #:

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

au minimum...

Tu sais ce qui est le plus ennuyeux ? Que tout comportement est trompé en silence, sans avertissement.
Et puis les gens sont blessés. J'en ai marre de ce metatrader.

 
Roman #:

Tu sais ce qui est le plus ennuyeux ? Que tout comportement est trompé en silence, sans avertissement.
Et puis les gens sont blessés. J'en ai marre de ce metatrader.

Tout est comme avant.
C'est votre faute.
Conseil - apprenez à utiliser le débogueur et vous ne devrez plus faire de relecture, vous verrez toutes vos fautes d'un seul coup.
 
Roman #:

Tu sais ce qui est le plus ennuyeux ? Que tout comportement est trompé en silence, sans avertissement.
Et puis les gens sont blessés. J'en ai marre de ce metatrader.

Je n'ai pas remarqué de changement dans le calcul des indicateurs. Comme vous l'avez vu ci-dessus, Nikolay a expliqué à juste titre ce que signifient les valeurs limites calculées comme rates_total-prev_calculated.

Et ça marche depuis des années - depuis le quatrième terminal.

 
Nikolai Semko #:
C'est là que vous avez besoin du moins un :))
L'impression montre que les dimensions sont correctes.
Utilisez la logique :
Si la limite = 0, alors un nouveau tick
Si limite = 1, cela signifie une nouvelle barre (le dernier élément du tampon rates_total est -1, et vous avez rates_total, d'où le débordement)
Si la limite > 1, il est préférable de recalculer l'ensemble de l'indicateur.

Nikolay je connais les constructions si et pour un,
mais j'ai toujours travaillé avec pour, je m'y suis habitué, c'est plus pratique.
Mais j'ai remarqué des choses étranges depuis longtemps et je n'ai pas cherché à les comprendre.
Il fonctionnait bien avant

pour i>=0 ticks
pour i>0 bars

Et il n'y avait pas besoin de "si".

 
Roman #:



Étape 1 : Créez un modèle en utilisant 'MQL5 Wizard' :

//+------------------------------------------------------------------+
//|                                                       Simple.mq5 |
//|                              Copyright © 2022, Vladimir Karputov |
//|                      https://www.mql5.com/en/users/barabashkakvn |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2022, Vladimir Karputov"
#property link      "https://www.mql5.com/en/users/barabashkakvn"
#property version   "1.00"
#property indicator_chart_window
#property indicator_buffers 1
#property indicator_plots   1
//--- plot Close
#property indicator_label1  "Close"
#property indicator_type1   DRAW_LINE
#property indicator_color1  clrRed
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1
//--- input parameters
input int      Input1=9;
//--- indicator buffers
double         CloseBuffer[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   SetIndexBuffer(0,CloseBuffer,INDICATOR_DATA);
   
//---
   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[])
  {
//---
   
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+


Étape 2 : épellez correctement "limite" et UTILISEZ le tableau de fermeture - PAS l'appel iClose ! !!

//+------------------------------------------------------------------+
//|                                                       Simple.mq5 |
//|                              Copyright © 2022, Vladimir Karputov |
//|                      https://www.mql5.com/en/users/barabashkakvn |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2022, Vladimir Karputov"
#property link      "https://www.mql5.com/en/users/barabashkakvn"
#property version   "1.00"
#property indicator_chart_window
#property indicator_buffers 1
#property indicator_plots   1
//--- plot Close
#property indicator_label1  "Close"
#property indicator_type1   DRAW_LINE
#property indicator_color1  clrRed
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1
//--- input parameters
input int      Input1=9;
//--- indicator buffers
double         CloseBuffer[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   SetIndexBuffer(0,CloseBuffer,INDICATOR_DATA);
//---
   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 limit=prev_calculated-1;
   if(prev_calculated==0)
      limit=0;
   for(int i=limit; i<rates_total; i++)
     {
      CloseBuffer[i]=close[i];
     }
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+


Résultat :

Et il n'y a pas d'erreurs.

Dossiers :
Simple.mq5  5 kb
 
Vladimir Karputov #:

Étape 1 : Créez un modèle en utilisant 'MQL5 Wizard' :


Étape 2 : épellez correctement le mot "limite" et UTILISEZ le tableau de fermeture - PAS l'appel iClose ! !!


Résultat :

et il n'y a pas d'erreurs.

Merci pour l'exemple direct de i++ bien sûr.
Mais le fait que j'aie une boucle inversée, vous ne l'avez pas remarqué.
Et si iClose est cité en exemple, il doit être utilisé pour montrer que l'indice i sera ensuite utilisé dans d'autres fonctions.

 
Roman #:

Nikolaï, je connais les constructions de si et pour un,

sinon si

Nikolai Semko #:
Utilisez la logique :
Si la limite = 0, alors un nouveau tick
Si limite = 1, cela signifie une nouvelle barre (le dernier élément du tampon rates_total est -1, et vous avez rates_total, d'où le débordement)
Si la limite > 1, il est préférable de recalculer l'ensemble de l'indicateur.

c'est ici que
est erroné - il vaut mieux utiliser
if limit != 1

Donc toute la logique est à peu près ce qu'elle est :

limit = rates_total - prev_calculated;
if (limit == 0) {..} // новый тик
else if ( limit == 1) {..} // новый бар
else {..} // полный пересчет всего индикатора
Je comprends que certaines personnes vont s'indigner et dire pourquoi je devrais tout recalculer si limit == 2,
mais lorsque limit n'est pas égal à 1 et n'est pas égal à 0, cela signifie qu'il s'agit de la première initialisation de l'indicateur ou que quelque chose s'est mal passé (par exemple, un échec de connexion ou un échec du serveur)
De plus, j'ai souvent rencontré des situations où prev_calculated était plus grand que rates_total. Il s'agissait probablement d'un problème antérieur qui a été corrigé, mais depuis lors, j'utilise ce modèle par mesure de sécurité.
 
Nikolai Semko #:

si limite != 1

Quelle différence cela fait-il ? Peut-il être inférieur à zéro ?
 
Vladimir Karputov #:

Étape 1 : Créez un modèle en utilisant 'MQL5 Wizard' :


Étape 2 : épellez "limite" correctement et UTILISEZ le tableau de fermeture - PAS l'appel iClose ! !!


Résultat :

et il n'y a pas d'erreurs.

Qui a dit que c'était le seul calcul correct de la limite et de l'indicateur ?

Nous discutons d'un autre calcul de limite et de l'indicateur lui-même - de gauche à droite - depuis le début de l'histoire jusqu'à l'époque actuelle. C'est plus simple et plus évident.

Dans une telle limite calculée (int limit = rates_total - prev_calculated ; if(limit>1) limit=rates_total-1 ;) toutes les données relatives à

  1. s'il s'agit d'un tic actuel,
  2. que ce soit l'ouverture d'un nouveau bar,
  3. s'il s'agit d'un changement de données historiques.

Si le tick actuel (limite==0), alors for(int i=limite ; i>=0 ; i--) { // . } calculera l'indicateur à chaque nouveau tick, et seule la barre zéro sera recalculée.

Si nous ouvrons une nouvelle barre (limite==1), alors for(int i=limite ; i>=0 ; i--) { // ... } effectuera le calcul de la première et de la barre zéro - précédente et nouvellement ouverte.

Si cette histoire change (limite>1), alors for(int i=limite ; i>=0 ; i--) { // ... } va effectuer un recalcul complet de l'indicateur pour tout l'historique disponible (l'historique a été modifié quelque part).

Raison: