B题很简单,我们首先看看问题要求:
(1 )对所提供的各项指标进行分析,从中提取出与 数字经济 板块有关的主要指标。
(2 )以 2021 年 7 月 14 日至 2021 年 12 月 31 日的每 5 分钟 数字经济 板块指数为训练集,以2022 年1 月4 日至2022 年1 月28 日的每5 分钟“数字经济”板块指数为测试集。根据问题(1)提取出来的各项指标对“数字经济”板块指数每5 分钟成交量进行预测。
(3)以2021 年7 月14 日至2021 年12 月31 日的每5 分钟“数字经济”板块指数为训练集,以2022 年1 月4 日至2022 年1 月28 日的每5 分钟“数字经济”板块指数为测试集。根据(1)(2)建立模型对每5 分钟的“数字经济”板块指数(收盘价)进行预测。
(4)假设以“数字经济”板块指数为交易对象(在实际交易中指数无法交易,只能交易其中的个股),给定初始资金100 万元,交易佣金为0.3%,根据(3)得到的结果对“数字经济”板块每5 分钟频率价格进行买卖交易,计算在2022 年1 月4 日至2022 年1月28 日期间交易的总收益率、信息比率、最大回撤率。
已经写出论文:
上市公司股价的变化,可以直接反映上市公式的运行状况和市场的认可度。然而,由于股票市场是一个非常典型的非线性复杂系统(股票价格既有趋势性因素又有随机性因素),股价预测一直是一个难点。从混沌理论出发,建立一个能在一定程度上反映股票市场规律的数学模型,为此类问题提供答案或提供可靠的建议。对于问题一,首先对标题中给出的数据进行预处理,根据股票交易规则的异常波动情况,对异常数据进行筛选。选取月K线、周K线、20日均线(股票生命线)和日K线进行定性分析,得到每日、每周和每月的数据,并根据基本指标计算出若干技术指标,作为判断股票走势的依据;对于问题二,对于第二个问题,我们需要找到一个数学模型来处理这个多变量的非线性问题。本研究综合考虑了基本指标和技术指标,建立了基于LSTM的股价和随机性预测模型,并利用最近若干天的数据对模型的准确性进行了评估,结果表明该模型是可靠的;对于问题三,本研究在问题二的基础上引入关键转折点指标,根据问题二的结果建立了一个股票反转判断模型:基于LSTM的股价逆转判断模型,以确定股票在某一时刻的涨跌。我们从第二个问题的结果中精心挑选了40-50个主观“转折点”,然后将它们应用到第三个问题的模型中,并利用过去若干天的数据对模型的准确性进行了评价。结果表明,该模型是可靠的。
基本假设
I:假设当时间序列足够长时,股价数据呈正态分布;
II:假设问题中给出的三类股票的股市稳定健康;
III:假设问题中给出的数据的时间间隔内没有重大外部因素。
长短期记忆网络(LSTM)是专门为解决一般循环神经网络(RNN)的长期依赖问题而设计的一种时间循环神经网络。所有的RNN都有一系列重复的神经网络模块。样式表。递归神经网络擅长解决与时间序列相关的问题,而股票趋势预测是一个非常典型的时间序列预测问题。普通的RNN在计算远程节点之间的连接时会导致梯度消失和梯度爆炸,不能解决“长期依赖”的问题。然而,LSTM可以通过独特的栅极结构和单元状态更新来有效地节省长期时间。记忆。
在经过预处理的数据集的基础上构造特征,将处理后的数据集划分为训练集和测试集,选取相关的输入特征,建立训练模型。最后,将模型预测结果与实际测量结果进行了对比,并用预测精度和均方根误差进行了评估,根据评估结果连续进行了调整,以提高模型的泛化能力。
在训练过程中,为了获得更好的模型性能,对LSTM模型的参数进行了如下设置和优化:(1)对原始数据中的属性值进行Z-Score标准化,使处理后的数据符合标准正态分布,以加快模型的收敛速度,保证训练数据的有效性;(2)为了减少存储负担,加快训练速度,本文将LSTM模型的参数设置为60,一次计算一批的损失函数,并结合BP算法对参数进行优化;(3)根据输入输出向量的大小,将隐节点数设置为20,根据时间序列的长度将LSTM循环体的长度设置为20,隐层数设置为2;(4)LSTM不同层次的循环体之间采用丢包,在模型训练阶段随机让一些隐含层节点不工作,提高神经网络的泛化能力;(5)激活函数采用RELU函数,计算量小,计算速度快,避免了梯度消失的现象。
从上图可以看出,随着迭代次数的不断增加,模型的精度不断提高,最终稳定在90%-100%之间;模型损失持续减少,最终稳定在0.5以下。由此可见,LSTM模型的训练和预测效果良好
以下是代码分析:LSTM的股票价格预测
LSTM(Long Short Term Memory)是一种 特殊的RNN类型,同其他的RNNs相比可以更加方便地学习长期依赖关系,因此有很多人试图将其应用于 时间序列的预测问题 上。
我们将首先将数据从 CSV 文件转换并加载到 pandas 数据帧,然后将其用于输出将馈送 LSTM 的 numpy 数组。Keras LSTM 层的工作方式是采用 3 维(N、W、F)的 numpy 数组,其中 N 是训练序列的数量,W 是序列长度,F 是每个序列的特征数。我们选择使用 50 的序列长度(读取窗口大小)
序列本身是滑动窗口,因此每次移动 1,导致与之前的窗口不断重叠。绘制时,序列长度为 50 的典型训练窗口如下所示:
为了加载这些数据,我们在代码中创建了一个 DataLoader 类来为数据加载层提供抽象。您会注意到,在初始化 DataLoader 对象时,会传入文件名,以及用于确定用于训练与测试的数据百分比的拆分变量和允许选择一列或多列数据的列变量用于单维或多维分析。
class DataLoader():
def __init__(self, filename, split, cols):
dataframe = pd.read_csv(filename)
i_split = int(len(dataframe) * split)
self.data_train = dataframe.get(cols).values[:i_split]
self.data_test = dataframe.get(cols).values[i_split:]
self.len_train = len(self.data_train)
self.len_test = len(self.data_test)
self.len_train_windows = None
def get_train_data(self, seq_len, normalise):
data_x = []
data_y = []
for i in range(self.len_train - seq_len):
x, y = self._next_window(i, seq_len, normalise)
data_x.append(x)
data_y.append(y)
return np.array(data_x), np.array(data_y)
在我们拥有一个允许我们加载数据的数据对象之后,我们将需要构建深度神经网络模型。再次为了抽象,我们的代码框架使用 Model 类和 config.json 文件来轻松构建我们模型的实例,给定所需的架构和存储在配置文件中的超参数。构建我们网络的主要函数是 build_model() 函数,它接收解析的配置文件。
class Model():
def __init__(self):
self.model = Sequential()
def build_model(self, configs):
timer = Timer()
timer.start()
for layer in configs['model']['layers']:
neurons = layer['neurons'] if 'neurons' in layer else None
dropout_rate = layer['rate'] if 'rate' in layer else None
activation = layer['activation'] if 'activation' in layer else None
return_seq = layer['return_seq'] if 'return_seq' in layer else None
input_timesteps = layer['input_timesteps'] if 'input_timesteps' in layer else None
input_dim = layer['input_dim'] if 'input_dim' in layer else None
if layer['type'] == 'dense':
self.model.add(Dense(neurons, activation=activation))
if layer['type'] == 'lstm':
self.model.add(LSTM(neurons, input_shape=(input_timesteps, input_dim), return_sequences=return_seq))
if layer['type'] == 'dropout':
self.model.add(Dropout(dropout_rate))
self.model.compile(loss=configs['model']['loss'], optimizer=configs['model']['optimizer'])
print('[Model] Model Compiled')
timer.stop()
加载数据并构建模型后,我们现在可以继续使用我们的训练数据训练模型。为此,我们创建了一个单独的运行模块,该模块将利用我们的模型和数据加载器抽象将它们结合起来进行训练、输出和可视化。
下面是训练我们模型的通用运行线程代码。
configs = json.load(open('config.json', 'r'))
data = DataLoader(
os.path.join('data', configs['data']['filename']),
configs['data']['train_test_split'],
configs['data']['columns']
)
model = Model()
model.build_model(configs)
x, y = data.get_train_data(
seq_len = configs['data']['sequence_length'],
normalise = configs['data']['normalise']
)
model.train(
x,
y,
epochs = configs['training']['epochs'],
batch_size = configs['training']['batch_size']
)
x_test, y_test = data.get_test_data(
seq_len = configs['data']['sequence_length'],
normalise = configs['data']['normalise']
)
对于输出,我们将运行两种类型的预测:第一种将以逐点的方式进行预测,也就是说,我们每次只预测一个点,将此点绘制为预测,然后沿用下一个窗口使用完整的测试数据并再次预测下一个点。
我们要做的第二个预测是预测一个完整的序列,这样我们只用训练数据的第一部分初始化一个训练窗口一次。然后模型预测下一个点,我们移动窗口,就像逐点方法一样。不同之处在于我们然后使用我们在先前预测中预测的数据进行预测。在第二步中,这意味着只有一个数据点(最后一个点)来自先前的预测。在第三个预测中,最后两个数据点将来自先前的预测,依此类推。在 50 次预测之后,我们的模型随后将根据自己的先前预测进行预测。这使我们能够使用该模型来预测未来的许多时间步长,
继续进行完整的序列预测,这似乎被证明是对这种类型的时间序列最没用的预测(至少在这个模型上用这些超参数训练过)。我们可以在预测开始时看到轻微的颠簸,其中模型遵循某种动量,但是很快我们可以看到模型决定最佳模式是收敛到时间序列的某个平衡点。在这个阶段,这似乎并没有提供太多价值,但是均值回归交易者可能会介入,宣称该模型只是在寻找价格序列在波动性消除后将恢复到的均值。
我们为这个模型做了第三种预测,我称之为多序列预测。这是完整序列预测的混合,因为它仍然使用测试数据初始化测试窗口,预测下一个点并使用下一个点创建一个新窗口。然而,一旦它到达输入窗口完全由过去的预测组成的点,它就会停止,向前移动一个完整的窗口长度,用真实的测试数据重置窗口,然后再次开始该过程。从本质上讲,这给出了对测试数据的多个趋势线之类的预测,以便能够分析模型对未来动量趋势的把握程度。
代码地址:https://mianbaoduo.com/o/bread/YpqTmJxy
论文地址:https://mianbaoduo.com/o/bread/YpqTmJlr