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