コンテンツ
Introduction
This time, we will use machine learning LSTM, which is an AI method, to predict how much the stock price will change in three days. The implemented site is published at the following URL.
Stock price prediction by AI https://www.mhr-y.com/jp/ai-stock/
I created this without any prior knowledge of machine learning, so there may be some misunderstandings. Please note. If you have any suggestions for improvement, please leave a comment.
Introduction to Machine Learning with Python: A Guide for Data Scientists
Prediction algorithm
This is the prediction algorithm.
The basic idea is as follows.
First, obtain past stock prices and calculate technical indicators.
Next, you will learn the relationship between the values of technical indicators and the rise and fall of stock prices.
Finally, input the price movements for the last 10 days and predict how likely the stock price will change three days from now.
Prepare input data
First, use pandas_datareader to retrieve the past 180 days of daily data for the input ticker symbol from yahoo.com.
# Specify the ticker symbol to predict as an argument
code = argv[1]
today = date.today()
ago = today - relativedelta(days=180)
# Get data
# data is pandas.DataFrame type
data = pdr.get_data_yahoo(code, start=ago, end=today, progress=False)
Next, calculate the following technical indicators for Close (closing price) of the obtained stock price data.
- Simple Moving Average (SMA) : 7, 14, 24
- Moving Average Deviation rate (MAD) : 7, 14, 24
- Moving Average Convergence/Divergence (MACD) : short-term EMA12、long-term EMA26、MACD signal 9
- Relative Strength Index (RSI) : 14
- Bollinger Bands : 20
data = sma(data,7)
data = sma(data,14)
data = sma(data,24)
data = macd(data)
data = rsi(data,14)
data = sigma(data,20)
def sma(df, window):
df['SMA' +str(window)] = df['Close'].rolling(window=window).mean()
df['Moving_average_divergence' +str(window)] = 100.0 *(df['Close'] -df['SMA' +str(window)]) /df['SMA' +str(window)]
return df
def macd(df):
FastEMA_period = 12
SlowEMA_period = 26
SignalSMA_period = 9
df['MACD'] = df['Close'].ewm(span=FastEMA_period).mean() -df['Close'].ewm(span=SlowEMA_period).mean()
df['Signal'] = df['MACD'].rolling(SignalSMA_period).mean()
return df
def rsi(df, window):
df_diff = df['Close'].diff(1)
df_up, df_down = df_diff.copy(), df_diff.copy()
df_up[df_up <0] = 0
df_down[df_down >0] = 0
df_down = df_down *-1
df_up_sma = df_up.rolling(window=window,center=False).mean()
df_down_sma = df_down.rolling(window=window,center=False).mean()
df['RSI'+str(window)] = 100.0 *(df_up_sma /(df_up_sma +df_down_sma))
return df
def sigma(df, window):
df_mean = df['Close'].rolling(window=window).mean()
df_std = df['Close'].rolling(window=window).std()
df['sigma' +str(window)] = (df['Close'] -df_mean) /df_std
return df
Next, since the scale of each technical indicator value is different, it is normalized. Normalization is calculated by subtracting the mean value from all elements and dividing by the standard deviation.
# Specify numbers to standardize
use_cols = ['SMA7', 'Moving_average_divergence7',
'SMA14', 'Moving_average_divergence14',
'SMA24', 'Moving_average_divergence24',
'MACD', 'RSI14', 'sigma20']
# Normalize the specified number
n_df = mean_norm(data[use_cols])
# Normalization
def mean_norm(df_input):
return df_input.apply(lambda x: (x -x.mean()) /x.std(), axis=0)
Interpretable AI: Building explainable machine learning systems
Create training data and learning data
The next step is to extract data for n_prev days from the technical indicator values you created.
The extracted data is used as training data, and the correct data is how much the closing price rose or fell three days after the last closing price of the data for n_prev days.
# n_prev days of training data in docx
# Correct data on how much stock prices actually rose and fell on docy
docx, docy = [],[]
n_prev = 10 # Number of days to study
n_df = n_df[25:] # Skip the first 25 rows of the standardized pd.DataFrame. This includes data such as the 24-day simple moving average above, but due to calculation reasons, there is no data for the first 24 days, so I deleted the first 25 days so that all the data was properly aligned. to be in a state of being
# Repeat loop processing for n_df rows minus 13 times
for i in range(len(n_df) -13):
docx.append(n_df.iloc[i:i+n_prev][use_cols].values)
docy.append(100.0 *(data.iloc[i+13]['Close'] -data.iloc[i+10]['Close']) /data.iloc[i+10]['Close'])
arrayX = np.array(docx) # Value of each technical indicator
arrayY = np.array(docy) # 3-day stock price change rate
Next, we will categorize the rate of change in stock prices. If the stock price has fallen by -2.5% or more after 3 days, it is classified into 7 categories, such as -3, and if it is in the range of -0.5% decline to 0.5% increase, it is 0.
Furthermore, by applying a one-hot encoder, the 7 categories are converted into a 7-column matrix.
# Divide the rate of change into seven categories
arrayY[arrayY <= -2.5] = -3
arrayY[(arrayY > -2.5) & (arrayY <= -1.5)] = -2
arrayY[(arrayY > -1.5) & (arrayY <= -0.5)] = -1
arrayY[(arrayY > -0.5) & (arrayY < 0.5)] = 0
arrayY[(arrayY >= 0.5) & (arrayY < 1.5)] = 1
arrayY[(arrayY >= 1.5) & (arrayY < 2.5)] = 2
arrayY[arrayY >= 2.5] = 3
# One-hot encode the numbers divided into 7 categories
enc = sp.OneHotEncoder(sparse_output=False)
arrayY = enc.fit_transform(arrayY.reshape(-1,1))
Of the data created, 90% will be used as training data and the remaining 10% will be used as test data.
ntrn = round(len(arrayX) *(1 -0.1)) # 90% is for training, remaining 10% is test data
ntrn = int(ntrn)
# X_train is training data, y_train is its correct data
# X_test is test data, y_test is test correct data
X_train, y_train = arrayX[0:ntrn], arrayY[0:ntrn]
X_test, y_test = arrayX[ntrn:], arrayY[ntrn:]
Building and training machine learning models
Build the model with model.compile.
As a machine learning model, we use an artificial recurrent neural network (RNN) architecture suitable for classification, processing, and prediction based on time-series data called LSTM (Long Short-Term Memory).
hidden_dim is a variable that specifies hidden layers; increasing the number of hidden layers increases calculation time, but allows for more flexible learning.
input_shape is specified as (10,9). This number is because the input data consists of 10 days worth of data and a matrix of 9 technical indicators.
Dropout (0.2) intentionally disables 20% of the calculation flow from above. This has the effect of preventing a decline in predictive ability for unknown data due to over-learning.
Dense(7) makes the output 7 numbers. Since the correct answer data has 7 categories, we will output 7-dimensional data.
Activation (‘softmax’) converts the sum of the last 7-dimensional data output to 1. We want the percentage changes in the seven categories of stock prices to add up to 100%.
Specify Adam and learning rate for the optimization algorithm.
hidden_dim = 128
model = Sequential()
model.add(LSTM(hidden_dim, input_shape=(10,9), stateful=False, return_sequences=False))
model.add(Dropout(0.2))
model.add(Dense(7))
model.add(Activation('softmax'))
opt = keras.optimizers.Adam(learning_rate=0.0001)
model.compile(optimizer=opt ,loss='categorical_crossentropy',metrics=['accuracy'])
Train the model built with model.fit. Specify the number of learning times with epochs.
epochs = 100
verbose = 0
history = model.fit(X_train, y_train, batch_size=128, epochs=epochs, verbose=verbose, validation_split=0.2, validation_data=(X_test, y_test))
Output prediction
If you input the technical indicators for the last 10 days into the model you built, the model will output the probabilities for each of the 7 categories.
predict = model.predict(n_df.iloc[-10:][use_cols].values.reshape(1,10,9), verbose=verbose)
columns =['~ -2.5%', '-2.5% ~ -1.5%', '-1.5% ~ -0.5%', '-0.5% ~ 0.5%', '0.5% ~ 1.5%', '1.5% ~ 2.5%', '2.5% ~ ']
pred = pd.DataFrame(predict, columns=columns)
You can try the actual output at the following URL.
Stock price prediction by AI https://www.mhr-y.com/jp/ai-stock/
Artificial Intelligence Programming with Python: From Zero to Hero
Finally
This time, we used LSTM to predict the stock price in 3 days.
This implementation is based on the following site.
https://note.com/happy_ice_cream/n/n0cae976e5c78
I’m glad if you can use it as a reference.