Fehler, Irrtümer, Fragen - Seite 3028

 
fxsaber:
Eine Vereinigung mit einem einzigen Feld ist eine seltsame Sache.

Dies ist dasselbe wie bei struct - nur der Fehler ist offensichtlicher. Es steht sogar in der Dokumentation dazu:"Ansonsten verhält sichunion wie structure".

Union\char\char ist auch seltsam, und auch aus Gründen der Klarheit, aber es kann umgeschrieben werden:

union X3 { //(3) Error: 'X2' - struct is too large
        char x31[INT_MAX/2+1];
        int  x32[INT_MAX/8+1];
};
Es scheint also auch niemandem seltsam zu sein.
 
Andrey Dik:

denken Sie noch einmal nach.

Du musst nachdenken, Andrej. Die Kakerlaken befinden sich in Ihrem Code.

Nun, ich bin heute so geneigt... Ich werde versuchen, in die richtige Richtung zu gehen:

Ein neuer Balken hat sich geöffnet... iBars() hat sich um one...... erhöht, aber die Anzahl der gezählten Balken hat sich nicht geändert. Und das wird sich erst ändern, wenn der neue Balken neu berechnet wird...

Was kommt als Nächstes?

 
Igor Makanu:

sollte dies in Indikatoren nicht korrekt funktionieren:

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 auf diese Weise 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

Sind Sie sicher, dass Sie die Bedeutung des Codes verstehen?

 
Alexey Viktorov:

Du musst nachdenken, Andrej. In Ihrem Code gibt es Kakerlaken.

Nun, ich bin heute so geneigt... Ich werde versuchen, in die richtige Richtung zu gehen:

Ein neuer Balken wurde geöffnet... iBars() wurde um one...... erhöht, aber die Anzahl der gezählten Balken hat sich nicht geändert. Und das wird sich erst ändern, wenn der neue Balken neu berechnet wird...

Was kommt als Nächstes?

mein guter Mann, bitte schreiben Sie mir nicht, Sie sind nicht eingeweiht.

Oder beweisen Sie es mit Code.

 
Andrey Dik:

Sind Sie sicher, dass Sie die Bedeutung des Codes verstehen?

Mit hoher Wahrscheinlichkeit - sicher und verstanden

Sie möchten, dass der Indikator die "höhere TF" synchronisiert, bevor er einen anderen Indikator aufruft

mein Indikator funktioniert, richtig? - können Sie BarsCalculated() hinzufügen - aber wie in den Beispielen der Indikatoren aus der Lieferung, zum Beispiel MACD.mql5


HH: es gibt eine Menge Multitimeframe-Indikatoren in QB. Wenn ich mich daran erinnern muss, was zu tun ist und wie es zu tun ist, suche ich normalerweise nach Indikatoren von Mladen Rakic und schaue seine durch, der Stil der Codierung ist eigenartig (genauer gesagt die Formatierung), aber sie sind 100% funktional

https://www.mql5.com/ru/users/mladen

 
Andrey Dik:

Bitte schreiben Sie mir nicht, Sie sind nicht eingeweiht.

Oder beweisen Sie es mit einem Code.

Na dann, puh, auf dich...

Entwickler reagieren nicht auf solchen Unsinn, Igor wird sich bald langweilen... Und bleiben Sie und reden Sie mit sich selbst...

Bitten Sie Drummer einfach, Ihre Ergüsse in einen separaten Thread zu verschieben ... um den eigentlichen Thread nicht zu überladen...

 

Forum zum Thema Handel, automatisierte Handelssysteme und Testen von Handelsstrategien

Wanzen, Wanzen, Fragen

Andrey Dik, 2021.05.28 05:16

Ich versuche, die Datensynchronisation auf dem angeforderten Zeitrahmen (M5) und die Bereitschaft des Indikators auf sie zu überprüfen, wenn es nicht bereit ist, werde ich 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.

Ich verstehe Ihren Code nicht ganz. Was soll nach "return 0;" beim nächsten Aufruf von OnCalculate geschehen?
 
Alexey Viktorov:

Auch Igor wird sich bald langweilen...

Ich habe einfach den Wunsch zu verstehen

im MT5 gibt es eine Menge Fallstricke bei der Synchronisation, jetzt ist die Frage auch dazu

imho, wenn der Indikator Konstruktionen auf jedem Balken verwendet (Linien, nicht Pfeile)

Dieser Zyklus ist ausreichend für eine wirtschaftliche Berechnung:

for(int i = prev_calculated; i < rates_total; i++)
   {
      Buffer[i] = close[i];
   }

beim ersten Aufruf ist prev_calculated = 0, bei den folgenden Aufrufen werden die neuen Balken neu errechnet


und wenn beide Indikatoren korrekt geschrieben sind, brauchen Sie nichts zusätzlich zu synchronisieren, alles wird funktionieren, das einzige, was übrig bleibt, ist CopyBuffer() mit der erforderlichen Anzahl von Werten des aufgerufenen Indikators zu vergleichen

 
Igor Makanu:

Ich will es einfach herausfinden.

im MT5 gibt es eine Menge Fallstricke bei der Synchronisation, die Frage ist nun auch das

imho, wenn der Indikator eine Konstruktion auf jedem Balken verwendet (Linien, nicht Pfeile)

Dieser Zyklus ist ausreichend für eine wirtschaftliche Berechnung:

beim ersten Aufruf ist prev_calculated = 0, bei den folgenden Aufrufen werden die neuen Balken neu errechnet


und wenn beide Indikatoren korrekt geschrieben sind, brauchen Sie nichts zusätzlich zu synchronisieren, alles wird funktionieren, das einzige, was übrig bleibt, ist CopyBuffer() mit der erforderlichen Anzahl von Werten des aufgerufenen Indikators zu vergleichen

Das ist es, was ich meine. Es wäre in Ordnung, wenn Sie versuchen würden, vor dem ersten Lauf zu synchronisieren, aber auf diese Weise............

 
Igor Makanu:

Ich will es einfach herausfinden.

im MT5 gibt es eine Menge Fallstricke bei der Synchronisation, die Frage ist nun auch das

imho, wenn der Indikator eine Konstruktion auf jedem Balken verwendet (Linien, nicht Pfeile)

Dieser Zyklus ist ausreichend für eine wirtschaftliche Berechnung:

beim ersten Aufruf ist prev_calculated = 0, bei den folgenden Aufrufen werden die neuen Balken neu errechnet


und wenn beide Indikatoren korrekt geschrieben sind, brauchen Sie nichts zusätzlich zu synchronisieren, alles wird funktionieren, das einzige, was übrig bleibt, ist CopyBuffer() mit der erforderlichen Anzahl von Werten des aufgerufenen Indikators zu vergleichen

wenn Sie verstehen und nicht widersprechen wollen, sollten Sie etwas wie den folgenden Code schreiben:

#property indicator_chart_window
#property indicator_buffers 1
#property indicator_plots   1

#property indicator_label1  "I"
#property indicator_type1   DRAW_LINE
#property indicator_color1  clrRed
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1

double         IBuffer[];

int OnInit()
{
   SetIndexBuffer   (0,IBuffer,INDICATOR_DATA);
   ArraySetAsSeries (IBuffer, true);

   return(INIT_SUCCEEDED);
}

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[])
{
   if (rates_total == prev_calculated) return rates_total;
   
   ulong t = GetMicrosecondCount ();
   
   ArraySetAsSeries (high,        true);

   int limit = rates_total - prev_calculated - 1;

   for (int i = limit; i >= 0; i--)
   {
      IBuffer [i] = high [i];
   }

   //----------------------------------------------------------------
   double e = (GetMicrosecondCount () - t) / 1000000.0;
   Print (DoubleToString (e, 6), " sec, рассчитано ", rates_total - prev_calculated, " баров, всего баров ", rates_total);
   return(rates_total);
}
#property indicator_chart_window
#property indicator_buffers 1
#property indicator_plots   1

//--- plot I
#property indicator_label1  "I"
#property indicator_type1   DRAW_LINE
#property indicator_color1  clrRed
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1

input ENUM_TIMEFRAMES  OldTF = PERIOD_M5;

double IBuffer[];
int    Handle = 0;

int OnInit()
{
   SetIndexBuffer   (0,IBuffer,INDICATOR_DATA);
   ArraySetAsSeries (IBuffer, true);

   Handle = iCustom (Symbol (), OldTF, "OldTF.ex5");
   if (Handle == INVALID_HANDLE)
   {
      Print ("Не удалось получить хендл индикатора OldTF.ex5");
      return INIT_FAILED;
   }

   return INIT_SUCCEEDED;
}

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[])
{
   if (rates_total == prev_calculated) return rates_total;

   if (SeriesInfoInteger (Symbol (), OldTF, SERIES_SYNCHRONIZED))
   {
      if (iBars (Symbol (), OldTF) != BarsCalculated (Handle))
      {
        Print ("Индикатор на периоде ", OldTF, " ещё не рассчитан");
        return 0;
      }
   }
   else 
   {
     Print ("Период ", OldTF, " не синхронизирован.");
     return 0;
   }

   ulong t = GetMicrosecondCount ();

   ArraySetAsSeries (high, true);
   ArraySetAsSeries (time, true);

   int limit = rates_total - prev_calculated - 1;

   double buff [];
   int ind = 0;
   for (int i = limit; i >= 0; i--)
   {
      ind = iBarShift (Symbol (), OldTF, time [i], false);
      if (CopyBuffer (Handle, 0, ind, 1, buff) != -1)
      {
        IBuffer [i] = buff [0];
      }
      else
      {
        Print ("Ошибка копирования буфера ", GetLastError ());
        return 0;
      }
   }

   //----------------------------------------------------------------
   double e = (GetMicrosecondCount () - t) / 1000000.0;
   Print (DoubleToString (e, 6), " sec, расcчитано ", rates_total - prev_calculated, " баров, всего баров ", rates_total);
   return(rates_total);
}

Kompilieren Sie beide Codes und führen Sie den zweiten aus. In den Protokollen sehen Sie so etwas, wenn Sie auf M1 und M3 des älteren Indikators laufen:

2021.05.28 19:05:01.408 OldTF (EURUSD,M3) 0.000234 sec, 50000 Bars berechnet, 50000 Bars gesamt

2021.05.28 19:05:03.860 LitTF (EURUSD,M1) 0.007452 sec, 50023 Bars berechnet, 50023 Bars gesamt

2021.05.28 19:06:00.670 OldTF (EURUSD,M3) 0.000001 sec, berechnet 1 bar, total bars 50001

2021.05.28 19:06:02.211 LitTF (EURUSD,M1) 0.008180 sec, 50024 Bars berechnet, 50024 Bars gesamt

2021.05.28 19:07:00.780 LitTF (EURUSD,M1) 0.000004 sec, berechnet 1 bar, total bars 50025

2021.05.28 19:08:01.246 LitTF (EURUSD,M1) 0.000014 sec, abgewickelt 1 bar, total bars 50026

2021.05.28 19:09:00.959 OldTF (EURUSD,M3) 0.00000014 sec, berechnet 1 Balken, Balken gesamt 50002

2021.05.28 19:09:01.775 LitTF (EURUSD,M1) 0.006898 sec, 50027 Bars berechnet, insgesamt 50027 Bars

2021.05.28 19:10:00.830 LitTF (EURUSD,M1) 0.000004 sec, berechnet 1 bar, total bars 50028

selbst mit bloßem Auge kann man erkennen, dass erstens die schnellstmögliche Art und Weise, schnelle Indikatoren zu erstellen, und zweitens, dass die Vorberechnung auf Null gesetzt ist

In diesem Beispiel wird der Indikator gezwungen, bei jedem neuen Takt M3 komplett neu berechnet zu werden.

Alexey Viktorov:

Das müssen Sie aber nicht tun.

Entwickler reagieren nicht auf solchen Unsinn, Igor wird sich auch bald langweilen... Und bleiben Sie und reden Sie mit sich selbst...

Ich muss drubashka nur bitten, deine Ergüsse in einen anderen Thread zu verschieben, um den richtigen nicht zu verstopfen...

Schauen Sie sich den obigen Code an, essen Sie Ihren Pass, streuen Sie Asche auf Ihr Haupt und schieben Sie Ihre Hybris dorthin, wo sie niemand sehen kann.