天天看點

在量化交易中應用卷積神經網絡CNN做時間序列預測

量化交易中,最直接的判斷政策是根據曆史的價格走勢或者交易量的變化,來預測未來的價格。這一點對于傳統看K線的形态派,和現在使用機器學習的煉丹派應該都是一樣的。對價格預測的有效性基于兩個假設:

  1. 市場參與者的某種交易心理或者說情緒,會形成特定模式的下單流,從結果來看,就是造成特定的交易量演變以及價格走勢。也就是說價格波動不是一個完全的随機遊走過程,而是前後關聯的。
  2. 市場參與者不會在某個時間點全部離場而進入全新的交易者,而是一個逐漸加入/退出的過程。這導緻一個模式不會馬上消失,而是逐漸演變。也就是說價格波動的形态是會重複發生的。

通過機器學習方法進行的量化預測,本質上就是先基于交易量和價格這兩個市場行為的結果,找出潛在的交易心理/模式,當我們找到的模式在未來某個時間點再重制的時候,我們就可以從中獲利。這個過程有點像自然語言處理,比如機器翻譯要把中文翻譯為英文,第一步是找出中文背後的語義,然後在把語義變為英文,這背後的語義就跟我們所說的交易模式一樣,不可描述。

LSTM

時間序列預測,這個是一個典型的序列問題,直覺的可以用循環神經網絡(RNN, Recurrent Neural Networks)解決,RNN應用了序列的上下文關系。多數情況都會使用長短期記憶(LSTM,Long Short-Term Memory)網絡,一種特殊的RNN。RNN在 語音識别、機器翻譯這些場景應用很廣泛。RNN的結構:

在量化交易中應用卷積神經網絡CNN做時間序列預測

原始RNN的缺點是無法實作長期依賴(Long-Term Dependencies),也就是說随着時間序列的增長,序列的開頭對于後面的作用幾乎不存在了。LSTM是這針對這個問題進行優化的RNN變種,它可以儲存幾十個步驟以前的資訊。LSTM的實作細節可以參考

Understanding LSTM Networks -- colah's blog

但是在金融時間序列的問題上,時間序列的會很長,可能上千個神經元,LSTM無法解決這麼久遠的資訊依賴。另外一個問題是RNN模型的訓練過程的效率非常低,因為同一層的神經元計算是順序進行的,這個順序沒法實作并行化。現在最新的研究也是正在放棄RNN/LSTM,比如 ResNet 和 Attention。

CNN

卷積神經網絡(CNN,Convolutional Neural Networks)在計算機視覺中應用非常廣泛,其最基本的理念就是對圖像進行特征抽取。特征抽取是基于圖像的兩個性質:局部相關性和空間不變性。先說局部相關性,圖像的本質是一個像素點組成的矩陣,單個像素與周圍相鄰的像素是有關聯的,這種關聯可能是他們共同組成圖像中的一個結構,也叫特征。而空間不變性,就是指在對圖像進行變換之後,一系列列相鄰的像素點組成的特征依然存在。我們先看一下一個完整的CNN架構,這裡是的目标是識别圖檔中的數字:

在量化交易中應用卷積神經網絡CNN做時間序列預測

CNN裡面主要包含兩個操作:卷積和池化。池化就是對圖檔資料進行采樣,是一個相對簡單的過程。卷積操作才是特征提取的核心。先要定義一個卷積核,不同的卷積核定義的是想要提取的目标特征特征,下面是卷積運算的計算過程:

在量化交易中應用卷積神經網絡CNN做時間序列預測

常用的卷積核定義以及特征提取的效果:

在量化交易中應用卷積神經網絡CNN做時間序列預測

CNN的具體細節參考一下兩篇博文,上文的圖檔也是來自于這兩篇文章:

對于量化交易中假設時間序列資料中存在特定的模式,可以關聯到上文的圖檔特征,了解為時間次元上的局部相關性,也就是說相鄰的時間點組成了一個模式,我們可以通過CNN把潛在的模式提取出來。這個應用從直覺上不是很好了解,因為從時間序列的角度來說,點與點之間是有先後的順序關系的,也就一般所說的上下文,但是在CNN中,這個上下文資訊被平面化了,認為所有的曆史資訊對于目前點的影響都是等價的。基于這一點,也有将CNN和LSTM結合在一起使用的工作:

Twitter Sentiment Analysis using combined LSTM-CNN Models

。當然從卷積運算的角度來看,卷積核探測到的模式其實是确定了其中的相對位置關系的,這也可以說是上下文資訊的一種變形。

使用CNN相對于LSTM最大的優點是它可以運用并行化計算,計算效率遠比LSTM高,進而我們可以把網絡做的更深。

實作

我們先把問題進行轉化,其實我們可以把我們的目标弱化,我們并不需要知道未來某一時刻價格精确的位置,而是隻需要知道價格波動在未來是否達到了我們可以盈利的預期值,也就是價格是否漲/跌超過一個門檻值,這樣原始的問題我們形式化為一個分類問題。

下圖是借用CNN處理文本處理的架構,并在圖上做了修改,

A Sensitivity Analysis of (and Practitioners' Guide to) Convolutional Neural Networks for Sentence Classification

在量化交易中應用卷積神經網絡CNN做時間序列預測

在這個架構中,卷積運算的次元從上文介紹的圖檔分類的2維空間資訊轉變為1維時間資訊。而橫向(d=5)的資料是同一類别的量化因子,作為描述同一時間點的原始特征值。比如基于價格計算出來的不同周期的MACD,也可以直接是價格的OHLC,隻要保證不同列的因子資料是可比較的就行。多個不同的大小的核,表示想要探測不同時間長度的模式。不同類型的因子可以通過上述的架構中,最後一步softmax之前,把所有因子中提取出來的特征值拼接在一起,最後做分類。這個模型是借用文本分類的架構,為了友善說明在在1維資料中使用CNN的過程。

PyTorch中的一維卷積

nn.Conv1d

就可以完成時間序列上的卷積運算,參考

pytorch之nn.Conv1d詳解
class Conv1d(_ConvNd):
    """
    in_channels (int): 輸入通道數,也就是上圖中的d=5
    out_channels (int): 卷積産生的通道。有多少個out_channels,就需要多少個1維卷積
    kernel_size (int or tuple): 卷積核的大小,上圖3組核的的大小分别為4、5、6
    stride (int or tuple, optional): 卷積步長,每一次卷積計算之間的跨度,預設1
    padding (int or tuple, optional): 輸入的每一條邊補充0的層數,預設0
    dilation (int or tuple, optional): 卷積核元素之間的間距
    groups (int, optional): 輸入通道到輸出通道的阻塞連接配接數
    bias (bool, optional): 是否添加偏置項
    """           

用PyTorch定義一個處理時間序列的CNN網絡:

import torch
import torch.nn as nn

class TimeSeriesCNN(nn.Module):
    def __init__(self):
        super(TimeSeriesCNN, self).__init__()
        kernel_sizes = [4, 5, 6]
        ts_len = 7 # length of time series
        hid_size = 1
        self.convs = nn.ModuleList([
            nn.Sequential(
                nn.Conv1d(
                    in_channels=5,
                    out_channels=2,
                    kernel_size=kernel_size,
                ),
                nn.ReLU(),
                nn.MaxPool1d(kernel_size=ts_len - kernel_size + 1))
            for kernel_size in kernel_sizes
        ])
        self.fc = nn.Linear(
            in_features=hid_size * len(kernel_sizes),
            out_features=3,
        )

    def forward(self, x):
        output = [conv(x) for conv in self.convs]
        output = torch.cat(output, dim=1)
        output = output.view(output.size(1), -1)
        output = self.fc(output)
        return output           

繼續閱讀