MT4 iMAOnArray und iBandsOnArray Auswirkungen der Anzahl der Elemente auf die Berechnungen - Seite 2

 
Sergey Efimenko:
Was meinen Sie damit, was ich erwarte? Ich habe oben geschrieben, dass ich 300 letzte (aktuelle) aktuelle Werte benötige, und nicht 300 erste (anfängliche), außerdem, dass ich auf ein Array am Offset 299-0 zugreife, aber Daten am Offset von "Array-Ende" bis "Array-Ende - 300" Werte erhalte (in meinem Fall von 4999 bis 4700), d.h. am Offset 299 ist ein Wert, der am Offset 4999 sein sollte und ebenso am Offset 0 ist ein Wert, der am Offset 4700 sein sollte. Es stellt sich die Frage, welchen Sinn es hat, alte Werte zu berechnen, wenn aktuelle Werte nicht berechnet werden.

Wenn das, was Sie geschrieben haben, eindeutig wäre, gäbe es keine Fragen.

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

Sie wurden gebeten, ein Codebeispiel zu zeigen, während Sie nur ein Fragment eines Beispiels gezeigt haben. Was den Rest angeht, kann man nur vermuten, dass alles im Fluss ist. Bei welchem Wert von i möchten Sie die letzten, aktuellen Werte erhalten? Bei i = 4700 oder wo?

 
Alexey Viktorov:

Wenn das, was Sie geschrieben haben, klar wäre, dann gäbe es keine Fragen.

Sie wurden gebeten, ein Code-Beispiel zu zeigen, und Sie haben nur ein Stückchen Beispiel gezeigt. Über den Rest kann man nur vermuten, dass es sich um eine Schleife handelt. Bei welchem Wert von i wollen Sie die letzten, aktuellen Werte erhalten? Bei i = 4700 oder wo?

Wenn Sie diese Funktionen mit Längenbeschränkung des Berechnungsfeldes in der Praxis verwendet haben, werden Sie verstehen, was ich meine, denn wozu sonst die theoretischen Überlegungen...? Und was ist an meinem Code unklar? Ich habe absolut identische Abschnitte zitiert, mit dem einzigen Unterschied, dass ich im ersten Fall keine Längenbegrenzung für die Berechnung des Arrays verwende. In diesem Fall spielt es überhaupt keine Rolle, welcher Berechnungszeitraum, der Schichtdurchschnitt oder die Mittelwertbildung, verwendet wird, da sie in beiden Fällen identisch sind? Der Wert von "shift" wird, wie ich oben geschrieben habe, ebenfalls genau gleich verwendet. Ersetzen Sie "i" durch Ihre Shift-Variable in der Schleife, ersetzen Sie die Funktion GetValue(i) durch mindestens Open[i], machen Sie die drei genannten Arrays zu 3 Anzeigepuffern des Indikators und sehen Sie, wie die erste und die zweite funktionieren. Hier ist jedoch ein Beispiel für den vollständigen Code der einfachen Variante des Indikators in zwei Varianten zum besseren Verständnis des Problems:

//Das funktioniert gut:
#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); }

//es funktioniert nicht richtig:

#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); }

Nach dem Zeichnen der Indikatoren auf dem Diagramm, gehen Sie an den Anfang (nach links) des Diagramms und Blick auf 1 Indikator von 12 Bars und weiter, es ist der Beginn der "nicht leeren" Füllung von 2 und 3 des Arrays, etwa erinnern die ersten paar Werte, die von 0 abweichen, dann verschieben Sie das Diagramm auf die aktuellen Kurse und schauen Werte ab 300 Bars, so dass die Werte von 2 (unten) Indikator wird gleich denen, die Sie am Anfang des Diagramms von 1 Indikator sah, während in der Idee, sollten die Werte mit dem aktuellen. Ich hoffe, ich habe das deutlich erklärt. Wenn Sie die Diagramme in ein Online-Diagramm einfügen, funktioniert das erste einwandfrei, während das zweite sich selbst überlassen wird.

 
Sergey Efimenko:


Der Code ist nicht nur ungestylt, sondern Sie fügen ihn auch als reinen Text ein. Bitte geben Sie den Code korrekt ein.
 

Ich werde Ihren Code in einer besser lesbaren Form und in einer neuen Notation darstellen (wie lange können wir wirklich noch diesen anachronistischen int start() in Indikatoren verwenden???):

Indikator 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);
  }
//+------------------------------------------------------------------+

Indikator 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);
  }
//+------------------------------------------------------------------+

Und das Ergebnis der Hinrichtung:

Ergebnis

о

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

Wenn Sie diese Funktionen verwendet haben

Wenn ich das nicht getan hätte, würde ich keine Fragen stellen, um die richtige Lösung vorzuschlagen.

Was nützt es, 300 Balken zu nehmen, wenn man eine Periode von 12 berechnen muss? Auch wenn Sie es brauchen, "weil", sollten Sie verstehen, was 12 Elemente in der Berechnung des Durchschnitts sein würde. Und der Hinweis auf die Richtung der Array-Indexierung war sehr richtig.

Führen Sie zum Verständnis Experimente mit manuellen Berechnungen auf Papier oder mit einem Taschenrechner oder in Excel durch.

 

Wenn ich mir die Antworten ansehe, wird mir klar, dass ich hier nur meine Zeit verschwende, indem ich versuche, das Wesen des Problems zu zeigen, und als Antwort die "Schönheit" des Codes erhalte (danke natürlich, aber der vorgeschlagene Code wurde in zwei Minuten geschrieben, nur um das Wesen des Problems zu zeigen, und erfordert keine Lesbarkeit oder andere Umwandlungen)...

Und besonders erfreut über die Antwort vor meinem Beitrag... Welcher Taschenrechner, welche manuellen Berechnungen, welche Indexierung? Liebe Nutzerinnen und Nutzer, bitte verstehen Sie das Wesentliche der Situation, damit Sie nicht nur Ihre Zeit, sondern auch die eines anderen Menschen nicht verschwenden. Bitte lesen Sie meine Beiträge sorgfältig, aber wenn es schwierig ist, werde ich kurz antworten: die Richtung der Indizierung von Array in beiden Fällen ist richtig, die Größe der notwendigen Berechnungen und andere veränderbare Parameter, wie es in primären Code gezeigt wird, ist mit externen Variablen festgelegt, die Variante der Schaffung eigener Funktion wurde oben diskutiert (und es ist eigentlich die einzige richtige Lösung), aber ich wiederhole, ich möchte es von eingebauten MT4 bekommen.

Im Allgemeinen danke Ihnen allen, werde ich zusammenfassen: entweder servicedesk oder eigene Analoga von Funktionen.

 

Und ich bin entmutigt durch die Antwort vor meinem Beitrag...

Wenn Sie so hartnäckig sind, => servicedesk, und sie beantworten solche Fragen nur aus Langeweile, und die haben selten Langeweile.

Lassen Sie es mich noch einmal versuchen...

iMAOnArray() nimmt in Ihrem Fall 300 Balken und berechnet den Durchschnittswert der letzten 12 Balken von dreihundert. Um die ersten 12 Balken zu mitteln, sollten Sie die Array-Indexierung umkehren, ArraySetAsSeries(BufferMA, false); oder nur 12 Balken nehmen.

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

Anstatt zu versuchen zu verstehen, wie es funktioniert und wie man es benutzt, haben Sie einfach behauptet, es funktioniere nicht oder nicht richtig. Und das ist Ihrer Meinung nach nicht richtig.

Wie geht es weiter mit der Schönheit des Codes? Glauben Sie, dass es für jemanden interessant ist, sich beim Lesen Ihres Codes die Augen zu brechen, wenn alles in einer Zeile geschrieben ist? Falsch. Ich habe ihn nicht persönlich gelesen. Danke an den kleinen Trommler, der mehrmals am Tag die Geduld aufbrachte, alle zu dirigieren... an den falschen Ort.

 

Ich wollte sehr "ausführlich" antworten, aber dann, nachdem ich die Beiträge noch einmal gelesen hatte, löschte ich meine Antwort und stellte schließlich fest, dass ich hier nur Zeit vergeude, indem ich dieselbe Sache mehrmals mit anderen Worten erkläre...

PS Alle Dank und wirklich danke "Barabashke" (Vladimir), er tat gut, aber diese ganze Situation war nicht wert, seine Arbeit, ich werde noch dankbarer sein, wenn es nicht schwierig sein wird, einen Screenshot in einem Schlüssel vor, das Hinzufügen einer dritten Option und zeigt, was passieren würde, wenn Sie den Rat, die Richtung der Indizierung ändern folgen. Um die Frage nach der Funktionsweise der Funktion zu klären.

 
Sergey Efimenko:

Ich wollte sehr "ausführlich" antworten, aber dann, nachdem ich die Beiträge noch einmal gelesen hatte, löschte ich meine Antwort und stellte schließlich fest, dass ich hier nur Zeit vergeude, indem ich dieselbe Sache mehrmals mit anderen Worten erkläre...

PS Alle Dank und wirklich danke "Barabashke" (Vladimir), er tat gut, aber diese ganze Situation war nicht wert, seine Arbeit, ich werde noch dankbarer sein, wenn es nicht schwierig sein wird, einen Screenshot in einem Schlüssel vor, das Hinzufügen einer dritten Option und zeigt, was passieren würde, wenn Sie den Rat, die Richtung der Indizierung ändern folgen. Um die Frage nach der Funktionsweise der Funktion zu klären.

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);
  }
//+------------------------------------------------------------------+

Und das Gesamtergebnis:

Optionen 1, 2 und 3

Dateien:
 

Nein, Vladimir. Das ist ein bisschen falsch.

In diesem Fall sollten Sie ArraySetAsSeries(array, false); auf ein Array mit dreihundert Elementen anwenden, bei dem iMAOnArray() berücksichtigt wird. Aber wir sollten besser CopyOpen() anstelle der Füllschleife des Arrays verwenden.

Nach meinem Verständnis ist es bei dieser Variante besser, wenn

   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);
     }