Jeśli cena przez dziesięć świec jest nad średnią, close > average może być prawdziwe dziesięć razy. Do oznaczenia samego przejścia z dołu w górę potrzebujesz też relacji na poprzedniej świecy.

Sytuacja i jej początek

Załóżmy, że średnia teraz i poprzednio wynosi 100. Poprzednie zamknięcie to 99, obecne 101. Cena jest nad średnią i przecięła ją w górę względem poprzedniej świecy.

Jeśli kolejne zamknięcie wyniesie 102, nadal leży nad średnią. Nie ma jednak nowego przecięcia, bo poprzednio też było wyżej.

ta.crossover(first, second) jest prawdziwe, gdy pierwsza wartość teraz przewyższa drugą, a przy poprzednim wykonaniu była mniejsza lub równa. ta.crossunder jest odpowiednikiem w dół.

Obecna równość jeszcze nie jest przecięciem: samo dotknięcie nie spełnia >. Równość na poprzedniej świecy pozwala jednak uznać obecne przejście w górę za przecięcie.

Być powyżej a przeciąć w góręCena zamknięcia przecina średnią w górę tylko na trzeciej świecy. Na czwartej pozostaje powyżej bez nowego sygnału. Równość na poprzedniej świecy również pozwala na przecięcie. close: 99 → 100 → 101 → 102. average: 100 → 100 → 100 → 100. close > average: False → False → True → True. ta.crossover(close, average): False → False → True → False.Cena zamknięciaaverage = 100991FalseFalse1002FalseFalse1013TrueTrue1024TrueFalseŚwiecaclose > averageta.crossover(close, average)
Być powyżej a przeciąć w góręCena zamknięcia przecina średnią w górę tylko na trzeciej świecy. Na czwartej pozostaje powyżej bez nowego sygnału. Równość na poprzedniej świecy również pozwala na przecięcie.

Przecięcie dwóch średnich

Kontynuujemy przykład dwóch średnich z rozdziału o średnich kroczących. Krótsza, szybsza będzie niebieska, dłuższa, wolniejsza pomarańczowa. Zielony trójkąt oznacza przecięcie szybkiej w górę, czerwony w dół.

Utwórz cross_signals.py:

"""
@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)

Uruchom na demonstracji z domyślnymi 5 i 20. Znaki pojawiają się tylko na świecach z przecięciem. Na dłuższym odcinku, gdzie niebieska linia stale leży nad pomarańczową, nie dostajesz nowego zielonego znaku na każdej świecy.

Wykres cross_signals.py zawiera szybką i wolną średnią oraz zielone i czerwone oznaczenia przecięć.
Przecięcia średnich pojawiają się jako odrębne zdarzenia.

Dlaczego przecięcie liczymy osobno?

ta.crossover i ta.crossunder działają na każdej świecy. Dzięki temu ich poprzednie wykonanie odpowiada poprzedniej przetworzonej świecy.

Gdybyś wywoływał przecięcie tylko pod dodatkowym warunkiem, dawny stan niekoniecznie pochodziłby z poprzedniej świecy. Linia i oznaczenie mogłyby badać różne szeregi czasowe.

Stosujemy więc poprzednią regułę: na każdej świecy obliczamy potrzebne wyniki ze stanem, a potem decydujemy na podstawie gotowych wartości.

Tutaj też widać rozgrzewkę

Dwudziestoświecowa SMA jest ważna od dwudziestej świecy. Przy pierwszej poprawnej wartości poprzednia SMA jeszcze nie istnieje, więc brak dwóch kompletnych świec do ustalenia przecięcia.

Warunek potrzebuje obecnych i poprzednich wartości obu średnich.

Nie zastępuj na zerem dla uzyskania znaku. Zerowa średnia mogłaby stworzyć sztuczne przecięcie tam, gdzie rzeczywistej jeszcze nie da się obliczyć.

Moment danych

W książce uruchamiamy programy na zamkniętych historycznych świecach. Sygnał oparty na dziennym zamknięciu używa informacji znanych przy zakończeniu świecy.

Zamknięcie tworzącej się świecy nadal może się zmieniać. Przecięcie obserwowane w trakcie może zniknąć do końca. Nie myl tego z kontrolą na świecach zamkniętych.

Sygnał na historycznym wykresie nie oznacza automatycznie transakcji wykonanej na tej samej świecy. Wskaźnik rysuje oznaczenie; zlecenie i moment realizacji określimy przy strategii.

Spróbuj samodzielnie

Utwórz kopię price_crossings.py. Zamiast przecięcia średnich oznacz przejście zamknięcia ponad lub pod wolną średnią. Zachowaj wolną linię.

Rozwiązanie zadania
crosses_up = ta.crossover(close, slow_average)
crosses_down = ta.crossunder(close, slow_average)

Oznaczenia używają dwóch zmiennych logicznych, więc wiersze plotshape nie wymagają zmiany. Warto jednak zmienić tytuły na Price cross up i Price cross down.

Jeśli szybkiej średniej już nie używasz, usuń jej obliczenie, rysowanie i wejście. Interfejs będzie oferował tylko faktycznie używane ustawienia.

Prześledź przecięcie

Wybierz świecę z zielonym znakiem i odczytaj obie linie na niej i poprzedniej. Opisz dwa porównania, dzięki którym sygnał stał się prawdziwy. Taką kontrolę wykorzystasz także przy strategii.