Python生成对抗神经网络GAN预测股票及LSTMs、ARIMA对比分析ETF金融时间序列可视化
全文链接:https://tecdat.cn/?p=38528
本文聚焦于利用生成对抗网络(GANs)进行金融时间序列的概率预测。介绍了一种新颖的基于经济学驱动的生成器损失函数,使 GANs 更适用于分类任务并置于监督学习环境中,能给出价格回报的全条件概率分布,突破传统点估计方式,实现不确定性估计。通过股票数据的数值实验验证了所提方法的有效性,相比经典监督学习模型如 LSTMs 和 ARIMA 获得了更高的夏普比率。
引言
时间序列预测多年来一直是工业界和学术界关注的核心话题。现实世界中多数过程天然具备时间序列结构,在金融和经济领域,像金融工具价格、通货膨胀率以及诸多关键宏观经济指标都是如此。交易策略往往基于对某一金融工具价格走势(上升或下降以及变动幅度)的合理判断,所以时间序列的预测与分类在金融环境中极为重要。传统上,这项任务主要依靠仅基于点估计的方法来完成。而本文旨在突破这类传统方法,借助生成对抗网络(GANs)为目标变量的未来分布提供概率预测。
生成对抗网络
(一)经典 GAN
生成对抗网络(GANs)由 Goodfellow 等人在 2014 年提出,当前在诸多任务中处于领先地位,尤其在图像和视频生成方面表现突出,在科学、视频游戏、照片编辑、视频质量提升等众多领域也有着广泛应用。它属于生成模型家族,其任务是从未知的数据分布中生成新样本。
从博弈论角度来看,可假设有两个参与者,即生成器 G
和判别器 D
,它们相互博弈。G
负责生成它认为看起来真实的样本,而 D
则判断给到它的样本是来自真实数据还是来自生成器。G
的目标是让 D
相信其输出是来自真实数据,并尽可能生成看起来真实的样本;反过来,D
要学习如何正确区分数据样本和来自生成器的样本。G
会利用从 D
得到的反馈来改进生成的样本。在 GANs 中,生成器 G
和判别器 D
相对于它们的参数都是可微函数,并且通常用神经网络来表示。G
以通常为高斯分布的噪声作为输入,输出一个生成的样本。D
以 G
生成的样本或者来自真实数据的样本作为输入,输出其输入为真实样本的概率。GANs 通过对抗过程进行训练,也就是同时训练两个不同的模型(生成器和判别器),若是采用神经网络,可通过反向传播高效实现训练。
-
# 以下是简单示意代码,并非完整实现
-
import torch
-
import torch.nn as nn
-
# 定义生成器G
-
class Generator(nn.Module):
-
def __init__(self):
-
super(Generator, self).__init__()
-
# 这里可以添加生成器的网络结构相关代码,比如一些线性层等
-
def forward(self, noise):
-
# 实现生成器前向传播,将输入噪声转换为生成的样本
-
generated_sample = None # 这里需按实际情况替换为具体生成逻辑代码
-
return generated_sample
-
# 定义判别器D
-
class Discriminator(nn.Module):
-
def __init__(self):
-
super(Discriminator, self).__init__()
-
# 这里可以添加判别器的网络结构相关代码,比如一些线性层等
-
def forward(self, input_sample):
-
# 实现判别器前向传播,判断输入样本是真实还是生成的概率
-
probability = None # 这里需按实际情况替换为具体判断逻辑代码
-
return probability
(二)条件 GAN
条件生成对抗网络是标准 GAN 的自然延伸,最早在最初的 GAN 论文中被提及,并由 Mirza 和 Osindero 在 2014 年首次进行探索。它假设数据 x
来自一个条件分布 pdata(x|condition)
(给定某个确定性条件),与标准 GAN 不同的是,生成器和判别器除了标准输入外,还会被给予进一步的确定性信息(条件)。当这个条件是标签时,通常将其编码为独热向量,判别器也会被给予相同条件。
比如我们想要生成猫和狗的照片,我们有猫和狗的标签(以独热向量形式给出),生成器会将噪声和一个标签(比如猫的标签)作为输入,输出它认为是猫的照片。判别器会将来自原始数据的猫照片以及生成器网络生成的猫照片,连同表明是猫照片的标签一起作为输入,然后对来自真实数据的猫照片和来自生成器的猫照片给出反馈并学习。
(三)ForGAN
ForGAN 是一种条件 GAN,其架构非常适合用于时间序列的概率预测,由 Koochali 等人在 2019 年提出。其思路是利用条件 GAN,根据时间序列之前的 L
个值(记为 x-Lt+1
,也就是 xt, x t−1,..., x t−(L−1)
)对 xt+1
进行概率预测。与标准点估计相比,它能利用更多信息,并且便于获得不确定性估计。
为利用时间序列结构,生成器和判别器首先会将它们的输入通过一个循环神经网络层。ForGAN 架构根据数据情况包含门控循环单元(GRU)或者长短期记忆(LSTM)单元,本文因 LSTM 单元在金融领域应用广泛而选用它。
Fin-GAN损失函数
我们工作的主要贡献在于为生成器引入了一种新颖的经济驱动损失函数,这将生成对抗网络(GANs)置于有监督学习环境中。这种方法使我们能够超越传统的逐点预测方法,转向概率预测,从而提供不确定性估计。此外,我们基于预测的符号(方向)来评估性能,这意味着我们对分类感兴趣,而我们的损失函数更适合于此。
动机
GANs的主要目标是创建模仿真实数据的合成样本。然而,一个重要的问题是,我们希望通过模拟重现真实数据的哪些属性。在我们的案例中,是预测的符号。我们更感兴趣的是正确地对收益/超额收益进行分类,特别是当价格变动幅度较大时,而不是生成接近实际值的预测。其动机在于,可能会产生一个接近时间序列实际值但符号相反的预测。在金融时间序列预测中,在最重要的时候正确估计符号通常比预测接近实际值更为重要。我们旨在为生成器提供更多信息,使其更好地复制数据的符号,这是任务的关键组成部分。使用新颖损失函数项的主要原因和好处可总结如下:
- 将生成的条件分布向正确方向移动;
- 使GANs更适合分类任务;
- 提供有效的正则化;
- 帮助生成器学习更多,特别是在梯度较弱的情况下;
- 有助于避免模式崩溃;通过使生成器损失表面更加复杂,生成器可能会收敛到尖锐的局部最小值。
我们已经看到了不同损失函数的几个示例以及它们带来的好处。最值得注意的是,W-GAN-GP(Gulrajani等人,2017)在判别器损失中添加了一个额外项,以强制执行Lipschitz约束。向生成器添加损失项不太常见,但在Bhatia等人(2021)最近的工作中用于生成极端样本,在VolGAN(Vuleti´c和Cont,2023)中用于模拟无套利隐含波动率表面。其他定制损失函数在金融领域也被证明是有用的,例如Tail-GAN(Cont等人,2022),其侧重于投资组合尾部风险的估计。
新颖损失函数
假设我们的GAN旨在预测(x_i),其中(i = 1,\cdots,n_{batch})。对于每个(x_i),给定噪声样本(z)和由时间序列(x)的前(L)个值组成的条件(x_{-Li}),生成器的输出为
设(x=(x_1,\cdots,x_{n_{batch}}))和(\hat{x}=(\hat{x}1,\cdots,\hat{x}{n_{batch}}))是(x)的预测。我们定义三个损失函数项,即基于PnL、均方误差(MSE)和夏普比率(Sharpe Ratio)的项,我们用它们来训练生成器。
(一)PnL项
在生成器训练目标(最大化)中包含的损失函数项的第一个也是最明显的选择是PnL。然而,符号函数不可微,使得无法执行反向传播。为了缓解这个问题,我们提出了对(PnL)的平滑近似,我们将其表示为(PnL^*),定义为
其中(PnL_a^*)是对特定预测的(PnL)的平滑近似
并且(\tanh(x))定义为
超参数(k_{tanh})控制我们近似的准确性。由于超额收益的值通常较小,期望(k_{tanh})足够大以获得良好的近似,但同时又足够小以使生成器能够从中学习到强梯度。请注意,在PnL项的表达式中,我们考虑的是每笔交易的PnL。这不是在每天平均的PnL,因为训练数据集在每个训练周期开始时都会被打乱。我们使用(k_{tanh}=100)。
Fin-GAN损失函数的好处和挑战
新颖的损失函数项确实会移动生成的分布,有助于避免模式崩溃,并提高夏普比率性能,我们在大量数值实验中证明了这一点。包含新的损失函数项引入了四个需要调整的新超参数,使得优化成为一个更具挑战性的问题。然而,梯度范数匹配方法缓解了这个问题。
此外,损失表面变得更加复杂,增加了收敛挑战。在初始数值实验中,当探索更广泛的超参数(\alpha,\beta,\gamma)范围时,MSE和夏普比率项似乎鼓励生成器产生非常狭窄的分布。为什么具有高(\gamma)系数的夏普比率项会导致模式崩溃并不明显,因为它鼓励PnL具有低标准差,而不是生成的样本。然而,包含基于PnL的项有助于缓解模式崩溃问题,这与收敛到尖锐局部最小值有关(Durall等人,2021)。PnL项帮助生成器逃离损失表面的此类区域。当使用梯度范数匹配来调整超参数(\alpha,\beta,\gamma,\delta)时,无论网络权重的初始化如何,Fin-GAN都没有模式崩溃。然而,我们注意到使用Xavier初始化(Glorot和Bengio,2010)而不是He初始化(He等人,2015)有助于减少ForGAN出现模式崩溃的迭代次数。使用He初始化时,这种情况在67%的案例中发生。使用普通Xavier初始化解决了这个问题。
Fin-GAN算法
输入:生成器的隐藏维度、判别器的隐藏维度、噪声维度。目标大小、条件窗口、滑动窗口。判别器学习率、生成器学习率。训练数据、验证数据、测试数据。梯度匹配的训练周期数(n_{grad})、训练周期数(n_{epochs})、小批量大小(n_{batch})、模式崩溃阈值(\alpha)。加权策略的样本数量(B)。
步骤0:从训练数据集中取出前(n_{batch})个项目作为数据归一化的参考批次。初始化生成器(gen)和判别器(disc)网络。
步骤1:匹配梯度范数以找到(\alpha,\beta,\gamma,\delta)。
-
for n_grad 个训练周期 do
-
将训练数据分割成小批量。
-
for 小批量数量 do
-
计算关于\(\theta_g\)的BCE、PnL*、MSE、SR*、STD项的梯度范数。
-
将它们标记为grad0、gradα、gradβ、gradγ、gradδ。
-
通过RMSProp和BCE损失更新disc,然后更新gen参数。
-
end for
-
end for
-
\alpha \leftarrow mean(grad0/gradα); \beta \leftarrow mean(grad0/gradβ);
-
\gamma \leftarrow mean(grad0/gradγ); \delta \leftarrow mean(grad0/gradδ)
步骤2:训练和验证。
将可能的损失函数组合((PnL*)、(PnL&STD)、(PnL*&MSE)、(PnL&SR*)、(PnL&MSE&STD)、(PnL*&MSE&SR)、(SR*)、(SR*&MSE))分别标记为(L_i),对于(i = 1,\cdots,8)。
-
for i = 1,\cdots,8 do
-
geni \leftarrow gen; disci \leftarrow disc.
-
for nepochs do
-
将训练数据分割成小批量。
-
for 小批量数量 do
-
通过RMSProp和J(D)更新disc。
-
通过RMSProp和Li更新gen。
-
end for
-
end for
-
从验证集中的每一天从geni中取出B个样本。
-
SR_ival \leftarrow 验证集上加权策略的夏普比率。
-
end for
-
i^* \leftarrow argmax\{SR_ival : i = 1,\cdots,8\}; gen^* \leftarrow geni^*
步骤3:在测试集上评估。
对于测试集中的每个时间(t),从(geni^*)中取出(B)个独立同分布的输出(\hat{r}_{it}),(i = 1,\cdots,B)。
每个时间的点估计(\tilde{r}t \leftarrow mean(\hat{r}{it}))。
(MAE \leftarrow MAE(r_t,\tilde{r}_t); RMSE \leftarrow RMSE(r_t,\tilde{r}_t));
实施加权策略,将天数配对成两组。
计算年化夏普比率(SR_w)和平均每日PnL (PnL_w)。
-
if std(\{\hat{r}_{i0}\}_{i = 1,\cdots,B}) < \alpha 或 std(\{\tilde{r}_t\}_{t\in测试集}) < \alpha then
-
模式崩溃。
-
else
-
无模式崩溃。
-
end if
上述论文对Fin - GAN损失函数进行了较为全面的阐述,包括其动机、新颖损失函数的构建、带来的好处与挑战以及相关算法流程等内容。在实际应用中,可根据具体的金融数据和需求进一步调整和优化相关参数与模型结构,以达到更好的预测和分类效果。
数据描述与实现考量
在本节中,我们将对所使用数据集的主要特征进行阐述,介绍ForGAN架构,讨论训练设置情况,并展示Fin - GAN模型在数值实验中的一般行为表现。
数据描述
我们选取的是CRSP中提取的每日股票ETF超额收益以及每日原始ETF收益数据,时间跨度为2000年1月至2021年12月。所有时间序列按照80 - 10 - 10的比例划分训练 - 验证 - 测试阶段,具体而言,训练期是2000年1月3日至2017年8月9日,验证期为2017年8月10日至2019年10月22日,测试期则是2019年10月23日至2021年12月31日。值得注意的是,测试数据涵盖了新冠疫情起始阶段,这无疑增加了问题的挑战性。
在收益考量方面,我们依次关注开盘 - 收盘和收盘 - 开盘收益,将它们分别视作一个时间单位,也就是说输入的时间序列交替呈现日内收盘 - 开盘以及隔夜开盘 - 收盘收益情况。其中,滑动窗口设定为一个时间单位,条件窗口设为十个时间单位(对应五个交易日收益,即一个完整交易周),预测窗口是提前一个时间单位。
以下是用于数值实验的股票代码及对应的ETF等相关信息展示:
-
-
data_ETFs = pd.read_csv("ETFsta.csv")
-
data_ETFs['date_dt'] = pd.to_datetime(data_ETFs['date'])
-
data_ETFs['AdjClose'] = data_ETFs['PRC'] / data_ETFs['CFACPR']
-
data_ETFs['AdjOpen'] = data_ETFs['OPENPRC'] / data_ETFs['CFACPR']
-
ETF_list = data_ETFs['TICKER'].unique()[2:]
-
-
ETF_dfs = [None] * len(ETF_list)
-
-
for i in tqdm(range(len(ETF_list))):
-
ETF = ETF_list[i]
-
ETF_dfs[i] = data_ETFs[data_ETFs.TICKER == ETF].copy().reset_index()
-
ETF_dfs[i].to_csv("C:\\"+ETF+".csv")
-
plt.figure(ETF + "price")
-
plt.plot(ETF_dfs[i]['date_dt'],ETF_dfs[i]['AdjOpen'],label='open')
-
plt.plot(ETF_dfs[i]['date_dt'],ETF_dfs[i]['AdjClose'],label='close')
ForGAN架构
针对单只股票/ETF数值实验,利用LSTM单元构建的经典ForGAN架构。鉴于所使用数据集规模较小,相应各层维度以及噪声维度统一设置为8。生成器激活函数选用ReLU,而判别器激活函数采用sigmoid函数。
基线算法
除了标准的ForGAN(通过BCE损失训练、具备ForGAN架构的GAN)之外,我们还将Fin - GAN模型与更为常见的时间序列预测监督学习方法,像ARIMA和LSTM进行对比分析。
-
sgn_fake = torch.sign(predicted)
-
PnL = torch.sum(sgn_fake*real)
-
PnL = 10000*PnL/nsamp
-
return PnL
上述两图用于展示Fin - GAN损失函数项对生成分布产生影响的情况,图中所有分布都是基于相同的条件窗口生成,黑色垂直线代表真实值,也就是目标值。
此图所使用的数据是PFE的ETF超额收益,通过不同损失函数组合训练后,展示在测试集上生成的样本外(一步超前)均值情况。比如在该特定实例中,在验证集上夏普比率性能表现最佳的损失函数是PnL - MSE - SR。
另外,我们训练了LSTM - Fin,即在(基线)MSE损失、(PnL*)、(SR*)和STD损失项的合适组合上对LSTM开展训练,目的是更好地与Fin - GAN进行对比。训练过程中运用和Fin - GAN设置相同的方法,通过执行梯度范数匹配来确定与新加入的损失项对应的超参数值。
数值实验
首先,在单只股票设置情境下,我们针对特定股票/ETF的ETF超额收益/原始收益对Fin - GAN和各基线模型展开训练。随后,依照Sirignano和Cont(2019)所提出的思路,在三组不同股票数据上探究普遍性概念。我们把单只股票设置中不同股票代码对应的数据进行整合,模拟数据来自同一数据源对Fin - GAN进行训练。
不同模型在股票和ETF上的各项性能指标总结如下表所示:
注:SR指年化夏普比率,PnL指平均每日PnL,MAE和RMSE分别表示平均绝对误差和均方根误差,表格中突出显示的是各指标下表现最优的结果。
图呈现的是Fin - GAN不同损失函数组合在不同股票代码上达成的累积PnL情况,其中投资组合PnL是图中黑色显示的平均PnL乘以工具数量。
图展示的是不同模型的投资组合累积PnL,图中虚线对应的是由合适的Fin - GAN损失函数组合(仅包含MSE)生成的PnL路径。
通过上述实验可知,平均来看,Fin - GAN方法在性能上优于ForGAN、LSTM、ARIMA以及长期持有这些基线模型。进一步分析单个股票代码层面的夏普比率情况,从各模型和股票代码对应的年化夏普比率性能图能发现,Fin - GAN模型比其他基线模型表现更佳,能够获取极具竞争力的夏普比率,尤其考虑到处理的是单只股票投资组合这一情况。Fin - GAN所实现的夏普比率相较于LSTM更加稳定,唯一夏普比率低于 - 1的股票代码是XLY(可选消费),这是由于该板块ETF在新冠疫情初期出现暴跌,而在验证阶段又持续增长所致。在LSTM实现夏普比率高于1或2的数据集上,Fin - GAN同样能达到相近甚至更高的夏普比率,比如在CL的情况中。总之,对比其他方法,Fin - GAN在夏普比率性能方面优势明显。
从整体性能角度而言,Fin - GAN和LSTM的表现优于其他被研究的方法。各投资组合累积PnL情况如图所示,深度学习模型从新冠疫情冲击中恢复的速度明显快于ARIMA和长期持有模型,并且生成的PnL波动大多源于疫情影响。图中展示的不同Fin - GAN损失组合对应的累积PnL情况表明,使用验证环节来确定损失组合(而非一开始就对各数据集使用固定的损失组合)有助于提升整体性能。虽然LSTM的投资组合PnL相对较高,但其波动更大,特别是在2020年3月至6月期间,这也使得其夏普比率低于Fin - GAN。
针对图展示的平均每日PnL性能,ARIMA和长期持有方法生成的平均每日PnL规模相近,LSTM平均获得的PnL最高,不过LSTM的PnL在不同股票代码间波动明显较大。GAN方法实现的平均每日PnL标准差(Fin - GAN为4.85,ForGAN为4.00)明显低于LSTM(7.48)、LSTM - Fin(7.53)、ARIMA(6.26)和长期持有(5.97),这体现出利用不确定性估计来构建动态规模加权策略的优势。
接下来,我们对影响Fin - GAN性能的所选损失函数组合细分情况展开探讨。
图展示的是Fin - GAN在测试集上通过不同损失组合得到的SR(年化夏普比率),各股票代码括号内所报告的是在验证集上实现最高夏普比率的所选损失组合。
图呈现的是Fin - GAN损失项组合在不同股票代码上的平均样本外(测试)PnL相关性情况。
图是通用模型中单个股票的夏普比率性能总结,每列代表损失函数项的不同组合,“单只股票”列展示的是针对特定股票/ETF训练时Fin - GAN的最优性能表现,其中CCL、EBAY、TROW和CERN在训练阶段未被模型涉及。
图是对XLP板块股票成分的SR性能总结,每列表示损失函数项的不同组合,SYY和TSN在训练阶段未被模型纳入。
图呈现的是在训练数据包含XLP数据时,属于XLP板块股票的SR性能总结,同样每列代表损失函数项的不同组合,SYY和TSN在训练阶段未被模型关注到。
综上所述,在对Fin - GAN模型的多方面研究中,从数据的特征分析、架构搭建,再到与其他算法对比等环节,都为深入认识其性能提供了详实依据。数据的不同阶段划分、不同板块股票数据运用,以及与ARIMA、LSTM等算法在各类性能指标对比上,都凸显出Fin - GAN在金融数据处理及预测领域的独特价值与优势。特别是其在夏普比率、平均PnL等关键指标的表现,还有不同损失函数组合对最终结果的影响等内容,对于后续进一步优化和拓展Fin - GAN模型应用有着重要的参考意义。
结论
在金融数据背景下,我们已证明生成对抗网络(GANs)可成功应用于概率时间序列预测,尤其是在预测方向(符号)至关重要的情况下,如在大幅价格波动前的预测。我们引入了一种新颖的经济驱动生成器损失函数,它包含适当加权的利润与损失(PnL)、PnL 的标准差、均方误差(MSE)、基于夏普比率的损失函数项,这使得 GANs 更适用于分类任务,并将其置于有监督学习环境中。
通过一系列全面的数值实验,我们将自己的方法与标准 GAN 模型、长短期记忆网络(LSTM)、自回归移动平均模型(ARIMA)以及长期持有策略进行了比较,并在实现的夏普比率方面展示了我们模型的优越性能。此外,我们在三种设定下考虑了通用模型:汇集来自不同板块股票和板块 ETF 的数据;考虑一个板块,将板块 ETF 纳入训练数据以及将板块 ETF 排除在训练阶段之外。尽管股票范围较小,但我们注意到即使在未见过的股票上也可能有良好表现。并且,当板块 ETF 被纳入训练数据时,单板块设定中的性能有所提升。
我们的工作引出了一些有趣的未来研究方向。探索新损失函数项的添加如何影响路径模拟,以及如何利用跨资产交互、从相关性中学习并在更大的股票范围内探索普遍性概念,可能会带来深刻见解。超越股票数据并探索其他资产类别(如期权),可能在一个联合框架中进行,是未来工作的另一个有趣途径。
参考文献
- Arjovsky, M. and Bottou, L., Towards principled methods for training generative adversarial networks. In International Conference on Learning Representations, 2017.
- Arjovsky, M., Chintala, S. and Bottou, L., Wasserstein generative adversarial networks. In International Conference on Machine Learning, pp. 214–223, 2017 (PMLR).
- Assefa, S.A., Dervovic, D., Mahfouz, M., Tillman, R.E., Reddy, P. and Veloso, M., Generating synthetic data in finance: Opportunities, challenges and pitfalls. In Proceedings of the First ACM International Conference on AI in Finance, pp. 1–8, 2020.
- Bhatia, S., Jain, A. and Hooi, B., ExGAN: Adversarial generation of extreme samples. Proc. AAAI Conf. Artif. Intell., May 2021, 35(8), 6750–6758. doi:10.1609/aaai.v35i8.16834.
- Box, G.E., Jenkins, G.M., Reinsel, G.C. and Ljung, G.M., Time Series Analysis: Forecasting and Control, 2015 (John Wiley & Sons: Hoboken, NJ).
- Buehler, H., Gonon, L., Teichmann, J. and Wood, B., Deep hedging. Quant. Finance, 2019, 19(8), 1271–1291.
- Buehler, H., Horvath, B., Lyons, T., Perez Arribas, I. and Wood, B., Generating financial markets with signatures. Available at SSRN 3657366, 2020.
- Chen, T. and Guestrin, C., Xgboost: A scalable tree boosting system. In KDD, 2016.
- Cho, K., van Merriënboer, B., Gulcehre, C., Bahdanau, D., Bougares, F., Schwenk, H. and Bengio, Y., Learning phrase representations using RNN encoder-decoder for statistical machine translation. In Proceedings of the 2014 Conference on Empirical Methods in Natural Language Processing (EMNLP), pp. 1724–1734, October 2014 (Association for Computational Linguistics: Doha, Qatar).