Die erste Strategie schloss nur bei der entgegengesetzten Kreuzung. Jetzt verwenden wir zusätzlich einen Verlust- und Gewinnabstand zum Einstiegskurs. Die bisherige Schließung durch Kreuzung bleibt erhalten.

Drei unterschiedliche Ausstiegsgründe

In diesem Beispiel können drei Ereignisse die Long-Position schließen:

  • Der Kurs erreicht das Niveau der Stop-Order zur Verlustbegrenzung.
  • Der Kurs erreicht das Niveau der Limit-Order zur Gewinnmitnahme.
  • Der schnelle Durchschnitt kreuzt den langsamen nach unten, und die Schließung per Market-Order wird ausgeführt.

Stop und Limit sind Orders mit einer Kursbedingung. strategy.close erteilt eine Market-Order zur Schließung. Ihre Ausführungsregeln können verschieden sein, deshalb musst du in der Trade-Tabelle sowohl Kurs als auch Zeitpunkt prüfen.

Abstand oder konkreter Kurs?

Bei strategy.exit gibt es zwei Arten der Angabe:

ArgumentWas gibst du an?
lossVerlustabstand in Ticks
profitGewinnabstand in Ticks
stopKonkreten Stopkurs
limitKonkreten Limitkurs

loss=100 bedeutet nicht 100 Prozent und nicht unbedingt 100 Geldeinheiten. Du verlangst einen Abstand von hundert Ticks zum Einstiegskurs.

Die Tickgröße von DEMO beträgt 0,01. Hundert Ticks sind daher 1 Kurseinheit, zweihundert Ticks 2 Kurseinheiten. Bei einem Long-Einstieg zu 200 ergeben sich ein Stopniveau von 199 und ein Zielniveau von 202, ohne weitere Auswirkungen von Slippage und Ausführungsbedingungen.

Das vollständige Programm

Lege die Datei protected_strategy.py an:

"""
@pyne edge
"""
from pynecore.lib import close, color, input, plot, script, strategy, ta


@script.strategy(
    "Crossing Strategy with Exits",
    overlay=True,
    initial_capital=10000,
    default_qty_type=strategy.fixed,
    default_qty_value=1,
    pyramiding=1,
    commission_type=strategy.commission.percent,
    commission_value=0.1,
    slippage=2,
)
def main(
    fast_length: int = input.int(5, title="Fast length", minval=1, maxval=200),
    slow_length: int = input.int(20, title="Slow length", minval=1, maxval=200),
    stop_ticks: int = input.int(100, title="Stop distance (ticks)", minval=1),
    target_ticks: int = input.int(200, title="Target distance (ticks)", minval=1),
):
    fast_average = ta.sma(close, fast_length)
    slow_average = ta.sma(close, slow_length)
    crosses_up = ta.crossover(fast_average, slow_average)
    crosses_down = ta.crossunder(fast_average, slow_average)
    if crosses_up:
        strategy.entry("Long", strategy.long)
    if crosses_down:
        strategy.close("Long")
    strategy.exit("Bracket", "Long", loss=stop_ticks, profit=target_ticks)
    plot(fast_average, "Fast average", color=color.blue, linewidth=2)
    plot(slow_average, "Slow average", color=color.orange, linewidth=2)

Bracket ist die Kennung der Ausstiegsordergruppe. Das zweite Argument Long gibt an, zu welchem Einstieg sie gehört. loss und profit verwenden die beiden obigen Inputs.

Wir führen den Ausstiegsaufruf auf jeder Kerze mit derselben Kennung aus. Er verwaltet die angegebene Ausstiegsregel; er eröffnet nicht bei jedem Aufruf eine neue unabhängige volle Position.

Führe das Programm auf den Demodaten aus. Unter Trades können jetzt neben der Market-Schließung durch Kreuzung auch Ausstiege mit Bracket erscheinen.

Die Ausführung von protected_strategy.py in der PyneIDE; Trades können auch durch Stop- oder Zielorders geschlossen werden.
Neben der Schließung durch Kreuzung verwendet die Strategie einen Stop und ein Kursziel in Ticks.

Wann erscheint der schützende Ausstieg?

Das Programm kann in derselben Ausführung eine Einstiegsanweisung und einen zugehörigen Ausstieg erteilen. Den in Ticks angegebenen Abstand kann die Laufzeit auf den tatsächlichen Ausführungskurs des Einstiegs beziehen.

Würdest du stattdessen aus dem Schlusskurs des Signals einen konkreten Kurs für stop berechnen, ginge das Niveau vom Signalkurs aus. Bei einem abweichenden nächsten Eröffnungskurs hätte es nicht mehr denselben Abstand zum tatsächlichen Einstieg.

Wähle die Angabe deshalb passend zur gewünschten Regel. loss ist ein Tickabstand zum Einstieg, stop ein konkretes Kursniveau.

Eine Kerze enthält nicht jeden Kursschritt

Aus OHLCV-Daten kennen wir Eröffnung, Hoch, Tief und Schluss einer Kerze. Die zeitliche Reihenfolge aller Kurse dazwischen kennen wir damit nicht automatisch.

Erreicht das Hoch derselben Kerze das Ziel und ihr Tief den Stop, verraten die vier Kurse allein nicht, welches Ereignis zuerst eintrat. Der Simulator verwendet dafür die Regeln seines Ausführungsmodells. Daten eines kleineren Zeitrahmens können eine feinere Untersuchung ermöglichen.

Prüfe diesen Fall gesondert, statt von Hand immer den günstigeren Ausgang zu wählen. Die Annahme des Modells gehört zum Ergebnis.

Auch der Stopkurs garantiert keinen exakten Ausführungskurs. Eröffnet die nächste Kerze jenseits des Stops, kann die Ausführung ungünstiger als das übersprungene Niveau ausfallen. Slippage kann eine weitere Kursabweichung verursachen.

Stop und Kursziel in derselben KerzeBeide Pfade ergeben dieselbe OHLC-Kerze. Der Stop bei 199 und das Kursziel bei 202 sind bereits aktiv. Ohne Daten einer kleineren Zeiteinheit beginnt das Modell mit dem Extrem, das näher an der Eröffnung liegt; hier wird der Stop zuerst ausgeführt. Der andere Pfad zeigt, warum die Reihenfolge wichtig ist. open: 200; high: 203; low: 198; close: 201. stop: 199; limit: 202. open → low → high → close; open → high → low → close.Pfad des OHLC-ModellsAndere mögliche ReihenfolgeO → L → H → CO → H → L → C202199202199OLHCOHLCStop wird zuerst ausgeführtKursziel wird zuerst erreichtO = 200 · H = 203 · L = 198 · C = 201Offene Long-Position; aktive Ausstiege. Ohne Kurslücken oder Slippage.
Stop und Kursziel in derselben KerzeBeide Pfade ergeben dieselbe OHLC-Kerze. Der Stop bei 199 und das Kursziel bei 202 sind bereits aktiv. Ohne Daten einer kleineren Zeiteinheit beginnt das Modell mit dem Extrem, das näher an der Eröffnung liegt; hier wird der Stop zuerst ausgeführt. Der andere Pfad zeigt, warum die Reihenfolge wichtig ist.

Abstand und Verlustbetrag

Bei einer Long-Position von einer Einheit und einem Punktwert von 1 bedeuten 100 Ticks mit Tickgröße 0,01 eine Kursdifferenz von 1 Geldeinheit. Bei zehn Einheiten ist das Kursergebnis zehnmal so groß.

Menge, Tickgröße und Punktwert bestimmen gemeinsam den Geldbetrag der Bewegung bis zum Stop. Hinzu kommen Provision und die tatsächlichen Ausführungsbedingungen.

Gibst du direkt einen Wert für qty in einer Order an, ist das deren eigene Menge. Das Beispiel verwendet die Standardmenge, die sich auch unter Properties → Order size überschreiben lässt.

Die 100 und 200 Ticks der DEMO-Übung dienen der Veranschaulichung. Bei einem anderen Instrument können dieselben Zahlen andere Kursabstände und Geldbeträge bedeuten.

Probiere es selbst aus

Lasse schnelle und langsame Länge, Menge und Kosten unverändert. Starte eine Variante mit Stop/Ziel 100/200 und anschließend eine mit 200/400 Ticks. Prüfe, was aus demselben Einstiegssignal wird.

Lösung der Aufgabe

Ändere unter Inputs nur Stop distance (ticks) und Target distance (ticks). Die größeren Abstände können dazu führen, dass die Position auf einer anderen Kerze oder aus einem anderen Grund schließt.

Die Schließung durch Kreuzung bleibt in beiden Varianten erhalten. Ein größeres Kursziel bedeutet daher nicht, dass die Position zwangsläufig bis dahin offen bleibt. Die Ausstiegsregeln wirken zusammen.

Warte nach dem Speichern der Inputs immer auf die Neuberechnung und lies dann das neue Ergebnis ab. Bewahre die beiden Exporte unter verschiedenen Namen auf, wenn du sie später vergleichen möchtest.

Finde den Ausstiegsgrund

Wähle einen geschlossenen Trade und prüfe Einstiegskurs, vorgegebene Tickabstände und OHLC-Werte der Ausstiegskerze. Bestimme anhand von Kurs und Zeitpunkt des Ausstiegs, welche erfüllte Regel den Trade erklärt. Berührt die Kerze mehrere Niveaus, berücksichtige auch das Ausführungsmodell.