MT4 iMAOnArray et iBandsOnArray : effet du nombre d'éléments sur les calculs - page 2

 
Sergey Efimenko:
Que voulez-vous dire, qu'est-ce que j'attends ? J'ai écrit plus haut que j'avais besoin de 300 dernières valeurs réelles (actuelles), et non de 300 premières (initiales). De plus, j'accède à un tableau à l'offset 299-0, mais je reçois des données à l'offset de "fin de tableau" à "fin de tableau - 300" valeurs (dans mon cas de 4999 à 4700), c'est-à-dire qu'à l'offset 299 se trouve la valeur qui devrait être à l'offset 4999 et de même à l'offset 0 se trouve la valeur qui devrait être à l'offset 4700. La question est de savoir à quoi sert de calculer les anciennes valeurs, alors que les valeurs actuelles ne sont pas calculées.

Si c'était clair d'après ce que vous avez écrit, il n'y aurait pas de questions.

double  iMAOnArray(
   double       array[],          // массив               // С этим понятно...
   int          total,            // количество элементов // Это у тебя 300
   int          ma_period,        // период               // Это ???
   int          ma_shift,         // сдвиг средней        // понятно
   int          ma_method,        // метод усреднения     // понятно
   int          shift             // сдвиг                // А здесь чему равна i???
   );

On vous a demandé de montrer un échantillon de code, mais vous n'avez montré qu'un fragment d'exemple. Pour le reste, on ne peut que supposer que tout est dans la boucle. À quelle valeur de i voulez-vous obtenir les dernières valeurs, les valeurs actuelles ? A i = 4700 ou où ?

 
Alexey Viktorov:

Si c'était clair d'après ce que vous avez écrit, alors il n'y aurait pas de questions.

On vous a demandé de montrer un exemple de code et vous n'avez montré qu'un morceau d'exemple. Pour le reste, on ne peut que supposer qu'il s'agit d'une boucle. À quelle valeur de i voulez-vous obtenir les dernières valeurs, les valeurs actuelles ? A i = 4700 ou où ?

Si vous avez utilisé ces fonctions avec une limitation de la longueur du tableau de calcul dans la pratique, vous comprendrez ce que je veux dire, sinon à quoi sert le raisonnement théorique... ? Et qu'est-ce qui n'est pas clair dans mon code ? J'ai cité des sections absolument identiques avec la seule différence que dans le premier cas je n'utilise pas la limitation de longueur pour le calcul du tableau. Dans ce cas, la période de calcul importe peu, qu'il s'agisse de la moyenne de l'équipe ou de la méthode de calcul de la moyenne, car elles sont les mêmes dans les deux cas ? La valeur de shift, comme je l'ai écrit plus haut, est utilisée exactement de la même manière. Remplacez "i" par votre variable shift dans la boucle, remplacez la fonction GetValue(i) par au moins Open[i], faites des trois tableaux mentionnés 3 tampons d'affichage de l'indicateur et voyez comment le premier et le second fonctionnent. Cependant, voici un exemple du code complet de la variante simple de l'indicateur en deux variantes pour mieux comprendre le problème :

//cela fonctionne bien :
#property strict
#property indicator_separate_window
#property indicator_buffers 3
#property  indicator_color1 clrYellow
#property  indicator_color2 clrGreen
#property  indicator_color3 clrRed
double Buffer[],BufferMA[],BufferBMA[]; bool firstrun=true;
int init() { firstrun=true; SetIndexBuffer(0,Buffer); SetIndexBuffer(1,BufferMA); SetIndexBuffer(2,BufferBMA); return(0); }
int start() { int i,limit; int counted_bars=IndicatorCounted(); if(counted_bars<0) return(-1); if(counted_bars>0) counted_bars--; limit=Bars-counted_bars-1;
   if(firstrun) {ArrayInitialize(Buffer,Open[Bars-1]); ArrayInitialize(BufferMA,Open[Bars-1]); ArrayInitialize(BufferBMA,Open[Bars-1]); firstrun=false; }
   for(i=limit; i>=0; i--) { Buffer[i]=Open[i]; BufferMA[i]=iMAOnArray(Buffer,0,12,0,0,i); BufferBMA[i]=iBandsOnArray(Buffer,0,12,2,0,MODE_MAIN,i); }
return(0); }

//il ne fonctionne pas correctement :

#property strict
#property indicator_separate_window
#property indicator_buffers 3
#property  indicator_color1 clrYellow
#property  indicator_color2 clrGreen
#property  indicator_color3 clrRed
double Buffer[],BufferMA[],BufferBMA[]; bool firstrun=true;
int init() { firstrun=true; SetIndexBuffer(0,Buffer); SetIndexBuffer(1,BufferMA); SetIndexBuffer(2,BufferBMA); return(0); }
int start() { int i,limit; int counted_bars=IndicatorCounted(); if(counted_bars<0) return(-1); if(counted_bars>0) counted_bars--; limit=Bars-counted_bars-1;
   if(firstrun) {ArrayInitialize(Buffer,Open[Bars-1]); ArrayInitialize(BufferMA,Open[Bars-1]); ArrayInitialize(BufferBMA,Open[Bars-1]); firstrun=false; }
   for(i=limit; i>=0; i--) { Buffer[i]=Open[i]; BufferMA[i]=iMAOnArray(Buffer,300,12,0,0,i); BufferBMA[i]=iBandsOnArray(Buffer,300,12,2,0,MODE_MAIN,i);  }
return(0); }

Après avoir dessiné les indicateurs sur le graphique, allez au début (à gauche) du graphique et regardez l'indicateur 1 à partir de 12 barres et plus, c'est le début du remplissage "non vide" de 2 et 3 du tableau, souvenez-vous approximativement des premières valeurs qui diffèrent de 0, puis déplacez le graphique vers les cotations actuelles et regardez les valeurs à partir de 300 barres, ainsi les valeurs de l'indicateur 2 (en bas) seront égales à celles que vous avez vues au début du graphique de l'indicateur 1, tandis que dans l'idée, les valeurs devraient correspondre à celles actuelles. J'espère l'avoir expliqué clairement. De même, si vous mettez les cartes sur un tableau en ligne, la première fonctionnera bien et la seconde "s'accrochera toute seule".

 
Sergey Efimenko:


Non seulement le code n'est pas stylisé, mais vous insérez le code comme du texte brut. Veuillez insérer le code correctement.
 

Je vais présenter votre code sous une forme plus lisible et dans une nouvelle notation (vraiment, combien de temps encore pouvons-nous utiliser cet anachronique int start() dans les indicateurs ???):

Indicateur 1 :

//+------------------------------------------------------------------+
//|                                                         Test.mq4 |
//|                        Copyright 2015, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2015, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict
#property indicator_separate_window
#property indicator_buffers 3
#property  indicator_color1 clrYellow
#property  indicator_color2 clrGreen
#property  indicator_color3 clrRed
double Buffer[];
double BufferMA[];
double BufferBMA[];
bool firstrun=true;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   firstrun=true;
   SetIndexBuffer(0,Buffer,INDICATOR_DATA);
   SetIndexBuffer(1,BufferMA,INDICATOR_DATA);
   SetIndexBuffer(2,BufferBMA,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 i,limit;
   limit=rates_total-prev_calculated-1;
   if(prev_calculated==0)
     {
      ArrayInitialize(Buffer,open[rates_total-1]);
      ArrayInitialize(BufferMA,open[rates_total-1]);
      ArrayInitialize(BufferBMA,open[rates_total-1]);
     }
   for(i=limit; i>=0; i--)
     {
      Buffer[i]=open[i];
      BufferMA[i]=iMAOnArray(Buffer,0,12,0,MODE_SMA,i);
      BufferBMA[i]=iBandsOnArray(Buffer,0,12,2,0,MODE_MAIN,i);
     }
   return(rates_total);
  }
//+------------------------------------------------------------------+

Indicateur 2 :

//+------------------------------------------------------------------+
//|                                                         Test.mq4 |
//|                        Copyright 2015, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2015, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict
#property indicator_separate_window
#property indicator_buffers 3
#property  indicator_color1 clrYellow
#property  indicator_color2 clrGreen
#property  indicator_color3 clrRed
double Buffer[];
double BufferMA[];
double BufferBMA[];
bool firstrun=true;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   firstrun=true;
   SetIndexBuffer(0,Buffer,INDICATOR_DATA);
   SetIndexBuffer(1,BufferMA,INDICATOR_DATA);
   SetIndexBuffer(2,BufferBMA,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 i,limit;
   limit=rates_total-prev_calculated-1;
   if(prev_calculated==0)
     {
      ArrayInitialize(Buffer,open[rates_total-1]);
      ArrayInitialize(BufferMA,open[rates_total-1]);
      ArrayInitialize(BufferBMA,open[rates_total-1]);
     }
   for(i=limit; i>=0; i--)
     {
      Buffer[i]=open[i];
      BufferMA[i]=iMAOnArray(Buffer,300,12,0,MODE_SMA,i);
      BufferBMA[i]=iBandsOnArray(Buffer,300,12,2,0,MODE_MAIN,i);
     }
   return(rates_total);
  }
//+------------------------------------------------------------------+

Et le résultat de l'exécution :

Résultat

о

Dossiers :
Test.mq4  3 kb
Test300.mq4  3 kb
 
Sergey Efimenko:

Si vous avez utilisé ces fonctions

Si je ne l'avais pas fait, je ne poserais pas de questions afin de proposer la bonne solution.

Quel est l'intérêt de prendre 300 mesures si vous devez calculer une période de 12 ? Même si vous en avez besoin "parce que", vous devez comprendre quels sont les 12 éléments qui entrent dans le calcul de la moyenne. Et l'indication sur la direction de l'indexation des tableaux était très correcte.

Pour comprendre, faites des expériences de calcul manuel sur papier ou sur une calculatrice, ou dans Excel.

 

Quand je regarde les réponses, je me rends compte que je ne fais que perdre mon temps ici, en essayant de montrer l'essence du problème, et en obtenant la "beauté" du code en réponse (merci bien sûr, mais le code proposé a été écrit en deux minutes juste pour montrer l'essence du problème et ne nécessite aucune lisibilité ou autre conversion)...

Et surtout ravi de la réponse qui précède mon post... Quelle calculatrice, quels calculs manuels, quelle indexation ? Chers utilisateurs, veuillez comprendre l'essence de la situation afin de ne pas perdre non seulement votre temps mais aussi celui de quelqu'un d'autre. S'il vous plaît relire mes messages attentivement, mais si c'est difficile, je vais répondre brièvement : la direction de l'indexation du tableau dans les deux cas est correcte, la taille des calculs nécessaires et d'autres paramètres modifiables, comme il est montré dans le code primaire est fixé avec des variables externes, la variante de la création de la fonction propre a été discuté ci-dessus (et il est effectivement la seule solution correcte), mais je veux répéter, je veux l'obtenir à partir de MT4 intégré.

En général, je vous remercie tous, je vais résumer : soit servicedesk ou propres analogues de fonctions.

 

Et je suis découragé par la réponse qui précède mon message...

Si vous êtes si têtu, => servicedesk, et ils ne répondent à ce genre de questions que par ennui, et ils s'ennuient rarement.

Laissez-moi essayer à nouveau...

iMAOnArray() prend, dans votre cas, 300 barres et calcule la valeur moyenne des 12 dernières barres sur 300. Pour calculer la moyenne des 12 premières barres, vous devez inverser l'indexation du tableau, ArraySetAsSeries(BufferMA, false) ; ou prendre seulement 12 barres.

BufferMA[i]=iMAOnArray(Buffer,12,12,0,MODE_SMA,i);

Il s'avère donc qu'au lieu d'essayer de comprendre comment il fonctionne et comment l'utiliser, vous avez simplement déclaré qu'il ne fonctionne pas ou qu'il fonctionne mal. Et ce n'est pas bien selon vous.

Qu'en est-il de la beauté du code ? Vous pensez qu'il est intéressant pour quelqu'un de se casser les yeux en lisant votre code quand il est tout écrit en une seule ligne ? Faux. Je ne l'ai pas lu personnellement. Merci au petit batteur pour sa patience plusieurs fois par jour pour diriger tout le monde... au mauvais endroit.

 

Je voulais répondre très "en détail", mais ensuite, après avoir relu les messages, j'ai supprimé ma réponse, et j'ai finalement réalisé que je ne faisais que perdre du temps ici, en expliquant la même chose plusieurs fois avec des mots différents...

PS Tous les remerciements et vraiment merci "Barabashke" (Vladimir), il a bien fait, mais toute cette situation ne vaut pas son travail, je serai encore plus reconnaissant s'il ne sera pas difficile de faire, une capture d'écran dans une clé précédente, en ajoutant une troisième option et en montrant ce qui se passerait si vous suivez le conseil de changer la direction de l'indexation. Pour mettre un terme à la question du fonctionnement de la fonction.

 
Sergey Efimenko:

Je voulais répondre très "en détail", mais ensuite, après avoir relu les messages, j'ai supprimé ma réponse, et j'ai finalement réalisé que je ne faisais que perdre du temps ici, en expliquant la même chose plusieurs fois avec des mots différents...

PS Tous les remerciements et vraiment merci "Barabashke" (Vladimir), il a bien fait, mais toute cette situation ne vaut pas son travail, je serai encore plus reconnaissant s'il ne sera pas difficile de faire, une capture d'écran dans une clé précédente, en ajoutant une troisième option et en montrant ce qui se passerait si vous suivez le conseil de changer la direction de l'indexation. Pour mettre un terme à la question du fonctionnement de la fonction.

Option 3 :

//+------------------------------------------------------------------+
//|                                         Test300AsSeriesFalse.mq4 |
//|                        Copyright 2015, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2015, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict
#property indicator_separate_window
#property indicator_buffers 3
#property  indicator_color1 clrYellow
#property  indicator_color2 clrGreen
#property  indicator_color3 clrRed
double Buffer[];
double BufferMA[];
double BufferBMA[];
bool firstrun=true;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   firstrun=true;
   SetIndexBuffer(0,Buffer,INDICATOR_DATA);
   SetIndexBuffer(1,BufferMA,INDICATOR_DATA);
   SetIndexBuffer(2,BufferBMA,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[])
  {
//---
   ArraySetAsSeries(open,false);
//---
   int i,limit;
   limit=rates_total-prev_calculated-1;
   if(prev_calculated==0)
     {
      ArrayInitialize(Buffer,open[rates_total-1]);
      ArrayInitialize(BufferMA,open[rates_total-1]);
      ArrayInitialize(BufferBMA,open[rates_total-1]);
     }
   for(i=limit; i>=0; i--)
     {
      Buffer[i]=open[i];
      BufferMA[i]=iMAOnArray(Buffer,300,12,0,MODE_SMA,i);
      BufferBMA[i]=iBandsOnArray(Buffer,300,12,2,0,MODE_MAIN,i);
     }
   return(rates_total);
  }
//+------------------------------------------------------------------+

Et le résultat global :

Options 1, 2 et 3

Dossiers :
 

Non, Vladimir. C'est un peu faux.

Dans ce cas, vous devez appliquer ArraySetAsSeries(array, false) ; à un tableau de trois cents éléments parmi lesquels iMAOnArray() est considéré. Mais nous ferions mieux d'utiliser CopyOpen() au lieu de la boucle de remplissage du tableau.

Si je comprends bien, dans cette variante, il sera préférable de

   for(i=limit; i>=0; i--)
     {
      Buffer[i]=open[i];
      BufferMA[i]=iMAOnArray(Buffer,12,12,0,MODE_SMA,i);
      BufferBMA[i]=iBandsOnArray(Buffer,12,12,2,0,MODE_MAIN,i);
     }
Raison: