Jump to content
Tom Next - Daytrading Community

iCustom - Das Wichtigste


NikkChade

Recommended Posts

Guten Morgen...

 

Ich programmiere seit ca. 6 Monaten MQL4 und kann sagen, dass ich einen kleinen fundierten Wissensstand habe, was das Programmieren von ExpertAdvisor angeht. Jedoch reichen mir(und Anderen sicherlich auch)die Standard-Indikatoren im MT4 nichtmehr aus um wirklich weiter zu kommen. Deshalb müssen jetzt externe Indikatoren her...

Die iCustom-Indikatoren sind deshalb die nächste Stufe um das Fundament weiter auszubauen...

 

Jetzt Besitze ich aus diesem Kapitel natürlich nur "gefährliches Halbwissen" und auch nur einzelne Puzzleteile davon. Deshalb suche ich hier Hilfe zum Zusammenfügen des Puzzles und um auch eventuell ein kleines "Nachschlage-Topic" für nachkommende Leser zu schaffen. Das Topic soll demnach auch als kleines Tagebuch dienen, um meine Fortschritte, Probleme und Lösungen zu dokumentieren.

 

Jetzt hoffe ich natürlich, dass ich tatkräftige Unterstützung erfahren werde. Mir ist dabei auch sehr wohl bewusst, dass ich viel Eigenleistung mit einbringen muss. Doch die bin ich bereit zu leisten... :ot:

 

LG NC

Link to comment
Share on other sites

Wenn ich einen externen Indikator in einem EA einbinden möchte, dann wird er ja über die Funktion "iCustom()" aufgerufen und eingebunden.

Jetzt muss ich für diesen Vorgang natürlich auch die richtige BufferStelle wissen.

 

Jetzt habe ich natürlich auch schon die ersten Frage:

Wie ist denn nun die etwas genauere Definition eines Buffers und wie kann man es einem Noob erklären. Gibt es da Beispiele, wie man es Bildlich darstellen kann?

 

Mein bisheriges Wissen würde mich das ganze so erklären lassen:

 

Der externe Indikator ist ein elektronisches Gerät mit maximal 8 Einsteckmöglichkeiten für Kabel bzw Stecker. Die Anbindungsmöglichkeiten sind von 0 bis 7 Durchnummeriert. Kann ich nun die Anschlüsse des Gerätes als "Buffer" sehen oder ist das falsch?!

 

Soviel zum Thema "Laufen lernen" mit iCustom...

 

LG NC

Link to comment
Share on other sites

Also wenn wir bei deiner Analogie bleiben, dann würde ich das etwas mehr spezifizieren und erweitern.

 

Der externe Indikator ist ein Gerät mit maximal 8 Ausgängen (die du dir im Chart oder EA ausgeben lassen kannst) und mindestens einem Eingang (deine Daten des Charts im eingestellten Zeitrahmen die dir 'automatisch' zur Verfügung gestellt werden, aber beliebig um weitere Zeitrahmen oder Underlyings erweiterbar sind). Außerdem besteht die Möglichkeit durch Regler (Parameterset) bestimmte Voreinstellungen des Geräts durchzuführen.

 

 

Zum Thema Buffer das sind spezielle Arrays (oder Felder) die Daten in einer nummerierten Liste ablegen. Du kannst die Werte dann mit deren Nummer (Index) abrufen (zB. Buffer[5]). Wobei MT4 selbst dafür sorgt das nach jedem verstrichenen Zeitraum (eingestellter Timeframe) ein weiterer Wert am Beginn der Liste aufgenommen wird und daher alle alten Werte auf der Liste einen Platz nach hinten rücken. Der externe Indikator erhält dann die Möglichkeit per start() diesem 'leeren' Listenplatz einen korrekten Wert zu geben.

Die Liste wird mit einem vorher festgelegten Standardwert belegt, das gilt auch für Werte die so weit zurück liegen das es dafür (in der History) noch keine Daten gab.

 

Zum Thema Array hab ich noch einen kleinen Link für dich der das technisch ein wenig erklärt:

Arraybeschreibung

  • Upvote 1
Link to comment
Share on other sites

Also das Thema Array ist mir bekannt und wusste ich zum Teil auch schon.

 

Jetzt kann ich nun davon ausgehen, dass der Indikator für bis zu 8 Buffer(Arrays) einen bestimmten Speicherplatz reserviert und dort Daten abspeichert, die von Außen(EA) abgerufen werden können.

Natürlich immer mit der Maßgabe die Daten auf dem Buffer zu erneuern, sobald sich die Daten auch verändern.

 

Jetzt tauchen ab hier natürlich weitere Fragen auf.

Wie kann ich feststellen, was auf dem Buffer gespeichert wird oder was dieser zurück gibt?

 

Ich könnte mir gut vorstellen, dass es da nur zwei Möglichkeiten gibt.

Entweder ich spreche die Buffer über einen EA an und lasse das Ganze Printen, oder ich habe mich so gut mit dem Quelltext auseinander gesetzt, dass ich weiß was er zurück geben soll.

 

Unterbrecht mich einfach, wenn ich was falsches Schreibe :ot:

 

Jetzt kenne ich natürlich meine Schwächen und weiß, dass ich im Quelltext gerne mal was überlese. Demnach muss ich es also über die Printfunktion in einem EA auswerfen lassen.

 

Jetzt ist mein Wissen bis hierher natürlich gestärkt, aber Alles was danach kommt ist recht dünn.

Wie finde ich denn nun die Buffer und wie spreche ich sie richtig an?

Werde wahrscheinlich so verfahren müssen...

 double ExtIndi = iCustom(Symbol,TimeFrame,"Name",Parameter des ExtIndi,BufferStelle,Shift);

Worauf muss ich jetzt hier besonders achten, wenn ich die Parameter übernehme?

Gibt es da eine bestimmte Reihenfolge in der ich die Parameter einsetzen muss?

Muss ich die eigentlich eintragen oder kann ich die für Tests auch frei lassen?

Und wenn ich sie nicht frei lasse und Parameter eintrage: Müssen die Variablen für die Parameter so heißen wie die GV im EA oder wie die Parameter im Indikator?

 

Hui...anfänglich schon 'ne harte Nuss.

 

@ Tommyknocker

Kann es sein, dass C# einiges mit Java gemein hat?!

 

LG NC

Link to comment
Share on other sites

Also das Thema Array ist mir bekannt und wusste ich zum Teil auch schon.

 

OK, dass wusste ich natürlich nicht.

 

Wie kann ich feststellen, was auf dem Buffer gespeichert wird oder was dieser zurück gibt?

 double ExtIndi = iCustom(Symbol,TimeFrame,"Name",Parameter des ExtIndi,BufferStelle,Shift);

 

Ja genau, das ist die Möglichkeit des Zugriffs vom EA auf einen custom indicator. Wo ich mir nicht sicher bin ob du das richtige meinst, ist die BufferStelle den an der Position muss die Nummer des buffers eingetragen, von dem du einen Wert erhalten willst. Also eben 0 .. 7, 0 = der erste und 7 = der letzte.

Also im Prinzip wie auch auf jeden fest eingebauten Indikator mit der Ausnahme, dass du dich selbst um die Übergabe der Parameter kümmern musst, und der Buffer angegeben werden muss auf den du zugreifen willst.

 

Worauf muss ich jetzt hier besonders achten, wenn ich die Parameter übernehme?

Gibt es da eine bestimmte Reihenfolge in der ich die Parameter einsetzen muss?

Muss ich die eigentlich eintragen oder kann ich die für Tests auch frei lassen?

Und wenn ich sie nicht frei lasse und Parameter eintrage: Müssen die Variablen für die Parameter so heißen wie die GV im EA oder wie die Parameter im Indikator?

 

Ja, die Reihenfolge muss exakt der entsprechen die du auch in deinem Indikator verwendest. Also zB.

// Indikator
extern int param1 = 1;
extern int param2 = 10;
extern int param3 = 100;

dann muss der Aufruf

 // EA
double ExtIndi = iCustom(Symbol,TimeFrame,"Name",p1,p2,p3,BufferNr,Shift);
// wobei p1 bis p3 die Parameter sind die du übergeben willst.

 

Du kannst die Parameter auch frei lassen. Dann wird der Standardwert den du im Indikatorcode angegeben hast verwendet. Allerdings bleibt dabei die Notwendigkeit der richtigen Reihenfolge aufrecht, daher kannst du immer nur die letzten und auch nur alle auf einmal weglassen!

 

 
// param3 = 100
double ExtIndi = iCustom(Symbol,TimeFrame,"Name",p1,p2,BufferNr,Shift);
// param2=10, param3 = 100
double ExtIndi = iCustom(Symbol,TimeFrame,"Name",p1,BufferNr,Shift);
// param3 = 1, param3 = 10, param3 = 100
double ExtIndi = iCustom(Symbol,TimeFrame,"Name",BufferNr,Shift);

 

Die Variablen in deinem EA Code haben nichts mit denen im Indikator gemeinsam und können daher verschieden gewählt werden. Es ist nur trotzdem sinnvoll einen sprechenden Namen zu verwenden. Also hat man einen Indikator der auf einem Moving Average bassiert ist es sinnvoll auch die Parameter entsprechen lperod, speriod für zB. long period und short period zu verwenden.

Wenn du Variablen verwendest die du dem EA Parameter von außen mitgeben willst, dann musst du die entsprechenden globalen Variablen als Parameter für die iCustom-Funktion verwenden.

 

Kann es sein, dass C# einiges mit Java gemein hat?!

 

Ja, alle diese Sprachen also C++, C#, Java, MQL-C basieren auf den glechen Sprachelementen und Syntax wie C, und sind sich daher sehr ähnlich. Sie sind nur um unterschiedliche Kozepte erweitert worden.

 

 

Zum Schluß empfehle ich dir noch dir sowohl den iCustom Abschnitt im MQL Book als auch die custom indicator Artikel anzusehen. Sind lesenswert und enthalten alle wichtigen Infos die du brachst um die ersten Strategien mit eigenen Indikatoren zu programmieren.

Link to comment
Share on other sites

Deshalb suche ich hier Hilfe zum Zusammenfügen des Puzzles und um auch eventuell ein kleines "Nachschlage-Topic" für nachkommende Leser zu schaffen. Das Topic soll demnach auch als kleines Tagebuch dienen, um meine Fortschritte, Probleme und Lösungen zu dokumentieren.

 

Klasse Idee NikkChade :ot: !

 

Jetzt hoffe ich natürlich, dass ich tatkräftige Unterstützung erfahren werde. Mir ist dabei auch sehr wohl bewusst, dass ich viel Eigenleistung mit einbringen muss. Doch die bin ich bereit zu leisten...

 

 

Tommyknocker ist ja bereits fleißig am supporten :ot: , denke da kommen mit der Zeit weitere Meinungen hinzu.

 

btw. Kennt Ihr diesen Thread? MQL Library mit Standardfunktionen

Link to comment
Share on other sites

Ich schalt mich auch gleich mal ein.

 

Wenn wir schon bei analogien sind noch eine kleine Ergänzung von mir (ich glaub Nikk braucht keine mehr, aber ich red halt gern und vielleicht hilfts wem anderen ;):

Einen Indikator kann man sich als Maschine vorstellen, die auf bis zu 8 "unendlich" lange Papierstreifen Werte schreibt (immer vom Typ double), jeweils ein Wert pro Bar pro Papierstreifen. Die Maschine kann (leider) alle bisher geschriebenen Werte jederzeit wieder ändern. Von außen kann man jetzt die Parameter der Maschine einstellen, sofern welche vorhanden sind. Und auf beliebige bereits geschriebene Werte auf den Streifen lesend zugreifen indem man angibt welchen Streifen (Buffer) man will, und wieviele Stellen man in die "Vergangenheit" (also den Papierstreifen entlang nach hinten) gehen will.

 

Jetzt kann ich nun davon ausgehen, dass der Indikator für bis zu 8 Buffer(Arrays) einen bestimmten Speicherplatz reserviert und dort Daten abspeichert, die von Außen(EA) abgerufen werden können.

Jup, da es in MQL keine Pointer und keine Speicherverwaltung gibt, brauchst du dir über den Speicherplatz keine Gedanken machen ;)

 

Wie kann ich feststellen, was auf dem Buffer gespeichert wird oder was dieser zurück gibt?

Verstehen des Source und Printausgabe sind gute Möglichkeiten. Eine weitere wäre das simple auf den Chart ziehen des Indis. Sämtliche Buffer die dir zur Verfügung stehen, werden auch im Chart angezeigt. Beim ersten Kontakt mit neuen Indis ist es meist am einfachsten das Verhalten erstmal am Chart zu analysieren.

 

Muss ich die eigentlich eintragen oder kann ich die für Tests auch frei lassen?

Frei lassen würd ich sie nicht, einfach aus dem Risiko heraus das man bei späterer Weiterverwendung/Änderung leicht Fehler macht. Und sobald man die Defaultparameter des Indi ändert, ändert sich damit auch das Verhalten des EA ohne das man daran was geändert hat.

 

Auf etwas muss man bei den Parametern auch unbedingt achten: Die Datentypen müssen übereinstimmen. Hier liefert MQL leider keine Fehlermeldung beim compilieren, ist dann aber ewig langsam weil er bei jedem Tick den Indi neu laden versucht und dann doch die Defaultparameter nimmt.

 

lg

Link to comment
Share on other sites

OK, dass wusste ich natürlich nicht.

Kein Problem...sollte auch nicht als Kritik rüber kommen. Wollte nur kurz noch meinen derzeitigen Wissenstand preisgeben um eventuelles "Vielschreiben" zu vermeiden :ot:

 
// param3 = 100
double ExtIndi = iCustom(Symbol,TimeFrame,"Name",p1,p2,BufferNr,Shift);
// param2=10, param3 = 100
double ExtIndi = iCustom(Symbol,TimeFrame,"Name",p1,BufferNr,Shift);
// param3 = 1, param3 = 10, param3 = 100
double ExtIndi = iCustom(Symbol,TimeFrame,"Name",BufferNr,Shift);

Dieses Bsp. habe ich aber noch nicht ganz geblickt. :ot:

Welche Parameter werden jetzt in den einzelnen Beispielen übernommen?

 

Aber ansonsten muss ich sagen: :blush: und großes Danke bis hier her...

Das Feld lichtet sich langsam :ot:

Verstehen des Source und Printausgabe sind gute Möglichkeiten. Eine weitere wäre das simple auf den Chart ziehen des Indis. Sämtliche Buffer die dir zur Verfügung stehen, werden auch im Chart angezeigt. Beim ersten Kontakt mit neuen Indis ist es meist am einfachsten das Verhalten erstmal am Chart zu analysieren.

Hier habe ich mal gehört, dass die Möglichkeit bestehen könnte, dass der Buffer nicht unbedingt das wiedergibt was im Chart angezeigt wird. In wie weit ist diese Aussage richtig oder falsch?

 

Jetzt gibt es ja auch Indikatoren die nicht nur mit Balken, Linien und Werten arbeiten, sondern auch mit Farben. Demnach müsste ja auch die Möglichkeuit bestehen "Farbbedingungen" einzubauen...oder liege ich da jetzt falsch?

Und sobald man die Defaultparameter des Indi ändert, ändert sich damit auch das Verhalten des EA ohne das man daran was geändert hat.

Also meinst Du damit, dass sich die Ausgangssituation der Werte die Berechnet werden, sich geändert hat...

sprich das Verändern des Berechnungszeitraumes im Indikator.

Im Indikator wurden die Parameter verlängert, aber im EA nicht...

War das in etwa richtig verstanden?!

Auf etwas muss man bei den Parametern auch unbedingt achten: Die Datentypen müssen übereinstimmen. Hier liefert MQL leider keine Fehlermeldung beim compilieren, ist dann aber ewig langsam weil er bei jedem Tick den Indi neu laden versucht und dann doch die Defaultparameter nimmt.

Das man also bei einer Ausgabe von Double auch Double abfragt...und nicht Int abfragen möchte.

Denn nur da wo Double rauskommt, war auch wirklich Double drin... :ot:

Und wenn die Sache nun umgekehrt läuft und der Indi den Datentyp Int ausgibt und ich Double abfrage?

Dürfte eigentlich nicht Schlimmes passieren, oder?

 

Was sind eigentlich DefaultParameter?

Klasse Idee NikkChade top.gif !

Danke...wenn ich schon was lerne, dann kann man es ja auch gleich für die Nachwelt festhalten. Nicht weil es so selten ist dass ich mal was begreife, sondern als ErgänzungsTopic zu den anderen Topics... :wink:

 

LG NC

Link to comment
Share on other sites

Hier habe ich mal gehört, dass die Möglichkeit bestehen könnte, dass der Buffer nicht unbedingt das wiedergibt was im Chart angezeigt wird. In wie weit ist diese Aussage richtig oder falsch?

? Beim programmieren des Indis schreib ich ihm in die Buffer welche Werte im Chart angezeigt werden. Somit zeigt der Chart genau die Werte der Buffer an.

 

Jetzt gibt es ja auch Indikatoren die nicht nur mit Balken, Linien und Werten arbeiten, sondern auch mit Farben. Demnach müsste ja auch die Möglichkeuit bestehen "Farbbedingungen" einzubauen...oder liege ich da jetzt falsch?

Jein, im Indi kannst du natürlich sagen welcher Buffer in welcher Farbe gemalt werden soll. Aber diese Farbe ist immer für alle Werte gleich. Du kannst AFAIK vom EA aus nicht fragen welche Farbe der Buffer hat, macht auch wenig sinn.

 

Also meinst Du damit, dass sich die Ausgangssituation der Werte die Berechnet werden, sich geändert hat...

sprich das Verändern des Berechnungszeitraumes im Indikator.

nicht unbedingt der Berechnungszeitraum.

 

Nehmen wir an du schreibst einen eigenen SMA (also einen normalen gleitenden Durchschnitt) mit einem Parameter (die Anzahl der Bars die für die Berechnung genommen werden.

 

Im Indikator code kannst du jetzt angeben welchen Wert der Parameter standardmäßig haben soll (Der sogenannte Defaultwert). Wenn du jetzt diesen SMA verwendest ohne den PArameter zu übergeben, und somit immer der Defaultwert genommen wird, funktioniert das, aber sobald du im Indikatorcode den Defaultwert änderst, ändert sich damit auch das Verhalten des EA, ohne das du im EA Code was geändert hast. Das sind die Fehler die man dann ewig sucht.

 

Das man also bei einer Ausgabe von Double auch Double abfragt...und nicht Int abfragen möchte.

Denn nur da wo Double rauskommt, war auch wirklich Double drin... :blush:

Und wenn die Sache nun umgekehrt läuft und der Indi den Datentyp Int ausgibt und ich Double abfrage?

Dürfte eigentlich nicht Schlimmes passieren, oder?

Die Buffer eines Indis sind immer double. Aber die Parameter können beliebige Datentypen haben. Schwierig wirds, wenn der Indi zB einen Int erwartet und du ihm einen String gibst.

 

Was sind eigentlich DefaultParameter?

 

default aus dem englischen: Fehlwert/standard.

Defaultwerte sind die Werte die genommen werden wenn der User/Programmierer keine Werte angibt. Defaultwerte für Parameter werden oft kurz als Defaultparameter bezeichnet.

 

hth

Link to comment
Share on other sites

sehr interessantes Topic.

 

Wenn ich noch eine Frage dazu stellen dürfte:

Wenn ich einen Indikator über iCustom aufrufe - wie oft wird der neu berechnet? Ist MQL so schlau die Indikator-Daten der Vergangenheit nur einmal zu generieren (der loop in der start() des indikators) oder wird der Indikator bei jedem Aufruf neu "aufgebaut"?

 

askerix

Link to comment
Share on other sites

Wenn ich einen Indikator über iCustom aufrufe - wie oft wird der neu berechnet? Ist MQL so schlau die Indikator-Daten der Vergangenheit nur einmal zu generieren (der loop in der start() des indikators) oder wird der Indikator bei jedem Aufruf neu "aufgebaut"?

 

MT4 ruft die Start()-Funktion des Indikators auf, wenn sich etwas an den Daten geändert hat. Also beim ersten Aufruf und bei jedem weiteren Tick der rein kommt. Und auch bei jedem Aufruf der Funktion iCustom. Der Wert des Indikatorbuffers wird aber aus dem Indikatorbuffer abgerufen und übergeben. Und daher muss man bei der Indikatorprogrammierung selbst darauf achten nicht jedesmal die gesamte Historie neu zu berechnen.

 

Für diese Behandlung des Ablaufs gibt es aber ein einaches Konstrukt das auch in der Doku so beschrieben wird.

Durch die Funktion IndicatorCounted() erhält man die Anzahl der Bars die bereits berechnet wurden und kann darauf hin nur noch die Werte berechnen die einem bis zur Gegenwart fehlen.

Ein wichtiger Hinweis noch sollte die Berechnung des Indikators auf die vorherigen Indikatorwerte angewiesen sein, so muss das bei der Berechnung berücksichtig werden, also immer erst die Werte die am längesten zurück liegen berechnen und dann weiter in die Gegenwart vorstossen.

Außerdem ist es sinnvoll den Indikator so zu Programmieren, dass alte Werte nicht mit neuen Werten überschrieben werden. Da es sonst zu Inkosistenzen kommt, wenn man den Indikator in einem EA verwenden will, und nicht weiß warum er da gehandelt hat, obwohl der gleiche Indikator denn man als Vergleich im Chart anzeigen lässt nun einen ganz anderen Wert anzeigt, bei dem er nicht handeln sollte. Und solche Fehler zu finden ist dann manchmal ziemlich schwierig. Daher ist es sinnvoll in einem EA immer mit einem shift = 1 zu arbeiten. Da dass die letzte wirklich abgeschlossene Candle ist.

 

Hier noch der Beispiel Indikatorcode der auch in der Dokumentation zu finden ist. Und sowohl das Problem des oft sinnlosen wiederholten Aufrufs aus einem EA als auch bei jedem Tick möglichst rasch abbricht.

 

int start() {
 int limit;
 int counted_bars=IndicatorCounted();
 //---- check for possible errors
 if(counted_bars<0) return(-1);
 //---- the last counted bar will be recounted
 if(counted_bars>0) counted_bars--;
 limit=Bars-counted_bars;
 //---- main loop
 for(int i=0; i<limit; i++) {
	// indicator calculations
 }
}

Link to comment
Share on other sites

MT4 ruft die Start()-Funktion des Indikators auf, wenn sich etwas an den Daten geändert hat. Also beim ersten Aufruf und bei jedem weiteren Tick der rein kommt. Und auch bei jedem Aufruf der Funktion iCustom. Der Wert des Indikatorbuffers wird aber aus dem Indikatorbuffer abgerufen und übergeben. Und daher muss man bei der Indikatorprogrammierung selbst darauf achten nicht jedesmal die gesamte Historie neu zu berechnen.

 

Danke Tommyknocker,

hast du dazu einen Link? Genau das ist, worüber ich mir Gedanken mache - wird bei jedem Aufruf aus dem EA der Indikator neu initialisiert oder merkt sich der EA, dass der Indi schon initialisiert ist und ruft nur noch die start()-Funktion auf?

 

Grüsse,

askerix

Link to comment
Share on other sites

Also der Indikator wird pro Verwendung (zB. EURUSD 5M in einer Strategie mit den gleichen Parametern) nur einmal initialisiert und danach nur noch die Start()-Funktion aufgerufen. Daher bleiben die Einstellungen/Parameter erhalten, und bereits berechnete Werte müssen nicht noch einmal berechnet werden. Das könntest du aber mit einem eigenen Testindikator und Test-EA durch Printausgaben leicht selbst überprüfen.

 

Ich bin mir nicht sicher ob du mit Link den vom Codebeispiel meinst oder für meine Angabe über den Indikatorprozess?

Also der Code ist aus der MQL-Doku hier die Links dazu:

ic.arrow.right.png http://docs.mql4.com/customind/IndicatorCounted

ic.arrow.right.png http://book.mql4.com/samples/icustom

 

Das der Aufruf der iCustom-Methode einen Aufruf der Start()-Funktion bewirkt kannst du leicht an Hand einer Print() Anweisung in einem der Beispielindikatorn überprüfen. Das stand glaub ich nirgends, aber es fällt dir bei der Programmierung irgendwann selbst mal auf.

Link to comment
Share on other sites

So, jetzt tun sich bei mir schon die ersten Fragen in der Praxis auf.

 

Wollte nun in einem kleinen Test-EA die Werte der Buffer über Print() zurückgeben lassen.

 

Jetzt steht im Journal:

"Old tick EURUSD15 1.33449/1.33474"

 

und bei ExpertenMenu/Ordner:

"TestfIndi EURUSD,M15: Wert für Buffer 1: 0"

 

und darunter steht im ExpertenMenu/Ordner:

"Can not open file ' C: ..."

 

Jetzt die einzelnen Fragen:

Wieso kann er die Datei nicht öffnen?

Und der Wert von "0" in Buffer 1...wird er von der Funktion "SetIndexEmptyValue(0, 0.0)" beeinflusst?

 

Aber kann es sein, dass ich einen Fehler beim EA gemacht habe?

//GlobVar
extern int TimeFrame = 15;
//-------------------------------------------------------------
//Funktion
double Buffer1()
  {
   double Indi1 = iCustom(NULL,TimeFrame,"Heiken Ashi ZoneTrade",0,1);
   
   return(Indi1);
  }
//-------------------------------------------------------------
int start()
 {
//----
  //Buffer 1
  Print("Wert für Buffer 1: ",Buffer1());
//----
  return(0);
 }

Ich habe in diesem TestEA mal die Parameter bei iCustom() freigelassen. Man muss es sich ja nicht gleich unnötig schwer machen :blush:

 

LG NC

Link to comment
Share on other sites

:ot:

So, da soll nochmal einer sagen das Arbeit nicht lohnt :blush:

 

Der Dateinname wurde von mir falsch eingegeben.

 

Als Notiz an mich selbst:

Wenn der Name des ExtIndi in der iCustom() eingetragen wird, dann sollte dort nicht die Bezeichnung aus dem Quelltext stehen, sondern die offizielle WindowsBezeichnung der Datei. Also am Besten einen rechten Mausklick auf die Datei im WindowsMenu->Umbenennen drücken->den Namen kopieren->bei iCustom() im Quelltext einfügen.

//falsche Schreibweise
iCustom(NULL,TimeFrame,"Heiken Ashi ZoneTrade",0,1);
//richtige Schreibweise
iCustom(NULL,TimeFrame,"HeikenAshiZoneTrade",0,1);

 

Deswegen konnte die Datei auch nicht geladen werden und es kam...

"Can not open file ' C: ..." und "TestfIndi EURUSD,M15: Wert für Buffer 1: 0"

 

LG NC

Edited by NikkChade
Link to comment
Share on other sites

Hab da auch noch eine nützliche Info zum Thema iCustom-Aufruf:

Wird beim Aufruf auf einen ungültigen Index zugegriffen, d.h. gibt es die Buffernummer im aufgerufenen Indikator nicht,

so liefert dir iCustom einen Wert von 2147483647 zurück.

Das passiert auch, wenn zum gegenwärtigen Zeitindex noch kein Wert für den Indikator-Buffer existiert.

 

Einfaches Beispiel:

Du legst in deinem Indikatorbuffer (warum auch immer) nur dann einen Wert ab, wenn innerhalb der letzten 5 Candles

ein neues Maximum auftrat. Wurde dann beim aktuellen Bar kein Wert abgelegt, so liefert dir iCustom ohne Fehlermeldung

den Wert 2147483647.

Dies kann dann ärgerlich sein, wenn du dann short gehst wenn dass der aktuelle Kurs kleiner ist, als das was iCustom zurückliefert...

Link to comment
Share on other sites

Wird beim Aufruf auf einen ungültigen Index zugegriffen, d.h. gibt es die Buffernummer im aufgerufenen Indikator nicht,

so liefert dir iCustom einen Wert von 2147483647 zurück.

Das passiert auch, wenn zum gegenwärtigen Zeitindex noch kein Wert für den Indikator-Buffer existiert.

Wenn ich das so lese, dann wird mir jetzt auch bewusst, warum im Quelltext

SetIndexEmptyValue(0, 0.0);
SetIndexEmptyValue(1, 0.0);
...

steht.

Ich vermute mal, dass diese Funktion gerade das verhindern soll. Oder täusche ich mich da?

Denn ich habe im Moment so einen iCustom, bei dem je nach Situation, verschiedene Buffer einen Wert besitzen und andere Buffer nicht. Je nach Marktlage ändert sich das Alles und es werden wieder andere Buffer angesprochen...

Liege ich damit so halb richtig oder bin ich da "on the Wooden Way"? :twiddle:

 

Kommen wir auch gleich zur nächsten Frage:

 

Wenn ich jetzt die GlobalenVariablen in der iCustom()-Funktion eingetragen habe. Kann ich die Veränderung dann im Chart sehen, oder kann ich die Veränderung nur über die Ausgabe von Werten nachvollziehen?

Als kleines Bsp.:

//Quelltext des EA
extern Periode = 14;
//------
double iCustom(NULL,TimeFrame,"NameIndi",Periode,BufferStelle,Shift)

Würde sich jetzt auch die Ansicht des Indikators ändern, wenn ich den Wert 14 in den Wert 200 ändere?

Oder würde sich hier nur das Berechnungsverhalten des Experten ändern, ohne eine sichtbare Veränderung beim Indikatoren zu sehen?

 

Wenn schlecht gesagt, bitte fragen nach! Nix deutsch, nur Moppen... :ot:

 

LG NC

Link to comment
Share on other sites

#property indicator_chart_window
#property indicator_buffers 1
#property indicator_color1 Green

int Index;
double Testbuffer[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int init()
{
//---- indicators
  IndicatorBuffers(1);
  SetIndexBuffer(0,Testbuffer);
  SetIndexStyle(0,DRAW_SECTION); //----
  SetIndexEmptyValue(0,6288.0);
  return(0);
}
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function |
//+------------------------------------------------------------------+
int deinit()
{
//----

//----
return(0);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int start()
{
int counted_bars=IndicatorCounted();
  if(counted_bars < 0) return(-1);   
  Index=Bars-counted_bars-1; 
//---

while(Index>=0)
{
  if(High[index]>High[index+1])
     Testbuffer[index]=High[index];
  Index--;
  
}

//---
}

 

Der Indikator verbindet alle Kerzen-Hochs wenn sie höher sind, als das Hoch des vorherigen Bars.

http://img36.imageshack.us/img36/3674/hoechstkurse.jpg

In meinem Beispiel hat der DAX am 21.4. um 08:05 den Höchstkurs 6288.0.

Obwohl der Kurs eigentlich den Kriterien des Indikators entsprechen würde, wird er nicht im Indikator

eingezeichnet, da ich 6288.0 von der Zeichnung ausnehme.

SetIndexEmptyValue(0,6288.0);

 

Zu deiner zweiten Frage.

Hier bin ich nicht ganz sicher, ob ich das richtig verstanden hab.

Wenn du iCustom aufrufst, dann gibt dir die Funktion ja einen Wert zurück.

Mit der Variablen "Periode" in deinem Beispiel übergibst du dem Indikator "NameIndi" ja einen

anderen Parameter. Abhängig von der Funktion des Indikators wird dir also wohl auch ein anderer

Wert zurückgegeben.

 

Hoffe ich lieg hier mit meiner Interpretation deiner Frage nicht total daneben :twiddle:

Link to comment
Share on other sites

Ok,

also das mit der SetIndexEmptyValue(0,0.0)-Funktion habe ich verstanden...glaube ich. :ot:

Demnach wird der Indikator nur ausgeführt, wenn der BufferWert unter diesem Wert liegt, den ich in die Klämmern geschrieben habe.

Hast Du dafür eventuell noch ein anderes Beispiel? Denn mir fällt spontan kein Szenario ein, bei dem ich das gebrauchen könnte... :twiddle:

 

Abhängig von der Funktion des Indikators wird dir also wohl auch ein anderer

Wert zurückgegeben.

...aber wird der Indikator auch sichtlich verändert oder nur die Ausgabewerte?

 

LG NC

Link to comment
Share on other sites

Ich habe jetzt mal ein Bischen mit dieser Funktion "SetIndexEmptyValue(0, 0.0)" rumprobiert und ein wenig geknobelt. Dabei sind mir ein paar interessante Sachen aufgefallen..

wenn der Indikator gezeichnet wird, die Stellen, an

denen der Wert 0.0 ist, nicht eingezeichnet werden.

...diese Aussage ist nicht ganz richtig. Die Ausführung ist von der Art des Indis abhängig. Bei einem Indikator habe ich diese Funktion mal aus dem Quelltext genommen und er gab mir die besagte Zahl "2147483647" zurück. Aber auch nur, wie Du bereits erwähntest, wenn der Buffer nicht in Benutzung ist oder noch kein Wert reserviert wurde.

In diesem Indikator hat es sich nicht auf die Darstellung ausgewirkt....lediglich auf die Wertausgabe.

Als ich direkt in der Schleife in den ausgeführten Segmenten, dem nicht benutzten Buffer die Zahl 0.0 zuwies, hat er es auch übernommen und 0.0 ausgegeben.

 

Jetzt habe ich noch mit einem anderen Indikator getestet und dieses Ergebnis war auch verblüffend.

Hier stand am Anfang der Schleife...

for (i = Bars; i >= 0; i--)
  {
  TrendUp[i] = EMPTY_VALUE;

...hier wird dem Buffer gleich der Empty-Status zugewiesen, welcher zur späteren Abfrage, ohne in Benutzung zu sein, den Wert "2147483647" ausgibt.

Als ich "EMPTY_VALUE" durch 0.0 ersetzte, wurde die Ausgabe mit 0.0 bestätigt. Jedoch gab es dann hier ein kleines Darstellungsproblem. Jedes mal, wenn "TrendUp" nicht in Benutzung war, wurde die eingezeichnete Linie auf den Chart-Wert 0.0 gesetzt. Also eine Gerade, quer über den Chart Richtung Boden... :twiddle:

Als nächste Variante habe ich "SetIndexEmptyValue(0, 0.0)" eingefügt und bin hier aber leider noch zu keinem klaren Ergebnis gekommen. Habe da im Moment noch ein paar kleine Differenzen mit meinem Programm...ständig unterschiedliche Wiedergaben und Werte. Aber nach der Behebung des Problems werde ich sofort neues Feedback geben.

 

Ein Fazit möchte ich da im Moment noch nicht abgeben.

Gibt noch viele Ungereimtheiten im Leben eines "iCustom-Noobs"

 

Wünsche aber vorerst ein schönes Wochenende...

 

LG NC

Link to comment
Share on other sites

Hallo NikkChade,

 

ich hab jetzt auch nochmal einwenig rumgespielt und widerrufe meine Aussage :twiddle: , dass SetIndexEmptyValue keinen Einfluss auf den Wert des Buffers hat.

Füg ich z.B. in einem Indikator die Anweisung

SetIndexEmptyValue(0,10000);

ein, so wird wirklich jeder nichtbeschriebene Bufferwert auf 10000 gesetzt.

Zeichne ich den Indikator dann in einen Chart ein, so werden aber die 10000er Werte nicht dargestellt.

Setz ich dann noch einige Werte auf EMPTY_VALUE, so werden diese auf 0x7FFFFFFF, also 2147483647 gesetzt.

Weder 0x7FFFFFFF noch 10000 wird im Chart angezeigt. Frag ich den Indikator aber (z.B. über iCustoms) ab,

so werden diese Werte sehr wohl zurückgeliefert.

 

Generell lässt sich also sagen:

1) Werte, die durch SetIndexEmptyValue() festgelegt werden, werden im Chart nicht eingezeichnet

2) Ein nicht aktiv geschriebener Bufferwert wird auf den durch SetIndexEmptyValue() festgelegten Wert gesetzt

2a) Ist kein SetIndexEmptyValue() vorhanden, so wird der Wert auf EMPTY_VALUE gesetzt.

3) Bufferwerte, die den Wert EMPTY_VALUE haben, werden auch nicht in den Chart eingezeichnet

4) Man kann nur einen SetIndexEMptyValue festlegen. Ruft man die Funktion im selben Indikator 2x hintereinander

auf, so wird nur der 2. Wert als Empty-Value (nicht zu verwechseln mit EMPTY_VALUE) übernommen

 

Zu deinem Beispiel.

Das bestätigt, soweit ich das sehe, das oben geschriebene.

Weist du TrendUp EMPTY_VALUE zu, so ist der Wert 2147483647.

Weist du dann 0.0 zu, so wird dieser Wert übernommen und in den Chart eingezeichnet, solange SetIndexEmptyValue(0,0.0) nicht aktiv ist.

Sobald SetIndexEmptyValue(0,0.0) aktiv ist, sollte der Wert 0.0 nichmehr im Chart eingezeichnet werden.

Schön sieht man das beispielsweise, wenn man sich den Indikator im Chart mit DRAW_LINE anstelle mit DRAW_SECTION

zeichnen lässt. Dann werden wirklich nur zugewiesene Bufferwerte gezeichent, bei 0-Werten entstehen Lücken.

 

Als Anwendung für SetIndexEmptyValue fällt mir z.B. ein, dass du 2 Kurven in deinem Indikator hast. Eine

für einen Long-Einstieg und eine für einen Short-Einstieg.

Die für den Long-Einstieg kann als Empty-Wert den Wert EMPTY_VALUE haben, die für den Short-Einstieg besser 0.0.

 

Solltest du noch zusätzliche Erkenntnisse haben, oder solltest du herausfinden, dass was von meinem geistigen

Erguss nicht stimmt, lass es mich bitte wissen.

 

Schönen Sonntag noch,

WOGO

Link to comment
Share on other sites

Ich glaube wir zwei haben das mit dem Erläutern für diese "SetIndexEmptyValue(0,0.0)" ganz gut hin bekommen. Für mich ist das ganze Spektakel ein wenig klarer. Habe auch nochmal im Navigator nachgeschlagen und dort steht als Beispiel:

//---- 0 value will not be displayed
SetIndexEmptyValue(0,0.0);
SetIndexEmptyValue(1,0.0);

...die einzelnen Buffer werden also komplett auf "0.0" gesetzt, sofern Sie keiner Berechnung oder einem anderen Wert unterliegen. Gilt aber in diesem Fall nur für das Drawing und nicht für die Wertausgabe. Diese wird auf "2147483647".

Demnach könnte man ja eigentlich auch behaupten, dass "SetIndexEmptyValue()" die Eigenschaften einer GlobalenVariablen bzw. eines DefaultParameters aufweist.

Man muss dem Buffer nicht ständig einen Wert zuweisen, wenn er mal nicht benutzt wird.

 

Jetzt vermute ich aber, warum es bei mir einige Fehler im Drawing gab. Manchmal wurde der Wert eingezeichnet und manchmal nicht. Wurde einmal die Gerade bis zur 0.0 gezogen und manchmal nicht.

"SetIndexStyle(0, DRAW_LINE, STYLE_SOLID, 2)" scheint einen beträchtlichen Teil dazu beigetragen zu haben und anscheinend hat meine Plattform das ständige Speichern, Kompilieren und Laden nicht verkraftet. Denn als ich den Chart mal von Links nach Rechts schob, wurden die Linien zu den veranschlagten Werten gezeichnet und mal nicht...

Das Alles war mir sehr suspekt! :twiddle:

Link to comment
Share on other sites

Denk auch, dass wir da ganzschön was an Erklärung rausgeholt haben :twiddle:

 

Denn als ich den Chart mal von Links nach Rechts schob, wurden die Linien zu den veranschlagten Werten gezeichnet und mal nicht...

 

Das Problem kenn ich auch.

Lag bei mir am Nachladen der historischen Daten. Das ist ein ganz gemeiner Effekt, der mich Tage gekostet hat und den ich nur mit Hilfe hier aus dem Forum lösen konnte.

 

Es ist so, wenn du einen Chart öffnest und der Indikator berechnet wir, dann sind noch nicht alle Balken des Charts geladen. Dein Indikator wird also schon mal für die geladenen Balken berechnet und dein Buffer wird gefüllt.

Sind dann alle Balken geladen, so liefert IndicatorCounted() wieder 0 und die Indikatorberechnung startet nochmal auf's neue für alle Balken. Im Indikatorbuffer sind aber noch die Werte aus dem ersten Durchlauf und es kommen zeitverschoben die Werte aus dem 2. Durchlauf dazu. Das sieht dann im Chart so aus, als hätte jemand deinen Indikator geschüttelt.

 

Zumindest war das bei mir das Problem.

Link to comment
Share on other sites

  • 2 weeks later...

Jetzt habe ich hier ein kleines Problem beim Einfügen eines iCustoms:

Ich wollte den Indi im Backtest laufen lassen und mir wurde folgendes angezeigt:

 

2010.05.15 13:49:22

TestGenerator: unmatched data error

(high value 1.4477 at 2010.01.13 01:00 is not reached from the least timeframe, high price 1.4473 mismatches)

 

und

 

2010.05.15 13:49:24

TestGenerator: unmatched data error

(volume limit 1776 at 2010.02.26 10:45 exceeded)

 

Kann es sein, dass der Auswurf der Parameter des iCustom nicht ganz mit dem Lesen im EA übereinstimmt?

Vielleicht die Datentypen?

Oder was könnte da nicht ganz passen?!

 

LG NC

Link to comment
Share on other sites

2010.05.15 13:49:22

TestGenerator: unmatched data error

(high value 1.4477 at 2010.01.13 01:00 is not reached from the least timeframe, high price 1.4473 mismatches)

 

Das hat nichts mit dem iCustom zu tun, sondern liegt rein an der Datenhistorie. Der Fehler sollte auch auftreten wenn du einen beliebigen anderen EA auf der gleiche Datenbasis (Symbol,TimeFrame) testest.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
×
×
  • Create New...