Teraz obok zamknięcia narysujemy także otwarcie. Rozszerzymy program z poprzedniego rozdziału: pobierzemy nową daną z biblioteki i dopiszemy wywołanie rysujące.

Przed zmianą przejdziemy przez kod, żeby było jasne, do czego służy każdy wiersz.

Kod jest dokładnym opisem

W programie wydajesz komputerowi instrukcje. Na przykład: „Użyj ceny zamknięcia świecy i pokaż ją niebieską linią”. Komputer oczekuje dokładnych nazw i znaków.

W Pyne code zapisujemy je składnią Pythona. Należą do niej nawiasy wywołań, dwukropki i wcięcia. W następnych częściach poznasz ich role.

Otwórz first_chart.py utworzony w drugim rozdziale. Zmiana nazwy wskaźnika w pliku nie wpływa na poniższe wyjaśnienie.

Znacznik Pyne na początku pliku

Pierwsze trzy wiersze:

"""
@pyne edge
"""

Trzy cudzysłowy oznaczają początek i koniec bloku tekstu. Na początku pliku taki blok może też zawierać opis programu. Python nazywa go docstringiem.

PyneCore odczytuje z niego @pyne. Znacznik informuje, że plik zawiera Pyne code i wymaga reguł innych niż zwykłe działanie Pythona. Przed uruchomieniem PyneCore przekształca kod, by umożliwić dostęp do wcześniejszych świec lub zachowanie wartości zmiennej na kolejną świecę. Omówimy to w osobnych rozdziałach.

Samo @pyne też jest poprawne. Plik Pyne code może zaczynać się tak:

"""
@pyne
"""

Co oznacza dopisane edge?

edge oznacza, że program używa określonej, ograniczonej części języka Pyne code. @pyne włącza wykonanie świeca po świecy, a edge określa dostępne elementy języka i funkcje. PyneIDE zgłasza przekroczenie tych granic.

W programach oznaczonych @pyne można korzystać również z dodatkowych możliwości i bibliotek Pythona. Programy @pyne edge opierają się na narzędziach dopuszczonych przez Pyne i nie importują dowolnych bibliotek Pythona. Dzięki temu mogą je przetwarzać także środowiska bez ogólnej maszyny wykonawczej Pythona.

We wszystkich pełnych programach książki zachowujemy @pyne edge i pracujemy w tych granicach języka.

Wybór narzędzi

Następny wiersz:

from pynecore.lib import close, color, plot, script

Konstrukcja from … import … udostępnia wymienione nazwy w programie. W przykładzie pobieramy cztery narzędzia z biblioteki pynecore.lib:

  • close: cena zamknięcia bieżącej świecy;
  • color: dostępne kolory;
  • plot: wyświetlenie wartości na wykresie;
  • script: określenie typu i podstawowych ustawień programu.

Nazwy rozdziela przecinek. Wielkość liter ma znaczenie: close i Close to różne nazwy.

Puste wiersze dzielą kod na części. Ułatwiają rozpoznanie końca listy narzędzi i początku programu.

Nazwa i sposób wyświetlania programu

@script.indicator("My First Chart", overlay=True)

Ten wiersz mówi, że tworzymy wskaźnik. Wskaźnik oblicza coś z danych i to wyświetla. Tutaj rysujemy zamknięcie.

W nawiasach podajemy ustawienia:

  • Tekst "My First Chart" w cudzysłowie jest nazwą wskaźnika.
  • overlay=True umieszcza rysunek na wspólnym wykresie ze świecami.

True oznacza prawdę, a False fałsz. Jeśli ustawisz overlay na False, wskaźnik pojawi się w osobnym panelu. Skorzystamy z tego w rozdziale o własnych obliczeniach.

Miejsce obliczeń

def main():
    plot(close, "Close", color=color.blue, linewidth=2)

def oznacza początek funkcji. Funkcja to nazwana sekwencja operacji. Tutaj nazywa się main.

PyneCore wykonuje ciało main() na świecach danych. To punkt wejścia programu. Po nawiasach stoi dwukropek, a wcięty wiersz pod nim należy do ciała funkcji.

Wcięcie określa, które wiersze należą do siebie. Jeden poziom to cztery spacje. Na początku wiersza naciśnij Tab: domyślna konfiguracja PyneIDE dodaje w ten sposób cztery spacje naraz. Shift + Tab cofa o poziom. Visual Studio Code zwykle automatycznie wcina też nowy wiersz po naciśnięciu Enter za wierszem zakończonym dwukropkiem.

O co prosimy plot?

plot(...) jest wywołaniem funkcji. W nawiasach podajemy wartości i ustawienia:

  • close: wyświetl tę wartość;
  • "Close": użyj tej nazwy rysunku;
  • color=color.blue: użyj niebieskiego;
  • linewidth=2: ustaw grubość linii na 2.

Rolę dwóch pierwszych wartości określa kolejność. color= i linewidth= podają nazwę ustawienia. Nazywamy je parametrami.

Kropka w color.blue oznacza dostęp do koloru blue należącego do color. Jest częścią dostępu do nazwy; nie zastępuj jej przecinkiem.

Narysuj dwie linie

Do zamknięcia używaliśmy close. Otwarcie jest dostępne jako open.

Utwórz kopię pliku two_lines.py w folderze scripts, zachowując przykład z drugiego rozdziału. W kopii:

  1. Dodaj open do importowanych narzędzi.
  2. Zmień nazwę wskaźnika na "Open and Close".
  3. Dodaj drugie wywołanie plot do ciała main().

Pełny program:

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


@script.indicator("Open and Close", overlay=True)
def main():
    plot(close, "Close", color=color.blue, linewidth=2)
    plot(open, "Open", color=color.orange, linewidth=2)

Przed uruchomieniem przewidź, gdzie linie spotkają się ze świecami. Zapisz plik i kliknij Run Pyne code. Użyj tych samych danych co wcześniej.

Obok two_lines.py wykres cen DEMO pokazuje osobne linie Close i Open.
Dwa wywołania plot, dwie linie: Close pokazuje zamknięcie, Open otwarcie na tym samym wykresie.

Co zaobserwować?

Niebieska linia łączy zamknięcia, pomarańczowa otwarcia. Rysunki mają nazwy Close i Open. Pomagają one rozpoznać linie także po zmianie kolorów.

Oba wywołania plot mają identyczne wcięcie czterech spacji, bo należą do tej samej funkcji main().

Jeśli pod open pojawi się błąd, sprawdź import. Użycie nowego narzędzia wymaga udostępnienia jego nazwy.

Komentarze w kodzie

Wiersz zaczynający się pojedynczym # jest komentarzem:

    # Show the opening price of each candle.
    plot(open, "Open", color=color.orange, linewidth=2)

Komentarz nie wykonuje operacji. Możesz nim opisać cel kroku dla siebie lub późniejszego czytelnika. Komentarze przykładów są po angielsku, objaśnienia w książce po polsku.

Komentarz może też kończyć instrukcję:

    plot(open, "Open", color=color.orange, linewidth=2)  # Show the opening price.

Wywołanie plot(...) normalnie się wykona. Tekst od # do końca wiersza jest komentarzem i zostanie pominięty. Między kodem a # zostawiamy dwie spacje dla czytelności.

Spróbuj samodzielnie

Dodaj trzecią linię pokazującą najwyższą cenę świecy. Dana nazywa się high. Nadaj rysunkowi nazwę "High" i kolor color.green.

Zastanów się, w których dwóch miejscach rozszerzyć program. Przewidź: czy High może być niżej od otwarcia lub zamknięcia własnej świecy?

Rozwiązanie zadania

high trzeba dopisać także do importu:

from pynecore.lib import close, color, high, open, plot, script

Do ciała main() dodaj ten wiersz, z takim samym wcięciem jak pozostałe wywołania:

    plot(high, "High", color=color.green, linewidth=2)

Maksimum świecy jest co najmniej równe otwarciu i zamknięciu. Punkt High nie może więc leżeć poniżej żadnego z nich na tej samej świecy. Odcinki łączące punkty oceniaj zawsze w miejscu odpowiadającej im świecy.

Sprawdź własną zmianę

Przejrzyj program z trzema liniami. Czy znajdujesz importowane dane, nazwę wskaźnika i wywołania rysujące? Sprawdź, czy każda nowa nazwa danych jest w imporcie i czy wywołania mają jednakowe wcięcia.

Zanim zaczniemy własne obliczenia na cenach, zobaczymy, jak PyneIDE pomaga używać funkcji.