prev_calculé - page 6

 
Tu n'as pas besoin de frapper des fers avec des noix.
 
Alexey Viktorov:
Ce n'est PAS dans la documentation ! Par conséquent, il s'agit d'un essai sur un sujet libre. Tout comme ma déclaration sur l'initialisation automatique, encore plus cool. Au moins le mien avait un avertissement...

Il est impossible de décrire absolument tout dans la documentation.

Si "prev_calculate==0" - cela signifie que nous devons parcourir tout le tampon de l'indicateur. Si "prev_calculate!=0", alors seule la barre la plus à droite ou plusieurs nouvelles barres seront calculées (nous utilisons la limite) :

                const int &spread[])
  {
//---
   if(prev_calculated==0)
     {
      Print("prev_calculated==0");
            for(int i=0;i<rates_total;i++)
              {
               //--- здесь принудительно каждому элементу массива присваиваем значение (мне лень писать эти массивы :) )
      
              }
      return(rates_total);
     }
//--- экономный пересчёт только самого правого бара или новых баров
   int limit=rates_total-prev_calculated+1;

//--- а ниже нужно использовать цикл для обсчета самого правого бара или новых баров
   for(int i=0;i<limit;i++)
     {
      ExtBuffer[i]=чевой-то там;
     }
 
Karputov Vladimir:

Il est impossible de décrire absolument tout dans la documentation.

Si "prev_calculate==0" - cela signifie que nous devons parcourir tout le tampon de l'indicateur. Si "prev_calculate!=0", alors seule la barre la plus à droite ou plusieurs nouvelles barres seront calculées (nous utilisons la limite) :

                const int &spread[])
  {
//---
   if(prev_calculated==0)
     {
      Print("prev_calculated==0");
            for(int i=0;i<rates_total;i++)
              {
               //--- здесь принудительно каждому элементу массива присваиваем значение (мне лень писать эти массивы :) )
      
              }
      return(rates_total);
     }
//--- экономный пересчёт только самого правого бара или новых баров
   int limit=rates_total-prev_calculated+1;

//--- а ниже нужно использовать цикл для обсчета самого правого бара или новых баров
   for(int i=0;i<limit;i++)
     {
      ExtBuffer[i]=чевой-то там;
     }




Quelle est la valeur ? Je n'ai pas besoin de valeurs sauf pour la barre la plus à droite. MAIS! !! Ensuite, lorsque ce dernier se déplace vers la gauche, ces données doivent être sauvegardées...

Vous n'êtes pas obligé d'écrire tous les tampons, mais vous pourriez en écrire un en tenant compte de mes souhaits. S'il s'agit de la première exécution, tout l'historique devrait être vide. Si prev_calculé a été remis à zéro suite à un échange d'historique, TOUT ce qui a été mis dans le tampon devrait rester inchangé. Même s'il y a des trous.

 
Karputov Vladimir:

Conclusions préliminaires :

1. Les indicateurs ne peuvent pas compter sur l'initialisation des tableaux d'indicateurs dans OnInit():

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
...
   ArrayInitialize(balance, 0.0);    // принудительная
   ArrayInitialize(equityMax, 0.0);  // инициализация
   ArrayInitialize(equityMaxB, 0.0); // всех
   ArrayInitialize(equityMin, 0.0);  // буферов
   ArrayInitialize(equityMinB, 0.0); // индикатора

...
//---
   return(INIT_SUCCEEDED);
  }

2. Dans les indicateurs, il est obligatoire de passer par le tableau entier ou seulement par les éléments modifiés dans OnCalculate().

Qu'est-ce que vous racontez comme bêtises ? Si cette initialisation est implémentée dans OnCalculate, elle sera initialisée sans aucune boucle. Mais si nous mettons à zéro prev_calculated, cela efface toutes les données qui ont été accumulées pendant le travail...
 
Alexey Viktorov:
Pourquoi dites-vous n'importe quoi ? Si cette initialisation est placée dans OnCalculate, elle est mise à zéro sans aucun cycle. Mais si nous mettons à zéro prev_calculated, cela efface toutes les données qui ont été accumulées pendant l'opération...
Veuillez utiliser des expressions. Et regardez les exemples d'indicateurs de l'ensemble de livraison standard : Catalogue de données\MQL5\Indicateurs\Exemples\.
 
Alexey Viktorov:

Quelle est la valeur ? Je n'ai pas besoin d'une autre valeur que la barre la plus à droite. MAIS! !! Ensuite, lorsque cette dernière se déplace vers la gauche, ces données doivent être sauvegardées...

...

J'ai déjà suggéré un moyen :

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

prev_calculé

Karputov Vladimir, 2016.10.18 15:11

Désolé pour le retard dans la réponse. Le seul moyen d'enregistrer les valeurs calculées pour une période donnée est de les sauvegarder dans un fichier. Vous devez vous occuper de la synchronisation - de sorte que lors de la lecture du fichier, les données soient placées sur leurs barres. La façon la plus logique est de le synchroniser avec l'heure d'ouverture de la barre, mais il peut y avoir quelques nuances : par exemple, l'heure d'ouverture de la barre (enregistrée dans un fichier) était 2016.09.05. 25:02, mais maintenant le graphique a une barre avec une heure égale à 2016.09.05. 25:01.

Un indicateur n'est pas une base de données ou un référentiel.

Par conséquent, si l'indicateur affiche des données qui ne peuvent pas être calculées sur l'historique, il suffit de sauvegarder le tampon de l'indicateur dans un fichier, puis (en cas d'échange d'historique) de lire et de synchroniser le fichier et les barres.
 
Karputov Vladimir:

J'ai déjà suggéré un moyen :

Un indicateur n'est pas une base de données ou un référentiel.

Par conséquent, si l'indicateur affiche les données qui ne peuvent pas être calculées sur l'historique, il suffit de sauvegarder le tampon de l'indicateur dans un fichier, puis (dans le cas de l'échange d'historique) d'effectuer la lecture et de synchroniser le fichier et les barres.

Alexey Viktorov:

... et de préférence sans écrire dans un fichier ou encore plus dans GV.

prev_calculated
prev_calculated
  • www.mql5.com
Форум трейдеров MQL5.community
 

Vladimir, puisque vous avez consacré ce sujet spécifiquement à prev_calculated, rendez-le utile sur ce sujet. Tout d'abord, vous devez préciser le problème qui se pose habituellement avec cette variable. Si vous n'êtes pas familier avec ces problèmes, je vais formuler

---

a-- même si c'est dit dans l'aide

prev_calculated  // обработано баров на предыдущем вызове

La raison en est (c'est écrit dans l'aide et dit par les développeurs) que la variable est remise à zéro lorsque vous changez la somme de contrôle - généralement à cause d'un échange d'historique.

---

b - vous ne pouvez pas non plus utiliser prev_calculated == 0 comme indicateur de la première exécution de onCalculate. Pour la même raison

---

c - et vous ne pouvez pas non plus utiliser prev_calculated == 0 comme indicateur de pagination de l'historique

---

Pour réduire l'usure des utilisateurs, la formulation doit être brève et sans ambiguïté : si la pagination de l'historique a échoué lors de l'appel actuel de OnCalculate, alors prev_calculated contient le nombre de barres traitées lors de l'appel précédent. Si cela s'est produit - il est remis à zéro

---

Les trois problèmes mentionnés peuvent être résolus avec des béquilles. Cependant, puisque MT5 ne peut pas avoir de béquilles par définition, Vladimir, pourriez-vous créer une solution attrayante pour ces trois problèmes ? Un mauvais exemple est quelque chose comme ça :

#property indicator_chart_window
#property indicator_buffers  0
#property indicator_plots    0


struct BROWNIE {
  int   i_Prew_Calculated;  // кол-во посчитанных баров
  bool  b_First_Run;        // флаг первого запуска
  bool  b_History_Updated;  // флаг обновления истории
  
  BROWNIE() {
    i_Prew_Calculated = WRONG_VALUE;
    b_First_Run = true;
    b_History_Updated = false;
  }
  
  void f_Reset(bool b_Reset_First_Run = true) {
    i_Prew_Calculated = WRONG_VALUE;
    if(b_Reset_First_Run) b_First_Run = true;
    b_History_Updated = false;
  }
  
  void f_Update(int i_New_Prew_Calculated = WRONG_VALUE) {
    if(i_New_Prew_Calculated > -1) {
      b_History_Updated = i_New_Prew_Calculated == 0 && i_Prew_Calculated > WRONG_VALUE;
      if(b_First_Run) b_First_Run = false;
      
      if(i_Prew_Calculated == WRONG_VALUE) i_Prew_Calculated = i_New_Prew_Calculated;
      else if(i_New_Prew_Calculated > 0) i_Prew_Calculated = i_New_Prew_Calculated;
    }
  }
};
BROWNIE go_Brownie;


int OnInit(void) {return(INIT_SUCCEEDED);}


void OnDeinit(const int reason) {
  go_Brownie.f_Reset(reason != REASON_CHARTCHANGE);
}



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 &TickVolume[],
    const long &Volume[],
    const int &Spread[]
) {
  if(go_Brownie.b_First_Run) {/* обработка 1го запуска */}
  if(go_Brownie.b_History_Updated) {/* обработка обновления истории */}
  go_Brownie.f_Update(prev_calculated);
  
  return(rates_total);
}

Clause de non-responsabilité : Code - juste une idée, je ne l'ai pas essayé sur un graphique.

Dans OnDeinit il y a un exemple - traitement pour l'indicateur, qui n'utilise pas de tampons, il ne se soucie pas de TF et de symbole, et à chaque changement de TF/symbole il n'y a pas besoin de recommencer à zéro. Par exemple, il fonctionne avec les éléments graphiques existants, produit des informations sur l'état des comptes, les commandes, etc.

---

D'ailleurs

Karputov Vladimir:

Si le tampon de l'indicateur était sauvegardé dans un fichier et ensuite (en cas de pagination de l'historique) il lirait et synchroniserait le fichier et les barres.

Vous n'êtes pas obligé de détruire le disque, vous pouvez le sauvegarder dans un élément du tableau.
 
Alexey Viktorov:
... et de préférence sans écrire dans un fichier ou a fortiori dans un GV.
Cela vous conviendrait-il ?
 
Konstantin Gruzdev:
Peut-être que ça te ferait du bien ?

Je ne suis pas entré dans les détails, mais ce problème est résolu par cette ligne de code. Copie d'un tableau dans lui-même avec un décalage d'index.

double arr[5];
ArrayCopy(arr, arr, 0, 1, 4);
// и дальнейшее заполнение 4го индекса массива.
Vous pouvez l'inverser et copier à partir de l'index zéro et coller à partir du premier. Ensuite, l'index zéro du tableau sera rempli. Et ceci est une chose bien différente...))