欢迎光临散文网 会员登陆 & 注册

[Quant 1.3] 粗略的用DNN做一个标普500交易策略

2022-06-30 03:52 作者:安平生一人好_  | 我要投稿


尝试搭建一个简单的深度神经网络,以S&P500做标的模拟一个基础的交易策略。我模仿了原视频up的思路,但是没有照抄代码,基本都是我看了视频之后自己写下来的。这个up大神的视频给了我很多启发。


策略的基本思路还是找technical indicators作为神经网络的输入,来预测S&P500在下一个交易日是涨还是跌。technical indicators的选取是基于up给的论文https://sci-hub.se/10.1016/j.eswa.2016.01.018。我在里面选了一些,具体如下

一共25个指标(实际上是21个,我把weekday转成了one-hot编码)。OHLC和Volume就是正常的价量数据,带lag的就是历史数据,例如lag1_open就是前一天的开盘价。RSI指数在论文中有特定的计算公式,我选择了7,15,30,60,90天的RSI指数。weekday指得是当天是星期几。对于每一个交易日,weekday_0到weekday_4这5个指标中只有一个是1,而其余4个是0。labels就是如果和昨天相比涨了就是1,没涨就是0。


1. 库Packages

前面都是常见的包,我就不赘述了。yfinance是雅虎金融的数据接口,我用这个来调取S&P500的价量数据。价量数据取的是从一年前到今天的数据,数据频率是一天。

2. 因子计算

这是一堆冗杂的数据处理,最后计算出来的factors都拼到raw_data的数据框里面。

3. 将数据框转化为可用作DNN输入的类型

对上一步计算得到的数据框,首先我们需要进行一些标准化操作。因为S&P500的价格在4000左右,而william R的数值基本在-1到1之间。数据数量级的巨大差别会造成拟合参数的数量级的巨大差别,因此在浮点数运算时会造成比较大的误差。所以我们需要进行变换将数据转换成相近的数量级。


我跟up一样对价格和成交量取了log。然后对RSI指数除以100,这一步体现在计算RSI函数的定义里面。weekday的处理方式就是变成one-hot编码。最后比较每一天和之后一天的收盘价判断后一天是涨还是跌,跌是0,涨是1。最终直接对features和labels对应的columns取np.array(),我们就获得了ndarray,离合适的DNN的输入又近了一步。


4. 定义DNN

我在这个DNN中定义了4个全连接层。然后在前向传播函数里面给前3层使用了sigmoid激活函数,但是输出层也就是第4层没有用激活函数。这是因为pytorch内置的交叉熵损失函数会先对输出进行一次softmax函数操作,这一点up在视频里面也强调过了。

5. 将ndarray转化为张量并将输入数据分批

这里我定义了一个generator,他的输入是我们在第3步获得的ndarray还有我们想一批输入几个样本进到DNN里面。每一次调用这个generator,它会生成一批次的features和labels张量。


在初始化这个generator之后,有两种使用方法。一是使用next函数,会自动输出下一批的张量,知道遍历训练集;二是使用for循环,将generator转化为iterator,每一次迭代一批训练机样本。后面我们会用第二种方式。


6. 训练模型

我把前2/3的数据作为训练集,后1/3部分的数据用作测试集基础学习率是0.1,然后随着学习次数增加,学习率会逐渐降低,这里改变学习率的函数参照了up的代码。在开始迭代之前,一定不要忘记三个要素,模型,损失函数和优化器。


在每一个epoch下面,我们建立generator来把训练集合分批次。然后就是一套范式了,训练集前向传播-计算损失-梯度清零-计算梯度-优化器更新-调整学习率-条件性输出。

7. 回测

为了得到预测结果,我把测试集的features做了前向传播之后取softmax,这是因为我们定义的DNN的最后一层是没有激活函数的全连接层,所以想要获得涨跌概率的话,需要对前向传播的输出套上softmax函数。如果预测结果是涨的概率或者跌的概率大于90%,那么我们就在当天做交易。即如果预测出来明天涨的概率超过了0.9,我们就在明天开盘买入;如果预测出来明天跌的概率超过了0.9,我们就在明天开盘做空。为了计算方便,我们假设每日等额做多或者做空,并当日清算,这就形成了一个策略的基本逻辑。这个策略的benchmark是从测试集日期的第一天一开始做多并持有至最后一天。然后我们做一下可视化对比一下我们的策略和benchmark收益率的对比。

在层层理想化的假设(交易不受限,等额交易,没有交易成本,不考虑slippage和market effect),策略是能打败S&P500的。但是up提到的问题很明显,每次拟合出来的模型带来的收益率都不一样,这是因为每次模型初始化的时候会随机生成一组参数,并以此参数为起点梯度下降,结果很可能会下降到局部最小值,所以最终的参数会有一些差异。

[Quant 1.3] 粗略的用DNN做一个标普500交易策略的评论 (共 条)

分享到微博请遵守国家法律