如何使用PyTorch的RNN模型来训练股票价格的回归模型,并使用该模型来生成交易信号。

  1. 准备数据

首先需要准备数据,数据可以从Yahoo Finance等股票数据提供商获取。这里采用Quandl提供的Apple股票数据,用于训练RNN模型。

import quandl
import pandas as pd

# 使用 Quandl API 获取股票数据
df = quandl.get('EOD/AAPL')
df.to_csv('AAPL.csv')

# 读取 CSV 文件
data = pd.read_csv('AAPL.csv')

# 选取股票收盘价列
data = data[['Adj_Close']]

# 归一化数据
data = (data - data.min()) / (data.max() - data.min())

# 将数据转为 PyTorch 需要的 tensor 格式
data = torch.tensor(data.values, dtype=torch.float32)
  1. 定义 RNN 模型

接下来需要定义RNN模型。这里选用PyTorch的LSTM模块作为RNN的基础。

import torch.nn as nn

class RNN(nn.Module):
    def __init__(self, input_size, hidden_size, output_size):
        super(RNN, self).__init__()
        self.hidden_size = hidden_size
        self.lstm = nn.LSTM(input_size, hidden_size)
        self.out = nn.Linear(hidden_size, output_size)
    
    def forward(self, input_data):
        lstm_out, _ = self.lstm(input_data.view(len(input_data), 1, -1))
        output = self.out(lstm_out.view(len(input_data), -1))
        return output[-1]

这个模型接受一个形状为 (sequence_length, input_size) 的输入,其中 sequence_length 是序列的长度,input_size 是每个时间步上的特征数。模型的输出是预测的股票价格。

  1. 定义训练过程

为了训练模型,需要定义优化器、损失函数和训练过程。

import torch.optim as optim

# 定义模型、优化器和损失函数
input_size = 1
hidden_size = 32
output_size = 1
learning_rate = 0.01

rnn = RNN(input_size, hidden_size, output_size)
criterion = nn.MSELoss()
optimizer = optim.Adam(rnn.parameters(), lr=learning_rate)

# 定义训练函数
def train_model(model, optimizer, criterion, data, num_epochs):
    for epoch in range(num_epochs):
        running_loss = 0
        for i in range(len(data) - sequence_length - 1):
            optimizer.zero_grad()
            input_data = data[i:i+sequence_length]
            target = data[i+sequence_length]
            output = model(input_data)
            loss = criterion(output, target)
            loss.backward()
            optimizer.step()
            running_loss += loss.item()
        print(f'Epoch {epoch}: loss={running_loss}')

在这里,我们使用MSE损失函数来计算预测值与目标值之间的差异,并使用Adam优化器来更新模型的权重。我们定义了一个训练函数,该函数每个epoch迭代训练集中的每个序列,并在每个epoch结束时保存模型。

  1. 训练模型并保存模型
# 训练模型
sequence_length = 10
num_epochs = 10
train_model(rnn, optimizer, criterion, data, num_epochs)

# 保存模型
torch.save(rnn.state_dict(), 'rnn.pth')
  1. 加载模型并生成交易信号
# 加载模型
saved_rnn = RNN(input_size, hidden_size, output_size)
saved_rnn.load_state_dict(torch.load('rnn.pth'))

# 使用模型生成交易信号
with torch.no_grad():
    signals = []
    for i in range(len(data) - sequence_length - 1):
        input_data = data[i:i+sequence_length]
        signal = saved_rnn(input_data).item()
        signals.append(signal)
        
    signals = pd.Series(signals, index=data.index[sequence_length:-1]).rename('signal')

最后,我们使用保存的模型来为测试集生成交易信号,其中保存的模型的输入长度为10,即使用10天的历史价格来预测下一天的价格。在这个示例中,我们只使用了一个模型来预测所有的交易信号。实际上,在实际交易中,可能需要使用多个模型来处理不同的市场情况,或使用模型集成技术来获得更精确的预测结果。

Logo

专业量化交易与投资者大本营

更多推荐