Własny zbiór danych: tablice
Zapiszesz świeże ceny w tablicy o ograniczonym rozmiarze i prześledzisz kolejność elementów.
Series przechowuje historię przypisaną świecom. Czasem chcesz jednak sam określić, które wartości zbiera program, w jakiej kolejności i kiedy je usuwa. Możesz użyć tablicy.
Co przechowuje tablica?
Tablica składa się z kolejnych elementów. Każdy ma indeks, pierwszy wynosi zero.
Tablica przechowuje elementy tego samego typu. Może zawierać liczby albo teksty, ale do tablicy liczbowej nie wkładamy tekstu. Ten sam typ nie oznacza tej samej wartości: 100, 103 i 101 są różnymi liczbami w jednej tablicy.
Po dodaniu 100, 103 i 101 w tej kolejności indeks 0 zawiera 100, indeks 1 — 103, a indeks 2 — 101. Indeks oznacza miejsce przechowywania, nie automatycznie liczbę świec wstecz.
close[1] jest poprzednim zamknięciem. array.get(prices, 1) drugim elementem prices. Wiek wartości zależy od sposobu zapełniania tablicy.
Przestrzeń nazw array
array.new_float(0) tworzy początkowo pustą tablicę liczbową. Zero jest liczbą elementów na początku, nie ceną.
| Operacja | Zadanie |
|---|---|
array.push(prices, close) | Dodaje element na końcu |
array.size(prices) | Podaje liczbę elementów |
array.shift(prices) | Usuwa i zwraca pierwszy element |
array.get(prices, 0) | Odczytuje pierwszy element |
array.avg(prices) | Oblicza średnią zapisanych liczb |
Indeks array.get musi wskazywać istniejący element. Dla trzech elementów poprawne są 0, 1 i 2; 3 już nie.
Przechowaj pięć świeżych cen
Utwórz recent_prices.py:
"""
@pyne edge
"""
from pynecore import Persistent
from pynecore.lib import array, close, color, plot, script, ta
@script.indicator("Recent Prices", overlay=True)
def main():
prices: Persistent[list[float]] = array.new_float(0)
array.push(prices, close)
if array.size(prices) > 5:
array.shift(prices)
stored_average = array.avg(prices)
full_average = ta.sma(close, 5)
plot(stored_average, "Stored average", color=color.blue, linewidth=2)
plot(full_average, "SMA 5", color=color.orange)list[float] jest typem tablicy liczb. Persistent zapewnia, że pozostanie na następnej świecy; nie tworzymy jej od nowa przy każdej.
Używamy operacji array. Nie trzeba importować ogólnej biblioteki Pythona ani pisać literału listy.
Ciekawostka dla znających Pythona: w pythonowym wykonawcy PyneCore tablicę przechowuje lista Pythona. Stąd typ list[float]. Elementy muszą pasować do typu tablicy; inaczej niż w ogólnej liście nie mieszamy liczb i tekstu.
W programie @pyne korzystającym z szerszych możliwości Pythona możesz używać też operacji listy: prices.append(close) dodaje element, prices.pop(0) usuwa pierwszy. W książkowym @pyne edge służą do tego array.push i array.shift. W Edge zamiast bezpośredniego prices[0] używamy array.get(prices, 0), a tablicę tworzymy na przykład array.new_float(0), nie literałem [].
Uruchom na demonstracji. Niebieska linia rysuje średnią z już zebranych cen. Na pierwszej świecy ma jedną, na drugiej dwie, potem trzy i cztery. Od piątej pozostaje pięć elementów.

Kolejność dodawania i usuwania
Na szóstej świecy najpierw dodajemy szóste zamknięcie. Jest sześć elementów. Warunek if jest prawdziwy, więc usuwamy pierwszy, najstarszy. Przy liczeniu średniej pozostają zamknięcia od drugiej do szóstej świecy.
Początek tablicy jest tutaj najstarszą zachowaną ceną, koniec najnowszą. Od pięciu elementów array.get(prices, 0) daje więc cenę sprzed czterech świec, nie obecną.
Najnowsza ma indeks array.size(prices) - 1. Liczba elementów i ostatni indeks różnią się o jeden, bo numerujemy od zera.
Częściowe i pełne okno
Średnie na początku zachowują się inaczej. Tablica liczy z rzeczywiście zebranych cen, także gdy jest ich najwyżej cztery. ta.sma(close, 5) zwraca wartość dopiero dla pełnej piątki.
Od piątej świecy średnie używają tych samych pięciu cen. Powinny zgadzać się w granicach dokładności liczb.
Dlatego średnia tablicowa nie zastępuje automatycznie gotowej średniej kroczącej. Sam ustalasz regułę początkowego okna.
Dlaczego ograniczamy rozmiar?
Jeśli tylko dodajesz, tablica rośnie z długością danych. Na końcu zawierałaby wszystkie przetworzone zamknięcia.
Potrzebujemy ostatnich pięciu, więc usuwamy starsze. Przy obliczeniu przechowuje najwyżej pięć wartości. Również w rzeczywistym zbieraniu danych określ, co i jak długo trzeba zachować.
Spróbuj samodzielnie
Zmień program, by zachowywał trzy ceny, i ustaw SMA na trzy. Potem jako trzecią linię narysuj najstarszy zachowany element.
Rozwiązanie zadania
Warunek usuwania:
if array.size(prices) > 3:
array.shift(prices)Gotowa średnia i nowa linia:
full_average = ta.sma(close, 3)
oldest_price = array.get(prices, 0)
plot(oldest_price, "Oldest stored price", color=color.gray)array.push poprzedza odczyt na każdej świecy, więc tablica ma wtedy co najmniej element. Po zapełnieniu trzech miejsc najstarsza cena pochodzi sprzed dwóch świec.
Rozpisz zawartość tablicy
Dla trzech zamiast pięciu elementów i cen 100, 103, 101, 105 zapisz zawartość po każdej świecy. Po czwartej ma zawierać 103, 101 i 105 w tej kolejności.