Diese Fragestellung steht fast immer Vordergrund, wenn der Tradingsystementwickler sich das erste Mal mit Tradingsystemen auseinandersetzt. Ohne jetzt zu früh den Zeigefinger zu heben, will ich aber darauf hinweisen, dass es wichtiger ist, sich mehr um die Fragestellung des Verkaufs und des Wie viel‘s zu kümmern.
Theoretische Definition
Zum Zeitpunkt n gibt eine Funktion auf die Menge aller zur Verfügung stehenden Datenreihen mit den letzten Elementen Xn den Wert wahr zurück. Wobei Xn für den letzten Wert in der einer beliebigen Datenreihe zum Zeitpunkt n steht.
Dann kann zum Zeitpunkt n + 1 gekauft werden!
Regeldefinition für Kauf
Wie in Achtung Basics beschrieben wird für jede Aktie eine indizierte Datenreihe abgelegt.
Nun wird in einer Schleife einzeln der Reihe nach auf die Elemente zu einem Index bzw. Datum zugegriffen.
Bedingungen
Bei diesem Schleifendurchlauf können einzelne Bedingungen für diese Elemente (Close, Volume…) abgefragt werden.
1) Die einfachste Bedingung, die für einen Kauf definiert werden kann, erfolgt, ohne auf ein Element der Datenreihe zu zugreifen. DH. es erfolgt der Kauf z.B. an einem bestimmten Tag.
Beispiel: Wenn der 2. Januar ist, dann kaufe zum Eröffnungskurs
if (Date(n) =“02.01.2011“)
{buy at open}
2) Auch der direkte Zugriff auf einen Preis und der Vergleich mit einer Konstante ist noch eine denkbar einfache Variante einer Regeldefinition
Beispiel: Wenn der Close > $ 5 dann kaufe zum nächsten Open
if (close[n] > 5.00)
{buy at next open}
3) Die Abfrage von Pattern, also Formationen, innerhalb der Datenreihen benötigt die Einbindung von Preisen der vorherigen Tage. Diese werden in der Regeldefinition relativ adressiert, z.B. mit n – 1 um auf ein Element des Vortages zu zugreifen.
Beispiel: Wenn der Close größer ist als der des Vortages, der Close größer ist als das Open und der Close des Vortages größer ist als das Open des Vortages, dann kaufe)
if ( (close[n] > close[n – 1])
and (close[n] > open[n])
and (close[n – 1] > open[n – 1]) )
{buy at next open}
4) Letztendlich kann statt der relationalen Operatoren auch eine Funktion stehen, die dann verwendet wird, wenn etwas mehrfach verwendet werden soll; entweder in derselben Strategie oder aber auch in verschiedenen Strategien.
Beispiel für 3) wäre:
Boolean function PatternTest(int i)
{ if ( (close[i] > close[i – 1])
and (close[i] > open[i])
and (close[i – 1] > open[i – 1]) )
return true
else
return false
}
Der Aufruf in der Schleife würde dann so aussehen:
if (PatternTest(n))
{buy at next open}
Mit Funktionen können dann auch Indikatoren berechnet werden, auf die ich unter 5) detailliert eingehe. Allerdings sprechen in der Regel zwei Aspekte dagegen, dies mit einfachen Funktionen zu machen. Denn bei jedem Funktionsaufruf mit dem gleichen Parametern (hier z.B. „n“) wird das Resultat erneut berechnet und für Indikatoren, die auf die Resultate des Vortages zugreifen. (F(n) = f(F(n-1)) wäre die einzelne Berechnung ein Overkill. Beispiel ist EMA (Exponential Moving Average).
Bei einem SMA (Simple Moving Average) könnte dies aber durchaus angewandt werden.
Beispiel:
if (Close[n] >SMA.Value(Close20)[n])
{buy at next open}
Das Value in SMA.Value soll verdeutlichen, das hier nur die SMA Funktion für den Parameter 20 für das Datum n aufgerufen wird.
5) Aus den Datenreihen der Preise können Indikatoren abgeleitet werden. Hier gibt es denkbar viele Varianten von den bekannten Lowest, Highest, Gleitender Durchschnitt (Moving Average = MA), MACD, RSI, Bolling Bänder, bis zu exotischen Konstruktionen. Diese Indikatoren werden in der Regel mit Parametern erzeugt, die z.B. angeben über wie viele Kurse sich rückwirkend die Berechnung erstreckt oder mit welcher Konstanten ein Wert multipliziert wird. Die Indikatoren werden selber wieder in Datenreihen gespeichert, die in der Regel während der Laufzeit berechnet werden.
Beispiel: Wenn der Close größer ist als das EMA der letzten 20 Tage, dann kaufe
DataSeries myEMA20 = EMA.Series(Close, 20);
if (close[n] > myEMA20[n])
{buy at next open}
Es gibt hierfür auch noch eine kürzere Variante, die aber nicht verdeutlicht, dass hier eine temporäre Datenreihe aufgebaut wird.
if (close[n] > EMA.Series(Close, 20) [n – 1])
{buy at next open}
6) Schlussendlich kann im Grunde jede Variante, die in einer modernen Programmiersprache zur Verfügung steht, zur Regeldefinition angewandt werden. Dies kann auch eine zusätzliche Datenreihe mit den P/E (Price per Earnings) sein, die eingebunden wird oder dies können (Zähl) Variablen sein, welche in einer Schleife gefüllt werden oder auch die Abfrage der Mondphase (grins) oder die Blackbox eines eingekauften Systems sein.
Abschließend betrachtet gibt es aber eine wichtige Sache, die bei der Regeldefinition immer beachtet werden muss. Sie ist eigentlich selbstverständlich, passiert aber immer wieder mal, gerade Anfängern bei Tradingsystemen.
Es gibt Programme, die dies sicherstellen, aber je freier die Programmiersprache ist desto eher kann dies passieren.
Also:
Es dürfen nie die Daten der Zukunft in die Regeldefinition mit einfließen!
Klar ist dies bei if (close[n] < close[n + 1]) {buy at next open}.
Aber auch schon wenn ich abfrage, ob open[n] < high[n] und zum close[n] reingehe, habe ich schon die Information, dass high != open ist, miteinfließen lassen!
Also Vorsicht, sonst erfüllen sich nicht die Testergebnisse im realen Trading und es wird einiges Geld verloren, bis möglicherweise der Fehler gefunden wird!