神经网络用于日内股票预测

作者:chen_h
微信号 & QQ:862251340
微信公众号:coderpai


上一篇我们研究了用一些线性模型来做股票回报预测,在这篇文章中,我们将专注于将神经网络应用于市场,从而来获得回报。

前馈神经网络

我们的目标是预测接下来 5 分钟内股票的价格变化。我们可以使用简单的前馈神经网络(FNN)。FNN的损失函数保持不变。损失函数与我们在上一篇文章中的线性回归部分中看到的相同。

J ( θ ) = 1 2 m ∑ i = 1 m ( h θ ( x i ) − y i ) 2 + α ∣ ∣ θ ∣ ∣ 2 2 J(\theta) = \frac{1}{2m}\sum^{m}_{i=1} (h_{\theta}(x^{i}) - y^{i})^{2} + \alpha||\theta||^{2}_{2} J(θ)=2m1i=1m(hθ(xi)yi)2+αθ22

其中,h(x) 是上一篇文章中的线性模型,但在今天的文章中它代表 FNN。我们也使用 l2_penalty 来保持稳定性。下面是 pytorch 的代码:

class FNN(nn.Module):
    def __init__(self, num_features):
        super(FNN, self).__init__()
        self.fc1 = nn.Linear(num_features, 100)
        self.bn1 = nn.BatchNorm1d(100)
        self.fc2 = nn.Linear(100, 20)
        self.bn2 = nn.BatchNorm1d(20)
        self.fc3 = nn.Linear(20, 1)
        self.relu = nn.ReLU()

    def forward(self, x):
        x = self.relu(self.bn1(self.fc1(x)))
        x = F.dropout(x, training=self.training)
        x = self.relu(self.bn2(self.fc2(x)))
        x = F.dropout(x, training=self.training)
        return self.fc3(x)

我在优化模型时学到的一些东西:

  • 标准化输入时必须滴。我使用了 scikit-learn 库中的 RobustScalaer 类来实现;
  • BatchNormalization 和 Dropout 可以显著提高泛化水平;
  • 归一化目标也是有帮助的;
  • early stopping 是非常有帮助的;

一个简单的多任务模型,用来预测所有证券

将多个任务建模在一起的能力是使用神经网络的一个非常好的优势。我们的假设是特征向量包含足够的信息以便能够预测多个证券。因此,我们可以直接预测所有证券的价格变化。我们仍然使用相同的 MSE 损失函数进行优化。

class FNN(nn.Module):
    def __init__(self, num_features, num_securities):
        super(FNN, self).__init__()
        self.fc1 = nn.Linear(num_features, 100)
        self.bn1 = nn.BatchNorm1d(100)
        self.fc2 = nn.Linear(100, 50)
        self.bn2 = nn.BatchNorm1d(50)
        self.fc3 = nn.Linear(50, num_securities)
        self.relu = nn.ReLU()

    def forward(self, x):
        x = self.relu(self.bn1(self.fc1(x)))
        x = F.dropout(x, training=self.training)
        x = self.relu(self.bn2(self.fc2(x)))
        x = F.dropout(x, training=self.training)
        return self.fc3(x)

多任务模型的训练与普通的 FNN 模型类似。

criterion = nn.MSE()
fnn = FNN(num_features, num_securities)

l2_penalty = 1e-3
learning_rate = 1e-3
optimizer = torch.optim.Adam(fnn.parameters(), lr=1e-3, weight_decay=l2_penalty)
for n in range(num_epochs):
    for i, batch in enumerate(train_loader):
        inputs, targets = Variable(batch[0]), Variable(batch[1])

        optimizer.zero_grad()
        outputs = fnn(inputs)
        loss = criterion(outputs, targets)
        loss.backward()
        optimizer.step()

LSTM 模型

由于 RNN 模型比较擅长预测序列,因此我们正在探索的证券预测模型可能非常适合它们。最原始的 RNN 模型会存在一个很大的问题就是梯度消失,所以我们采用 LSTM 来更好的处理这个问题。

然而,我们知道即使 LSTM 也有其自身的局限性 —— 它们通常擅长较短的序列,比如 10 到 30 的长度,所以我尝试了以下模型,长度为 15。

class LSTM(nn.Module):
    def __init__(self, input_size, hidden_size, dropout=0.2):
        super(LSTM, self).__init__()

        self.hidden_size = hidden_size
        self.rnn = nn.LSTM(
            input_size=input_size,
            hidden_size=hidden_size,
            num_layers=1,
            dropout=dropout,
            bidirectional=False, )
        self.fc1 = nn.Linear(hidden_size, hidden_size)
        self.bn1 = nn.BatchNorm1d(hidden_size)
        self.fc2 = nn.Linear(hidden_size, 1)
        self.relu = nn.ReLU()

    def forward(self, x):
        batch_size = x.size()[0]
        seq_length = x.size()[1]

        x = x.view(seq_length, batch_size, -1)

        # We need to pass the initial cell states
        h0 = Variable(torch.zeros(seq_length, batch_size, self.hidden_size))
        c0 = Variable(torch.zeros(seq_length, batch_size, self.hidden_size))
        outputs, (ht, ct) = self.rnn(x, (h0, c0))

        out = outputs[-1]  # We are only interested in the final prediction
        out = self.bn1(self.fc1(out))
        out = self.relu(out)
        out = F.dropout(out, training=self.training)
        out = self.fc2(out)
        return out

LSTM 解决多任务

与 FNN 例子类似,我们可以将所有证券一起建模。我们只需要在 LSTM 模型中进行以下更改。

self.fc2 = nn.Linear(hidden_size, num_securities)

LSTM 与 FNN 的性能类似。但是一起学习所有证券的数据,可以很容易的管理训练好的模型。所以,我最终使用 FNN 模型来预测所有证券的价格差异。选择 FNN 主要是因为它的简单性。

使用日内模型进行交易

此后的一项重要任务是将预测的价格变化转换为交易行为。一种流行的方法是,如果来自模型的预测信号大于特定阈值,则发送购买信号。如果信号在一段时间后低于阈值,我们可以选择持有或者卖出。

一种常见的方法是连续出现市场数据更新流。这将包括每一个相关的市场数据更新。例如,你正在交易 AAPL 股票,而你的模型包括 AAPL,MSFT,GOOGL,FB 和 AMZN,你可能希望持续流式传输每个新的订单。你可以实时计算功能并将其提供给神经网络。该模型将为 AAPL输出单个 5 分钟的预测。重要的是要记住这些预测通常是错误的。但是,我们不知道哪些是正确的。

无论如何,一旦你有了预测信号,你可以使用一个阈值来检查信号是否足够强。在预测方向上进行执行,以下是这种系统的粗略 Python 代码:

class TradingSystem(object):
    def trading_logic(self, signal):
        # Check if there is a BUY signal
        if signal > self.threshold and self.current_risk() < self.risk_threshold:
            # Send a new BUY order at the current bid price
            self.send_new_order('B', self.current_bid_price)

            # Cancel existing sell orders - since we have a BUY signal
            self.cancel_sell_orders()
        
        elif signal < -self.threshold and self.current_risk() > -self.risk_threshold:
            # Send a new SELL order at the current ask price
            self.send_new_order('S', self.current_ask_price)

            # Cancel existing buy orders - since we have a SELL signal
            self.cancel_buy_orders()
        
        else:
            # We may want to keep the existing orders
            # or we can cancel them as well
            self.cancel_all_orders()

你可能感兴趣的:(量化交易)