bueschl
Mitglied seit 11 Jahre 4 Monate
Gibt es eine Metastock-Formel zur ZigZag - Änderung ?
Das letzte Bein des Zig-Zag kann sich bekanntlich noch verändern.
Ich suche einen alternativen Zig-Zag, dessen letztes Bein sich nicht mehr verändert. Die Up und Downs sollen also fixiert werden. Dies bedeutet, dass innerhalb der herkömmlichen Zig-Zag-Kurve kleinere Swings angezeigt werden sollen.
Gibt es hierzu bereits Ansätze ? Hat jemand die Metastock-Formel für den herkömmlichen Zig-Zag ?
Danke
Geschrieben von bueschl
am
Meine erste Anfrage konnte leider nicht beantwortet werden, daher ein neuer Versuch:
Gibt es einen Indikator, der falsche Zig-Zag-Ausbrüche anzeigen kann? D.h. der Zig-Zag dreht z.B. von unten nach oben, nimmt aber später seine ursprüngliche Richtung nach unten wieder auf. Auf der Zig-Zag-Kurve ist der Ausbruch nach oben dann nicht mehr zu erkennen.
Mit einer Anzeige des "Fehlsignales" wäre mir sehr geholfen.
Danke und Gruss
Bueschl
Hallo Bueschl,
es ist nicht leicht, Deine Frage zu beantworten, da sie nicht klar verständlich gestellt ist (sie könnte präziser gestellt werden).
Wenn Du Dir mit Metastock einen Indikator wie folgt erstellst und dann im Chart anzeigen läßt, siehst Du, daß die Peaks und Troughs bei der Peak(), Trough(), PeakBars() und TroughBars()-Funktion erst dann feststehen, wenn definitiv feststeht, daß hier auch ein Peak bzw. Trough (somit Wendepunkt der ZigZag-Funltion) vorliegt. Sprich: die Lage der von den vorherigen Funktionen ermittelten Peaks und Troughs wird nicht mehr nachträglich geändert (sofern ich es richtig sehe).
Indikator WS_Peaks
{shows all Peaks}
m:= Input("PercentChange" ,0 ,100 ,3 ) ;
If(0=PeakBars(1,C ,m) ,1 ,0 )
Indikator WS_Troughs
{shows all Troughs}
m:= Input("PercentChange" ,0 ,100 ,3 ) ;
If(0=TroughBars(1,C ,m) ,1 ,0 )
Allerdings liegt das Problem woanders. Für die Entwicklung von Handelssystemen (oder selbst auch von Pattern-Matching-Funktionalität) können diese Funktionen nicht einfach in obiger Form eingesetzt werden. Der Grund ist, daß Metastock, um zu ermitteln, ob an einer Bar wirklich ein Peak/Trough vorliegt, auch die folgenden Bars betrachtet, um eindeutig zu sehen, daß die aktuelle Bar ein Wendepunkt ist. Relativ von der Lage der Peak/Troughs blickt die Implementierung der ZigZag-Funktion somit in die Zukunft.
Wenn man das verstanden hat, kann man aber trotzdem auf Basis der ZigZag-Funktion Indikatoren bzw. Handelssysteme entwickeln. Man darf sie eben nur nicht so verwenden, daß ihr Wissen in die Zukunft zu schauen ausgenutzt wird.
Beispielsweise folgt aus If(0=TroughBars(1,C ,m) ,1 ,0 ) == true, daß die nächsten Tage steigen werden, sonst wäre diese Bar kein Wendepunkt für die ZigZag-Funktion. Dieses Wissen darf an an der Bar, an der If(0=TroughBars(1,C ,m) ,1 ,0 ) == true ist, nicht verwendet werden.
Der folgende Indikator von mir ist ein Beispiel, wie die ZigZag-Funktion korrekt eingesetzt wird (ohne ihr Zukunftswissen zu nutzen). Er liefert an einer Bar true, wenn der letzte via der ZigZag-Funktion definitiv ermittelte Peak-Wendepunkt nach oben überwunden wurde (übrigens eine interessante Alternative zum Aroon).
Indikator WS_Break_Above_Last_Peak
m:=3;
cond1:=TroughBars(1 ,C,m)
Peak(1,C,m);
cond2:= 0=PeakBars(1,C ,m) AND C>Peak(2,C,m);
If( cond1 OR cond2, 1, 0)
Sonst eine generelle Bemerkung: Wie Metatrader schon seiner Antwort auf die Frage zur Erkennen der Dreiecksformationen erwähnt hat (und da hat er Peak() und Trough() übrigens so genutzt, dass versehentlich auch Zukunftswissen eingehen kann), wäre es am besten, viele kompliziertere Sachen in einer externen Programmiersprache via DLL zu implementieren (wobei die Funktionen von der Metastock Formula-Language aus dann via FMLext() genutzt werden).
Leider ist die Firma EQUIS an Arroganz nicht zu überbieten; ihre Strategie ist, selbst die Schnittstelle zur Entwicklung solcher DLLs praktisch geheimzuhalten. Mal ganz abgesehen davon, daß EQUIS das Metastock SDK zu Mondpreisen verkaufen möchte (für ein paar einfache Header-Files, damit man eine DLL erstellen kann),
ist es inzwischen auch nur nach Registrierung als Entwickler erhältlich, an der grundsätzlich überhaupt nichts auszusetzen ist; Problem ist in der Praxis nur, daß offenbar die Sache nicht akzeptiert wird, wenn man selber kein kommerzielles Unternehmung betreibt. Equis kann wohl kaum erwarten, daß ich ihnen im voraus detailliert den Code und gezielte Ideen von brauchbaren Ansätzen schicke, damit sie mir die möglichst klauen; immerhin taugen ihre völlig überteuerten Plugs-Ins allenfalls nur begrenzt was. Bei Tradestation hingegen ist die Beschreibung der externen Schnittstelle zur Entwicklung von DLLs standardmäßig in der Dokumentation enthalten.
Ich halte die Arroganz von EQUIS für so unübertroffen hoch, daß ich mit Sicherheit kein weiteres Geld für EQUIS-Produkte ausgeben werde. Und es ist auch ein Grund, wieso ich mich bei Foren-Anfragen (wie beispielsweise dieser Anfrage zur ZigZag-Funktion oder auch Sachen wie das Dreiecks-Pattern-Matching) zukünftig zurückhalten und somit dann nicht mehr EQUIS durch Hilfestellung anderer User unterstützen werde. Anders als Metatrader bin ich ja nicht mit einem kommerziellen Metastock-Distributor assoziiert.
Gruß,
Wolfgang
> Das letzte Bein des Zig-Zag kann sich bekanntlich noch verändern.
Verändern tut sich nur das letzte Bein, wenn der in Metastock eingebaute Indikator im Chart geplottet wird. Was für die Funktionen peak(), trough(), peakbars(), troughbars() gilt, habe ich weiter oben beschrieben.
> Gibt es einen Indikator, der falsche Zig-Zag-Ausbrüche anzeigen kann? D.h.
> der Zig-Zag dreht z.B. von unten nach oben, nimmt aber später seine
> ursprüngliche Richtung nach unten wieder auf. Auf der Zig-Zag-Kurve ist der
> Ausbruch nach oben dann nicht mehr zu erkennen. Mit einer Anzeige
> des "Fehlsignales" wäre mir sehr geholfen.
Du musst hier näher präzisieren, welche Signale Du genau haben willst.
Genaugenommen kann das letzte Bein in 2 Teil-Segmente unterteilt werden.
Solange noch nicht der nächste Wendepunkt definitiv ermittelt wurde, können sich diese beiden letzten Teil-Segmente ändern.
Allerdings ändert sich nicht die Groborientierung (d.h. up vs. down) des letztens Beins (= beide Teilsegmente zusammengefaßt).
Hallo global2,
ich muss vorausschicken, dass ich gerademal mit den Metastock-Grundfunktionen vertaut bin. Entschuldige also die vielleicht blöde Frage.
Du schreibst: "Der folgende Indikator ("WS_Break_Above_Last_Peak") von mir ist ein Beispiel, wie die ZigZag-Funktion korrekt eingesetzt wird (ohne ihr Zukunftswissen zu nutzen). Er liefert an einer Bar true, wenn der letzte via der ZigZag-Funktion definitiv ermittelte Peak-Wendepunkt nach oben überwunden wurde (übrigens eine interessante Alternative zum Aroon)."
Heißt das jetzt im Klartext, dass dieser Indikator WIRLKLICH nie und ÜBERHAUPT nicht in die Zukunft blickt (eben im Gegensatz zum herkömmlichen Zig-Zag)?
Das heißt konkret: könnte man die Signale eines solchen Indikators real handeln, so wie man das Kreuzen eines MACD handeln könnte?
Vielen Dank im voraus jedenfalls für die Aufklärung.
PS: Ich verspreche, dass mich fortan mehr mit MS-Language befassen werde, damit ich nächstes Mal nicht mehr so blöd fragen muss.
@ Global 2
Können wir für Sie bei Equis etwas tun, zum Beispiel Sie als freien Mitarbeiter der Ebert AG anmelden, damit Sie die notwendigen Informationen und die Registrierung als Entwickler erhalten ?
@ Rubelit
@ alle
Solche Versprechen lese ich gerne. Genauso freut mich, dass Mitglieder, die früher nur gefragt haben, jetzt die Antworten geben. Sie können das Wissen, dass ihnen von anderen geschenkt wurde, jetzt weitergeben.
Hallo Herr Ebert,
das ist ein interessanter Vorschlag. Ich hatte mich bei Equis vor einiger Zeit via Webformular für das Metastock SDK registriert und in gutem English recht ausführlich meine Intention beschrieben (developing custom formulas and trading systems for Metastock using an external programming language). Ich hatte zu sämtlichen Punkten ausführliche Angaben gemacht, dabei u.a. auch klar erklärt, daß ich _nicht_ als Data Vendor das Angebot von Kursdaten beabsichtige.
Punkte wie die Frage, welcher Nutzen für Equis herausspringen würde, konnte ich nur allgemein derart beantworten, daß meiner Ansicht nach die Verfügbarkeit von Tools & Addons der Attraktivität von Metastock (und somit den Sales von Equis) eigentlich nur förderlich wäre. Auf meine Registrierung erfolgte keinerlei Reaktion von Equis. Allerdings muß ich einräumen, daß ich daraufhin noch nicht nachgehakt habe.
Das liegt auch daran, das es mir eigentlich auch noch nicht darum ging, schnell ein konkretes Produkt herauszubringen (letzteres wäre durchaus eine theoretische Option, falls eine Sache in der Praxis nützlich sein sollte), sondern erstmal darum, daß ich gerne mal einige Ideen auf Praxistauglichkeit hin evaluieren würde. Zudem benötige ich das Metastock SDK aktuell nicht, da ich derzeit an mehreren anderen Sachen (nicht Investment-bezogen) arbeite. Ich kann mir aber gut vorstellen, auf Ihren Vorschlag zukünftig zurückzukommen, wenn ich mich wieder mit dem Thema verstärkt beschäftigen will.
@ Rubelit
Die Problematik mit dem "in die Zukunft schauen" besteht beim Backtesting. Beim regulären Handel können Indikatoren zwangsläufig nur Kursdaten bis zum aktuellen Zeitpunkt verwenden (denn Daten für zukünftige Zeitpunkte gibt es ja noch gar nicht). Anders sieht es beim Backtesting aus, wenn ein Handelssystem anhand einer Kursdatenzeitreihe simuliert werden soll. Hier muß aufgepaßt werden, daß nicht versehentlich zu einem Zeitpunkt Kursdaten verwendet werden, die es in der Realität zu diesem Zeitpunkt noch gar nicht geben würde.
So wie der "WS_Break_Above_Last_Peak"-Indikator programmiert ist, verwendet er die Peak()-Funktion derart, daß ihre Eigenschaft, in die Zukunft zu schauen, nicht ausgenutzt und somit bewußt ignoriert wird (relativ vom jeweils aktuellen Handelstag aus gesehen). Das Backtesting und Handel des Indikator kann problemlos erfolgen.
Beim Indikator verschluckt die Forumsoftware übrigens ein "kleiner"-Zeichen, im folgenden mit "lessThan" umschrieben:
Indikator WS_Break_Above_Last_Peak
m:=3;
cond1:=TroughBars(1 ,C,m) "lessThan" Peak(1,C,m);
cond2:= 0=PeakBars(1,C ,m) AND C>Peak(2,C,m);
If( cond1 OR cond2, 1, 0)
Hm, da ist von der Terminmarktwelt-Forumsoftware mehr als nur das "kleiner"-Zeichen verschluckt worden:
Hier nochmal die vollständige Formel:
m:=3;
cond1:=TroughBars(1 ,C,m) "lessThan" PeakBars(1,C,m) AND C "greaterThan" Peak(1,C,m);
cond2:= 0=PeakBars(1,C ,m) AND C "greaterThan" Peak(2,C,m);
If( cond1, 1, 0)
Indikator WS_Break_Above_Last_Peak:
m:=3;
cond1:=TroughBars(1 ,C,m) "lessThan" PeakBars(1,C,m) AND C "greaterThan" Peak(1,C,m);
cond2:= 0=PeakBars(1,C ,m) AND C "greaterThan" Peak(2,C,m);
If( cond1 OR cond2, 1, 0)
@ Global_2
Mit Formeln kenne ich mich nicht aus. Sicherheitshalber habe ich den Webmaster alarmiert, der sich der verschwundenen Zeichen annehmen kann. Nur heute wohl nicht mehr.
Eine Notlösung könnte sein, dass Sie das Tabellen-Format für die Formel verwenden. Sie finden dieses in der Kurzanleitung, während Sie einen Beitrag schreiben.
@ignore
m:=3;
cond1:=TroughBars(1 ,C,m) < PeakBars(1,C,m) AND C > Peak(1,C,m);
cond2:= 0=PeakBars(1,C ,m) AND C > Peak(2,C,m);
If( cond1, 1, 0)
--
Indikator WS_Break_Above_Last_Peak:
m:=3;
cond1:=TroughBars(1 ,C,m) < PeakBars(1,C,m) AND C > Peak(1,C,m);
cond2:= 0=PeakBars(1,C ,m) AND C > Peak(2,C,m);
If( cond1 OR cond2, 1, 0)
--
Hmm, das ist mal wieder typisch. Wenn man selber versucht, das Problem mit den verschluckten Zeichen zu finden, funktioniert wieder alles korrekt.
Gruss
Heiko Weber
Entscheident ist, daß es wirklich "If( cond1 OR cond2, 1, 0)" und nicht nur "If( cond1, 1, 0)" heißt.
Cond2 beseitigt das "in die Zukunft schauen". Wenn die Bedingung 0=PeakBars(1,C ,m) gilt, bedeutet dies nichts anderes, als daß an der aktuellen Bar ein Wendepunkt (Peak) für den ZigZag festgestellt wurde. Genau diese Feststellung ist aber nur möglich, wenn Wissen vorliegt, dass die Kursdaten für den nächsten Tag tiefer als am aktuelle Tag liegen (andernfalls wäre der aktuelle Tag kein relatives Maximum/Peak). In diesem Fall ignorieren wir einfach das neue gefundene Peak, berücksichtigen aber trotzdem, daß sich die Numerierung des vorherigen Peaks von 1 auf 2 ändert.
Hallo,
man kann die Gültigkeit des ZigZag auch näherungsweise durch die folgende Funktion überprüfen
(Im Original von Spyros Raftopoulos)
{1 = valid, 0 = invalid}
perc:=Input("Percent",1,200,10);
Z:=Zig(C,perc,%);
last:=ValueWhen(1,( Z > Ref(Z,-1) AND Ref(Z,-1) Ref(Z,-2) )
OR ( Z Ref(Z,-1) AND Ref(Z,-1) > Ref(Z,-2) ), Ref(Z,-1) );
pc:=If(C > last, (C-last) * 100 / last, (last-C) * 100 / last);
pc:= Abs(pc);
cdBars:= BarsSince( (ZRef(Z,-2) ) OR
(Z>Ref(Z,-1) AND Ref(Z,-1)=perc,1,0);
indBars:= BarsSince(ind=1 AND Ref(ind,-1)=0);
If(indbars
> Man sollte nur allgemein bedenken, das weniger als 1% der Benutzer überhaupt
> in der Lage sind zu programmieren und wer wirklich ernsthaft Tools für MS
> entwickeln will muss halt den Weg über eine Registrierung bei Equis gehen.
Klar, gegen die Registrierung habe ich gar nichts gesagt. Nur scheint genau die Kompetenz in der SW-Entwicklung eben _nicht_ das Kriterium dafür zu sein, ob Equis die Registrierung akzeptiert oder nicht. Das Kriterium sind eher Punkte wie Company-Zugehörigkeit, Nature of Business sowie am wichtigsten wohl bereits ein Marketing-Plan fürs Produkt mit Absatzprognose. Ein Problem ist oft, wenn BWLer ohne Fachwissen zuständig sind. Mein Bruder wollte Anfang der 90er Jahre mal eine Spezifikation der externen Programmierer-Schnittstelle zu einer Soundkarte haben (ich glaube sie hieß Pro Audio Spectrum), und die BWLer weigerten sich zunächst heftig und hatten die Specs erst später zugeschickt, da sie erst dachten, sie würden damit Industriegeheimnisse preisgeben und es wäre eine Anleitung, um den Chip einfach nachzubauen (= völliger Blödsinn, die Knaller hätten nur einen Blick in die Spezifikation werfen müssen. Und vor allem auch nachdenken müssen, dass Unterstützung ihrer Soundkarte, insbes. auch der über die Soundblaster-Kompatiblität hinausgehenden Features, den eigenen Absätzen nur förderlich gewesen wäre.).
Aber vielleicht war bei mir auch einfach nur was schief gelaufen, ich habe nicht explizit bei Equis nachgehakt.
Mit meiner Äußerung "nur ein paar Header Files" meinte ich übrigens, dass das MDK nicht ein richtiges Framework für die Entwicklung externer Funktionen darstellt, sondern in Form des MSX API eher nur rudimentäre Funktionalität für den Zugriff auf Preisdaten in Metastock bereitstellt (sofern meine Infos richtig sind). Wahrscheinlich ist das MSX API ähnlich wie das DLL Extension Kit der Tradestation. Früher hatte Equis die Read/Write Version des MDK für über $200 verkauft (wenn ich mich recht erinnere), was ein unverschämter Preis ist, wenn man einzig die Header Files für die Implementierung externer Funktionen benötigt.
Vorab ein grosses Dankeschön an Alle für die Hilfestellungen.
#global2
Es wäre schade, wenn Du nicht mehr mit Rat und Tat zur Seite stehen würdest!
Bezüglich der untigen Formel habe ich noch ein Verständnisproblem:
Indikator WS_Break_Above_Last_Peak
m:=3;
cond1:=TroughBars(1 ,C,m) "lessThan" Peak(1,C,m);
cond2:= 0=PeakBars(1,C ,m) AND C>Peak(2,C,m);
If( cond1 OR cond2, 1, 0)
In conditon 1 soll das letzte Trough kleiner sein als das letzte Peak. Ist das denn nicht generell der Fall? Sagt die Formel im Ganzen denn nichts anderes als dass das Close grösser sein muss als das 2. jüngste Peak?
Um meine Anfrage nochmals zu präzisieren:
Ich suchte einen Indikator, der mir die Bars anzeigt, an denen der geplottete Zig-Zag "Fehlalarm" erzeugt hat. Soll z.B. bedeuten, am Tag x wird ein Trough erzeugt, am Tag x+1 liegt Zig-Zag über Trough und am Tag x+2 plötzlich wieder unter Tag x (das letzte Bein ist plötzlich wieder verschwunden). Ich denke, ohne externe Programmierung wird dies wohl nicht möglich sein. Leider beherrsche ich keine Programmiersprache.
Nochmals Dank an Alle, es macht mächtig Spass hier!
@Bueschl
1) Du hast die Formel für Cond1 aus der (fehlerhaften) Version entnommen, wo etwas wegen der Sonderzeichen abgeschnitten wurde. Sie muss korrekt wie folgt heißen:
cond1:=TroughBars(1 ,C,m) "lessThan" PeakBars(1,C,m) AND C "greaterThan" Peak(1,C,m);
In Worten: Letztes via ZigZag definitiv ausgemachtes Trough liegt zeitlich später als das letzte erkannte Peak und Close ist größer als dieses Peak (genau diesen BreakAboveLastPeak wollen wir ja feststellen).
Problem ist nun folgendes: Seit t_n der aktuellste Zeitpunkt beim Backtesting. Wenn Metastock nun erkennt, daß t_n ein neues Peak ist (da die ZigZag-Funktion auch den zukünftigen Tag t_n+1 betrachtet), dann wurde etwas festgestellt, was in der Realität so nie feststellbar wäre. In diesem Fall können wir unseren Vergleich nicht mehr mit Formel "cond1" durchführen, sondern wir müssen berücksichtigen, daß sich die Numerierung desjenigen Peaks, mit dem wir unseren Vergleich durchführen wollen, von 1 auf 2 erhöht.
2) Ich glaube, daß ich jetzt weiß, was Du unter "Fehlalarm" verstehst. Du plottest den in Metastock eingebauten ZigZag-Indikator grafisch im Chart und beobachtest dann die Veränderung des "letzten Beins". Inwieweit man mit der Metastock Formula Language einiges machen kann, kann ich jetzt aber nicht vorschnell beantworten, ohne darüber erstmal in Ruhe nachzudenken.
Problematisch bei Deinem Indikator-Wunsch ist, daß sich die Indikatorwerte für vergangene Tage nachträglich im Laufe der Zeit ändern sollen (Bars mit "Fehlalarm" lt. Deiner Definition sollen nachträglich markiert werden). Man muß übrigens das Verhalten der ZigZag()-Funktion von den Peak() und Trough() Funktionen trennen. Letztere erzeugen erst dann Peaks() und Troughs(), wenn diese definitiv feststehen.
Hallo bueschel,
5 Beiträge höher steht eine Formel, mit der die Validität der ZigZag Formel überprüft werden kann.
Metatrader:
5 Beiträge höher steht eine Formel, mit der die Validität der ZigZag Formel überprüft werden kann.
Offenbar hat auch da die Forumsoftware gnadenlos zugeschlagen, so dass es auch bei dieser Formel zu Verkürzungen gekommen ist.
Den ZigZag Validity Indikator von Spyros Raftopoulos findet man auch u.a. auf der folgenden Website (siehe Link), wobei die Formel aber etwas anders als die von Metatrader ist. Dort ist auch eine Erklärung von Spyros Raftopoulos beigefügt.
http://eis.pl/kr/AFM/e-w-ZigZag_Validity.html
Eine 1 beim Indikator bedeutet, dass das ZigZag-Signal definitiv gültig ist und sich nicht mehr ändern kann (da Distanz zum letzten Wendepunkt größer als der vorgegebene ZigZag-Prozentwert). Eine 0 bedeutet hingegen, dass das ZigZag-Signal (zum jeweiligen Zeitpunkt) sich noch prinzipiell ändern könnte. Stellen mit 0 können sich daher an den Folgebars in der Terminologie von Bueschl noch als "Fehlalarm" herausstellen, wobei dies aber nicht zwingend ist.
Der ZigZag-Validity Indikator ist insofern nicht 100% das, was Bueschl genau möchte. Bueschl möchte einen Indikator, der genau anzeigt, wann der ZigZag einen "Fehlalarm" (lt. seiner Terminologie) lieferte. Das ist eine erheblich schwierigere Problemstellung, die möglicherweise mit der Metastock-Formula Language nicht zu lösen ist.
Wenn ich es richtig sehe (wobei ich es das aber jetzt noch nicht formal verifiziert habe), ist die Formel von Spyros Raftopoulos insofern nicht optimal, da sie in bestimmten Situationen auch schon früher eine 1 anzeigen könnte. Es ist wohl möglich, über eine andere Art der Berechnung bereits früher die "1" (d.h. die Stabilitität des ZigZag-Signals) zu erkennen. Die Idee dazu wäre die Verwendung der Peak()/Trough()-Funktion, die (wie oben von mir beschrieben) stets stabile Ergebnisse liefert.
Ich habe die Sache nicht verfolgt, aber offenbar hat auch Spyros Raftopoulos seine ZigZag-Indikatoren fortentwickelt, siehe beispielsweise
http://www.purebytes.com/archives/metastock/2002/msg01138.html
Mich würde die Formel vom Zig-Zig interessieren, bisher bin ich diesbezüglich nicht fündig geworden.
Baut der Zig-Zag auf Peak() und Trough() auf und misst die Steigung zwischen dem letzten Preis und dem letzten Wendepunkt ?
Hallo Global_2,
danke zunächst für Deine Antwort. Mittlerweile habe ich mir das genauer angeschaut und vielleicht ist es auch für Dich von Interesse, dass der Indikator "WS_Break_Above_Last_Peak", mitunter schon in die Zukunft schaut.
Überprüft habe ich das am Nasdaq Composite. Im folgenden nur einige Beispiele:
Signal im Backtest / Tatsächlich wird das Signal nachträglich eingefügt am:
18.7.00 / 19.7.00
8.8.00 / 10.8.00
5.9.00 / 6.9.00
23.10.00 / 25.10.00
6.12.00 / 7.12.00
24.1.01 / 25.1.01
Die verwendete Einstellung war: "close 0".
Danke erstmal für den Hinweis, Rubelit. Der 18.07.00 ist ein gutes Beispiel. Dort wechselt der Indikator schon zu früh auf 0, was nur durch "in die Zukunft schauen" möglich ist. Es müßte aber möglich sein, hier Abhilfe zu schaffen.
Es zeigt sich hier einmal mehr, mit welcher Vorsicht man die ZigZag-Funktionen nur in Handelssystemen einsetzen darf.
@ Rubelit
So, dieser Bug ließ sich beseitigen. Es muß aber noch überprüft werden, ob noch ein weiterer Fall des in die Zukunfts schauens beseitigt werden muss.
{WS BreakAboveLastPeak 2}
m:=3;
cond1:=TroughBars(1 ,C,m) "lessThan" PeakBars(1,C,m) AND C "greaterThan" Peak(1,C,m);
cond2:= 0=PeakBars(1,C ,m) AND C "greaterThan" Peak(2,C,m);
pc:=(Peak(1,C,m)-C)*100/Peak(1,C,m);
cond3:= TroughBars(1 ,C,m) "greaterThan" PeakBars(1,C,m) AND pc "lessThan" m AND
C "greaterThan" Peak(2,C,m);
If( cond1 OR cond2 OR cond3, 1, 0)
Was meinst Du mit Einstellung "Close 0"? Und wie hast Du die Sachen effektiv getestet?
Ja, u.a. muß durch die neue Condition 3 ein weiterer Fall abgefragt werden, damit nicht ein fehlerhaftes 1 Signal entsteht.
Es läuft darauf hinaus, dass eine Art ZigZag-Validity eingebaut werden muss (was ich jetzt über einen anderen Ansatz als den von Spyros Raftopoulos versucht habe). Der folgende Code sollte eine weitere Verbesserung sein, wobei dies jetzt alles andere als verifiziert ist [da ich aktuell noch nebenbei einen Blick auf den RT-Streamer laufen habe ;) ]. Zudem sind gegebenfalls noch weitere Sonderfälle zu überprüfen und auszumerzen, ohne daß dies neue Probleme aufwirft.
{WS BreakAboveLastPeak 3}
m:=3;
cond1:=TroughBars(1 ,C,m) "lessThan" PeakBars(1,C,m) AND C "greaterThan" Peak(1,C,m);
cond2:= 0=PeakBars(1,C ,m) AND C "greaterThan" Peak(2,C,m);
pc:=(Peak(1,C,m)-C)*100/Peak(1,C,m);
cond3:= TroughBars(1 ,C,m) "greaterThan" PeakBars(1,C,m) AND pc "lessThan" m AND C "greaterThan" Peak(2,C,m) AND BarsSince( pc "greaterThan" m) "greaterOrEqual" PeakBars(1,C,m);
If( cond1 OR cond2 OR cond3, 1, 0)
Konfiguration zum (grafischen) Testen:
Cond3==true impliziert Cond2==true, insofern kann Cond2 gestrichen werden.
Da habe ich mich eben vertippt: Cond2==true ==> Cond3==true
Ich mache jetzt lieber Schluss für heute.
@ Rubelit
Ich habe mir eben noch die von Dir aufgeführten Fälle kurz angeschaut. Vorhin während der US-Handelszeiten hatte ich nur den 18.7.00 herausgegriffen.
Die folgenden Stellen halte ich eigentlich auch bereits mit der alten Version für korrekt. Wo soll denn da Deiner Ansicht nach das Fehlverhalten sein? Wie sollte dort das Sollverhalten sein? Ich frage, weil ich vielleicht was übersehen habe.
8.8.00
5.9.00
6.12.00
24.01.01
18.7.00 und 23.10.00 waren hingegen die Fehler, die jetzt nicht mehr vorkommen.
Hallo Global_2,
Du hängst Dich ja ganz schön rein ;-) Wobei ich das wirklich zu schätzen weiß.
Zu Deiner Frage von oben: "Was meinst Du mit Einstellung "Close 0"? Und wie hast Du die Sachen effektiv getestet?"
Mit "close 0" meinte ich nur, dass die Signalumsetzung am Tag des Auftretens erfolgen sollte. Das hatte lediglich den Hintergrund, dass ich ja einige Fehl-Signale (mit Datum) angegeben hatte, anhand derer sich jeder selbst ein Bild machen konnte. Bei einem ev. voreingestellten delay auf "open next day", wären die Signale ja einen Tag später angezeigt worden.
Getestet hab ich auf ganz primitive Weise, d.h. ich habe die Datenreihe sukzessive neu geladen (sukzessive verlängert), und stets den Systemtester auf´s Neue bemüht.
Die Ergebnisse waren dann problemlos mit einem Test auf die vollständige Datenreihe (bei dem die Zukunft der Signale ja "bekannt" war) vergleichbar.
@ Global_2
Jetzt sehe ich gerade Dein letztes Posting und werde mir das nochmal ansehen.
Du hängst Dich ja ganz schön rein ;-)
eigentlich gar nicht so sehr; aktuell beschäftige ich mit der Metastock Formula Language nicht mehr viel. Es ist nur so, daß mich die Sache gestern etwas gewurmt hat. Meinen BreakAboveLastPeak-Indikator hatte ich weiter oben in diesem Thread nur deshalb als Beispiel erwähnt, um zu zeigen, mit welchem Ansatz man grundsätzlich das "in die Zukunft schauen" der ZigZag-Funktionen entschärfen kann. Nämlich so, daß man diejenigen Fälle identifiziert, wo in die Zukunft geschaut wurde, und dann die daraus gewonnenen Erkenntnisse nicht verwendet. In der ursprünglichen Version identifizierte Cond2 einen solchen Fall. Allerdings blieben die andere Fälle (die jetzt mit Cond3 abgedeckt werden) noch unberücksichtigt. Das lag auch daran, daß für meine ursprüngliche Zielsetzung einzig der Signalwechsel von 0 auf 1 von Interesse war (um Überwindung des bisherigen Peaks anzuzeigen).
Diverse Handelsansätze (Point&Figure, Rosshaken, Aroon, Darvas Boxen) haben alle gemeinsam, daß die Überwindung bisheriger Hochpunkte (bzw. auch Tiefpunkte) von Bedeutung ist.
Hallo Global_2,
hab´s mir nochmal angesehen: Die Signale vom 8.8.00 (wird erst angezeigt, nachdem der 10.8.00 geladen ist), vom 5.9 (beim Laden des 6.9.00) und vom 24.1.01 (25.1.01) haben sich bei mir nach der alten Formel erneut als Fehlsignale herausgestellt. Beim 6.12.00 habe ich mich offenbar geirrt (verschrieben?).
Aber das ist Schnee von gestern. Die neuere Version Deines Indikators dürfte nach grober Durchsicht klaglos funktionieren, leider auf Kosten der Signalqualität.
Ich will nicht ausschliessen, dass ich irgendwas übersehen habe, aber der 08.Aug.2000 ist m.E. völlig korrekt, bei beiden Indikatorversionen. Ebenso am 5/6 Sept. 2000 und 24/25.Jan 2001 sehe ich keinerlei Fehlverhalten.
Hier der erste Fall: 8.Aug.2000 bis Anfang Sep 2000:
Wenn man beim Nasdaq Composite Daten nur bis (einschließlich) 08.Aug.2000 berücksichtigt, ist feststellbar, daß
* letztes Trough am 2.08.2000 war
* letztes Peak am 20.7.2000 liegt
* der Close am 08.08.2000 (3845.55) liegt zwar 5.1% höher als das Trough am 2.Aug.2000, allerdings deutlich niedriger als das letzte definitiv erkannte Peak vom 20.Jul.2000. Deshalb liefern sowohl die alte als auch neue Indikatorversion beide dasselbe Ergebnis, nämlich eine 0.
Berücksichtigt man Daten bis (einschl.) 09.Aug.2000, bleibt das letzte endgültig erkannte Trough am 2.Aug.2000 und das letzte Peak am 20.7.2000.
Hat man Daten bis (einschl.) 10.Aug.2000, ändert sich nach wie vor nichts.
10.Aug.2000 hat zwar eine grosse schwarze Kerze, aber ihr Close (3759.99) liegt nur 2.4% tiefer als das letzte bekannte relative Maximum seit dem Trough am 2.Aug.2000 (was der Close am 9.Aug.2000 ist, 3853.50). Da wir eine ZigZag-Mindestveränderung von 3% zum letzten relativen Maximum/Minimum erfordern, reicht das nicht aus, um den 9.Aug zum neuen Peak zu deklarieren. Das letzte erkannte Peak bleibt insofern der 20.Jul.2000.
Daran ändert sich nichts bis zum 31.Aug.2000, erst an diesem Tag liegt der Close (4206.35) über dem Peak vom 20.07.2000. Sowohl die alte als auch neue Indikatorversion liefern jetzt beide korrekt eine 1, um den BreakAboveLastPeak anzuzeigen
Am Folgetag 01.Sept.2000 bleiben beide Indikatoren auf 1, da der Close ebenfalls über dem alten Peak vom 20.07.2000 liegt.
Am 05.Sept.2000 kann noch nicht erkannt werden, dass der 01.Sept. 2000 später sich als neues Peak herausstellen wird. Denn am 05.Sep 2000 beträgt die prozentuale Veränderung zum 01.Sept.2000, d.h. dem bisherigen relativen Maximum seit letztem Trough (02.Aug.2000), weniger als 3%. Deshalb muß laut Sollverhalten der Close nach wie vor mit dem letzten erkannten Peak, d.h. dem 20.Jul.2000 verglichen werden. Da er tiefer als dieses liegt, ist das Sollverhalten, dass nun der Indikator eine von 1 auf 0 geht. Das tun beide Indikatorversionen, wobei das bei der ersten Version aber deswegen erfolgt, da sie am 05.09.2000 bereits für das letzte Peak nun den 01.09.2000 sieht (was aber nur deswegen möglich ist, da Metastocks Peak()-Funktion in die Zukunft schaut, d.h. die Folgetage berücksichtigt).
Die erste Indikatorversion hat m.E. völlig korrekt funktioniert, was den Signalwechsel von 0 auf 1 betraf. Allerdings konnten Signalwechsel zurück von 1 auf 0 aufgrund von Zukunftsinformation erfolgen. Dass ich das in der ersten Version nicht ausgeschlossen hatte, lag auch daran (wie bereits weiter oben erwähnt), dass ich eigentlich einzig am Signalwechsel von 0 auf 1 interessiert war (der eben das Überwinden des bisherigen klar identifizierten Peaks signalisiert).
Nur der Korrektheit halber um Mißverständnissen vorzubeugen:
In der vorangegangenen Grafik muß die Beschriftung des blauen Indikators "WS BreakAboveLastPeak" anstatt "WS BreakAboveLastPeak 2" heissen, damit sie mit den Versionsnummern aus diesem Thread konsistent ist.
Angesichts des weiter oben in diesem Thread erwähnten Metastock Development Kits noch ein Nachtrag der Vollständigkeit halber: Equis hat jetzt mit Verzögerung auf meinen Antrag fürs MDK reagiert (ohne daß ich von mir aus irgendwie nachgehakt habe) und mir Conditional Approval gegeben, unter der Bedingung dass ich auf 7.2 oder 8.0 upgrade.
Gründe für die Upgrade-Bedingung hat Equis zwar nicht genannt, ich kann sie aber im gewissen Sinn durchaus nachvollziehen (z.B. damit externe Functions, falls sie in der Öffentlichkeit vermarktet werden sollten, auch mit den neuesten Metastock-Versionen getestet wurden).
Ich will ein Upgrade nicht ausschliessen, werde in der näheren Zeit aber noch weiterhin etwas abwarten, da ich momentan ohnehin mit anderen Projekten (als Indikatoren/Handelssystemen) beschäftigt bin.
Hallo Global_2,
warum Equis jetzt reagiert hat, weiss ich nicht.
Mir ist jedoch bekannt, dass man dort immer wieder in dieses Forum reinsieht.
Ich habe diesen Thread mit Interesse verfolgt.
Leider kann man die hier erwähnten Indikatoren nicht auf Intraday-Daten anwenden. Liegt das eventuell am fehlendem Datum ?
Danke
Hallo beginner,
Der BreakAboveLastPeak-Indikator funktioniert auch mit Intraday-Daten (beisp. Charts mit TimeFrame= 1 Minute). Wenn er bei Dir nichts anzeigt, liegt das vermutlich daran, dass die ZigZag-Schwankungen innerhalb des im Chart betrachteten Zeitraums nicht ausreichend sind.
Bei den weiter oben im Thread von mir geposteten Experimental-Indikatoren hatte ich mit der Konstante m:=3 eine Mindestveränderung (als Bedingung für ein ZigZag-Reversal) von 3 Prozent festgelegt. Das dürfte für viele Intraday-Charts (insbesondere Minutencharts) aber viel zu hoch sein. Mit m:=0.5 (oder sogar noch kleiner, z.B. 0.3) dürften dagegen in Intraday-Charts Auschläge viel häufiger angezeigt werden. Wenn der Default-Wert für m in der ersten Zeile im folgenden Code mit 3 zu gering ist, diesen einfach auf 0.5 ändern.
{Indikator WS BreakAboveLastPeak}
m:=Input("ZigZag Mindestveränderung in Prozent", 0.1, 99, 3);
cond1:=TroughBars(1 ,C,m) <PeakBars(1,C,m) AND C>Peak(1,C,m);
pc:=(Peak(1,C,m)-C)*100/Peak(1,C,m);
cond3:= TroughBars(1 ,C,m) >PeakBars(1,C,m) AND pc<m AND C>Peak(2,C,m) AND BarsSince( pc>m) >=PeakBars(1,C,m);
If( cond1 OR cond3, 1, 0)
Es hat tatsächlich an dem zu großem Wert gelegen. Die Ergebnise sind jetzt trotzdem nicht sehr "Tradingfreundlich". Ich würde gern den abgeänderten Parabolic SAR nach Meyers ausprobieren. Der wirft einen nicht so schnell aus einem Trend raus. Außerdem generiert dieser nicht so häufig Fehlsignale in Seitwärtsphasen. Ich kann die Metastockformel jedoch nirgends finden. Gibt es dafür vielleicht eine Quelle? Den VB-Code und ein Excel-Sheet habe ich zwar, kann damit aber nichts anfangen.
Gruß, Beginner
Option Explicit
Public Function Calculate(Werte As Collection, Parameter As Variant, Ergebnis!())
'' Werte: die Daten-Collection
'' Ergebnis!(): das Ergebnisfeld
Dim Indexkey$, AccStep!, AccMax!, CrossL$, CrossS$ 'CrossL und CrossS sind als String angegeben, damit auch Ergebnisse von Berechnungen möglich sind
Indexkey = Parameter(1) 'der Zeiger auf die zu berechnenden Daten (=Parameter(1))
AccStep = Parameter(2) ' Die Beschleunigung (=Parameter(2))
AccMax = Parameter(3) 'Der max. Faktor (=Parameter(3))
CrossL = Parameter(4) 'Der Crossover-Betrag zum Wechsel auf Long (=Parameter (4))
CrossS = Parameter(5) 'Der Crossover-Betrag zum Wechsel auf Short (=Parameter (5))
Dim i&, j&, mini&, maxi&, signale&
Dim AktH!, AktL!, SARLong!, SARShort!, AktSARL!, AktSARS!, LowIndex&, HighIndex& 'AktSARL und AktSARS, damit Parabolic auf aktuellem Wert gehalten werden kann, bis Basiswert wieder in unterstellter Richtung weiterläuft
Dim AktStepLong!, AktStepShort!, Aktposition%
Dim Feld!()
Feld = Werte.Item(Indexkey) ' die zu berechnenden Daten
mini = LBound(Feld)
maxi = UBound(Feld)
Dim XOLong!()
XOLong = Werte.Item(CrossL) 'Daten für den Long Crossover
Dim XOShort!()
XOShort = Werte.Item(CrossS) 'Daten für den Short Crossover
'' SetzeGrenzen() aus dem Entwicklertool
If SetzeGrenzen(Feld, mini, maxi) > True Then
Calculate = ErrNoData
Exit Function
End If
If mini + 1 > maxi Then
Calculate = ErrNoData
Exit Function
End If
''''' Initialisierung:
SARLong = Feld(mini)
SARShort = Feld(mini)
AktH = Feld(mini)
AktL = Feld(mini)
AktStepLong = AccStep
AktStepShort = AccStep
Aktposition = 0 '' Start mit Position =0 eingenommen
mini = mini + 1
For i = mini To maxi
'Long:*********
If Aktposition >= 0 Then
If Feld(i) > AktH Then
AktH = Feld(i)
HighIndex = i
'' Beschl.-Faktor bis zum Max. erhöhen
AktStepLong = AktStepLong + AccStep
If AktStepLong > AccMax Then
AktStepLong = AccMax
End If
End If
AktSARL = SARLong 'Wenn SAR in die Zwei-Tage-Kursrange läuft, wird er festgehalten, bis die Kurse wieder in die unterstellte Richtung laufen oder sich ein Positionswechsel ergibt
If SARLong + AktStepLong * (AktH - SARLong) >= Feld(i) Or _
SARLong + AktStepLong * (AktH - SARLong) >= Feld(i - 1) Then
SARLong = AktSARL
Else
SARLong = SARLong + AktStepLong * (AktH - SARLong)
End If
End If
'Short: *********
If Aktposition = 0 Then
If Feld(i) AktL Then
AktL = Feld(i)
LowIndex = i
'' Beschl.-Faktor bis zum Max. erhöhen
AktStepShort = AktStepShort + AccStep
If AktStepShort > AccMax Then
AktStepShort = AccMax
End If
End If
AktSARS = SARShort 'Wenn SAR in die Zwei-Tage-Kursrange läuft, wird er festgehalten, bis die Kurse wieder in die unterstellte Richtung laufen oder sich ein Positionswechsel ergibt
If SARShort + AktStepShort * (AktL - SARShort) = Feld(i) Or _
SARShort + AktStepShort * (AktL - SARShort) = Feld(i - 1) Then
SARShort = AktSARS
Else
SARShort = SARShort + AktStepShort * (AktL - SARShort)
End If
End If
Select Case Aktposition
Case Is >= 0 '' Wir sind Long:
If SARLong >= Feld(i) + XOShort(i) Then '' Stopkurs inklusive Crossover-Betrag erreicht!
''' Eine neue Short-Position eröffnen:
signale = signale + 1
SARShort = AktH ' + AccMax * (AktH - Feld(i)) '' SAR initialisieren
'' Eventuell
Aktposition = -1
AktStepShort = AccStep
AktL = Feld(i)
If signale > 2 Then
Ergebnis(i) = SARShort '' Ab hier zählt der Short!!
End If
Else
If signale > 2 Then
Ergebnis(i) = SARLong '' Der Long ist noch in Betrieb
End If
End If
Case Is = 0 ''''' Wir sind Short
If SARShort = Feld(i) - XOLong(i) Then '' Stopkurs inklusive Crossover-Betrag erreicht!
''' Eine neue Long-Position eröffnen:
signale = signale + 1
SARLong = AktL ' - AccMax * (Feld(i) - AktL) '' SAR initialisieren
Aktposition = 1
AktStepLong = AccStep
AktH = Feld(i)
If signale > 2 Then
Ergebnis(i) = SARLong '' Ab hier zählt der Long!!
End If
Else
If signale > 2 Then
Ergebnis(i) = SARShort '' Der Short ist noch in Betrieb
End If
End If
End Select
Next i
Calculate = True
End Function