Po kolejnych świecach przechodzi wykonawca. Wewnątrz jednej możesz jednak potrzebować powtórzeń, na przykład do dodania ostatnich pięciu zamknięć. Służy do tego pętla.

for i range

for offset in range(5):
    total += close[offset]

range(5) nadaje offset kolejno 0, 1, 2, 3 i 4. Nie zawiera 5. Wcięty wiersz wykonuje się raz dla każdej wartości.

close[offset] oznacza więc obecne zamknięcie, potem jedno, dwa, trzy i cztery świece wcześniej. Dodajemy dokładnie pięć cen.

Przed pętlą trzeba wyzerować total. To wynik pośredni dla jednej świecy, nie zachowywany między nimi licznik.

range(1, 5) daje 1, 2, 3, 4. Początek należy do zakresu, koniec nie. Pominięty początek oznacza zero.

Ręcznie napisana średnia

Utwórz manual_average.py:

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


@script.indicator("Manual Average Check", overlay=False)
def main(
    length: int = input.int(5, title="Length", minval=1, maxval=100),
):
    total = 0.0
    for offset in range(length):
        total += close[offset]
    manual_average = total / length
    builtin_average = ta.sma(close, length)
    difference = manual_average - builtin_average
    plot(difference, "Difference", color=color.blue)

Uruchom na demonstracji. Linia pokazuje różnicę własnej i gotowej SMA. Po rozgrzewce powinna przebiegać po zerze lub bardzo blisko wskutek reprezentacji liczb.

Obok manual_average.py osobny panel PyneIDE pokazuje różnicę średnich.
Różnica wyników własnej pętli i gotowej SMA po rozgrzewce pozostaje blisko zera.

Nie rysujemy dwóch nakładających się linii, bo małe różnice byłyby niewidoczne. Sama różnica bezpośrednio pokazuje zgodność obliczeń.

Co robi jedno wykonanie?

Przy długości pięć kolejność jest taka:

  1. total otrzymuje zero.
  2. Pętla dodaje obecne i cztery poprzednie zamknięcia.
  3. Dzielimy sumę przez pięć.
  4. Obliczamy gotową SMA i różnicę wobec własnego wyniku.
  5. Rysujemy pojedynczy punkt różnicy.

Potem wykonawca przechodzi do kolejnej świecy. total znów zaczyna od zera, a pętla dodaje pięć cen należących do nowego okna.

Gdyby total było Persistent, kolejna świeca zaczynałaby od poprzedniej sumy. Dodawałbyś następne pięć wartości do starego wyniku zamiast liczyć średnią obecnego okna.

Brakująca historia

Na pierwszych czterech świecach do pięciu elementów brakuje co najmniej jednego zamknięcia. na w sumie powoduje brak własnej średniej. Gotowa SMA też jest prawidłowa dopiero od piątej świecy.

W demonstracji wszystkie zamknięcia są prawidłowe. W źródłach z brakami także w środku obsługa ta.sma może różnić się od prostego dodawania po przesunięciach świec. Dlatego sprawdzamy przykład na podanych danych.

Ile powtórzeń zlecasz?

Okno stu świec wymaga stu dodawań na świecę. Przy dwóch tysiącach to dwieście tysięcy kroków pętli.

Gotowa ta.sma ma wykonywać to częste zadanie przy użyciu zaprojektowanego do niego mechanizmu. Własna pętla służy tu zrozumieniu i porównaniu. Korzystaj z gotowej funkcji, jeśli wykonuje potrzebne zadanie.

Koniec pętli musi być znany i ograniczony. Maksimum wejścia określa też, ile pracy użytkownik może zlecić na jedną świecę.

break i continue

break przerywa pętlę. continue pomija resztę bieżącego kroku i przechodzi do następnego.

Przy średniej stosuj je ostrożnie. Jeśli dodasz trzy wartości i zatrzymasz pętlę, nie możesz dzielić przez pięć jak przy pięciu wartościach. Pomijanie zmienia sens obliczeń.

Spróbuj samodzielnie

Ustaw długość trzy. Na jednej świecy zapisz przesunięcia i odpowiadające im trzy ceny. Potem zmodyfikuj program, by obok kontroli różnicy pokazać własną i gotową średnią w trybie overlay.

Rozwiązanie zadania

Przesunięcia to 0, 1, 2. W dekoratorze ustaw overlay=True, po obliczeniu dodaj:

plot(manual_average, "Manual average", color=color.blue, linewidth=2)
plot(builtin_average, "Built-in average", color=color.orange)

Usuń rysowanie różnicy z tego widoku. Linia blisko zera i średnie na poziomie cen są mało czytelne we wspólnej skali. Oryginalny panel różnicy możesz zachować w osobnej wersji do sprawdzania.

Znajdź przesunięte okno

Rozważ zmianę na range(1, length + 1). Elementów nadal byłoby pięć, ale zabrakłoby obecnej świecy, a pojawiłaby się cena sprzed pięciu. To okno poprzedniej świecy, nie obecnej.