Как подобрать выигрышные акции с помощью анализа и визуализации на Python

RedDeveloper
30.03.2023 13:54
Как подобрать выигрышные акции с помощью анализа и визуализации на Python

Как выбрать выигрышные акции с помощью анализа и визуализации на Python

Сравните показатели акций и визуализируйте данные с помощью Plotly и Seaborn

Отказ от ответственности: Эта статья предназначена только для демонстрации и не должна использоваться в качестве инвестиционного совета.

Чаще всего мы хотим сравнить показатели акций в одной отрасли, например, какой банк показал наилучшие результаты за последний год или какая технологическая компания получила наибольший прирост за последние два года? Эта статья проведет вас через процесс анализа и визуализации этих данных с помощью Python, что позволит вам получить полезные выводы.

Подготовка данных

Прежде чем мы продолжим, давайте импортируем необходимые библиотеки Python для последующих разделов. По мере продвижения по шагам я буду давать пояснения по пакетам по мере их вызова.

from pandas_datareader import data as pdr
import yfinance as yf
import pandas as pd
import numpy as np
import datetime
import time
yf.pdr_override()
import seaborn as sns 
import cufflinks as cf

Здесь я создам список тикеров банков, импортирую их информацию из Yahoo Finance и консолидирую их в один Panda DataFrame. У вас есть возможность указать предпочтительные даты начала и окончания анализа:

bank = ['C','JPM','BAC','WFC']

df_all = pd.DataFrame()
for ticker in bank:
    df = pdr.DataReader(ticker, data_source='yahoo', start='2020-01-01', end='2021-08-01')
    df['Symbols'] = ticker
    df_all = pd.concat([df_all,df],axis=0)
df_all

Полученный DataFrame 'df_all', содержит временной ряд цен открытия, максимума, минимума, закрытия/скорректированной цены закрытия акций и соответствующий объем сделок.

Полученный DataFrame 'df_all' содержит временной ряд цен открытия максимума минимума

Проверка наличия недостающих значений в данных :

df_all.isnull().sum()
Проверка наличия недостающих значений в данных

Следующим шагом будет создание DataFrame с минимальной и максимальной ценой закрытия каждой акции за указанный период:

df1 = df_all.groupby('Symbols')['Adj Close'].agg(('min','max')).reset_index().rename(columns = {"min": "Min Close","max":"Max Close"})
df1
Следующим шагом будет создание DataFrame с минимальной и максимальной ценой закрытия

Далее мы объединим df1 и df_all DataFrame, чтобы добавить минимальные/максимальные цены в основной DataFrame (будет создан "df_all2")

df_all1 = df_all.reset_index()
df_all2 = pd.merge(df_all1, df1 ,on = ['Symbols'])
df_all2
Далее мы объединим df1 и df_all DataFrame чтобы добавить минимальные/максимальные цены в

Ниже приведен процесс создания DataFrame со скользящими 5-дневными, 30-дневными и 90-дневными средними ценами закрытия банков.

dfcomp = pdr.DataReader(bank, data_source='yahoo', start='2022-01-01', end='2023-03-01')
dfcomp1 = dfcomp['Adj Close']
df_5days = dfcomp1.rolling(window=5).mean().tail(1)
df_30days = dfcomp1.rolling(window=30).mean().tail(1)
df_90days = dfcomp1.rolling(window=90).mean().tail(1)
df_5days_new = df_5days.T
df_30days_new = df_30days.T
df_90days_new = df_90days.T
df_5days_new.columns = ['rolling_5days']
df_30days_new.columns = ['rolling_30days']
df_90days_new.columns = ['rolling_90days']
rolling = pd.concat([df_5days_new,df_30days_new,df_90days_new], axis = 1).reset_index().rename(columns = {"index":"Symbols"})
rolling
Ниже приведен процесс создания DataFrame со скользящими 5-дневными 30-дневными и

Мы также хотим сохранить последнюю цену закрытия акций:

dfcomp_close = dfcomp1.tail(1)
dfcomp_close = dfcomp_close.T
dfcomp_close = dfcomp_close.reset_index()
dfcomp_close.columns = ['Symbols','Close Price']
dfcomp_close
мы также хотим сохранить последнюю цену закрытия акций

Чтобы объединить всю информацию, мы объединим три DataFrame: 'df_all2', 'rolling' и 'dfcomp_close'. Теперь объединенный DataFrame содержит всю историческую информацию о ценах, а также дополнительные характеристики, такие как минимальная и максимальная цены, скользящая средняя цена и последняя цена закрытия.

df_all3 = pd.merge(df_all2, rolling ,on = ['Symbols'])
df_all4 = df_all3.merge(dfcomp_close, on = ['Symbols'])
df_all4
Чтобы объединить всю информацию мы объединим три DataFrame 'df_all2' 'rolling' и

До этого момента было бы полезно определить акции с наибольшим приростом от минимальной цены до последней цены закрытия, а также акции с наибольшим процентным падением от максимальной цены. Для этого мы добавляем следующие два столбца, выполнив приведенный ниже код:

#calculating percentage of gain from minimum price to close price
df_all4['min_to_close_pct_change'] = (df_all4['Close Price'] - df_all4['Min Close'])/df_all4['Min Close']
#calculating percentage of price drop from the maximum price
df_all4['close_to_max_pct_change'] = (df_all4['Max Close'] - df_all4['Close Price'])/df_all4['Close Price']

Наконец, мы дедуцируем данные до уникального уровня запасов и сохраняем их в другой DataFrame, чтобы позже использовать их для визуализации.

df_all4_unique = df_all4.drop_duplicates(subset = ['Symbols'])
df_all4_unique = df_all4_unique.reset_index()
df_all4_unique = df_all4_unique.drop(columns = ['index','Date','Open','High','Low','Close','Adj Close','Volume'])
df_all4_unique
Наконец мы дедуцируем данные до уникального уровня запасов и сохраняем их в другой

Визуализация данных

Теперь у нас есть практически все необходимые данные, давайте приступим к визуализации.

  1. . Рассмотрим одну конкретную акцию, в качестве примера возьмем тикер "C".
c = df_all4.loc[df_all4['Symbols'] == 'C']
c = c[['Date','Adj Close', 'Max Close','rolling_5days', 'rolling_30days', 'rolling_90days']]
c.set_index("Date", inplace = True)
c
Теперь у нас есть практически все необходимые данные давайте приступим к визуализации

Мы импортировали библиотеку "cufflinks" заранее (import cufflinks as cf), Cufflinks - это библиотека, которая соединяет рамку данных Pandas с Plotly, позволяя пользователям создавать визуализации прямо из Pandas.

cf.go_offline()
c.iplot()
plt.show()
Мы импортировали библиотеку "cufflinks" заранее (import cufflinks as cf) Cufflinks - это

Выше показана историческая скорректированная цена закрытия, максимальная цена и несколько скользящих средних цен на одном графике, график динамический, вы можете увидеть значение определенной временной точки при наведении на нее курсора мыши.

2). Мы также можем визуализировать тренд цены закрытия нескольких акций на одном графике.

bank_close_price = dfcomp['Adj Close']
import cufflinks as cf
cf.go_offline()
bank_close_price.iplot()
plt.show()
2) Мы также можем визуализировать тренд цены закрытия нескольких акций на одном графике

3). Похоже, что все 4 банка имели очень похожий паттерн в плане изменения цены, давайте построим гистограмму с помощью библиотеки Python Seaborn, чтобы увидеть, какой из них имел наибольший выигрыш от минимальной цены.

Библиотека Seaborn была импортирована заранее (import seaborn as sns). DataFrame, который мы будем использовать, это тот, который мы создали выше на уровне уникальной компании (df_all4_unique).

Библиотека Seaborn была импортирована заранее (import seaborn as sns) DataFrame который
plt.figure(figsize=(20,10), tight_layout=True)
ax = sns.barplot(x=df_all4_unique['Symbols'], y=df_all4_unique['min_to_close_pct_change'], palette='pastel', ci=None)
ax.set(title='Barplot', xlabel='Symbols', ylabel='min_to_close_pct_change')
plt.show()
Библиотека Seaborn была импортирована заранее (import seaborn as sns) DataFrame который

Мы можем заметить, что JPM получила больший прирост от самой низкой цены, чем остальные три акции за этот период.

Мы можем сделать еще одну гистограмму, чтобы посмотреть на нее под другим углом, чтобы увидеть, у какой акции был наибольший процент падения цены от максимальной цены.

plt.figure(figsize=(20,10), tight_layout=True)
ax = sns.barplot(x=df_all4_unique['Symbols'], y=df_all4_unique['close_to_max_pct_change'], palette='pastel', ci=None)
ax.set(title='Barplot', xlabel='Symbols', ylabel='close_to_max_pct_change')
plt.show()
Мы можем сделать еще одну гистограмму чтобы посмотреть на нее под другим углом чтобы

У "BAC" было самое большое падение цены от максимальной цены в течение этого периода.

Резюме

В этой статье я продемонстрировал процесс получения данных из Yahoo и проведения простого анализа для сравнения конкурирующих акций в одной отрасли, а также представил различные методы визуализации. Вы можете настроить анализ, выбрав различные наборы акций за разные периоды времени.

Надеюсь, вы найдете эту статью полезной!

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?

20.08.2023 18:21

Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в 2023-2024 годах? Или это полная лажа?".

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией

20.08.2023 17:46

В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.

Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox

19.08.2023 18:39

Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в частности, магию поплавков и гибкость flexbox.

Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest

19.08.2023 17:22

В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для чтения благодаря своей простоте. Кроме того, мы всегда хотим проверить самые последние возможности в наших проектах!

Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️

18.08.2023 20:33

Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий их языку и культуре.

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL

14.08.2023 14:49

Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип предназначен для представления неделимого значения.