Enter

Eröffnet von stock-profi im Board Handelssysteme mit Equilla

Seitenlänge102030
Seite 1 von 612345
#55: 15.06.2009 19:03 stock-profi
Ein Nutzer hat angeregt, die Anzahl der Stücke beim Ausstieg in Prozent der vorhandenen Stücke anzugeben.

Gerne komme ich diesem Wunsch nach. Die Anzahl kann z.B. in der Form „20%“ angegeben werden, sie muß eine Ganzzahl sein, das Prozentzeichen muß das letzte Zeichen sein, Leerzeichen vor oder hinter der Ganzzahl sind erlaubt.

Hier ist der Code, wobei ich einige Beipieltrades für Siemens eingefügt habe:

Equilla Skript "disDefineDataCont (Strategy)"

Und der Chart:
SIEMENS AG NA
#54: 12.06.2009 17:19 stock-profi
Das diskretionäre Trading mit disEntryPF funktioniert gut. Allerdings ist das Handelssystem aus #53 schon mehr als 600 Codezeilen lang, von denen ca. 200 auf die Definition der Daten und ca. 400 auf den ausführenden Code entfallen.

Wenn man disEntryPF eine Weile in der Praxis eingesetzt hat, nimm die Definition der Daten einen enormen Umfang an, und das Modul schwillt erheblich an. Um hier den Überblick zu behalten, kann man folgende Unterteilung vornehmen:

1. Man legt mehrere Portfolios an: z.B. je eines für Rohstoffe, Devisen und Aktien.

2. Innerhalb eines Portfolios legt man mehrere Exemplare von disEntryPF (mit unterschiedlichen Namen) an und zieht diese nacheinander auf den Chart. Die Unterteilung kann man z.B. nach dem Zeitraum und/oder nach den Instrumenten vornehmen. So hat man z.B. für das erste Quartal 2009 in einem Aktienportfolio von 100 Aktien ein disEntryPF1 und für das 2. Quartal ein disEntryPF2. Steigert man im 2. Quartal die Handelsfrequenz, kann man statt disEntryPF2 3 verschiedene Strategien anlegen: disEntryPF21 für de ersten 30 Aktien, disEntryPF22 für die zweiten 30 Aktien und disEntryPF23 für die letzten 40 Aktien.

Mit den geschilderten Maßnahmen bleiben die Module übersichtlich. Allerdings missfällt mir, dass man im letzten geschilderten Beispiel 4 Module hat, die sich nur in der Definition unterscheiden, während der ausführende Code immer identisch ist. Jedes der Module ist z.B. 600 Zeilen lang, und der identische Code von 400 Zeilen wird pro Stab und Instrument 4mal ausgeführt.

Ich trenne daher disEntryPF in die beiden Module disDefineData zur Festlegung der Daten an Stab 1 und disTrader zur Ausführung des Codes. Vom Modul disDefineData kann man wie oben geschildert mehrere Exemplare anlegen, die sich z.B. nach Zeitraum und / oder Instrumenten unterscheiden. Das Modul disTrader liegt nur einmal auf dem Chart. Die in disEntryPF benötigten Vektoren dates, orders, prices etc. werden zu instrumentenspezifischen globalen Vektoren data1::dates, data1::orders, data1::prices etc. Liegen mehrere Module disDefineData auf dem Chart, führen sie einen von einem Vorgängermodul begonnenen Aufbau der Vektoren fort. Das Modul disTrader verarbeitet die Vektoren data1::dates etc. und generiert die Trades. Jedes der Exemplare des Moduls disDefineData kann an- oder abgeschaltet werden, ohne dass man es vom Chart oder aus dem Portfolio entfernen muß. So kann man sehr schnell die Performance für einen Zeitraum oder eine Gruppe von Instrumenten ermitteln.

Hier sind jetzt die beiden Module:

Equilla Skript "disDefineData (Strategy)"

Das Definitionsmodul enthält in diesem Beispiel etwa 200 Zeilen, das Tradermodul ist unabhängig vom Beispiel und enthält etwa 400 Zeilen Code.

Um den Effekt des Hintereinanderschaltens deutlich zu machen, schreibe ich ein zweites Exemplar von disDefineData, welches ich disDefineDataCont nenne. Hier ergänze ich 2 Trades für Allianz, von denen der erste bewusst identisch ist mit einem Trade aus disDefineData, und zwei Trades für Siemens.

Equilla Skript "disDefineDataCont (Strategy)"

Hier ist das Ergebnis für dasselbe Portfolio wie in #53.
Portfolio "testListe"
Stellt man in disDefineDataCont defineOn auf nein, ergibt sich dasselbe Ergebnis wie in #53.
Wer debugOn auf ja stellt, kann den Aufbau der Vektoren im Ausgabefenster verfolgen.
#53: 04.05.2009 11:18 stock-profi
Die Einschränkung, dass man an einem Stab nicht mehrere gleiche Orders mit verschiedenen Preisen definieren kann, habe ich jetzt durch einen plumpen Trick überwunden. Ich erzeuge einfach drei identische Orders, die somit unterschiedliche Codestellen haben und von TS5 als drei verschiedene Orders erkannt werden. Das sieht im Code zwar etwas bescheuert aus, funktioniert aber. Wer mehr als 3 Orders an einem Stab mit unterschiedlichen Preisen benötigt, kann den Code erweitern. Vielleicht sollte er aber auch über einen Wechsel in eine tiefere Zeitebene nachdenken.

Hier wieder der neue Code:
Portfolio "Portfolio (1)"
Um die neuen Features zu sehen, bitte VOW öffnen. Ich habe den 9.1.2009 mit 5 Ausstiegen und den 25.3.2009 mit 4 Einstiegen versehen. Nur die ersten drei werden jeweils berücksichtigt.
VOLKSWAGEN AG ST O.N.
#52: 03.05.2009 15:31 stock-profi
Um die Handhabung weiter zu vereinfachen, habe ich jetzt die Möglichkeit vorgesehen, zum open des nächsten Stabes zu handeln: dies wird mit „ONB“ angegeben. Ferner ist jetzt auch die Angabe der Stücke beim Einstieg optional. Wird keine Angabe vorgenommen, gilt die Standardanzahl aus dem MoneyManagement oder die Angabe aus einem vorgelagerten Position Sizer.

Schließlich kann man jetzt mit Einschränkungen mehrere Befehle an einem Stab definieren. So ist es z.B. möglich, am Einstiegsstab auszusteigen, was allerdings die Angabe einer Stückzahl für den Ausstieg voraussetzt, oder neben einem Kauf zum Open einen weiteren Kauf am selben Stab zu tätigen, wozu man Pyramidisieren einstellen muß.

Was noch nicht geht, ist die Angabe von mehreren Käufen am selben Stab mit der Angabe von verschiedenen Preisen. Dies liegt an einer Eigenart von TS5: jede Order kann an einem Stab nur einmal erzeugt werden, wobei die Order durch die Position im Code identifiziert wird. Es ist also nicht möglich, mehrere Orders in einer Schleife zu generieren. Definiert man in den Vektoren trotzdem mehrere Orders, wird nur die zuletzt angegebene Order von TS5 ausgeführt. Ich habe ein Beispiel bei VOW am 24.3.2009 eingebaut.

Hier ist jetzt der neue Code:
Portfolio "Portfolio (1)"
Um die neuen Features zu sehen, bitte VOW öffnen.
VOLKSWAGEN AG ST O.N.
#51: 26.04.2009 15:02 stock-profi
Nachdem ich die stopEngine so geändert habe, daß ich auch diskretionäre Stops verarbeiten kann (siehe #244 bis #246 in stopEngine), kann ich in disEntryPF auch einen diskretionären Stop vorsehen. Dieser wird nur angezeigt und ausgelöst, wenn die neue stopEngine auf den Chart gezogen wird.
Ferner habe ich ein profitTarget vorgesehen. Dieses wird nur angezeigt und an ein Folgemodul weitergereicht. Wenn es zu einer Aktion führen soll, muß ein Folgemodul geschrieben werden. Es bietet sich z.B. die Anpassung des trailStops nach Schäfermeier an (siehe trail4Phase, # 191 in stopEngine).
Um eine einheitliche Behandlung aller Aktionen zu gewährleisten, habe ich die this bar Ausstiege bei sell und cover durch next bar Ausstiege ersetzt. Außerdem habe ich das Schlüsselwort total bei sell und cover hinzugefügt, damit beim Pyramidisieren um die angegebene Anzahl verringert wird.
Auf Wunsch eines Nutzers habe ich beim Einstieg die Möglichkeit "CL -close limit" hinzugefügt, damit die Eingabe vereinfacht wird.

Bei umfangreichen Eingaben in den Vektoren besteht die Gefahr, daß man Fehleingaben tätigt. Daher habe ich weitgehende Prüfungen eingebaut. Es ist also sinnvoll, das Ausgabefenster anzusehen, bevor man die Equity-Kurve studiert. :)

Schließlich habe ich die Dokumentation verfeinert, damit die Handhabung vereinfacht wird.

Das Skript disEntryPF kann jetzt schon eine Menge: man kann alle Orders eingeben, in Teilen aussteigen und im Zusammenhang mit Pyramidisieren auch in Teilen einsteigen. Zusammen mit der stopEngine kann man einen stopLoss diskretionär oder systematisch hinzufügen, und zwar pro Trade. Nutzt man zusätzlich trailStops, kann man die Ausstiege automatisieren, während man die Einstiege diskretionär vornimmt.

Es gibt jedoch noch einen Punkt, der nicht möglich ist, das ist die Eingabe von mehreren Orders an einem Stab.

Hier der neue Code:
#50: 10.03.2009 10:37 stock-profi
Ein aufmerksamer User hat mich darauf aufmerksam gemacht, daß eine Änderung von period in disEntryPF zu einer Änderung des Ergebnisses führen kann, selbst wenn filterMode auf none steht.

Das hat folgenden Grund:

Im Code von disEntryPF habe ich einen Durchschnitt verwendet:

avg = averageFC (close, period);

Dieser Befehl führt dazu, daß currentBar = 1 nach period vielen Stäben erreicht ist. Wenn period z.B. auf 100 steht, aber schon am 50. Stab ein diskretionärer trade angelegt wurde, so wird dieser nicht durchgeführt.

Für jemanden, der ohne Filter arbeitet, ist es deshalb sinnvoller, den obigen Befehl in den folgenden Block zu verschieben:

if filterMode <> none then
begin
avg = averageFC (close, period);
...
end;


Will er den Durchschnitt anzeigen, zieht er den mitgelieferten Indi Moving Average Simple auf den Chart.

Wenn jemand mit Filter arbeitet, muß er unabhängig von der Position des obigen Befehls beachten, daß kein Trade vor period vielen Stäben durchgeführt wird.
#49: 05.11.2008 16:21 stock-profi
Der Beitrag wurde vom Verfasser bearbeitet. Originalbeitrag anzeigen.
@stock-profi (#48)
DisEntry erfreut sich offenbar einiger Beliebtheit, jedenfalls haben mich ein paar Anfragen wegen einer Nutzung im Portfolio erreicht.

Handelt man mit wenigen Instrumenten, z.B. mit 4 Instrumenten, so bietet es sich an, die 4 Instrumente auf einen Chart zu ziehen und jeweils eine Ausprägung von disEntry auf ein Instrument anzuwenden.

Unterliegt dem Handel dagegen ein Portfolio aus etwa 60 Instrumenten, so scheidet diese Vorgehensweise aus. Stattdessen sollte man das folgende Skript disEntryPF als Grundlage nehmen und dort die getätigten Trades eintragen. Dieses Skript hat den Vorteil, dass es sowohl im Portfolio als auch im Einzelchart läuft. Damit das Skript nicht zu unübersichtlich wird, kann man es von Zeit zu Zeit je nach Anzahl der Trades einfrieren und ein neues Exemplar eröffnen, z.B. DisEntryPF1 für das 1. Quartal 2008, DisEntryPF2 für das zweite Quartal 2008 usw. Die alten Skripts kann man nach Belieben auf dem Portfolio liegen lassen oder entfernen.

In disEntryPF kann man die Trades in jeder Reihenfolge eingeben, allerdings müssen alle Trades zu einem Instrument in einem Block pro Instrument stehen, die Reihenfolge dieser Blöcke bzw. Instrumente ist beliebig. Der Ausstieg kann über ein target- oder Stopp- oder trail – Modul erfolgen, aber auch diskretionär. Bei einem diskretionären Ausstieg kann man auch in Teilen aussteigen; gibt man für einen Ausstieg keine Anzahl an, werden alle Stücke verkauft. Außerdem habe ich nun auch beim Ausstieg die Möglichkeit eingebaut, den Preis mit 0 zu belegen. In diesem Falle steigt man bei long mit low Stopp am nächsten Bar aus, bei short mit high Stopp.

Stellt man debugOn auf ja, sieht man im Fenster auf einen Blick, welche Instrumente gehandelt wurden.

Hier ist disEntryPF: Über den Einsatz im Portfolio enthält man dann die gemeinsame Equity-Kurve und die gemeinsame Statistik.
Portfolio "Germany/DAX"
#48: 29.07.2008 16:11 stock-profi
@stock-profi (#45)

das Modul disEntry habe ich auf Wunsch eines Benutzers um einen Filter erweitert. Ein buy oder short wird bei Bedarf nur dann ausgeführt, wenn ein Filter auf "wahr" steht. Als Beispiel habe ich die beiden einfachsten Filter eingebaut, die es gibt: "Schlußkurs über Durchschnitt (avgCross)" und "Durchschnitt steigt (avgSlope)" (long). Jeder Benutzer kann natürlich die Filter einprogrammieren, die er für sinnvoll hält.
#47: 12.03.2008 16:34 stock-profi
Das im letzten Beitrag skizzierte Verfahren der Prüfung eines Handelssystems möchte ich an einem kleinen Beispiel näher ausführen.

Hier ist das Handelssystem ChannelBreakout im DAX seit dem 1.1.2003 in der Standardeinstellung LE, LX, dem ich noch einen stopLoss von 2 ATR mitgegeben habe. In jeden Trade gehe ich mit 100.000 (normedPosSize), so dass das in TS5 ausgewiesene Ergebnis, geteilt durch 1.000, das prozentuale Ergebnis darstellt.
DAX P-IN. (1)
Das Ergebnis:

netProfit		76.023,76
Trades			12
winningTrades	8
AvgProfit		6.335,31
RiskRatio		0,7373
ProfFactor		8,96
PercTime		65,66%
AvgLength		68,83


Sieht doch ganz gut aus, oder? Der Haken bei der Sache ist allerdings, dass 12 Trades viel zu wenig sind, deshalb ist auch der ProfFactor nicht ernst zu nehmen. Außerdem habe ich einen Zeitabschnitt gewählt, in dem die Kurse seit dem 1.1.2003 0,5 Jahre abwärts, 1,5 Jahre seitwärts und etwas mehr als 3 Jahre aufwärts gelaufen sind. Also nicht sehr ausgewogen, aber es soll ja hier übersichtlich bleiben.

Jetzt ersetze ich das Einstiegssignal durch den Zufall, indem ich in ChannelBreakout bullish auf NoBullishSignal stelle und sRandom mit dem SignalProcessor aufziehe. In sRandom setze ich shortProb auf Null, weil ich nur long-Signale brauche. Bzgl. longProb probiere ich kurz rum, bis ich mit dem Wert 5 eine Einstellung gefunden habe, die bzgl. Anzahl Trades, PercTime und avgLength mit dem obigen Ergebnis vergleichbar ist. Die beiden Ausstiege bleiben unverändert, Einstieg zwecks Vergleichbarkeit mit Channel über buy Stopp, also NBPS.
DAX P-IN.
Bereits das hier zu sehende Ergebnis ist bzgl. Profit und PercTime besser als das obige:

netProfit		94849,21
Trades			11
winningTrades	6
AvgProfit		8622,66
ProfFactor		8,77
PercTime		53,19%


Immer wenn ich den Wert von counter in sRandom ändere, findet eine Neuberechnung statt, so dass ich jedes Mal ein Ergebnis erhalte, das ich mit dem obigen vergleichen kann.

Um den Vergleich zu automatisieren, bemühe ich den Optimierer (bruteForce, Parameter counter in der Einstellung von 1 bis 1000 (1), Zeitspanne 1.1.2003 bis 12.3.2008), der mir 1000 Ergebnisse mitteilt.

Die Ergebnistabelle des Optimierers kann ich z.B. nach netProfit absteigend sortieren. Das höchste Ergebnis beträgt 119.427, 194 Ergebnisse haben einen netProfit, welcher größer ist als der obige von 76.000. Das sind fast 20% aller Durchläufe, und das ist meilenweit entfernt von den 5% bzw. 1%, welche man üblicherweise fordert. Wenn man den netProfit nicht für sehr aussagefähig hält, kann man es ja mit avgProfit versuchen: der höchste Wert beträgt 10.795, und es gibt 93 Durchläufe, deren avgProfit über dem obigen von 6.333 liegt. Also sind bzgl. avgProfit fast 10% der Durchläufe besser als unser Channel-Signal (30). Selbst beim profFactor gibt es 49 Durchläufe mit höheren Ergebnissen als 8,96, das sind kurioserweise genau 5%.

Die Schlußfolgerung ist also enttäuschend: so gut das obige Ergebnis für das Channel-Signal auch ausgesehen haben mag: wir sollten nach einem besseren Einstiegssignal suchen!

Aber das haben wir ja vorher schon gewusst, oder? :)

Die Charts sind bis zum 30.6.2008 zu öffnen.
#46: 12.03.2008 11:05 stock-profi
Der Beitrag wurde vom Verfasser bearbeitet. Originalbeitrag anzeigen.
In #22 habe ich eine kleine Strategie vorgestellt, die Zufallssignale erzeugt. Sie orientiert sich an einem Buch von Stridsman und erzeugt an ca. 20% der Stäbe long- und an ca. 20% der Stäbe short-Signale.

Will man die Güte eines Einstiegssignals testen, kann es sinnvoll sein, das Einstiegssignal durch den Zufall zu ersetzen und die Ergebnisse miteinander zu vergleichen. Wenn man dabei 1000 Zufallsläufe macht, erhält man 1000 Werte für den netProfit, für den ProfitFactor, für den averageTrade etc.
Wann ist das Einstiegssignal besser als der Zufall? Gängige Meinung: Wenn in 95% (oder in 99%) der Durchläufe die wesentlichen Kriterien wie ProfitFactor, averageTrade, percentProfitable etc. schlechter ausfallen als bei dem Handelssystem mit dem Einstiegssignal. Voraussetzung für einen sinnvollen Vergleich ist in meinen Augen allerdings eine ähnliche Charakteristik, was z.B. die Anzahl der Trades, die Zeit im Markt und die durchschnittliche Dauer im Trade angeht.

Da ich eine ähnliche Charakteristik mit der Routine aus #22 häufig nicht realisieren kann, habe ich diese jetzt verbessert, indem ich für long und für short getrennt die ungefähre Anzahl der Signale vorgebe. Die Routine aus #22 habe ich umbenannt, sie heißt jetzt sRandomStr (für Stridsman). Hier ist die neue Routine: Die alltrades-Variablen dienen zur Ermittlung der tatsächlichen Anzahl der Signale. Ich ziehe sRandom zusammen mit irgendeiner Strategie (z.B. Bollinger) auf einen Chart mit 2000 Stäben und optimiere nach counter von 1 bis 1000 (1), wodurch ich 1000 Ergebnisse erhalte. Im Ergebnis des Optimierers füge ich die Spalten „alle Trades::longSig“ und „alle Trades::shortSig“ hinzu, die Tabelle exportiere ich nach Excel, wo ich eine kleine Statistik durchführe. Ergebnis: der Mittelwert für die Anzahl der long-Signale liegt bei 599,8, die kleinste Anzahl beträgt 526, die größte 667. Der Mittelwert für die Anzahl der short-Signale liegt bei 398,343, die kleinste Anzahl beträgt 349, die größte 459. Da nicht 2000 Stäbe zur Verfügung stehen, sondern nur 1998, stimmen die Mittelwerte, geteilt durch 1998, fast perfekt mit den vorgegebenen Wahrscheinlichkeiten überein (30,02 gegenüber 30 und 19,94 gegenüber 20). Also liefert die Strategie im Mittel die gewünschte Anzahl von Signalen.

Stellt man longProb auf 100 und shortProb auf Null, erzeugt die Strategie an jedem Stab ein long-Signal. Entsprechend für short.
Seite 1 von 612345