Zum Inhalt springen
View in the app

A better way to browse. Learn more.

#T/N/X/T

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

Arrays beim umschalten der Zeitbasis

Geschrieben

Hallo,

 

was passiert eigenlich mit Arrays/Variablen in Indikatoren, wenn ich in einem Chart die Zeitbasis ändere?

 

Hintergrund meiner Frage:

Ich habe im ZigZag-Indikator folgendes Konstrukt gefunden:

 

   if (counted_bars==0 && downloadhistory) 
 {
  ArrayInitialize(ZigzagBuffer,0.0);
  ArrayInitialize(HighMapBuffer,0.0);
  ArrayInitialize(LowMapBuffer,0.0);
 }
  if (counted_bars==0) 
 {
  limit=Bars-ExtDepth;
  downloadhistory=true;
 }

 

downloadhistory wird in der Init-Funktion mit "false" initialisiert.

Ich wäre jetzt davon ausgegangen, dass die if-Bedingung von (counted_bars==0 && downloadhistory) nie erfüllt würde.

Hab dann aber nach den ArrayInitialize-Aufrufen einen Alert gesetzt und beim Umschalten der Zeitbasis z.B. von H1 auf M1

wird tatsächlich eine Meldung ausgegeben. Ich dachte immer beim Umschalten der Zeitbasis würde die Init-Funktion neu aufgerufen.

 

Kann mir jemand erklären, was hierbei genau abläuft?

Was passiert beispielsweise mit meinen verwendeten Variablen? Bleibt deren Wert erhalten?

Bleiben die Arrays mit ihren ursprünglichen Werten/Größe erhalten?

 

Vielen Dank,

WOGO

Bearbeitet von whipsaw
code tags eingefügt

Featured Replies

Geschrieben

Hallo, WOGO

Das ist gut, dass du so tief in die Materie reinschaust

und jede Kleinigkeit zu verstehen versuchst.

 

Tatsächlich ist es auch, dass bei jedem switscgen auf ein anderes TF die Funktion init() erneut aufgerufen wird.

Das funktioniert auch ...

In deinem Beispiel schaltest du von M30 auf M1 - in diesem Moment, wenn sich eine neue Kerze

gebildet hat, wird die Variable IndicatorCounted() auf NULL gesetzt und Indikator neu berechnet.

Hier wird natürlich nicht erneut init() augerufen, da wir uns momentan in der Funktion start() befinden.

Es folgt also solange die Neuberechnung bis die hostorische Daten vollständig geladen wurden.

Hier steckt also der Auslöser für dein ALert.

Die Variablen werden nach dem Umschalten auf anderes TF neuinitialisert ( ausser globalen ) und die Arrays werden ohnehin neuinitialisiert und neuberechnet.

Ich würde für deinen Fall einfach den standarten Konstrukt nehmen

 int limit;
int counted_bars = IndicatorCounted();
//---- check for possible errors
if(counted_bars < 0) return(-1);
//---- last counted bar will be recounted
if(counted_bars > 0) counted_bars--;
limit = Bars - counted_bars;

 

Ich habe für dich einen kleinen Code zur Überprüfung geschrieben:

#property indicator_chart_window

bool downloadhistory;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
 {
//---- indicators
downloadhistory = false;
Print("__INIT__");
//----
  return(0);
 }
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit()
 {
//----
  
//----
  return(0);
 }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start()
 { 
  int    counted_bars=IndicatorCounted();

  if (counted_bars==0 && downloadhistory)
    {
     Alert("__ALERT__!");
    }
  if (counted_bars==0)
    { 
     downloadhistory=true;
    }
 //---  
   Print("__START__","  counted_bars: ",counted_bars,
              "  downloadhistory: ",downloadhistory);
 //---
 }
//+------------------------------------------------------------------+

Geschrieben
  • Autor

Hallo titanfx,

 

vielen Dank für die schnelle äußerst Kompetente Hilf. Bin echt baff.

 

Ich faß nochmal zusammen.

Der Indikator wird gestartet, Init wird ausgeführt, dann springt das Program zu Start. IndicatorCounted() liefert 0.

Dann wird der Indikator für alle historischen Daten berechnet

z.B. mit :

 

for(shift=limit; shift>=0; shift--)
{
 //Indikatorberechnung
}

 

Danach wartet der Indikator auf einen neuen Tick.

Wenn der kommt sollte IndicatorCounted() Bars entsprechen.

Bildet sich dann eine neue Kerze, erhöht sich IndicatorCounted() um 1.

Die obrige Schleife wird dabei jeweils 1x durchlaufen.

 

So,

jetzt schalte ich die Zeitbasis um z.B. von M30 auf M1.

Daraufhin wird deinit() ausgeführt, dann wieder init() und dann Start()

Genau hier sollte IndicatorCounted() wieder 0 sein. Soweit klar.

Alle Variablen und Arrays sind jetzt zurückgesetzt.

In meinem Eingangsbeispiel wird nun downloadhistory auf true gesetzt (weil

counted_bars ja auf 0 steht) und der

Indikator wieder für alle historischen Werte von M1 neu berechnet.

Start wird dann verlassen und beim nächsten Tick wieder gestartet.

 

Hier setzt es bei mir leider aus.

Jetzt sollte IndicatorCounted doch auf Bars stehen. Warum wird dann aber

beim nächsten Durchlauf die Bedingung (counted_bars==0 && downloadhistory) erfüllt.

Irgendwo hab ich da einen Denkfehler.

Vielleicht kannst du mir nochmal einen Tip geben.

 

Danke,

Wogo

Bearbeitet von whipsaw
code <> eingefügt

Geschrieben

Danach wartet der Indikator auf einen neuen Tick.

Wenn der kommt sollte IndicatorCounted() Bars entsprechen.

Bildet sich dann eine neue Kerze, erhöht sich IndicatorCounted() um 1.

Die obrige Schleife wird dabei jeweils 1x durchlaufen.

 

Erstmal kurz tur IndicatorCounted():

IndicatorCounted() ist immer gleich Bars-1.

Aussnahme ist nur wenn sich die neue Kerze ausgebildet hat,

dann hat IndicatorCounted() nur für diesen Agenblick den Wert Bars-2

Geschrieben
  • Autor

Stimmt!

Das war ein Denkfehler meinerseits. IndicatorCounted() gibt ja die Anzahl der sich nicht geänderten Bars seit dem letzten Indikatoraufruf -1 zurück.

 

Dann nochmal:

Wenn mein Indikator also 1x durchlaufen wurde steht counted_bars beim nächsten Tick auf Bars - 1.

downloadhistory ist hier bereits true.

Schalt ich nun aber die Zeitbasis um wird doch counted_bars wieder auf 0 gesetzt und da alle Variable ja neu initialisiert werden ist doch downloadhistory

wieder false.

Wie kann dann aber

 

if (counted_bars==0 && downloadhistory)

 

erfüllt sein???

Geschrieben
Jetzt sollte IndicatorCounted doch auf Bars stehen. Warum wird dann aber

beim nächsten Durchlauf die Bedingung (counted_bars==0 && downloadhistory) erfüllt.

 

Beim Umschalten auf ein anderes Timeframe werden die Funktionen (wie du schon richtig sagtest)

deinit(), init() und start() ausgeführt.

Also nach dem Durchgang von der start() werden alle Indicatorbuffers berechnet, die Variable downloadhistory auf true gesetzt und es sollte beim nächsten Tick wie man auch erwartet IndicatorCounted() gleich Bars-1 sein.

Das geschieht auch in den mesten Fällen, ausser in deinem Fall, wo die veraltete Daten aktualisiert worden.

Da die Daten heruntergeladen und aktualisiert werden, wird Indicatorcounted() wieder auf NULL zurückgesetzt und die Bedienung

if(counted_bars==0 && downloadhistory)
    {
     Alert("__ALERT__!");
    }

wird wahr, Alert wird ausgegeben!

Das geschieht solange, bis die Daten volständig aktualisert werden.

Hier ist ein Auszg aus der Logdatei:

ttt.png

Hier sieht man, dass bei den ersten 3 Durchgängen der Funktion start() die Funktion IndicatorCounted() ständig auf NULL zurückgesetzt war, weil es immer neue Bars heruntergeladen wurden.

Das ist ein Sonderfall, weil die Daten zu den alten Daten hinzugefügt werden

und die Berechnung für alle Bars wiederholt werden muss.

Wenn man durch alle Timeframes geschaltet hat und somit die aktuellen Daten für den jeweiligen Währungspaar hat,

tritt dieser Effekt nicht mehr auf.

 

Hier ist noch mal Stückchen Code für den Indikator ur Überprüfung

#property indicator_chart_window

bool downloadhistory; 

int init() {
  downloadhistory = false; 
  Print("__INIT__");
}

int deinit() {
  Print("__DEINIT__");
} 

int start() { 
  Print("__START__");
  int counted_bars=IndicatorCounted();

  if (counted_bars==0 && downloadhistory)
    {
     Alert("__ALERT__!");
    }
  if (counted_bars==0)
    { 
     //Print("__DL_HISTORY____TRUE");
     downloadhistory=true;
    }
   static int cnt;
   if(cnt < 10) {
     cnt++;
     Print(cnt,". Bars: ",Bars,"   IndicatorCounted: ",IndicatorCounted()); 
   }
 /*  
   Print("__START__","  counted_bars: ",counted_bars,
              "  downloadhistory: ",downloadhistory);
 */
 }
//+------------------------------------------------------------------+

Geschrieben
  • Autor

Aha!

 

dass historische Daten zu Beginn des Umschaltens nachgeladen werden, hab ich mir schon gedacht,

dass allerdings dabei IndicatorCounted() 0 zurück liefert war mir komplett neu.

 

Das erklärt auch ein Problem mit einem Indikator, das ich seit längerer Zeit zu lösen versuche.

Ich fülle einen Buffer mit Werten aus den Extremas des Charts und zeichne dann die Verbindung

mit DRAW_SECTION. Werte zwischen den Extremas bleiben im Buffer leer.

Nun hatte ich immer das Problem, dass beim Aufmachen des Charts die Kurve kurzzeitig korrekt

war, dann aber komplett verschoben wurde und neue, völlig unpassende, Punkte eingefügt wurden.

Das kam einfach daher, dass mein Index-Handling nicht bedachte, dass IndicatorCounted mehrmals

0 sein kann und alle Werte basierend auf den "verschobenen" Chart neu berechnet wurden.

Es kamen somit Werte in den Buffer, die real garnicht existent waren.

 

Vielen Dank titanfx, du hast mir wirklich sehr geholfen!

Wogo

Dein Kommentar

Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.

Gast
Auf dieses Thema antworten...

Account

Navigation

Suche

Suche

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.