股价预测一直以来都是幻想能够被解决的问题,本文中主要使用了lstm模型去对股价做一个大致的预测,数据来源是tushare,非常感谢tushare的数据!!

为什么要用LSTM?

LSTM是一种序列模型,是RNN中最典型的一个网络结构,对RNN做了一些改进同时具有RNN的特性,可以更好的处理时序数据。

如果可以实现对股价的预测,作为一个股民,可以更好的掌握买卖点,以及辅助自己做决策等等,以此提高自己的收益率。你可以合理地决定什么时候买股票,什么时候卖股票来获利。这就是时间序列建模的用武之地。你需要一个好的机器学习模型,它可以观察一系列数据的历史,并正确预测序列的未来元素是什么。

股票市场价格高度不可预测和波动。这意味着,在数据中没有一致的模式可以让你在一段时间内对股票价格进行近乎完美的建模。然而,我们不要一直认为这只是一个随机或随机的过程,机器学习是没有希望的。让我们看看您是否能够至少对数据建模,以便您所做的预测与数据的实际行为相关联。换句话说,你不需要确切的未来股票价值,而需要股票价格的变动(也就是说,如果它在不久的将来会上涨或下跌)。

import torch
import torch.nn as nn
import torch.optim as optim
from tqdm import tqdm
import tushare as ts
from copy import deepcopy as copy
import matplotlib.pyplot as plt
from torch.utils.data import DataLoader, TensorDataset
import numpy as np

获取数据

获取数据部分使用了一个专业获取股票数据的第三方库:tushare

tushare非常强大,各种有关股票的数据都可以很方便的下载,甚至包括股票新闻数据。最近在搞NLP,下次有机会后尝试加入一些股票新闻和公司公告等文本信息帮助预测股票走势,应该会有较大提升。

老版本:Tushare -财经数据接口包

新版本:Tushare大数据社区

我这里仅仅是做了一个demo,仅供参考思路,并没有用到过多的股票数据特征所以就使用了老版本的历史行情数据接口API:ts.get_hist_data(stock_id)

更多信息详见官网:

这里我使用了开盘价、收盘价、最高价、最低价、成交量这五个特征,使用每天的收盘价作为学习目标,每个样本都包含连续几天数据作为一个序列样本,处理出训练集和测试集。

class GetData:def __init__(self, stock_id, save_path):self.stock_id = stock_idself.save_path = save_pathself.data = Nonedef getData(self):self.data = ts.get_hist_data(self.stock_id).iloc[::-1]self.data = self.data[["open", "close", "high", "low", "volume"]]self.close_min = self.data['close'].min()self.close_max = self.data["close"].max()self.data = self.data.apply(lambda x: (x - min(x)) / (max(x) - min(x)))self.data.to_csv(self.save_path)# self.data = self.data.apply(lambda x: x-min(x)/(max(x)-min(x)))return self.datadef process_data(self, n):if self.data is None:self.getData()feature = [self.data.iloc[i: i + n].values.tolist()for i in range(len(self.data) - n + 2)if i + n < len(self.data)]label = [self.data.close.values[i + n]for i in range(len(self.data) - n + 2)if i + n < len(self.data)]train_x = feature[:500]test_x = feature[500:]train_y = label[:500]test_y = label[500:]return train_x, test_x, train_y, test_y

搭建LSTM模型

使用了一个单层单向lstm网络,加一个全连接层输出。

class Model(nn.Module):def __init__(self, n):super(Model, self).__init__()self.lstm_layer = nn.LSTM(input_size=n, hidden_size=128, batch_first=True)self.linear_layer = nn.Linear(in_features=128, out_features=1, bias=True)def forward(self, x):out1, (h_n, h_c) = self.lstm_layer(x)a, b, c = h_n.shapeout2 = self.linear_layer(h_n.reshape(a*b, c))return out2

训练与测试

训练

还是pytorch训练三部曲:

  1. 计算损失loss
  2. 损失 backward
  3. 优化器 step

(不要忘记优化器清零梯度)

def train_model(epoch, train_dataLoader, test_dataLoader):# 训练模型best_model = Nonetrain_loss = 0test_loss = 0best_loss = 100epoch_cnt = 0for _ in range(epoch):total_train_loss = 0total_train_num = 0total_test_loss = 0total_test_num = 0for x, y in tqdm(train_dataLoader,desc='Epoch: {}| Train Loss: {}| Test Loss: {}'.format(_, train_loss, test_loss)):x_num = len(x)p = model(x)# print(len(p[0]))loss = loss_func(p, y)optimizer.zero_grad()loss.backward()optimizer.step()total_train_loss += loss.item()total_train_num += x_numtrain_loss = total_train_loss / total_train_numfor x, y in test_dataLoader:x_num = len(x)p = model(x)loss = loss_func(p, y)optimizer.zero_grad()loss.backward()optimizer.step()total_test_loss += loss.item()total_test_num += x_numtest_loss = total_test_loss / total_test_num# early stopif best_loss > test_loss:best_loss = test_lossbest_model = copy(model)epoch_cnt = 0else:epoch_cnt += 1if epoch_cnt > early_stop:torch.save(best_model.state_dict(), '../data/lstm_.pth')break

测试

测试部分很简单,我就不赘述了

def test_model(test_dataLoader_):pred = []label = []model_ = Model(5)model_.load_state_dict(torch.load("../data/lstm_.pth"))model_.eval()total_test_loss = 0total_test_num = 0for x, y in test_dataLoader_:x_num = len(x)p = model_(x)print('##', len(p), len(y))loss = loss_func(p, y)total_test_loss += loss.item()total_test_num += x_numpred.extend(p.data.squeeze(1).tolist())label.extend(y.tolist())test_loss = total_test_loss / total_test_num# print('##', len(pred), len(label))return pred, label, test_loss

可视化效果

可视化了一下,绿线预测,蓝线是真实数据,在真实曲线上加了短的红线作为趋势预测。

def plot_img(data, pred):# plt.figure(figsize=(18, 9))plt.plot(range(len(pred)), pred, color='green')# plt.plot(range(len(data)), data)plt.plot(range(len(data)), data, color='b')for i in range(0, len(pred)-3, 5):price = [data[i]+pred[j]-pred[i] for j in range(i, i+3)]plt.plot(range(i, i+3), price, color='r')plt.xlabel('Date', fontsize=18)plt.ylabel('Close', fontsize=18)plt.show()

代码跑起来

if __name__ == '__main__':# 参数days_num = 5epoch = 20fea = 5batch_size = 20early_stop = 5# 初始化模型model = Model(fea)# 数据处理部分GD = GetData(stock_id='000963', save_path='../data/data.csv')x_train, x_test, y_train, y_test = GD.process_data(days_num)# print(x_train)x_train = torch.tensor(x_train)x_test = torch.tensor(x_test)y_train = torch.tensor(y_train)y_test = torch.tensor(y_test)train_data = TensorDataset(x_train, y_train)train_dataLoader = DataLoader(train_data, batch_size=batch_size)test_data = TensorDataset(x_test, y_test)test_dataLoader = DataLoader(test_data, batch_size=batch_size)# 损失函数和优化器loss_func = nn.MSELoss()optimizer = optim.Adam(model.parameters(), lr=0.001)train_model(epoch, train_dataLoader, test_dataLoader)p, y, test_loss = test_model(test_dataLoader)print(len(p), len(y))# 画图pred = [ele * (GD.close_max - GD.close_min) + GD.close_min for ele in p]data = [ele * (GD.close_max - GD.close_min) + GD.close_min for ele in y]plot_img(data, pred)print(test_loss)

效果与总结

可以看到绿线是预测的曲线,蓝线是真实的曲线。绿线已经大致模仿出了蓝线的走势,感觉效果很不错,但是这当中存在一个很大的问题,如果我们把epoch调大,把earlystop去掉,让lstm完全的拟合这个曲线,其实远远没有过拟合,loss在波动的下降。会出现这样的情况:

可以看到红线是预测的曲线,蓝线是真实的曲线,两条曲线的形状几乎是完全相同了。但是红线相对蓝线整体向右平行移动了一天。实际上网络学到的策略是,尽量把上一天的价格作为当前的预测输出,就是模型倾向于保留之前的趋势。这和人的想法很相似,对于一个股市小白来说,只给他开盘价、收盘价、最高价、最低价、成交量这五个特征,让他判断接下来股票走势,他也只能把之前的趋势当作下一天的趋势了。

这个模型只提供一个思路,不能作为股市实战的决策依据,谨慎使用。这个模型还有很多可以改进的地方,例如增加特征,给收盘价加个扰或者不使用收盘价作为特征,加入其他模态的信息,例如文本信息等等,也可以加入一些人工特征,例如爬取一些某股票全网点击量,搜索量等等。

或者换一个思路,训练一个分类模型判断上涨还是下跌,这样的准确率应该会好于回归的方式。我还看到一些博主提到波动率预测的思路,由于我对股票了解有限,还没有想到很好的方法,有思路欢迎补充。

pytorch LSTM的股价预测相关推荐

  1. 利用LSTM进行股价预测

    利用LSTM进行股价预测 效果 原理 代码 应用 效果 原理 LSTM即长短记忆网络,是一种很强的RNN,这种网络的特性是以前的输入会影响现在的输出,具体原理请自行搜索. 算法流程: 获取yahoo财 ...

  2. 基于Informer的股价预测(量化交易综述)

    摘要 股票市场是金融市场中不可或缺的组成部分.准确预测股票趋势对于投资者和市场参与者具有重要意义,因为它们可以指导投资决策.优化投资组合以及降低金融风险.而且可以提升国家国际地位以及金融风险控制能力, ...

  3. MATLAB-基于长短期记忆网络(LSTM)的SP500的股票价格预测 股价预测 matlab实战 数据分析 数据可视化 时序数据预测 变种RNN 股票预测

    MATLAB-基于长短期记忆网络(LSTM)的SP500的股票价格预测 股价预测 matlab实战 数据分析 数据可视化 时序数据预测 变种RNN 股票预测 摘要 近些年,随着计算机技术的不断发展,神 ...

  4. 银行股价预测——基于pytorch框架RNN神经网络

    银行股价预测--基于pytorch框架RNN神经网络 任务目标 数据来源 完整代码 流程分析 1.导包 2.读入数据并做预处理 3.构建单隐藏层Rnn模型 4.设计超参数,训练模型 5.加载模型,绘图 ...

  5. 基于LSTM的剩余寿命预测(PyTorch实现)

    首先,我们需要准备数据.对于剩余寿命预测问题,我们需要有一些历史数据来训练我们的模型,并且需要一些测试数据来验证模型的性能.假设我们有一个包含多个传感器读数的数据集,我们可以将其转化为一个序列预测问题 ...

  6. Pytorch LSTM实现中文单词预测(附完整训练代码)

    Pytorch LSTM实现中文单词预测(附完整训练代码) 目录 Pytorch LSTM实现中文单词预测(词语预测 附完整训练代码) 1.项目介绍 2.中文单词预测方法(N-Gram 模型) 3.训 ...

  7. 毕业设计 金融量化股价预测算法 - lstm 深度学习

    文章目录 0 前言 1 课题意义 1.1 股票预测主流方法 2 什么是LSTM 2.1 循环神经网络 2.1 LSTM诞生 2 如何用LSTM做股票预测 2.1 算法构建流程 2.2 部分代码 3 实 ...

  8. python短期预测图_Python中利用长短期记忆模型LSTM进行时间序列预测分析

    原文链接:http://tecdat.cn/?p=6663 此示例中,神经网络用于使用2011年4月至2013年2月期间的数据预测都柏林市议会公民办公室的能源消耗. 每日数据是通过总计每天提供的15分 ...

  9. 基于LSTM的序列预测: 飞机月流量预测

    基于LSTM的序列预测: 飞机月流量预测 循环神经网络,如RNN,LSTM等模型,比较适合用于序列预测,下面以一个比较经典的飞机月流量数据集,介绍LSTM的使用方法和训练过程. 完整的项目代码下载:h ...

最新文章

  1. Angular 4 依赖注入教程之一 依赖注入简介
  2. sql 导航函数 lead
  3. C++ Primer 5th笔记(chap 15 OOP)派生类的拷贝控制成员
  4. 用户及用户组管理(week1_day4)--技术流ken
  5. 输入输出(Input and Output)
  6. 比亚迪定薪后多久给offer_比亚迪车主给爱车做四门隔音,没想到两年后肠子都悔青...
  7. 【CSS+HTML】关于字体的说明
  8. 用户界面设计参考 (ZT)
  9. 大数据分析如何助力制造行业
  10. 树莓派搭建DLNA客户端,使用gmediarender,DLAN render。
  11. 杭州电子科技大学acm--2020
  12. 微信商城 开发的准备工作
  13. 将寄存器放入IOB的方法
  14. 业务元数据管理——洞悉数据背后的业务含义
  15. matlab 画xos函数,振荡积分的数值计算与Matlab实现
  16. 企业微信审批页面HTML,企业微信审批模板调用示例及注意事项
  17. 达芬奇的这本“禁书”,竟让全世界顶礼膜拜了 500 年!
  18. 新能源汽车BMS开发工程师
  19. Flash Movie Player(Flash当影片来播放) V1.5_绿色官方简体中文版
  20. 位bit和字节Byte

热门文章

  1. an integer is required (got type tuple) 报错解决
  2. 如何用AML中的Designer创建一个AML pipeline来处理数据
  3. 富文本转化为普通文本
  4. 如何禁用Windows更新
  5. “小说极速版”用户隐私政策说明
  6. LSP劫持与网络数据转发代理服务器的心得笔记
  7. ernel 3.10内核源码分析--KVM相关--虚拟机运行
  8. 【TV Picture Quality - 03】TV屏幕解读
  9. Linux操作系统中man命令的用法,Linux 系统中的MAN命令使用祥解
  10. 几种概率分布(伯努利分布、二项分布、泊松分布、均匀分布、正态分布、指数分布、伽马分布)