Liegt der Kurs zehn Kerzen lang über dem Durchschnitt, kann close > average zehnmal wahr sein. Möchtest du nur das Ereignis markieren, bei dem er von unten darüber steigt, brauchst du auch die Beziehung auf der vorherigen Kerze.

Eine Situation und ihr Beginn

Angenommen, der Durchschnitt liegt jetzt und auf der vorherigen Kerze bei 100. Der vorherige Schlusskurs ist 99, der aktuelle 101. Auf der aktuellen Kerze liegt der Kurs über dem Durchschnitt und hat ihn gegenüber der vorherigen Kerze auch nach oben gekreuzt.

Ist der nächste Schlusskurs 102, liegt er weiterhin über dem Durchschnitt. Es gibt aber keine neue Aufwärtskreuzung, denn schon auf der vorherigen Kerze lag er darüber.

ta.crossover(first, second) ist wahr, wenn der erste Wert jetzt größer als der zweite ist und bei der vorherigen Ausführung kleiner oder gleich war. ta.crossunder ist das Gegenstück für die Kreuzung nach unten.

Gleichheit auf der aktuellen Kerze ist noch keine Kreuzung. Erreicht der erste Wert den zweiten lediglich, ist die Bedingung > nicht wahr. Gleichheit auf der vorherigen Kerze erlaubt dagegen, dass das jetzige Überschreiten als Kreuzung zählt.

Zwei gleitende Durchschnitte kreuzen sich

Wir verwenden die beiden Durchschnitte aus dem Kapitel Gleitende Durchschnitte weiter. Der kürzere, schnellere wird blau, der längere, langsamere orange. Das grüne Dreieck markiert eine Aufwärtskreuzung des schnellen Durchschnitts, das rote eine Abwärtskreuzung.

Lege die Datei cross_signals.py an:

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


@script.indicator("Average Crossings", overlay=True)
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),
):
    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)
    plot(fast_average, "Fast average", color=color.blue, linewidth=2)
    plot(slow_average, "Slow average", color=color.orange, linewidth=2)
    plotshape(crosses_up, "Cross up", style=shape.triangleup,
              location=location.belowbar, color=color.green)
    plotshape(crosses_down, "Cross down", style=shape.triangledown,
              location=location.abovebar, color=color.red)

Führe sie auf den Demodaten mit den Standardwerten 5 und 20 aus. Die Markierungen erscheinen nur auf Kerzen mit einer Kreuzung. In einem längeren Abschnitt, in dem die blaue Linie durchgehend über der orangefarbenen liegt, erhältst du nicht auf jeder Kerze ein neues grünes Signal.

Der Chart von cross_signals.py zeigt einen schnellen und langsamen gleitenden Durchschnitt sowie grüne und rote Kreuzungsmarkierungen.
Die Kreuzungen der beiden gleitenden Durchschnitte erscheinen als einzelne Ereignisse.

Warum berechnen wir die Kreuzung in einer eigenen Zeile?

ta.crossover und ta.crossunder laufen auf jeder Kerze. Dadurch gehört ihre jeweils vorherige Ausführung zur vorherigen verarbeiteten Kerze.

Würdest du die Kreuzung nur bei erfüllter anderer Bedingung berechnen, müsste der frühere Zustand des Aufrufs nicht von der vorherigen Kerze stammen. Linie und Markierung könnten unterschiedliche Zeitreihen untersuchen.

Deshalb folgen wir der Regel des vorherigen Kapitels: Wir berechnen alle benötigten zustandsbehafteten Ergebnisse auf jeder Kerze und entscheiden anschließend anhand der fertigen Werte.

Auch hier ist die Aufwärmphase sichtbar

Der SMA mit Länge zwanzig ist erst ab der zwanzigsten Kerze gültig. Bei seinem ersten gültigen Wert fehlt der vorherige SMA noch. Dort lässt sich deshalb noch keine Kreuzung aus zwei vollständigen Kerzen bestimmen.

Die Bedingung benötigt die Werte beider Durchschnitte auf der aktuellen und vorherigen Kerze.

Ersetze na nicht durch null, nur um ein Signal zu erhalten. Ein Durchschnitt von null könnte eine künstliche Kreuzung an einer Stelle erzeugen, an der der tatsächliche Durchschnitt noch nicht berechenbar ist.

Der Zeitpunkt der Daten

Im Buch führen wir Programme auf abgeschlossenen historischen Kerzen aus. Ein Signal auf Basis des Schlusskurses einer Tageskerze verwendet die bei ihrem Abschluss bekannten Daten.

Der Schlusskurs einer noch entstehenden Kerze kann sich weiter ändern. Eine während der Kerze beobachtete Kreuzung kann bis zum Ende verschwinden. Verwechsle das nicht mit einer Prüfung auf abgeschlossenen Kerzen.

Ein Signal im historischen Chart bedeutet nicht automatisch einen auf derselben Kerze ausgeführten Trade. Der Indikator zeichnet ein Signal; die Order und den Zeitpunkt ihrer Ausführung legen wir später bei der Strategie fest.

Probiere es selbst aus

Lege eine Kopie namens price_crossings.py an. Markiere statt der Kreuzungen der beiden Durchschnitte die Stellen, an denen der Schlusskurs über beziehungsweise unter den langsamen Durchschnitt wechselt. Der langsame Durchschnitt soll im Chart bleiben.

Lösung der Aufgabe
crosses_up = ta.crossover(close, slow_average)
crosses_down = ta.crossunder(close, slow_average)

Die Markierungen verwenden die beiden logischen Variablen. Deshalb musst du die Zeilen mit plotshape nicht ändern. Die Titel solltest du aber auf Price cross up und Price cross down anpassen.

Wenn du den schnellen Durchschnitt nicht mehr verwendest, lösche seine Berechnung, Darstellung und den zugehörigen Input. Dann bietet die Oberfläche nur tatsächlich verwendete Einstellungen an.

Verfolge eine Kreuzung

Wähle eine Kerze mit grünem Zeichen. Sieh dir die Werte beider Linien auf dieser und der vorherigen Kerze an. Formuliere die beiden Vergleiche, die das Signal wahr gemacht haben. Diese Prüfung hilft auch später beim Überprüfen einer Strategie.