Fehler, Irrtümer, Fragen - Seite 3027

 
Сергей Таболин:

Indikatoren sind mein größter Schwachpunkt ))))

Aber!

Entweder verstehe ich überhaupt nichts, oder Sie irren sich ein wenig.

Soviel ich weiß, ist prev_calculated ein Zähler für nicht berechnete Daten. Und sobald die eingehenden Daten gezählt sind, wird dieser Zähler zurückgesetzt... Das war's dann wohl, keine neuen Daten mehr zu berechnen.... )))

Und aus welchem Grund der Indikator in einem solchen Fall komplett neu berechnet werden sollte - ich weiß es nicht!

---------------

Ein wenig gelogen ))))

Es sind nicht die Indikatoren, die neu berechnet werden, sondern die "Indizes" werden neu berechnet, damit sie in der Historie "schön" aussehen ;)

der Zähler wird aus Gründen, die sich dem Einfluss des Programmierers entziehen, zurückgesetzt, als ob der Indikator zum ersten Mal gestartet worden wäre!

Ich möchte nicht, dass meine Nachricht inmitten von unverständlichen Erklärungen untergeht, aber sie hat die Entwickler schließlich erreicht.



Wir müssen den Zusammenhang zwischen dem von OnCalculate() zurückgegebenen Wert und dem zweiten Eingabeparameter prev_calculated beachten. Beim Aufruf der Funktion enthält der Parameter prev_calculated einen Wert, der von OnCalculate() beim vorherigen Aufruf zurückgegeben wurde. Dies ermöglicht sparsame Algorithmen für die Berechnung des benutzerdefinierten Indikators, um wiederholte Berechnungen für die Balken zu vermeiden, die sich seit dem letzten Aufruf dieser Funktion nicht verändert haben.

-Eine Berechnung, die nicht richtig funktioniert, macht das ganze Konzept der wirtschaftlichen Berechnung zunichte.
 
Andrey Dik:
Der Zähler wird aus Gründen, die außerhalb der Kontrolle des Programmierers liegen, zurückgesetzt, als ob der Indikator zum ersten Mal laufen würde!

Ich wollte nicht, dass meine Botschaft in dem unverständlichen Beifall untergeht, aber sie erreichte die geschätzten Entwickler.

Ist das bei jeder neuen Bar der Fall? Sie werden doch beruhigt, oder?

Wenn nicht jeder Balken, gibt es verschiedene Gründe für das Zurücksetzen des pre_calc.

 

Forum zum Thema Handel, automatisierte Handelssysteme und Testen von Handelsstrategien

Wanzen, Wanzen, Fragen

Andrey Dik, 2021.05.27 13:53

d.h. der vorberechnete Zähler wird auf Null gesetzt, sobald der neue Zeitrahmenbalken erscheint. Das bedeutet, dass der Indikator neu berechnet wird, als ob er das erste Mal gestartet worden wäre.

Ist Ihnen eine solche Konstruktion bekannt?

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

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

Das Problem liegt nicht in der EA-Logik (Neuzeichnen, Nicht-Neuzeichnen, Unterzeichnen oder was auch immer), sondern in der Tatsache, dass prev_calculated zurückgesetzt wird, obwohl niemand darum gebeten hat, dies zu tun!

Ich denke, das Problem ist:

if (rates_total == prev_calculated) return rates_total;

Sie lassen nicht zu, dass der aufgerufene Indikator auf einer anderen TF jeden Tick berechnet, und dann rufen Sie ihn auf, und die Geschichte wird synchronisiert und die Berechnung von Null dieses Indikators


Ich habe einen Test erstellt. Der aufgerufene Indikator zählt alles und wird nicht auf prev_calculated == 0 zurückgesetzt

Ich habe den Indikator geschlossen und das Ereignis mit einem neuen Takt und prev_calculated == 0 abgewickelt:

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

Rufen Sie diesen Indikator auf (holen Sie die letzten 2 Werte des Puffers) und zeichnen Sie auch Close auf Ihrem 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);
}


hat den letzten Indikator auf M1 ausgeführt, log:

2021.05.27 21:48:34.196 tst_tf (EURUSD,M1) tst_tf Neuer Balken 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) Fehler CopyBuffer # 4806

2021.05.27 21:48:34.197 tst (EURUSD,M5) tst Neuer Balken 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 new bar 2021.05.27 21:49:00

2021.05.27 21:50:00.149 tst_tf (EURUSD,M1) tst_tf Neuer Balken 2021.05.27 21:50:00

2021.05.27 21:50:00.149 tst_tf (EURUSD,M5) tst Neuer Balken 2021.05.27 21:50:00

2021.05.27 21:51:01.789 tst_tf (EURUSD,M1) tst_tf Neuer Balken 2021.05.27 21:51:00

2021.05.27 21:52:02.832 tst_tf (EURUSD,M1) tst_tf Neuer Balken 2021.05.27 21:52:00

2021.05.27 21:53:00.920 tst_tf (EURUSD,M1) tst_tf Neuer Balken 2021.05.27 21:53:00

2021.05.27 21:54:02.778 tst_tf (EURUSD,M1) tst_tf Neuer Balken 2021.05.27 21:54:00

2021.05.27 21:55:00.308 tst_tf (EURUSD,M1) tst_tf Neuer Balken 2021.05.27 21:55:00

2021.05.27 21:55:00.308 tst_tf (EURUSD,M5) tst Neuer Balken 2021.05.27 21:55:00

2021.05.27 21:56:00.118 tst_tf (EURUSD,M1) tst_tf Neuer Balken 2021.05.27 21:56:00

2021.05.27 21:57:00.419 tst_tf (EURUSD,M1) tst_tf Neuer Balken 2021.05.27 21:57:00

 
Andrey Khatimlianskii:

Ist das in jeder neuen Bar so? Sind sie überversichert oder so...

Wenn nicht bei jedem Takt, gibt es verschiedene Gründe für das Zurücksetzen von pre_calc.

genau bei jedem neuen Balken der großen TF.

Wenn der Indikator beispielsweise auf M1 arbeitet und auf den Indikator auf M5 zugreift, dann wird der Indikator alle 5 Minuten komplett neu berechnet.

 
Igor Makanu:

Ich denke, das Problem ist:

Sie lassen nicht zu, dass der aufgerufene Indikator auf einem anderen TF jeden Tick berechnet, und dann rufen Sie ihn auf, und es gibt einen History-Sync und eine Berechnung von Null dieses Indikators


Ich habe einen Test erstellt. Der aufgerufene Indikator zählt alles und wird nicht auf prev_calculated == 0 zurückgesetzt

Ich habe den Indikator geschlossen und das Ereignis mit einem neuen Takt und prev_calculated == 0 abgewickelt:

Rufen Sie diesen Indikator auf (holen Sie die letzten 2 Werte des Puffers) und zeichnen Sie auch Close auf Ihrem TF:

Ich überprüfe die Synchronisierung der Daten auf der angeforderten höheren TF (M5) und die Bereitschaft des Indikators auf dieser, wenn er nicht bereit ist, dann beenden.

Daher funktioniert der Indikator nur einmal beim Öffnen des M1-Balkens und nicht bei jedem 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;

Ich hoffe, dass die Entwickler auf meine Bitten hören werden.

 
Andrey Dik:

Ich überprüfe die Datensynchronisation auf dem angeforderten höheren TF (M5) und die Bereitschaft des Indikators auf diesem, wenn er nicht bereit ist, dann verlasse ich ihn.

Infolgedessen funktioniert der Indikator nur einmal bei der Eröffnung des M1-Balkens, und nicht bei jedem Tick:


Ich hoffe, dass die Entwickler auf meine Bitten hören werden.

sollte dies in Indikatoren nicht korrekt funktionieren:

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

Wenn ich mich nicht irre, gibt es in der Hilfe eine Aufschlüsselung des Skripts für das Paging von Daten für alle TFs und es sollte eine Warnung geben, dass historische Daten nicht vom Indikator angefordert werden können, da der Indikator asynchron arbeitet

und es wird empfohlen, BarsCalculated() einmal zu verwenden, nachdem Sie den Handle gebunden haben


UPD: Skript für History Paging und Erklärung, warum es in Indikatoren nicht funktioniert:https://www.mql5.com/ru/docs/series/timeseries_access

 
Andrey Dik:

Ich überprüfe die Datensynchronisation auf der angeforderten höheren TF (M5) und die Bereitschaft des Indikators auf dieser, wenn er nicht bereit ist, dann beende ich.

Infolgedessen funktioniert der Indikator nur einmal bei der Eröffnung des M1-Balkens, und nicht bei jedem Tick:


Muss ich wirklich meine benutzerdefinierte Vorberechnung verwenden? Ich hoffe, die Entwickler hören auf mein Flehen.

Wozu dient ein solcher Scheck?

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

Es wäre viel einfacher, return 0; ohne Bedingung zu schreiben, und das war's.

Bei jedem neuen Balken wird die Bedingung erfüllt und alle Balken werden unabhängig von der Synchronisation neu berechnet. Sie haben einen unüberlegten Code geschrieben und geben vor, dass es sich um einen Terminalfehler handelt...

 
Ein Kompilierungsfehler:
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];
};
Was ist der grundlegende Unterschied zwischen (1) und (2)?
 
Die Vereinigung mit einem einzigen Feld ist eine seltsame Sache.
 
Alexey Viktorov:

Welchen Sinn hat eine solche Prüfung?

Es wäre einfacher, return 0; ohne Bedingung zu schreiben und das war's...

Die Bedingung wird bei jedem neuen Balken erfüllt, und alle Balken werden unabhängig von der Synchronisierung neu errechnet. Sie haben einen unüberlegten Code geschrieben und ihn als Terminalfehler ausgegeben...

denken Sie noch einmal nach.