股票市场交易中的强化学习
在深度学习的世界中,无论您的模型多么先进,没有充分对业务充分理解和干净的数据都不会走得太远。这个事实在金融领域尤其如此,在我们的数据集中,只存在股票的开盘价,最高价,最低价,调整后的收盘价和交易量的5个变量。
在第一幅图中,不难发现这些原始数据值不足以训练机器学习模型。高度相关的变量乍看起来似乎很有希望,但是相关系数极高的缺点是实际上没有那么多的信息。数据集基本上有五个数字,它们对模型说的完全相同,这使得模型很难理解允许机器学习交易者获利的市场波动的复杂性。
数据的相关性显示在下面的分散矩阵内,其中对角线是变量分布的估计值。
技术分析:这是一个数学工具箱,用来将嘈杂的原始金融数据转换成可理解、清晰的信号,量化资产的动量、波动性、交易量和其他一般趋势。幸运的是,TA是一个很棒的python库,拥有所有这些指标,并允许对数据进行简单的实验。我们花费了大量时间来查找指标的不同组合,并对数据集进行自己的更改,以确保我们拥有最佳的数据集。 我们可以看到将相对强度指标(RSI)(其唯一输入为收盘价)相对于下面的原始收盘价得出了显着结果。
但是,在数学金融领域,一个重大谬论是存在一些功能的完美组合,这些功能可以为您'预测'市场。与数据科学和机器学习中的许多方法一样,这个工具实际上只在数据转换阶段提供帮助。这一事实在许多项目中得到了体现,因为最终您只需要相信您目前拥有的组合已经足够好,可以让模型学习。因此,我们确定了两个动量指标,即经典相对强度和另一个被有趣地命名为awesome指标,以及两个趋势指标,移动平均收敛散度和Aroon指标。
动量指标很有用,因为它们试图量化股票在先前价格的背景下的走势。这可能对代理人有所帮助,因为它可以尝试了解动量增加通常是股价可能上涨的好兆头,并且可以自信地持有股票直到动量开始减少。另一方面,趋势指标通常形成动量指标的超集,因为趋势跟踪通常涉及动量和移动平均值的计算。通常,我们尝试获取动量生成的不容易量化的值,并将其转换为百分比,其中正数和负数表示各自的趋势。这种设置将进一步帮助代理了解股票走势的能力,并希望了解趋势和动量都开始上升时获利的可能性很高。
一个关键的发现是在我们的数据上应用了信号处理滤波器,该滤波器在固定数量的点之间插入多项式以显着平滑数据。这是很重要的,因为我们使用的技术分析功能在本质上仍具有相当高的噪声和连续性,因此更平滑的数据将使模型具有更清晰的信息并在环境中做出更好的决策。下图通过显着消除了许多容易造成模型混乱的随机运动,证明了滤波器对开盘价的巨大平滑作用。
在特征被挑选出来之后,还有一个预处理的关键操作,即对我们的数据进行标准化。尽管很容易忽略,但是忘记进行标准化会严重影响模型性能。更有趣的是,由于财务数字是无界的,因此没有直接的方法来选择如何规范化我们的数据,这与像素值介于0到255之间的图像不同。例如,简单的滚动窗口z得分计算可以很好地解决此问题。很好,因为z分数会将我们的所有数据转换为大约-3到3的合理范围。
确定输入后,我们就进入了超参数调整和模型优化的阶段。在大多数深度学习应用程序中,模型具有多个可调超参数,即我们可以指定训练时使用的模型的变量。这些参数的变化可以说是对模型性能的最重要的结果,因为模型训练中的关键时刻受这些值控制。
我们能够了解近端策略优化(PPO)框架背后的机制,以帮助实验,调整和改进现有模型的超参数。在此过程中,我们能够深入了解某些超参数与代理获得的奖励之间的关系。这使我们能够真正了解代理是否真正在学习。通过我们的探索,我们能够发现我们的模型从股票交易中学到的一些有趣的见解。
为了测试不同的超参数值与模型性能之间的关系,我们决定采用科学的方法。这种方法涉及我们一次只更改一个超参数来测试代理的性能。通过确保所有其他超参数保持恒定,我们能够找出最有效地允许我们的代理学习的每个超参数的范围。我们还通过使用种子控制了每个试验中训练的数据的随机性。这样可以确保模型性能的任何变化都可以归因于指定的参数,而不是其他无关的变量。
默认参数值:
'n_steps': 1024,
'gamma': 0.9391973108460121,
'learning_rate': 0.0001,
'ent_coef': 0.0001123894292050861,
'cliprange': 0.2668120684510983,
'noptepochs': 5,
'lam': 0.8789545362092943
Nsteps:此超参数告诉我们每个环境在更新模型之前要运行的步骤数。这从根本上决定了单一学习经历对政策更新的影响程度。如果nsteps较低,则意味着该策略将不断变化,并适应可能由随机机会造成的经验。因此,当模型的n_steps低时,每种学习经历可能会对策略更改产生更大的影响。但是,与此有关的一个问题是,它可能导致相对不稳定的策略,该策略可能永远不会收敛到最佳状态。因此,通过调整超参数找到合适的平衡可以帮助获得更好的代理交易性能。
Gamma:接下来,我们继续修改伽玛值。这是折扣因子,基本上意味着它会削弱下一个奖励在政策上的权重。通过对此进行调整,我们可以优化新政策与旧政策之间的差异。这使我们的代理可以朝着其最大目标迈出较小的步伐,而不会受到最新经验的过度影响。
Entropy coefficient:我们还试图调整熵系数,该熵系数充当正则项并给策略增加随机性。探索是强化学习中找到一个好的策略的至关重要的一点,如果策略收敛得太快,代理可能会发现自己陷入重复执行相同次优操作的局部最大值中。可以通过调整熵系数来纠正此行为,以防止过早收敛并鼓励探索。
Lambda:Lambda是用于减少Generalized Advantage Estimator(GAE)中方差的平滑参数。 GAE使用每个时间步骤的奖励来估算采取特定行动后,代理的状况会好转多少。 Lambda通过确保策略不会过度适应特定的状态-操作对,帮助稳定这种学习。
关键发现
在运行和微调每个列出的超参数后,我们得出了一些有趣的结论。首先,较高的nstep值范围似乎会产生更健康的奖励和优势曲线。这意味着,当我们的代理在更新模型之前在每个环境中采取更多步骤时,它将学习更有效的交易策略。因为当nsteps参数较高时,模型的表现似乎更好,这可能意味着最佳策略是一种策略,即交易员购买股票并持有较长时间。这可能表明,我们在交易时可以采取的最佳策略是买入一只股票并持有它,而不是在更高的频率上进行微交易的股票。
除了从调整n_steps超参数中获得的一些有趣的见解外,我们还发现在我们的模型中gamma的最佳值相对较高,性能最大化可达0.99。gamma值代表折扣率,因此会影响我们根据最新经验更新策略的程度。这个超参数在较大值上的成功意味着,在改变策略时,新体验会得到轻微的权衡。这意味着代理只稍微优先考虑短期回报。
加入熵正则化有助于减少梯度估计中固有的噪声。通过调整熵系数,我们发现将默认值调整到较高的0.01会导致更稳定的情节奖励增加,并产生更健康的优势曲线。在1e-3到1e-5的较小范围内,我们看到熵损失迅速崩溃,这表明agent的策略过于迅速地变得确定性。相反,当熵系数过高的值(0.1 - -0.5),我们看到这一集奖励压扁和熵的减少损失,表明我们的代理无法学习由于高的概率熵系数是持有所有可能的行动几乎是相同的。对于我们的代理来说,拥有一个相当高的熵系数值有助于防止由于短期市场趋势而采取行动,因为它们并不总是转化为长期收益。
在改变lambda超参数时,我们发现它有一个很高的最优值范围为0.99 ~ 0.999。当lambda设置为0时,GAE就变成了一步优势估计器,它在进行策略更新时只考虑当前状态。这类政策有很高的偏见。另一方面,如果我们让lambda为1,GAE成为基线蒙特卡罗估计器,它可能会受到高方差的影响。有一个较高的lambda值表明在模型中注入一些偏差对我们的代理来说是重要的,但它确实有价值的长期回报。最大的增长是当我们的代理不受市场短期波动的影响,而是专注于长期的增量收益。
在进行了充分的超参数调整后,我们能够使用真实的市场数据生成我们的政策交易运行,每天政策可以买进、卖出或持有股票。灰色的点表示持有,黄色表示买入,绿色表示卖出。在下面的测试运行中,我们可以看到,总的来说,该政策在持有购买的资产几天来产生一些利润方面做得很好,但它也经历了缩水,损失了一些利润。这个测试运行是使用本文前面建议的超参数生成的。尽管超参数设置较强,但模型中仍存在大量波动性,这表明强模型训练性能与实时模型结果并不完全相关。这个结果通常是金融建模中反复出现的主题。尽管如此,我们的智能体知道除了最大化我们的目标函数,没有其他目标,却能够盈利,这无疑是强化学习的一个了不起的壮举。
总体而言,我们在这家PPO股票交易员上的工作使我们能够深入研究最先进的强化学习研究,同时还致力于利用我们的知识来解决实际问题。 尽管问题非常复杂,但是我们每个人都能够执行最适合我们每个技能的任务,并随后与团队的其他成员分享我们的结果以改善模型的性能。