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.

Candle Counter

Geschrieben

Hallo Leute,

 

ich bin wieder mal dabei, etwas rumzubasteln. Die Idee ist folgende: der Indikator soll mir innerhalb eines bestimmten Rahmens anzeigen, wie viele der letzten bspw. 10 Kerzen grün und wie viele rot waren. Dazu soll er noch die durchschnittlichen Punkte berechnen. Ich habe nun schon ein wenig rumprobiert, aber er macht noch nicht das, was er soll. Die Berechnungen scheinen nicht zu stimmen und gemalt wird auch nicht. Wenn jemand also auf Anhieb schon einen groben Fehler findet, freue ich mich über einen kleinen Hinweis.

 

Ich vermute mal, dass es auch mit den Buffern zusammenhängt.

 

 

//+----------------------------------------------------+
//|		   			CandleCounter.mq4 |
//+----------------------------------------------------+

#property copyright "conglom-o"

#property indicator_separate_window
#property indicator_buffers 4
#property indicator_minimum -10
#property indicator_maximum 10

extern int Candles = 10;

//---- buffers
int GreenCandles, RedCandles;
double GreenAvg, RedAvg;
double GreenSum, RedSum;
  
//+------------------------------------------------------------------+
//| Custom indicator initialization function					|
//+------------------------------------------------------------------+
int init()
 {
//---- indicators
 IndicatorBuffers(4);
 SetIndexStyle(0,DRAW_LINE,STYLE_SOLID,EMPTY,Green);
 SetIndexBuffer(0,GreenCandles);
 SetIndexStyle(1,DRAW_LINE,STYLE_SOLID,EMPTY,Red);
 SetIndexBuffer(1,RedCandles);
 SetIndexStyle(2,DRAW_LINE,STYLE_DOT,EMPTY,Green);
 SetIndexBuffer(2,GreenAvg);
 SetIndexStyle(3,DRAW_LINE,STYLE_DOT,EMPTY,Red);
 SetIndexBuffer(3,RedAvg);

 return(0);
 }
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function				|
//+------------------------------------------------------------------+
int deinit()
 {
//----
  
//----
  return(0);
 }
 
int start()
{
 
 if(IndicatorCounted() < 1)
 {
Print(Bars," Bars to be backfilled ");
int bar_index=0;
for(bar_index=1;bar_index < Bars;bar_index++)
{
  CountCandles(Bars-bar_index);
}
 }

  CountCandles(0);
  
  return(0);
 }
//+------------------------------------------------------------------+

int CountCandles(int bar_index)
{		   
  GreenCandles = 0;
  RedCandles = 0;
  GreenSum = 0;
  RedSum = 0; 
  
  for (int i=0;i<Candles;i++)
  {
  if (Open[bar_index+i] < Close[bar_index+i])
	 {
	  GreenCandles++;
	  GreenSum = GreenSum - (Open[bar_index+i] - Close[bar_index+i]);
	  if (GreenCandles>0) GreenAvg = GreenSum / GreenCandles;
	 }
  
  if (Open[bar_index+i] > Close[bar_index+i])
	 {
	  RedCandles++;
	  RedSum = RedSum + (Open[bar_index+i] - Close[bar_index+i]);
	  if (RedCandles>0) RedAvg = RedSum / RedCandles;
	 }	  
  
  
//zum Testen
  Print(GreenCandles + " " + RedCandles);
  Print (Open[bar_index+i] + " " + Close[bar_index+i]);
  Print(GreenSum + " " + RedSum);				 
  }
}

Bearbeitet von ronner
Code in mql-Tags umgewandelt

Featured Replies

Geschrieben
Ich vermute mal, dass es auch mit den Buffern zusammenhängt.

 

Also ich hab mir deinen Code mal angesehen und prinzipiell gibts 2 Probleme

1. die Buffer müssen auch solche sein also

 

double buffer[];

und nicht

dobule buffer;

 

2. müssen immer vom Typ double sein

 

Da ich nach kleiner Anpassung gemerkt hab, dass der Indikator ziemlich in die Knie geht bei längeren Zeiträumen. Hatte versehentlich die Candles auf 100 gestellt gehabt. Daher hab ich den MovingAverage Ansatz verwendet, bei dem die Werte "on the fly" neu berechnet werden. In dem bei der Berechnung immer die letzte Candle entfernt wird und dann die neuste hinzugefügt, das spart doch einige Rechenleistung.

 

Daher hier zunächst deine geänderte Version:

 

//+----------------------------------------------------+
//|                       CandleCounter.mq4 |
//+----------------------------------------------------+

#property copyright "conglom-o"

#property indicator_separate_window
#property indicator_buffers 4
/*#property indicator_minimum -10
#property indicator_maximum 10*/

extern int Candles = 10;

//---- buffers
double GreenCandles[], RedCandles[];
double GreenAvg[], RedAvg[];
 
//+------------------------------------------------------------------+
//| Custom indicator initialization function                    |
//+------------------------------------------------------------------+
int init()
 {
//---- indicators
 IndicatorBuffers(4);
 SetIndexStyle(0,DRAW_LINE,STYLE_SOLID,EMPTY,Green);
 SetIndexBuffer(0,GreenCandles);
 SetIndexStyle(1,DRAW_LINE,STYLE_SOLID,EMPTY,Red);
 SetIndexBuffer(1,RedCandles);
 SetIndexStyle(2,DRAW_LINE,STYLE_DOT,EMPTY,Green);
 SetIndexBuffer(2,GreenAvg);
 SetIndexStyle(3,DRAW_LINE,STYLE_DOT,EMPTY,Red);
 SetIndexBuffer(3,RedAvg);
 ObjectsDeleteAll(0,OBJ_TEXT);
 return(0);
 }
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                |
//+------------------------------------------------------------------+
int deinit()
 {
//----
 
//----
  return(0);
 }
 
int start()
{  
 if(Bars<=Candles) return(0);
 
 CountCandles();
 
 return(0);
}
//+------------------------------------------------------------------+

//int CountCandles(int bar_index)
int CountCandles()
{          
     int greencandles = 0;
     int redcandles = 0;
     double greensum = 0;
     double redsum = 0;

     int ExtCountedBars=IndicatorCounted();
     int    i,pos=Bars-ExtCountedBars-1;
     //---- initial accumulation
     if(pos<Candles) pos=Candles;
     for(i=1;i<Candles;i++,pos--) {
        if(Open[pos] < Close[pos])  {
           greensum+=(Open[pos] - Close[pos]);
           greencandles++;
        }
        if(Open[pos] > Close[pos]) {
           redsum+=(Open[pos] - Close[pos]);
           redcandles++;
        }
     }
     //---- main calculation loop
     while(pos>=0)
       {
      if(Open[pos] < Close[pos])  {
           greensum +=(Open[pos] - Close[pos]);
           greencandles++;
        }
        if(Open[pos] > Close[pos]) {
           redsum+=(Open[pos] - Close[pos]);
           redcandles++;
        }
        if(greencandles > 0) GreenAvg[pos] = greensum/greencandles;
        else GreenAvg[pos] = 0;
        if(redcandles > 0) RedAvg[pos] = redsum/redcandles;
        else RedAvg[pos] = 0;
        GreenCandles[pos] = greencandles;
        RedCandles[pos] = redcandles;
        
        if(Open[pos+Candles] < Close[pos+Candles])  {
           greensum -=(Open[pos+Candles] - Close[pos+Candles]);
           greencandles--;
        }
        if(Open[pos+Candles] > Close[pos+Candles]) {
           redsum -=(Open[pos+Candles] - Close[pos+Candles]);
           redcandles--;
        }
	      pos--;
       }

//---- zero initial bars
  if(ExtCountedBars<1) {
     for(i=1;i<Candles;i++) { 
        RedAvg[bars-i]=0;
        RedCandles[bars-i]=0;
        GreenAvg[bars-i]=0;
        GreenCandles[bars-i]=0;
     }
  }
}

 

Und weil du in jedem Fenster nur eine Ansicht/Skala haben kannst, und die Werte der Parameter viel größer als die der Mittelwerte sind. Hab ich noch eine weitere Version erstellt in der die Anzahl der Candles als Text dazu geschrieben wird.

 

//+----------------------------------------------------+
//|                       CandleCounter.mq4 |
//+----------------------------------------------------+

#property copyright "conglom-o"

#property indicator_separate_window
#property indicator_buffers 4
/*#property indicator_minimum -10
#property indicator_maximum 10*/

extern int Candles = 10;

//---- buffers
double GreenAvg[], RedAvg[];

int o=0;  
int window=0;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                    |
//+------------------------------------------------------------------+
int init()
 {
//---- indicators
 IndicatorBuffers(2);
 SetIndexStyle(0,DRAW_LINE,STYLE_DOT,EMPTY,Green);
 SetIndexBuffer(0,GreenAvg);
 SetIndexStyle(1,DRAW_LINE,STYLE_DOT,EMPTY,Red);
 SetIndexBuffer(1,RedAvg);  
 window=WindowsTotal();
 ObjectsDeleteAll(window,OBJ_TEXT);
 return(0);
 }
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                |
//+------------------------------------------------------------------+
int deinit()
 {
//----
 
//----
  return(0);
 }
 
int start()
{  
 if(Bars<=Candles) return(0);
 
 CountCandles();
 
 return(0);
}
//+------------------------------------------------------------------+

//int CountCandles(int bar_index)
int CountCandles()
{          
     int greencandles = 0;
     int redcandles = 0;
     double greensum = 0;
     double redsum = 0;

     int ExtCountedBars=IndicatorCounted();
     int    i,pos=Bars-ExtCountedBars-1;
     //---- initial accumulation
     if(pos<Candles) pos=Candles;
     for(i=1;i<Candles;i++,pos--) {
        if(Open[pos] < Close[pos])  {
           greensum+=(Open[pos] - Close[pos]);
           greencandles++;
        }
        if(Open[pos] > Close[pos]) {
           redsum+=(Open[pos] - Close[pos]);
           redcandles++;
        }
     }
     //---- main calculation loop
     while(pos>=0)
       {      	      
      if(Open[pos] < Close[pos])  {
           greensum +=(Open[pos] - Close[pos]);
           greencandles++;
        }
        if(Open[pos] > Close[pos]) {
           redsum+=(Open[pos] - Close[pos]);
           redcandles++;
        }
        if(greencandles > 0) GreenAvg[pos] = greensum/greencandles;
        else GreenAvg[pos] = 0;
        if(redcandles > 0) RedAvg[pos] = redsum/redcandles;
        else RedAvg[pos] = 0;
        Text(redcandles,Time[pos], RedAvg[pos]*0.9);
        Text(greencandles,Time[pos], GreenAvg[pos]*1.1);
        
        if(Open[pos+Candles] < Close[pos+Candles])  {
           greensum -=(Open[pos+Candles] - Close[pos+Candles]);
           greencandles--;
        }
        if(Open[pos+Candles] > Close[pos+Candles]) {
           redsum -=(Open[pos+Candles] - Close[pos+Candles]);
           redcandles--;
        }
	      pos--;
       }

//---- zero initial bars
  if(ExtCountedBars<1) {
     for(i=1;i<Candles;i++) { 
        RedAvg[bars-i]=0;         
        GreenAvg[bars-i]=0;         
     }
  }
}

void Text(string txt,int time,double price )
{
  ObjectCreate( "T" + o,OBJ_TEXT,window,time,price);
  ObjectSetText("T" + o,txt,8,"Comic Sans MS", Orange);
  o++;
}

Bearbeitet von Tommyknocker

Geschrieben
  • Autor
Also ich hab mir deinen Code mal angesehen und prinzipiell gibts 2 Probleme

1. die Buffer müssen auch solche sein also

 

double buffer[];

und nicht

dobule buffer;

 

2. müssen immer vom Typ double sein

[...]

 

Yep, das meinte ich mit den Buffern :wub:. Hatte nämlich mal alles als Array gemacht, was gebuffert sein müsste, aber dann blieb Greencandles bspw. immer auf 0 (warum auch immer - aber das mit den Arrays werde ich wohl nie ganz verstehen *ggg*). Ich werds mal ausprobieren, was Du da rein gebaut hast. Vielen Dank vorab - muss mich da nun erstmal reindenken, da es ja mit den verschachtelten Schleifen auf und ab doch etwas anders ist als mein Ansatz.

 

Update

Hier erstmal ein kleines Ergebnis nach dem ersten Test. Zunächst das Erfreuliche: er malt etwas :wub:. Nun ein paar kleine Anmerkungen, auf die ich den Quelltext hin mal untersuchen werde. Bei greensum muss man open und close vertauschen, damit die Summe positiv wird. Desweiteren herrscht noch ein Fehler beim Zählen: habe gerade mal 3 eingestellt (wir haben gerade drei grüne Kerzen am Stück) und er gibt mir an: grüne Kerzen 4, rote -1. Da passt also irgendwie noch was nicht.

Geschrieben
Vielen Dank vorab - muss mich da nun erstmal reindenken, da es ja mit den verschachtelten Schleifen auf und ab doch etwas anders ist als mein Ansatz.

 

Also wenn du willst kannst da natürlich auch deine eigene Implementierung verwenden. Sonst ist es wie gesagt nur die Umsetzung deiner Vorlage in den Moving Average Indicator der eine gute Vorlage für dieses Problem ist.

 

Desweiteren herrscht noch ein Fehler beim Zählen: habe gerade mal 3 eingestellt (wir haben gerade drei grüne Kerzen am Stück) und er gibt mir an: grüne Kerzen 4, rote -1. Da passt also irgendwie noch was nicht.

 

Also ich denke ich hab den Fehler gefunden: Das Hauptproblem war das pos--; in der Hauptschlaife war an der falschen Stelle.

Außerdem hab ich noch gemerkt, dass es ein Problem mit der Darstellung mit anderen Indikatoren gab die ich jetzt hoffe ich damit auch korrigiert hab.

 

//+----------------------------------------------------+
//|                       CandleCounter.mq4 |
//+----------------------------------------------------+

#property copyright "conglom-o"

#property indicator_separate_window
#property indicator_buffers 4
/*#property indicator_minimum -10
#property indicator_maximum 10*/

extern int Candles = 10;

//---- buffers
double GreenAvg[], RedAvg[];

int o=0;  
string shortname="";
//+------------------------------------------------------------------+
//| Custom indicator initialization function                    |
//+------------------------------------------------------------------+
int init()
 {
//---- indicators
 IndicatorBuffers(2);
 SetIndexStyle(0,DRAW_LINE,STYLE_DOT,EMPTY,Green);
 SetIndexBuffer(0,GreenAvg);
 SetIndexStyle(1,DRAW_LINE,STYLE_DOT,EMPTY,Red);
 SetIndexBuffer(1,RedAvg);  
 shortname = "candlecounter2 ("+Candles+")";
 IndicatorShortName(shortname);  
 ObjectsDeleteAll(WindowFind(shortname),OBJ_TEXT);
 return(0);
 }
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                |
//+------------------------------------------------------------------+
int deinit()
 {
//----
 
//----
  return(0);
 }
 
int start()
{ 
 if(Bars<=Candles) return(0);
   
 CountCandles();
 
 return(0);
}
//+------------------------------------------------------------------+

//int CountCandles(int bar_index)
int CountCandles()
{          
     static int greencandles = 0;
     static int redcandles = 0;
     static double greensum = 0;
     static double redsum = 0;
     static int sum=0;

     int ExtCountedBars=IndicatorCounted();
     int    i,pos=Bars-ExtCountedBars-2;

     //---- initial accumulation
     if(pos<Candles) pos=Candles;      
     for(i=1;i<Candles;i++,pos--) {
        if(Open[pos] < Close[pos])  {
           greensum+=(Close[pos]-Open[pos]);
           greencandles++;
        }
        if(Open[pos] > Close[pos]) {
           redsum+=(Close[pos]-Open[pos]);
           redcandles++;
        }
     }
     
     //---- main calculation loop
     while(pos>=0)
     {
      if(Open[pos] < Close[pos]) {
           greensum +=(Close[pos]-Open[pos]);
           greencandles++;
        }
        if(Open[pos] > Close[pos]) {
           redsum+=(Close[pos]-Open[pos]);
           redcandles++;
        }         
        if(greencandles > 0) GreenAvg[pos] = greensum/greencandles;
        else GreenAvg[pos] = 0;
        if(redcandles > 0) RedAvg[pos] = redsum/redcandles;
        else RedAvg[pos] = 0;
        Text(redcandles,Time[pos], RedAvg[pos]*0.8);
        Text(greencandles,Time[pos], GreenAvg[pos]*1.2);
        pos--;         
        if(Open[pos+Candles] < Close[pos+Candles]) {
           greensum -=(Close[pos+Candles] - Open[pos+Candles]);
           greencandles--;
        }
        if(Open[pos+Candles] > Close[pos+Candles]) {
           redsum -=(Close[pos+Candles] - Open[pos+Candles]);
           redcandles--;
        }         
     }

}

void Text(string txt,int time,double price )
{   
  ObjectCreate( "T" + o,OBJ_TEXT,WindowFind(shortname),time,price);
  ObjectSetText("T" + o,txt,8,"Comic Sans MS", Orange);
  o++;
}

Geschrieben
  • Autor

So, ich habe nun mal versucht, den Indikator zu erweitern. Dabei will ich das Verhältnis von grünen zu roten Kerzen mit ausgeben. Da bin ich jetzt am verzweifeln, warum das nicht geht.

 

Was ich gemacht habe:

- IndikatorBuffers auf 5 erhöht und entsprechend erweitert

- double Quote[] eingeführt

- Berechnung Quote[pos] = (greencandles/redcandles) eingeführt (wenn redcandles >0)

 

Das Problem was ich dabei habe ist, dass er da immer 0 berechnet. Wenn ich addiere, subtrahiere oder multipliziere, rechnet er richtig und gibt auch aus - beim dividieren gibts aber entweder 0 oder sonstige Fehler, obwohl Quote ja vom Typ double ist. Jemand eine Idee (bitte nicht gleich wieder so viel Arbeit ins Umsetzen stecken - ein Tip ist schon prima :wub:)?

Geschrieben
...

- Berechnung Quote[pos] = (greencandles/redcandles) eingeführt (wenn redcandles >0)

...

Das Problem was ich dabei habe ist, dass er da immer 0 berechnet. Wenn ich addiere, subtrahiere oder multipliziere, rechnet er richtig und gibt auch aus - beim dividieren gibts aber entweder 0 oder sonstige Fehler, obwohl Quote ja vom Typ double ist.

 

Zwei Punkte:

 

  • Du hattest geschrieben, was du geändert hast. Die property für buffercount wurde genannt, folgendes nicht: IndicatorBuffers(3); Ist aber wichtig, sonst laufen die Zuweisungen ins Leere und du erhältst immer 0.
  • greencandles und redcandles sind als int deklariert ----> Die RHS wird erst berechnet (da in diesem Fall int, werden alle Bruchstücke weggeworfen) danach zum LHS-Typ (hier double) konvertiert und zuletzt Quote[pos] zugewiesen.
    Also entweder Typgleichheit links u. rechts oder vor der Berechnung die Variablen der rechten Seite in ein double kopieren und das dann nutzen. Beides funktioniert, wie gewünscht.

 

  double _red = redcandles;
  double _green = greencandles;
  Quote[pos] = _green/_red; // Orig: greencandles / redcandles;

Geschrieben
  • Autor
Zwei Punkte:

 

    [*]Du hattest geschrieben, was du geändert hast. Die property für buffercount wurde genannt, folgendes nicht: IndicatorBuffers(3); Ist aber wichtig, sonst laufen die Zuweisungen ins Leere und du erhältst immer 0.

Mit Erhöhung des Buffers meinte ich natürlich beides - sowohl bei der property als auch bei der Definition der Indikatoren - es ist tatsächlich die Deklaration der Variablen gewesen. Hätte nun nicht gedacht, dass ich nicht zwei int-Variablen teilen darf, wenn das Ergebnis double ist (vor allem, weil ja die anderen Rechenoperationen gingen - da ist der MT4 also nicht sehr konsequent im rumnörgeln). Klappt aber nun - vielen Dank (und wieder was dazu gelernt) :wub:.

Geschrieben
Mit Erhöhung des Buffers meinte ich natürlich beides - sowohl bei der property als auch bei der Definition der Indikatoren - es ist tatsächlich die Deklaration der Variablen gewesen. Hätte nun nicht gedacht, dass ich nicht zwei int-Variablen teilen darf, wenn das Ergebnis double ist (vor allem, weil ja die anderen Rechenoperationen gingen - da ist der MT4 also nicht sehr konsequent im rumnörgeln). Klappt aber nun - vielen Dank (und wieder was dazu gelernt) :wub:.
,

 

natürlich gingen die anderen Rechenoperationen Add/Subtr/Mult ... da werden ja auch keine Bruchteile erzeugt, rumnörgeln sollte MT4 da nicht, da es einfach nur das eingebaute Typkonzept ablaufen lässt. Interpretationsabweichungen davon mit Warnungen auszugeben würde die Architekten von MQL4 gänzlich diskreditieren. In der MQL-Doku gibt es eine Auflistung verschiedener Berechnungen mit Zuweisungen, eigentlich sehr aufschlussreich. Btw. Ich selbst finde das Typ-Konzept von MQL einfach völlig daneben, irgenwie scheint der Preprocessor sogar abhängig vom Kontext Cast-Ausdrücke wie (double) zu kennen, aber wann und wo bzw. ob die überhaupt irgendwann greifen, ist mir ein Rätsel. Und im Ergebnis hat man dann solche Fehler, wo man den Wald nicht mehr versteht :sad: :wub:

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.