niedziela, 18 lutego 2024

Stopa zwrotu - ważone i roczna stopa zwrotu portfela

Ten post jest kontynuacją: https://kamilkondrat.blogspot.com/2024/02/stopa-zwrotu-zwrot-portfela.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.

W poprzednim wpisie nadałem wagi poszczególnym spółkom: "Pozwolę sobie zdecydować, że 25% kapitału zostanie zainwestowane w Alphabet, 25% w Microsoft i 50% Nvidia." Tworząc przy tym jednowymiarową tablicę "weights."

Następnie pomnożymy wszystkie stopy zwrotu dla każdej spółki z każdego dnia przez ustalone wagi "weights", aby następnie zsumować wyniki trzech spółek uzyskując jeden konkretny wynik, który wyrazi dany dzień. Krok po kroku, jak to działa...

Mam przed sobą tablicę ukazującą znormalizowane stopy zwrotu (obliczoną na podstawie kodu, który pojawił się wcześniej na tym blogu):


GOOGL MSFT NVDA
Date


2019-02-19 NaN NaN NaN
2019-02-20 -0.005255 -0.005199 0.012193
2019-02-21 -0.014617 0.021092 -0.017534
2019-02-22 0.011184 0.014258 0.021955
2019-02-25 0.000690 0.005587 -0.003141
... ... ... ...
2024-02-12 -0.009866 -0.012579 0.001594
2024-02-13 -0.016200 -0.021529 -0.001661
2024-02-14 0.005512 0.009665 0.024567
2024-02-15 -0.021721 -0.007155 -0.016806
2024-02-16 -0.015760 -0.006149 -0.000619


Jeśli chcę obliczyć ważoną stopę zwrotu, to dla każdego poszczególnego wiersza należy wykonać analogiczną operację: (-0.015760 * 25%) + (-0.006149 * 25%) + (-0.000619 * 50%) =
-0.00578687. Wynik powyższego równania analogicznie należy zastosować do każdego z wierszy, ten wyżej odpowiada ostatniemu, tj. z 2024-02-16.

Oczywiście do obliczeń wykorzystamy odpowiednią funkcję. To jest ważnym elementem naszej pracy, uczymy się korzystać z programowania i komputera, aby on wykonywał za nas złożone obliczenia oraz powtarzalne rzeczy pozwalające się zautomatyzować, tak abyśmy mogli skupić się na esencji, a jest nią wyciąganie wniosków rozwijając naszą inteligencję i zdobywać nową wiedzę z danych.

Zastosujmy odpowiednią metodę, która obliczy ważone stopy zwrotu z każdego dnia dla trzech spółek i stworzy tablicę danych z wynikami. Przypominam, każda wartość w tej tablicy będzie łączną sumą stóp zwrotu z trzech spółek dla każdego dnia pomnożona uprzednio przez jej wagi:

weighted_returns = np.dot(returns, weights)

"weighted_returns" przyjmuje i zapisuje obiekt zwrócony przez funkcje "np.dot()" i jest to tablica danych.

Teraz przejdziemy do rocznej stopy zwrotu z portfela inwestycyjnego, bez uwzględnienia ważonych.

annual_returns = returns.mean() * 252

Słowo "annual" to angielskie coroczny/rocznik. Kod tak jak ten i każdy inny najlepiej jeśli jest samo tłumaczący się. Zmienna "returns" przechowuje stopy zwrotu obliczone na podstawie znormalizowanych ceny zamknięcia dla każdego dnia i dla każdej spółki oddzielnie. Używając na niej funkcji "mean()" obliczamy średnią stopę zwrotu dla jednego dnia i mnożymy to przez 252 (ta wartość bierze się stąd, że są to dni handlowe, pozostałe dni w roku to weekendy i święta, które nie uznaje się jako dni handlowe). 

Pamiętajmy, że "returns" zostaje wyliczony z całych danych, które zostały pobrane na początku skryptu, jeśli wybraliście to co było zaproponowane w prezentowanym przeze mnie przykładzie, to jest to okres 5 lat. Średnia dla jednego dnia jest wyliczona z 5 lat i następnie pomnożona przez 252 odpowiadające jednemu rokowi finansowemu, nie dwóm lub więcej.

W moim przypadku obliczone "annual_returns" prezentuje się następująco:

GOOGL: 0,233875
MSFT: 0,320815
NVDA: 0,716708

Weźmy pod uwagę Nvidię. Mnożąc tę wartość razy 100%, mamy 71,6708%. Oznacza to, że zysk z rocznej stopy zwrotu (innymi słowy skalowany do tego jednego roku) oparty o uśrednione dane z 5 lat wyniósł (w zaokrągleniu) 72%. To bardzo dobry wynik. Nie jest to oczywiście jeszcze predykcją, nie jest to jeszcze przepowiadaniem określonej przyszłości z przypisanym do tego prawdopodobieństwem, jednak mając te dane uśrednione z okresu ostatnich 5 lat możemy przepuszczać, że w przybliżeniu i kolejny przyniesie podobną korzyść z inwestycji. Jednak póki co zostawiamy to, z pewnością szeregi czasowe i predykcją pojawią się na blogu, ponieważ leży to w moich zainteresowaniach.

Użyjmy jeszcze raz wag, tym razem na rocznej stopie zwrotów, aby ostatecznie obliczyć zwrot całego portfela uzyskując końcowy wynik. Wiemy już jak przebiega obliczanie wektora/produktu macierzy. Teraz obliczymy ten produkt korzystając z rocznej stopy zwrotu trzymając się tych samych wartości wag: 25%, 25%, 50%. To będzie zwrotem portfela.

portfolio_return = np.dot(annual_returns, weights) * 100

Powyższy kod da nam procentowy zysk całego naszego omawianego portfela i na moim komputerze rezultatem jest wynik, który w zaokrągleniu daje 49,7% zysku. To jest zwrot inwestycji w trzy spółki, Alphabet, Microsoft i Nividia. 

Rozważając to w kontekście danych historycznych (bez robienia predykcji), można powiedzieć, że inwestując w te trzy spółki 1zł, za każdą złotówkę mielibyśmy w przybliżeniu zarobione dodatkowe 50 groszy zysku. Trzeba tylko pamiętać, że są to wnioski wyciągnięte z analizy przeszłości poprzez normalizowanie, uśrednianie i relatywizowanie i nie są to predykcje. 

Z racji tego jak przez te ostatnie 5 lat radzą sobie te spółki, możemy przepuszczać, że kolejny rok również przyniesie owoce, jednak trzeba pamiętać, że nie jest to tożsame z predykcją w stylu: "Roczna stopa zwrotu z kolejnego roku przyniesie 51,24% zysku, z prawdopodobieństwem 84%."

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')....