Общеизвестно, что фондовый рынок трудно предсказать, поскольку на цены влияет широкий спектр экономических, политических и социальных факторов. Однако достижения в области глубокого обучения открыли новые возможности для прогнозирования цен на акции с использованием исторических данных.
В этой статье мы покажем, как использовать методы глубокого обучения, в частности модели LSTM, для прогнозирования будущих цен на акции с использованием Python. Мы рассмотрим два разных сценария: прогнозирование цены закрытия следующего дня для одной акции с использованием цен закрытия предыдущих девяти дней и прогнозирование цены закрытия последнего дня для всех акций в S&P 500 с использованием исторических данных.
Во-первых, мы начнем с более простого сценария прогнозирования цены закрытия следующего дня для отдельной акции, используя цены закрытия предыдущих девяти дней.
Далее мы распространим наш анализ на все акции S&P 500. Мы продемонстрируем, как загружать исторические данные о ценах для всех компонентов S&P 500 из Википедии и Yahoo Finance, предварительно обрабатывать данные, обучать модель и делать прогнозы. Мы также покажем, как сопоставить прогнозируемые цены с фактическими ценами для каждой акции, чтобы визуализировать производительность модели.
К концу этой статьи у вас будет четкое представление о том, как использовать глубокое обучение для прогнозирования цен на акции с помощью Python и как применять эти методы к реальному набору данных.
ЧАСТЬ 1: Прогноз для одного символа
Во-первых, мы можем загрузить исторические данные из Yahoo Finance, используя библиотеку yfinance. В следующей ячейке кода показано, как загрузить исторические данные для одного тикера.
import yfinance as yf symbol = 'AAPL' start_date = '2010-01-01' end_date = '2023-02-17' data = yf.download(symbol, start=start_date, end=end_date)
Мы можем использовать функцию графика для визуализации исторических данных.
import matplotlib.pyplot as plt plt.plot(data['Close']) plt.title(symbol + ' Close Price') plt.xlabel('Date') plt.ylabel('Price') plt.show()
Теперь, когда у нас есть исторические данные, мы можем построить модель LSTM для прогнозирования будущих цен. Модель LSTM — это тип рекуррентной нейронной сети, которая может учиться на последовательностях данных, таких как данные временных рядов. В следующей ячейке кода показано, как построить модель LSTM с помощью Keras, популярной библиотеки глубокого обучения.
from keras.models import Sequential from keras.layers import LSTM, Dense import numpy as np lookback = 9 def create_dataset(dataset): X, Y = [], [] for i in range(len(dataset)-lookback-1): X.append(dataset[i:(i+lookback), 0]) Y.append(dataset[i+lookback, 0]) return np.array(X), np.array(Y) # Scale data data = np.array(data['Close']).reshape(-1, 1) scaler = MinMaxScaler(feature_range=(0, 1)) data = scaler.fit_transform(data) # Train and test split train_size = int(len(data) * 0.8) train_data = data[:train_size] test_data = data[train_size:] train_X, train_Y = create_dataset(train_data) test_X, test_Y = create_dataset(test_data) train_X = np.reshape(train_X, (train_X.shape[0], train_X.shape[1], 1)) test_X = np.reshape(test_X, (test_X.shape[0], test_X.shape[1], 1)) # Create model model = Sequential() model.add(LSTM(50, input_shape=(lookback, 1))) model.add(Dense(1)) model.compile(loss='mean_squared_error', optimizer='adam') model.fit(train_X, train_Y, epochs=50, batch_size=64, verbose=2)
Мы разделяем данные на обучающий набор и тестовый набор и создаем последовательности прошлых цен и соответствующих им будущих цен с помощью функции create_dataset. Затем мы нормализуем данные с помощью MinMaxScaler и изменяем их форму, чтобы они соответствовали входному формату модели LSTM.
Модель LSTM состоит из входного слоя, слоя LSTM с 50 единицами и плотного выходного слоя. Мы компилируем модель с функцией потери среднеквадратичной ошибки и оптимизатором Адама и подгоняем ее к обучающим данным.
Как только модель обучена, мы можем использовать ее для прогнозирования тестовых данных. В следующей ячейке кода показано, как использовать модель для прогнозирования 10-й цены на основе 9 прошлых цен.
test_X = test_X.reshape((test_X.shape[0], lookback, 1)) predictions = model.predict(test_X) predictions = scaler.inverse_transform(predictions) actuals = scaler.inverse_transform(test_Y.reshape(-1, 1)) for i in range(10): print('Predicted:', predictions[i][0], 'Actual:', actuals[i][0])
Сначала мы изменяем тестовые данные, чтобы они соответствовали входному формату модели LSTM. Затем мы используем функцию прогнозирования, чтобы делать прогнозы, и инвертируем масштабирование, чтобы получить фактические цены. Мы печатаем первые 10 прогнозируемых цен и соответствующие им фактические цены.
Мы также можем построить график прогнозируемых цен с течением времени, используя следующую ячейку кода.
plt.plot(actuals, label='Actual') plt.plot(predictions, label='Predicted') plt.title(symbol + ' Close Price') plt.xlabel('Date') plt.ylabel('Price') plt.legend() plt.show()
На графике прогнозируемые цены показаны оранжевым цветом, а фактические цены — синим. Мы видим, что модель способна уловить общую тенденцию цены акций, но имеет некоторую ошибку в предсказании точной цены.
ЧАСТЬ 2: Прогноз для всех символов
В предыдущем разделе мы показали, как использовать модель LSTM для прогнозирования будущей цены отдельной акции. В этом разделе мы распространим наш анализ на все акции S&P 500.
Во-первых, нам нужно загрузить исторические данные для всех компонентов S&P 500 из Yahoo Finance. Мы будем использовать те же даты начала и окончания, что и раньше.
import yfinance as yf import pandas as pd # Download S&P 500 components from Wikipedia url = 'https://en.wikipedia.org/wiki/List_of_S%26P_500_companies' table = pd.read_html(url, header=0)[0] symbols = list(table.Symbol) # Download historical data for all S&P 500 components start_date = '2010-01-01' end_date = '2023-02-17' dfs = {} for symbol in symbols: print('Downloading', symbol) df = yf.download(symbol, start=start_date, end=end_date) if len(df) >= 50: dfs[symbol] = df
Приведенный выше код загружает исторические данные для всех компонентов S&P 500 и сохраняет их в словаре фреймов данных, где ключи — это символы, а значения — фреймы данных. Он сохраняет данные символа только в том случае, если его длина составляет 50 или более.
Теперь мы можем использовать те же функции create_dataset и train_test_split, что и раньше, для подготовки данных для каждого символа. Однако на этот раз мы будем обучать модель LSTM на всех данных, кроме последнего дня, и использовать ее для прогнозирования цены каждого символа в последний день.
from sklearn.preprocessing import MinMaxScaler import numpy as np def create_dataset(data, lookback=9): X, Y = [], [] for i in range(lookback, len(data)): X.append(data[i-lookback:i, 0]) Y.append(data[i, 0]) return np.array(X), np.array(Y) def train_test_split(data, test_size=0.2, lookback=9): train_size = int(len(data) * (1 - test_size)) train, test = data[:train_size], data[train_size-lookback:] return train, test lookback = 9 test_size = 0.2 results = [] for symbol, df in dfs.items(): # Prepare data data = df['Close'].values.reshape(-1, 1) scaler = MinMaxScaler(feature_range=(0, 1)) data = scaler.fit_transform(data) train, test = train_test_split(data, test_size=test_size, lookback=lookback) train_X, train_Y = create_dataset(train, lookback=lookback) test_X, test_Y = create_dataset(test, lookback=lookback) # Train model train_X = train_X.reshape((train_X.shape[0], train_X.shape[1], 1)) test_X = test_X.reshape((test_X.shape[0], test_X.shape[1], 1)) model = keras.models.Sequential([ keras.layers.LSTM(50, input_shape=(lookback, 1)), keras.layers.Dense(1) ]) model.compile(loss='mse', optimizer='adam') model.fit(train_X, train_Y, epochs=100, batch_size=32, verbose=0) # Make predictions test_X = test_X.reshape((test_X.shape[0], lookback, 1)) predictions = model.predict(test_X)[-1] predictions = scaler.inverse_transform(predictions.reshape(-1, 1))[0] actual = df['Close'][-1] results.append((symbol, actual, predictions))
Приведенный выше код перебирает все компоненты S&P 500 и обучает модель LSTM на исторических данных для каждой акции. Затем модель используется для прогнозирования цены закрытия для каждой акции в последний день доступных данных.
Результаты сохраняются в виде списка кортежей, где каждый кортеж содержит символ, фактическую цену и прогнозируемую цену. Мы можем построить график прогнозируемых цен против фактических цен для каждой акции, используя следующий код:
import matplotlib.pyplot as plt plt.figure(figsize=(16, 12)) for symbol, actual, predicted in results: plt.plot([symbol]*2, [actual, predicted], 'o-', label=symbol) # plt.legend() plt.title('Predicted vs Actual Prices for S&P 500 Stocks') plt.ylabel('Price ($)') plt.show()
Приведенный выше код отображает прогнозируемые цены и фактические цены для каждой акции в последний день доступных данных. Ось X представляет символ, а ось Y представляет цену. Фактическая цена показана синей точкой, а прогнозируемая цена показана оранжевой линией.
Из графика видно, что модель LSTM способна делать достаточно точные прогнозы для некоторых акций, в то время как для других прогнозы не столь точны. Это ожидаемо, поскольку фондовый рынок по своей природе непредсказуем и подвержен многим внешним факторам.
В этой статье мы показали, как использовать глубокое обучение, в частности модели LSTM, для прогнозирования будущей цены акций с использованием Python. Мы также продемонстрировали, как распространить этот анализ на все акции S&P 500 и как сопоставить прогнозируемые цены с фактическими ценами для каждой акции.
Станьте участником Medium сегодня и получите неограниченный доступ к тысячам руководств по Python и статьям по науке о данных! Всего за 5 долларов в месяц вы получите доступ к эксклюзивному контенту и поддержите меня как писателя. Зарегистрируйтесь сейчас, используя мою ссылку, и я получу небольшую комиссию без каких-либо дополнительных затрат для вас.
Дополнительные материалы на PlainEnglish.io.
Подпишитесь на нашу бесплатную еженедельную рассылку новостей. Подпишитесь на нас в Twitter, LinkedIn, YouTube и Discord .
Заинтересованы в масштабировании запуска вашего программного обеспечения? Ознакомьтесь с разделом Схема.