sobota, 27 stycznia 2024

Analiza SMA - definiowanie istotnej funkcji

W tym wpisie będziemy kontynuować analizę SMA: https://kamilkondrat.blogspot.com/2024/01/wprowadzenie-do-analizy-sma-przy-uzyciu.html

Ta praca odzwierciedla zainteresowanie autora analizą finansową i wykorzystaniem narzędzi informatycznych w jej realizacji. Niniejszy blog nie ma na celu dostarczania porad finansowych, lecz stanowi konstruktywne podejście autora do dzielenia się wiedzą. Autor widzi w tym sposobność do rozwijania swoich umiejętności i zachęcania do wzajemnej dyskusji. Należy pamiętać, że wnioski wynikające z analiz prezentowanych na tym blogu nie powinny być bezpośrednio stosowane do podejmowania decyzji finansowych. Nawet jeśli analizy są dokładne, stanowią one tylko fragment potrzebnych informacji do podjęcia w pełni świadomej decyzji. Brak szerszego kontekstu, w którym znajduje się potencjalny inwestor lub decydent, może prowadzić do niepełnych wniosków.

Po zaczytaniu odpowiednich bibliotek czas na właściwą pracę. Zaczniemy od pobrania danych finansowych i zdefiniowania odpowiednich struktur danych, którą pozwolą nam ruszyć z miejsca.

df = yf.download('AAPL', period = '1y')

df['SMA_30'] = ta.sma(df['Close'],30)
df['SMA_120'] = ta.sma(df['Close'],120)

"df" - definiujemy zmienną "df" inspirując się DataFrame, gdyż funkcja "download" zwraca obiekt tej właśnie klasy, czyli DataFrame. Będzie to przechowalnia naszych danych finansowych.

"AAPL" - to symboliczny zapis firmy Apple. Akurat kilka dni temu miałem okazje poznać i rozmawiać z osobą tam pracującą. :-) Stąd też postanowiłem, że przeprowadzę tę demonstrację z użyciem danych tej spółki.

"period = '1y'" - pobrane dane będą danymi zaczynając od tych (dostępnych) najnowszych kończąc na tych do 1 roku w tył. Dane z jednego roku nam wystarczą do policzenia SMA z 120 dni i mniej.

Następnie dodajemy dwie nowe kolumny do naszej ramki (tabeli) danych i jest to SMA_30 i SMA_120. Do policzenia SMA dla interesującego nas okresu 30 i 120 dni wykorzystujemy funkcję "sma()" z biblioteki "pandas_ta" oraz wartości z kolumny "Close" zawartej w naszych danych.

Ceny zamknięcia ("Close") są wartościami ostatniej transakcji kupna/sprzedaży danego aktywa w danym dniu handlowym.

Aby zapoznać się z matematycznym sposobem obliczania SMA można wejść tutaj: https://rankia.pl/analizy-gieldowe/prosta-wykladnicza-i-wazona-srednia-kroczaca-wzory-i-przyklady/ Ja nie będę rozwodził się nad matematycznymi wzorami, te obliczenia robi za nas komputer, a my mu "zlecamy" to przy pomocy Pythona.

Na moim urządzeniu pobranie danych przebiegło pomyślnie stąd też ten czerwony paseczek informujący o zakończeniu procesu. 

Po rozszerzeniu struktury danych o dwie kolumny dane prezentują się następująco:














Można zauważyć, że powyższe dane są z agregowane według daty.

Czas na esencję naszego skryptu. Funkcja "buy_sell_signal" porównuje ze sobą SMA oraz dopisuje sygnały o kupnie i sprzedaży:

def buy_sell_signal(df):
    
    buy_signal = []
    sell_signal = []
    position = False
    
    for i in range(len(df)):
        if df['SMA_30'][i] > df['SMA_120'][i]:
            if position == False:
                buy_signal.append(df['Adj Close'][i])
                sell_signal.append(np.nan)
                position = True
            else: 
                buy_signal.append(np.nan)
                sell_signal.append(np.nan)
        elif df['SMA_30'][i] < df['SMA_120'][i]:
            if position == True:
                buy_signal.append(np.nan)
                sell_signal.append(df['Adj Close'][i])
                position = False
            else:
                buy_signal.append(np.nan)
                sell_signal.append(np.nan)
        else:        
            buy_signal.append(np.nan)
            sell_signal.append(np.nan)            
                        
    return pd.Series([buy_signal, sell_signal])

"buy_signal" oraz "sell_signal" będą listami zbierającymi interesujące nas wartości.

"position" informuje nas o tym czy inwestor posiada aktywa czy nie. "True" będzie informować nas o tym, że inwestor, mówiąc kolokwialnie, "jest w grze." "False" oznacza, że inwestor jest "poza grą" i nie posiada aktywów.

Dzięki pętli "for" i funkcji "range" przechodzimy przez wszystkie wiersze w naszych danych. 

"[i]" - zawiera numer aktualnie porównywanych wartości dla danego wiersza. Porównywane są między sobą wartości z kolumn "SMA_30" i "SMA_120." Każdy wiersz z kolei to inny dzień i inny wyliczony na ten dzień współczynnik SMA. SMA przed tymi porównaniami było wyliczane w ten sposób, że każdy dzień był punktem zaczepienia i od tego dnia program cofał się 30 lub 120 dni licząc przy tym SMA i zrobiliśmy to dzięki funkcji "sma()" podanej na początku tego wpisu.

Kiedy krótkoterminowa SMA będzie większa niż długoterminowa, wtedy uznajemy to za sygnał kupna i dodajemy wartość z kolumny "Adj Close" przy użyciu funkcji "append()" do listy którą stworzyliśmy na początku: "buy_signal."

Kiedy krótkoterminowa SMA będzie mniejsza od długoterminowej, wtedy uznajemy ją za sygnał sprzedaży i dodajemy wartość z kolumny "Adj Close" przy użyciu "append()" do listy "sell_signal."

Ktoś z Was mógłby zapytać: "A dlaczego nie dodajemy do listy wartości z kolumny 'Close', która posłużyła nam do wyliczania SMA, a zamiast tego dodajemy wartości z kolumny 'Adj Close'?"

Bierze się to z tego, że do wyliczenia SMA jako tako potrzebujemy cen zamknięcia, czyli "Close", to jest istotą tego współczynnika. Natomiast idąc dalej kiedy zostawiamy same obliczenia SMA, która skupiają się wokół cen zamknięcia i pozwalają nam wstępnie wyłonić sygnały kupna i sprzedaży dochodzimy do punktu, w którym możemy analizować rezultat tego, czyli skupić się na sygnałach kupna i sprzedaży. Kiedy mamy już wyłonione wiersze i wartości, które przeszły już analizę SMA możemy zwrócić się do danych z kolumny "Adj Close", które będą bardziej stosowne, w późniejszych etapach podejmowania decyzji finansowej, niż "Close", gdyż będą uwzględniały dywidendy i podziały akcji.

Kiedy nie wyodrębniamy żadnego sygnału kupna lub sprzedaży polecamy komputerowi uzupełniać puste rekordy "wartościami" NaN (Not a Number) przy użyciu "np.nan", który jest obiektem tzw. specjalnym.

W ostateczności funkcja "buy_sell_signal" zwraca obiekt serii dzięki funkcji "Series()", który w naszym kodzie zawiera w sobie dwie listy, listę sygnałów kupna i listę sygnałów sprzedaży.

Cdn.

Brak komentarzy:

Prześlij komentarz

Analiza sentymentów - wpisy na mediach społecznościowych (podział danych)

Ten wpis zaczniemy od stworzenia DataFrame z danymi treningowymi train_df = pd.read_csv('train.csv', encoding='ISO-8859-1')....