HMM隱馬爾科夫模型與實例2: 預測股票走勢

from __future__ import print_function #python2.X,使用print就得像python3.X那樣加括號使用
import datetime
import numpy as np
import pandas as pd
from matplotlib import cm, pyplot as plt
import mpl_finance as mpf
from matplotlib.dates import YearLocator, MonthLocator
from hmmlearn.hmm import GaussianHMM
import math

start_date = datetime.date(2012, 1, 1)
end_date = datetime.date.today() - datetime.timedelta(days = 15)

data = pd.read_csv('data2.csv', header=0)
data['date'] = pd.to_datetime(data['date])
data.head()

在這裏插入圖片描述

data.reset_index(inplace=True, drop=False)
data.drop(['index','open','low','high','Adj Close'], axis=1, inplace=True)

data['date'] = data['date'].apply(datetime.datetime.toordinal)
# date.toordinal(): 返回日期對應的 Gregorian Calendar 日期

data.head()

在這裏插入圖片描述

  • itertuples() 將DataFrame迭代爲元祖
  • numpy.diff() 沿着指定軸計算第N維的離散差值, 其實就是執行後一個元素減去前一個元素
df = list(data.itertuples(index=False, name=Name))
dates = np.array([x[0] for x in df], dtype = int)
close_v = np.array(x[1] for x in df])
volume = np.array(x[2] for x in df)[1:]
print(dates.shape, close_v.shape, volume.shape)

diff = np.diff(close_v)
print(diff[:10])

dates = dates[1:]
print(dates[:10])

close_v = close_v[1:]
print(close_v[:10])

print(dates.shape, close_v.shape, diff.shape, volume.shape)

(2339,) (2339,) (2338,)
[-5.41, 3.28, 4.48, -2.97, -6.47, 2.94, 3.25, 0.15, -2.23, -4.44]
[732755, 732756, 732757, 732758, 732761, 732763, 732764, 732765, 732711, 732739]
[942.39, 945.67, 950.15, 947.18, 940.71, 943.65, 946.9 , 947.05, 944.82, 940.38]
(2338,) (2338,) (2338,) (2338,)

X = np.column_stack([diff, volume]) # 將兩個矩陣按列合併
print(X.shape)
X[:10]

(2338, 2)
在這裏插入圖片描述

model = GaussianHMM(n_components=3, covariance_type='diag', n_iter=1000).fit(X)
hidden_states = model.predict(X)

print(model.transmat_)
print(model.predict_proba)

print('Means and vars of each hidden state :')
params = pd.DataFrame(columns = ('State', 'Means', 'Variance'))
for i in range(model.n_components):
	params.loc[i] = [format(i), model.means_[i], np.diag(model.covars_[i])]
	# np.diag()矩陣對角元素提取
params

[[0.94069834 0.00210767 0.05719399]
[0.01743045 0.86197619 0.12059336]
[0.07360904 0.02640655 0.89998441]]


<bound method _BaseHMM.predict_proba of GaussianHMM(algorithm=‘viterbi’, covariance_type=‘diag’, covars_prior=0.01,
covars_weight=1, init_params=‘stmc’, means_prior=0, means_weight=0, min_covar=0.001, n_components=3, n_iter=1000,
params=‘stmc’, random_state=None, startprob_prior=1.0, tol=0.01, transmat_prior=1.0, verbose=False)>


Means and vars of each hidden state :
在這裏插入圖片描述

fig, axs = ple.subplots(model.n_components, sharex=True, sharey=True, figsize=(15,18))
colours = cm.rainbow(np.linspace(0, 1, model.n_components))

for i, (ax, color) in enumerate(zip(axs, colours)):
	mask = hidden_states == i
    ax.plot_date(dates[mask], close_v[mask], '.', c=color)
    ax.set_title('{}th hidden state'.format(i))
    
    ax.xaxis.set_major_locator(YearLocator())
    ax.xaxis.set_minor_locator(MonthLocator())
    
    ax.grid()
plt.show()

在這裏插入圖片描述

expected_returns_volumes = np.dot(model.transmat_, model.means_)
returns_volume_columnwise = list(zip(*expected_returns_volumes))
expected_returns = returns_volume_columnwise[0]
expected_volumes = returns_volume_columnwise[1]
params = pd.concat([pd.Series(expected_returns), pd.Series(expected_volumes)], axis=1)
params.columns = ['Returns', 'Volume']
params

在這裏插入圖片描述

lastN = 7
start_date = datetime.date.today() - datetime.timedelta(days=lastN*2)
end_date = datetime.date.today()

dates = np.array([q[0] for q in df], dtype=int)

predicted_prices = []
predicted_dates = []
predicted_volumes = []
actual_volumes = []

for idx in range(lastN):
    state = hidden_states[-lastN + idx]
    current_price = df[-lastN + idx][1]
    volume = df[-lastN + idx][2]
    actual_volumes.append(volume)
    current_date = datetime.date.fromordinal(dates[-lastN + idx])
    predicted_date = current_date + datetime.timedelta(days = 1)
    predicted_dates.append(predicted_date)
    predicted_prices.append(current_price + expected_returns[state])
    predicted_volumes.append(np.round(expected_volumes[state]))
    
ticker = 'gold'
plt.figure(figsize = (15, 5), dpi=100)
plt.title(ticker, fontsize = 14)
plt.plot(predicted_dates, close_v[-lastN:])
plt.plot(predicted_dates, predicted_prices)
plt.legend(['Actual', 'Predicted'])
plt.show()

plt.figure(figsize = (15, 5), dpi=200)
plt.title(ticker, fontsize = 14)
plt.plot(predicted_dates, actual_volumes)
plt.plot(predicted_dates, predicted_volumes)
plt.legend(['Actual', 'Predicted'], fontsize=14)
plt.show()

在這裏插入圖片描述
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章