In this tutorial we will learn the basics of risk-neutral options pricing and attempt to further our understanding of Geometric Brownian Motion (GBM) dynamic...
Understanding and modelling volatility accurately is of utmost importance in financial mathematics. The emergence of volatility clustering in financial marke...
In 1978, Breeden and Litzenberger showed how under risk-neutral pricing, that the discounted Risk-Neutral Density (RND) function could be estimated directly...
This is the first episode of the video series where we will try to create a trading strategy using the data science approach, deep learning models, TensorFlo...
为此,我们将采用窗口法,当价格越过窗口障碍时生成标签。它是这样工作的:我们定义了一个长度为 n 柱的窗口,并根据我们预期的百分比回报率设置了上、下窗口壁垒。当我们将此窗口滑动到所有柱上时,步长为一个柱,如果价格超出窗口,窗口中的第一个柱将收到标签。在继续生成标签之前,让我们为窗口设置参数。虽然其背后的想法很简单,但选择最佳窗口大小和屏障级别可能具有挑战性。就个人而言,我花了相当多的时间来解决这个问题,但尚未找到明确的解决方案。
This is the second episode of the video series where we will try to create a trading strategy using the data science approach, deep learning models, TensorFl...
This is the third part of the Deep Learning Trading Strategy from the beginning to the production series.In this video we are going to review our generated l...
This is the part IV of the Deep Learning Trading Strategy from the beginning to the production series.In this video we are going to diving deeper into the TF...
This is the part V of the Deep Learning Trading Strategy from the beginning to the production series.In this video we are going to have a look at my fails. W...
This is the part VI of the Deep Learning Trading Strategy from the beginning to the production series.In this video we are going to have a look at the main d...
This is the part VII of the Deep Learning Trading Strategy from the beginning to the production series.In this video we are going to have a look at the tradi...
Quants 的随机微积分 |衍生品的风险中性定价 |期权定价解释
Quants 的随机微积分 |衍生品的风险中性定价 |期权定价解释
在本视频中,我们将深入探讨使用蒙特卡罗模拟和风险中性定价对金融衍生品进行估值背后的金融数学。我们会回答为什么要用蒙特卡洛模拟,什么是风险中性定价,股票增长率为什么不进入衍生模型等问题。
风险中性定价是一种方法,其中期权的价值是其未来收益的贴现预期。换句话说,它是衍生品所有可能收益的预期值,贴现到现在。标的股票增长率不影响风险中性定价框架中的期权价格。这是因为衍生品和标的股票具有完美的相关性,允许复制和创建无风险的投资组合。
与其他估值方法相比,使用风险中性定价方法有几个好处。首先,对于复杂的导数公式,封闭形式的解决方案可能不可行。在这种情况下,使用复制方法和求解偏微分方程 (PDE) 的计算成本可能很高。另一方面,风险中性定价允许使用蒙特卡洛模拟轻松估算期权价值,这在计算上成本较低。
为了解释风险中性定价,我们首先考虑单期二项式模型。在这个模型中,股票可以上涨也可以下跌,期权价值取决于这两种可能的结果。通过构建标的股票和无风险资产的投资组合,我们可以复制期权的收益。使用无套利原则,期权在零时的价值必须等于投资组合在零时的价值。通过求解线性方程,我们可以得到一个表示二项式模型中贴现期望的公式。
我们引入了风险中性概率度量的概念,表示为 q,它允许我们从股票价格的物理概率转移到风险中性概率。这种转变是通过使用称为 random-nickdem 导数的随机变量重新加权物理概率来实现的。这种导数使我们能够将期权价值从风险中性定价世界转化为物理概率世界。
风险中性定价的目标是确定随机 nickdem 衍生过程,表示为 Zt,确保所有贴现股票价格在风险中性概率测度 q 下都是鞅。通过改变测度,我们可以将物理概率测度下的原始布朗运动转换为风险中性概率测度下的新布朗运动。这个新的布朗运动是一个鞅过程,表明它的期望随着时间的推移保持不变。
为了应用这些概念,我们考虑了几何布朗运动模型,它代表了非派息股票的动态。该模型由一个确定性成分和一个代表波动性的随机成分组成。然而,由于确定性成分,原始股票动态不是物理概率下的鞅。为了使动态成为鞅,我们引入了 Radon-Nikodym 导数,它去除了漂移项,将股票动态转化为风险中性概率测度下的鞅过程。
总之,风险中性定价和蒙特卡洛模拟为金融衍生品估值提供了一个有价值的框架。风险中性定价方法具有简单性、计算效率和处理复杂衍生结构的能力等优势。通过使用 random-nickdem 导数并将度量从物理概率更改为风险中性概率,我们可以准确地对导数进行估值并以无风险的方式复制它们的收益。
使用 Ornstein-Uhlenbeck 过程交易股票波动率
使用 Ornstein-Uhlenbeck 过程交易股票波动率
2020 年初,随着价格大幅下跌,标普 500 指数波动性显着增加。在一个月的时间里,该指数暴跌近千点。与此同时,基于交易指数期权的未来波动率预期在此期间也飙升,达到 66 的峰值。很明显,在指数值下降的市场波动期间,VIX(波动率指数)上升。 VIX 作为未来波动率的估计值。这种现象导致做市商和交易专业人士预计已实现的波动将持续存在。
在本视频中,我们旨在解释波动率的市场特征,并讨论通过将 Ornstein-Uhlenbeck 公式拟合到特定波动率指数来模拟波动率的方法。我们将使用最大似然估计方法将模型的三个参数校准为市场数据。随后,我们将在 Python 中模拟此过程,使我们能够理解和分析随时间变化的波动动态。
为此,我们将从 stats 模块导入各种依赖项,例如 time、math、numpy、pandas、datetime、scipy、matplotlib、pandas_datareader 和 plot_acf 函数。我们将使用的数据是标准普尔 500 指数从 2003 年开始的数据。研究金融时间序列的波动率聚类及其性质,可以参考Ramacant(2005)的研究论文“金融市场的波动率聚类”,该论文探讨了金融时间序列的统计性质。我们将关注的三个重要属性是过度波动、重尾和波动聚集。
波动率聚类是指观察到价格的大变化之后往往会出现其他大的变化,无论其方向如何,而小的变化往往伴随着小的变化。这种定量表现表明,尽管回报可能不相关,但绝对回报或它们的平方显示出随着时间的推移逐渐减小的小正相关。为了对此进行分析,我们检查了对数回报,它表示价格随时间变化的对数。通过目测标普 500 指数的对数回报,我们可以观察到特定时期内的高幅度集群,例如 2008-2009 年和 2020 年的显着集群。
接下来,我们评估滞后对数收益之间的相关性。值得注意的是,我们发现在指定数据范围内的对数收益中没有统计显着的自相关。然而,当我们对对数回报进行平方以关注绝对幅度时,我们观察到强烈的正相关性甚至延伸到滞后的几天和几周。这意味着在高波动时期,这种趋势可能会持续下去,而在低波动时期,这种趋势也可能会持续下去。这种现象被称为波动率聚类。
为了可视化特定天数内的滚动波动率,我们选择一个交易窗口并计算该窗口的标准差。为了对波动率进行年化,我们取一年交易日数的平方根,通常为 252。这种方法使我们能够观察到特定时期内已实现波动率的显着上升。
为了模拟这个已实现的波动率过程,我们求助于 Ornstein-Uhlenbeck 公式。这个公式在金融数学中也被称为Vasicek模型,考虑了三个参数:kappa,代表均值回归率; theta,价格围绕其波动的平均波动率;和 sigma,波动本身。我们的目标是找到使观察到的数据遵守该分布的可能性最大化的参数值。
为此,我们采用了最大似然估计 (MLE) 方法,该方法适用于随机样本和概率密度函数。在正态分布的情况下,似然函数是给定参数的单个样本概率的乘积。通过取似然函数的对数,我们可以转换
现在我们已经推导出 Ornstein-Uhlenbeck 过程的期望和方差,我们可以继续使用这个框架对波动率进行建模。为此,我们将使用最大似然估计 (MLE) 方法根据市场数据校准模型参数。
首先,我们导入必要的依赖项,包括 time、math、numpy、pandas、datetime、scipy、matplotlib、pandas_datareader 等库,以及来自 stats 模块的 plot_acf 函数。我们还导入了自 2003 年以来的标准普尔 500 指数数据,这些数据将作为我们的市场数据。
接下来,我们探讨金融时间序列中波动率聚类的概念。波动聚集是指价格的大变化往往伴随着其他大的变化,而小的变化往往伴随着小的变化的现象。在绘制标准普尔 500 指数的对数回报时,我们直观地观察到这种集群效应。我们可以看到,在市场波动期间,对数回报的幅度聚集在一起,表明大的价格变动之间存在相关性。例如,我们可以看到 2008-2009 年金融危机期间的集群和 2020 年的波动率飙升。
为了量化对数回报之间的相关性,我们计算了自相关函数 (ACF)。虽然对数收益本身没有显示出显着的自相关性,但平方对数收益(代表绝对幅度)显示出一个小的正相关性,该相关性随时间缓慢衰减。这种绝对幅度的自相关证实了波动率集群的存在,其中高波动率时期往往会持续存在,而低波动率时期也往往会持续存在。
为了进一步分析波动率,我们通过计算标准差并使用一年中交易日数的平方根对其进行年化,从而计算指定天数内的滚动波动率。通过绘制滚动波动率图,我们可以观察到波动率增加的时期,这表现为已实现波动率的显着上升。
现在,我们介绍用于对波动率建模的 Ornstein-Uhlenbeck (OU) 公式。 OU 模型包含均值回归、平均水平和围绕平均价格的波动。该模型的参数包括 kappa(均值回归率)、theta(平均水平)和 sigma(波动率)。为了估计这些参数,我们应用了最大似然估计 (MLE) 方法,该方法涉及找到使来自 OU 分布的观察数据的可能性最大化的参数值。
我们首先讨论似然函数,它是给定参数的观测数据的联合概率密度函数 (pdf)。在正态分布的情况下,似然函数是各个 pdf 值的乘积。对似然函数取对数可以简化计算,因为它将概率的乘积转换为对数之和。通过找到参数的最大似然估计 (MLE),我们可以确定使观测数据的似然最大化的值。
在 OU 过程的情况下,由于对数似然函数的不可微性,我们需要使用数值方法来找到最大似然估计。我们利用 scipy.optimize.minimize 函数来最小化负对数似然,因为它为最大化问题提供了数值解。通过定义对数似然函数、初始参数和约束,我们可以估计使观测数据的似然性最大化的参数。
一旦我们估计了 OU 过程的参数,我们就可以使用 Python 模拟该过程。我们可以通过离散化时间步长并获得随时间推移的路径或通过将其模拟为连续时间 Itô 过程来模拟该过程。后一种方法可以更准确地表示特定时间的波动动态。
最后,本文讨论了市场波动期间标准普尔 500 指数的波动特征。它引入了波动率聚类的概念,并使用对数收益和平方对数收益证明了它的存在。然后引入 Ornstein-Uhlenbeck (OU) 模型作为对波动率建模的框架,并使用最大似然估计 (MLE) 方法来估计模型参数。最后,解释了 OU 过程的模拟,允许分析和理解随时间变化的波动动态。
无风险交易期权的神奇公式
无风险交易期权的神奇公式
在本视频中,您将学习如何使用 Breeden-Litzenberger 公式从期权价格中推导出风险中性概率密度函数。当计算期权价格变得耗时且计算量大时,这种技术非常有用,尤其是对于复杂的动态和高维场景。 Breeden-Litzenberger 公式允许我们针对不同的行使价和到期时间值计算一次复杂的衍生品,从而产生风险中性的概率分布函数,从而简化各种复杂衍生品的计算。
首先,让我们了解风险中性概率的概念。 Feynman-Kac 分析使我们能够将风险中性概率定义为时间 (t) 处终端风险中性概率的度量 (Q)。累积概率分布函数 (F) 表示风险中性概率分布。可以通过采用收益的风险中性贴现期望来为时间 (t) 的欧式看涨期权定价,行使价 (k) 和到期时间 (tau)。这可以表示为 (S_t - k) 乘以行使价 (k) 和无穷大之间的风险中性密度函数 (pdf) 的积分,并按无风险利率进行贴现。
要直接从该公式计算风险中性概率,我们可以使用 1978 年的 Breeden-Litzenberger 公式。它指出积分关于行使价 (k) 的一阶导数等于减去指数贴现因子乘以(1 - F),其中 F 是累积密度函数。以行使价 (k) 为中心的积分的二阶导数提取 pdf,即贴现因子乘以风险中性 pdf。
现在,让我们讨论如何在 Python 中应用这个公式。我们需要导入 NumPy、SciPy、Pandas 和 Matplotlib 等库。例如,我们将考虑在 Heston 模型下具有随机波动率的欧式看涨期权。赫斯顿模型提供了标的资产的动态及其波动性。我们初始化必要的参数,例如股票价格、执行价格、到期时间、无风险利率,以及 Heston 模型参数,例如均值回归率、长期方差、初始波动率、相关性和波动率波动率。
使用 Breeden-Litzenberger 公式,我们可以确定风险中性概率分布函数。通过使用有限差分近似法对二阶导数进行近似,我们计算了不同行使价和到期时间值的风险中性分布。我们为特定的到期时间构造一个 2D pdf。
为了计算 Heston 模型下的期权价格,我们使用特征函数并使用矩形积分进行数值积分。我们定义特征函数并使用矩形积分计算指定域上的复积分。为积分选择的步长会影响精度,尤其是价外期权。
我们将使用矩形积分获得的结果与 QuantLib 库进行比较,后者在 C 中实现并提供更准确的数值积分。尽管这两种方法之间存在一些差异,但均方误差 (MSE) 很小。差异主要是由于 Python 中十进制值的二进制表示引起的舍入误差。
获得离散近似pdf后,我们将其乘以正向因子。我们使用插值来平滑曲线并创建连续的风险中性分布函数。最后,我们可以使用这种风险中性分布轻松地为各种复杂的衍生品定价。
总之,Breeden-Litzenberger 公式使我们能够从期权价格中推导出风险中性的概率密度函数。通过使用有限差分逼近二阶导数并执行数值积分,我们可以计算不同行使价和到期时间值的风险中性分布。这使我们能够有效地为复杂的衍生品定价。
使用 TensorFlow 2.0 和 TFX 从开始到生产的深度学习交易策略
使用 TensorFlow 2.0 和 TFX 从开始到生产的深度学习交易策略
我很高兴自我介绍为 Denis,我热烈欢迎您来到 ClosetoAlgotrading,这是您了解与算法交易相关的所有内容的首选渠道。
自从这个想法第一次在我脑海中闪现已经有一段时间了:创建一个完全利用深度学习的力量的交易策略。这个概念围绕着开发一个能够自主识别执行盈利交易所需参数的神经网络。为了踏上这段激动人心的旅程,我决定进行一次现场实验,希望这也能引起您的兴趣。在接下来的几集中,我将指导您完成实施数据科学方法所涉及的每个步骤,以制定稳健的交易策略,从初始阶段到最终生产。
我的目标是全面涵盖所有中间步骤,包括数据准备、严格测试等。展望未来,我将利用 TensorFlow 2.0 并探索 tfx 管道提供的可能性。我打算避免复杂的计算或规则,而是依靠深度学习的力量来确定我们是否可以创造一个真正有利可图的企业。如果这个想法引起您的共鸣,我鼓励您订阅该频道并加入我的这个迷人的探险。我们将一起探索算法交易的曲折,并努力释放其隐藏的潜力。
对于那些有兴趣深入研究数据科学方法的人来说,一个简单的谷歌搜索将提供各种资源来阐明这个主题。在这些结果中,您可能会看到内容丰富的文章和可视化表示,它们概述了遵循此方法所涉及的步骤。
我们旅程中的第一个关键块是业务理解阶段。在此关头,我们必须精心定义我们的目标并建立关键绩效指标 (KPI),作为可衡量的价值来评估我们的战略在实现这些目标方面的有效性。要开始这个阶段,花时间彻底理解您特定业务领域的复杂性至关重要。通过深入了解您的目标,您可以清晰而专注地前进。必须辨别您的目标是预测特定结果还是对特定现象进行分类。
为了确定我们任务的性质,我们必须寻求基本问题的答案。如果我们的询问围绕“多少”或“多少”展开,那么我们正在处理回归任务。另一方面,如果我们询问“哪个类别”,我们就是在冒险进入分类领域,等等。一旦我们掌握了要完成的任务类型,就必须定义表示成功的指标。在我们的案例中,这些指标可能包括投资回报率 (ROI) 和准确性。毕竟,我们的最终目标是从市场中赚取利润,因此需要牢牢把握未来的价格走势。
有效预测未来价格走势不仅需要确定方向,还需要确定准确的价格水平和达到价格水平的时间。然而,仅仅知道方向是不够的。我们需要准确的价格水平和达到它的时间。为了避免我们的目标价格无休止的等待期,我们可以定义一个最低预期价格目标和一个最长等待期。换句话说,我们寻求确定未来价格走势的方向,类似于价格可以上涨、下跌或保持在同一水平的分类任务。
为了初步衡量我们的模型在预测方向方面的性能,我们可以使用分类精度。该指标量化了正确预测的数量除以预测总数,再乘以 100 以百分比表示。现在,我们的目标价格水平如何?对于我们的交易策略,我们可以将利润水平定义为我们投资资本的百分比。此外,我们必须通过将止损水平作为单笔交易的最大可接受风险来确定我们的风险承受能力。我们的利润和止损水平作为每笔交易的 ROI 值。例如,假设我们以 100 美元的价格购买股票,并在价格达到 105 美元时卖出。这 5% 的价格变动将产生 5% 的投资回报。在确定了退出水平(包括止盈和止损)后,我们必须解决时间问题。我们不希望无限期地等待价格达到我们想要的水平。
因此,我们建立了最长持有期,尽管使用的是交易量而不是固定的时间范围。这一选择背后的理由将在下一集中变得更加清晰,我将在其中详细说明数据准备。
总结我们迄今为止的方法:我们正在开发一种日内策略,该策略采用止盈、止损和平仓的最长持有期。为了启动交易,我们将训练一个能够预测未来价格方向的分类模型:上涨、下跌或持平。最初,我们将使用准确性作为我们模型功效的衡量标准。有了这个基础,我们就结束今天的讨论。我们已经定义了我们的目标、指标和绩效指标。在下一集中,我们将深入研究我们的数据,准备数据集和标签以供进一步分析和开发。
不要错过我们旅程的下一部分。在那之前,保重,我热切地等待着我们的下一次相遇。
深度学习交易策略从开始到制作。第二部分。
深度学习交易策略从开始到制作。第二部分。
我很高兴欢迎您来到我们创建交易系统的迷人旅程的第二部分。在上一个视频中,我们讨论了我们的目标,今天我们将专注于准备和标记我们的数据集。因此,让我们开始吧!
首先,我定义了一组函数来帮助我们准备数据集。首先,我们需要加载数据。对于今天的演示,我将使用一个小型数据集来使代码的运行时间易于管理。如您所见,数据集包含报价数据,包括时间、价格、交易量、出价和要价等信息。出于演示目的,我将使用一年期间的数据。让我们从检查一些统计数据开始,以了解数据集的特征。我们观察到的一个关键方面是最低和最高价格,徘徊在 100 美元左右。这是有利的,因为它可以轻松计算利润百分比。
此外,我还为数据集引入了一个关键参数:传播大小。点差计算为卖价和买价之间的差额。为什么点差大小很重要?为了说明这一点,让我们考虑一个示例,其中出价为 100 美元,要价为 101 美元。在这种情况下,点差等于 1 美元。如果我们要买入并立即卖出股票,我们总是会损失价差,在本例中,价差为 1 美元。为了深入了解点差大小,我计算了所有天数中每一秒的平均点差。如图所示,价差通常在 1 到 2 美分之间,偶尔会出现略大的价差。基于此分析,我们可以决定仅在点差小于 3 美分时执行交易。
有趣的是,图表显示最大的点差往往出现在市场开盘后的前几分钟。因此,在实施日内策略时跳过最初的 10-15 分钟是明智的。现在我们已经定义了时间段并检查了价差,我们可以继续为我们的模型生成标签,这将预测价格变动方向。我们如何生成这些标签?正如上一个视频中提到的,由于我们缺少开仓的触发器,我们需要根据预期收益为每个柱生成标签。
为此,我们将采用窗口法,当价格越过窗口障碍时生成标签。它是这样工作的:我们定义了一个长度为 n 柱的窗口,并根据我们预期的百分比回报率设置了上、下窗口壁垒。当我们将此窗口滑动到所有柱上时,步长为一个柱,如果价格超出窗口,窗口中的第一个柱将收到标签。在继续生成标签之前,让我们为窗口设置参数。虽然其背后的想法很简单,但选择最佳窗口大小和屏障级别可能具有挑战性。就个人而言,我花了相当多的时间来解决这个问题,但尚未找到明确的解决方案。
为了应对这一挑战,我将计算当天和整个数据集的历史波动率。例如,所提供的图表说明了一天内每个报价单的价格变化,以及相应的波动率。此外,我们可以评估整个数据集的波动性。如图所示,平均波动率仅为 0.003%,相当于当前价格的大约 30 美分。但是,我不打算使用跨越一整天的窗口。为了确定窗口长度,我尝试生成 100 个随机大小的窗口并评估每个窗口内的平均波动率。生成的图表描绘了不同长度窗口的平均波动率。例如,通过选择 50 条柱的窗口大小,我们可以预期波动率约为 0.001%。
这个波动率值对于定义我们的最低预期回报和计算我们的止损价格大小很有用。掌握了这些信息后,我们可以继续从报价数据生成成交量条。使用柱而不是刻度使我们能够更轻松地计算窗口长度,因为一根柱通常包含相似的体积,从而确保稳定的条件。为了生成交易量条,我们遍历报价并累积交易量,直到它超过或等于预定义的目标交易量(例如,1000)。在此积累阶段遇到的报价代表一个交易量条。让我们以生成一天的交易量条为例。如图所示,我们获得了所选日期的 179 个柱。
因此,价格图现在由这些成交量条组成。此外,我们可以使用收盘价计算每根柱线的百分比变化和每日波动率。但是,我不打算使用跨越一整天的窗口。为了确定窗口长度,我对整个数据集采用了平均波动率和随机生成的窗口。生成的图表展示了整个数据集的窗口波动性。
现在我们已经完成了这些准备步骤,我们可以准备生成标签了。对于此演示,我选择了 50 条柱的窗口大小和 0.003% 的预期回报,这相当于基于平均价格的大约 30 美分。标记过程结束后,我们可能会发现几个相似的标签,称为交叉标签。为避免为不同的事件使用相同的标签,我们将只保留窗口的第一个柱与价格穿过窗口障碍的柱之间距离最近的标签。经过检查,我们发现我们有大约 700 个标签,均匀分布在三个类别(向上、向下和平坦)中。
现在,让我们保存我们的数据集。我们将创建两个文件:一个包含成交量条数据集,另一个文件包含每个条的报价信息。后者可能对我们的模型有用,因此值得保留。有了这个,我将暂停我们今天的讨论。我相信我们已经涵盖了广泛的基础知识,对于那些有兴趣深入研究数据标签的人,我建议您探索 Marcos Lopez de Prado 的书的第 3 章和第 4 章,它们提供了宝贵的见解。
我们的下一步将涉及特征工程并通过 tfx 管道运行所有内容。我希望尽快创建一个新的剧集来分享更多有趣的信息。
在那之前,保重,我期待我们的下一个视频。
深度学习交易策略从开始到制作。第三部分。 TFX 管道。
深度学习交易策略从开始到制作。第三部分。 TFX 管道。
丹尼斯,我很高兴欢迎你和我一起回到另一集“接近算法交易”。元旦过后我们又重新开始了实验,虽然进展缓慢,但我们仍在前进。在今天的视频中,我们将仔细查看标记数据并探索 TFX 管道。那么,让我们开始吧!
在上一个视频中,我们成功地为数据创建了标签,但我忘了向您展示它们在图表上的显示方式。作为快速复习,我们将所有数据存储在一个新的数据框中。让我们继续阅读这个数据框。
在我们的数据框中,“dir”列包含标签,而“cross_idx”列表示价格穿过我们定义的窗口时的分时编号。为了直观地表示基于这些列的开仓和平仓事件,我创建了一个简单的函数。在图表上,开仓事件由实心三角形表示,而平仓事件由空心三角形表示。
如您所见,大多数未平仓事件发生在价格图表中的局部最高点或最低点。展望未来,我们将继续使用一个小型数据集,类似于我们之前使用的数据集。此外,我会将数据集拆分为训练、评估和测试数据集。
现在我们对标签有了更好的了解,让我们继续下一步并开始使用 TFX 管道。对于那些不熟悉 TFX 的人,它代表 Tensorflow Extended,它是一个功能强大的框架,专为可扩展和高性能的机器学习任务而设计。 TFX 管道由一系列组件组成,这些组件执行机器学习工作流的各个阶段,例如数据摄取、建模、训练、服务推理和部署管理。
为了熟悉 TFX,我建议浏览官方 Tensorflow TFX 网页,其中提供了有关其组件及其互连方式的详细信息。您可以在视频说明中找到相关链接。
由于我也是 TFX 的新手,我们将在每一集中一起学习。今天,我们将重点关注管道的前四个组件。让我们简单介绍一下:
ExampleGen:管道的这个初始输入组件摄取输入数据集,并可选择将其拆分为不同的子集。在我们的例子中,它不直接支持自定义时间序列拆分,所以我手动将数据拆分为训练、评估和测试数据集。
StatisticsGen:该组件计算数据集的统计数据,提供对数据分布、标准差、缺失值等的洞察。它生成统计工件以供进一步分析。
SchemaGen:检查统计数据后,SchemaGen 组件根据观察到的数据特征创建数据模式。模式描述了我们数据的结构和属性。
ExampleValidator:此组件使用统计信息和模式作为参考来检查数据集中的异常值和缺失值。它有助于识别任何意外或不一致的数据模式。
为确保我们走在正确的轨道上,我将使用 Tensorflow 团队提供的芝加哥出租车示例作为模板。此示例演示了端到端的工作流程,包括数据分析、验证、转换、模型训练和服务。
现在,让我们将注意力转回我们自己的数据上。导入所需模块并为输入和输出数据文件夹设置必要变量后,我们可以尝试将数据加载到 TFX 管道中。输入文件夹包含评估、训练和测试数据集的子文件夹。
使用 ExampleGen 组件,我们应该能够轻松地将数据加载到管道中。但是,ExampleGen 似乎并不直接支持自定义时间序列拆分。默认情况下,它仅将数据拆分为训练集和评估集。幸运的是,我们可以手动拆分数据并配置我们自己的输入拆分配置,确保输入和输出拆分之间的一对一映射。
因此,ExampleGen 组件会生成两个工件:一个用于训练数据集,另一个用于评估数据集。让我们检查训练集的前三个元素,以验证它是否与我们的原始数据集匹配。继续,我们将 ExampleGen 组件的输出传递给 StatisticsGen 组件。该组件为训练和评估数据集生成统计工件。只需一条命令,我们就可以直观地展示数据集的统计信息,包括数据分布、标准差、缺失值等。
在这里,我们可以观察训练数据集的统计数据,获得对数据特征的宝贵见解。我们还可以检查评估集的同一组统计数据。根据统计数据,我们注意到只有 2% 的标签是非零的,这表明我们获利交易的进入事件可能是异常值。由于类之间的不平衡,这可能会在未来构成挑战。
接下来,我们使用 SchemaGen 组件自动生成数据模式。该模式源自观察到的统计数据,但如果需要,我们也可以定义自己的数据描述。输出是一个模式,它提供了我们数据结构和属性的全面描述。最后,我们到达 ExampleValidator 组件,它根据生成的统计信息和模式验证数据。它检查数据集中的任何异常或不一致。例如,在芝加哥出租车示例中,特征“_company”具有意外的字符串值。我们可以使用 ExampleValidator 来检测我们自己的数据集中的此类问题。
在我们的案例中,幸运的是,我们的数据集中没有遇到任何异常或不一致的情况。这是一个积极的迹象,表明我们的数据相对干净并且符合我们的预期。好了,我们对 TFX 的快速介绍到此结束。在下一集中,我们将深入研究其余的 TFX 组件,并探索如何转换数据和训练模型。
感谢您的收看,期待在下一个视频中见到您!
第四部分。深度学习交易策略从开始到制作。 TFX 管道 2。
第四部分。深度学习交易策略从开始到制作。 TFX 管道 2。
欢迎收看“接近算法交易”的另一集。我是丹尼斯,今天我们将继续探索 TFX 管道,作为我们交易策略构建的一部分。
在上一个视频中,我们介绍了 TFX 管道的前四个组件:ExampleGen、StatisticsGen、SchemaGen 和 ExampleValidator。这些组件为我们的管道奠定了基础,确保数据验证和一致性。
现在,让我们深入研究其余组件:Transformer、Trainer、Evaluator、ModelValidator 和 Pusher。这些组件将使我们能够转换数据、训练模型、评估其性能、根据基线验证模型,最后将经过验证的模型推送到生产环境。
但在我们继续之前,让我谈谈几个要点。虽然 TFX 管道提供了一个强大的框架,但值得注意的是它可能仍然存在一些错误,并且某些组件可能正在构建中。但是,让我们仔细研究每一步并讨论沿途的任何限制。在上一个视频中,我们成功地验证了数据,现在是时候进行转换步骤了。为此,我们将使用 TFX 提供的 Transformer 组件。
Transform 组件负责执行训练和服务一致的数据转换和特征工程。这意味着我们可以使用相同的数据转换函数来训练模型和在生产中使用它。此功能是我最初开始探索 TFX 的主要原因之一。
要开始转换过程,我们需要创建几个 Python 文件。第一个文件将包含我们的常量,例如数字特征和标签的列表。第二个文件将包含一个预处理函数 (preprocessing_fn),它是 tf.Transform 用来预处理输入数据的回调函数。在此函数中,我们将定义数据转换和特征构建步骤。现在,让我们专注于将所有数字输入特征转换为 z 分数,并将标签值从 -1、0 和 1 分别更改为 0、1 和 2。这种标签转换是必要的,因为 TensorFlow 估计器需要正值。
请务必注意,在当前版本的 TFX 中,仅支持 TensorFlow 估算器。如果您更喜欢使用 Keras 模型,则需要使用 model_to_estimator API 将其转换为估算器。尽管 TFX 0.21 版声称支持 Trainer 组件的 Keras 模型,但我在其交互式上下文功能方面遇到了一些问题。希望 TFX 团队能尽快解决这些问题,并提供稳定且功能齐全的工具。
现在,让我们继续进行数据转换。如您所见,Transform 组件需要以下参数作为输入:生成的示例、数据模式以及包含 preprocessing_fn 函数的文件的路径。转换完成后,我们可以继续创建和训练我们的模型。 Trainer 组件将负责根据我们定义的规范训练模型。
在包含模型和输入函数的 Python 文件中,我们定义了一个将由 Trainer 组件调用的 trainer_fn 函数。此函数应返回包含以下项目的字典:
在这个文件中,我们定义了 _input_fn 函数,它生成用于训练和评估的输入特征和标签。我们还有其他函数,例如构建服务输入的 _example_serving_receiver_fn 和为 TensorFlow 模型分析 (TFMA) 准备必要输入的 _eval_input_receiver_fn。
为了创建我们的估算器,我们定义了一个 build_estimator 函数。在这个函数中,我们设置输入特征集并创建我们的估计器。值得一提的是,我使用了 DNNLinearCombinedEstimator,因为 DNNClassifier 和 DNNEstimator 导致了与从 TensorFlow 1 传递特征相关的错误。我相信情况并非如此,因为我们使用的是 TensorFlow 2 方法。不幸的是,我还没有找到解决这个问题的方法。但是,线性估计器似乎工作正常。
现在我们的模型已经定义好了,我们可以使用 Trainer 组件继续训练它。如您所见,Trainer 组件需要一个包含 trainer_fn 函数的 module_file,以及其他参数,例如 transformer_examples、数据模式、转换图以及训练和评估参数。目前,我们只指定了训练和评估的步骤数。模型训练完成后,我们可以继续使用 TensorFlow 模型分析 (TFMA) 进行模型分析。在我们继续之前,请确保您已经通过提供的链接安装了 TFMA。 TFMA 允许我们对我们的模型进行分析,无论是在整个数据集上还是在特定的特征切片上。在这种情况下,我们将对三个切片进行分析:完整数据集、标签和两个特定特征。
分析完整的数据集,我们观察到 98% 的惊人准确率。然而,当基于标签检查模型的性能时,我们注意到它始终如一地预测标签 0。由于标签不平衡并且我们的模型中缺少有用的特征,因此可以预料到这一结果。然而,TFMA 提供了一种评估模型性能的便捷方法。
展望未来,我们有 ModelValidator 组件,它可以帮助我们验证导出的模型。它将新模型与基线(例如当前服务的模型)进行比较,并确定它们是否符合预定义的标准。此验证包括在评估数据集上评估模型和计算 AUC 和损失等指标。如果新模型的指标满足开发人员指定的相对于基线的标准,则该模型被认为“足够好”并被标记为如此。
最后,我们有 Pusher 组件,它检查模型是否已通过验证。如果模型满足验证标准,它会被推送到指定的文件目的地。此步骤可确保仅将经过验证的模型部署到生产环境中。
总结我们的管道,我们可以将所有组件导出到 Apache Beam 管道中。然后我们可以将所有必要的文件打包成一个 zip 存档。通过将存档中的文件解压缩到服务器上的工作目录中,我们可以执行管道。执行完成后,我们将拥有一个训练有素的模型,可以与 TensorFlow Serving 一起使用。如果您有兴趣了解如何从 Docker 容器启动和使用 TensorFlow Serving,可以在我的频道上找到视频教程。
尽管我们在本系列中介绍了很多内容,但请务必注意,当前版本的 TFX 仍然存在某些局限性。根据您的具体要求,可能有必要实施一个完全依赖于 Keras 模型的转换函数的管道。但是,我希望对 TFX 的探索能够提供有用的信息和帮助。
在下一个视频中,我们将回到制定交易策略的主要目标。请继续关注!不要忘记评论、订阅和喜欢这个视频。感谢您的收看,我们下期再见!
第五部分 GIGO。深度学习交易策略从开始到制作。
第五部分 GIGO。深度学习交易策略从开始到制作。
欢迎回到“接近算法交易”的另一集。我叫 Denis,我在这里分享我在开发深度学习交易系统方面的经验和失败。
我已经投入了大量时间来使用 TensorFlow 实现整个系统,但我必须承认我对该库的质量感到非常失望。虽然我很欣赏这个概念,但 TensorFlow 提供的文档一直令人沮丧。似乎即使是拥有博士学位的聪明人也很难编写出结构良好的文档。尽管与过去相比有所改进,但在几个方面仍然令人困惑。
但是,与我遇到的更大问题相比,文档只是一个小问题。很多功能在我尝试使用的时候根本就没有达到预期的效果,甚至连官方的例子有时也无法正常使用。这让我怀疑我是否错过了这个框架的一些核心要点。但让我们回到本视频的主题:我的失败。您可能还记得,我决定根据指定的百分比为价格变动生成标签。大多数这些标签原来是数据中的局部最小值或最大值。
在进行了一些简单的数据处理和准备之后,我创建了一个简单的 LSTM 网络并进行了测试。我的期望不是特别高,但结果确实令人失望。正如您在随附的图片中看到的那样,网络未能学到任何有意义的东西。
现在,重要的是要记住神经网络并不意味着创造奇迹。也许是时候重新评估我们的方法了。我们试图预测的事件仅占整个数据集的 2%。这些事件可以被认为是异常值,我们的简单网络很难将它们与其余数据区分开来。此外,这些事件很可能是不相关的并且有不同的原因,因此很难建立一个准确预测它们的模型。
鉴于这些挑战,很明显,我们需要专注于更好地理解数据和识别具有预测能力的特征。考虑到这一点,我决定重新审视简单的移动平均线策略。在我们最初的方法中,我们对为什么要建仓缺乏清晰的理解。但是,现在我们有了开仓策略。虽然它并不完美,但它是我们可以利用的广泛使用的策略。我在数据集中添加了两条移动平均线和一个 RSI(相对强度指数)指标,并收集了移动平均线相互交叉的所有事件。这使我们能够估计价格变动方向。
接下来,我使用与之前相同的标记方法创建了元标签,但这次,我只标记了移动平均线相互交叉的条柱。这里有一个重要的区别:因为我们已经知道头寸方向(多头或空头),所以我们标签的含义会有所不同。标签 1 表示盈利,-1 表示亏损,其他情况分配 255。使用更新的数据集和标签,我训练了一个简单的 LSTM 模型并获得了完美的 ROC(接受者操作特征)曲线。 ROC 曲线显示了分类模型在不同分类阈值下的性能。 ROC 曲线的 AUC(曲线下面积)值帮助我们评估模型区分类别的程度。
然而,在检查模型的预测时,我注意到它始终如一地预测 0 类。出现这种结果是因为我再次使用了整个数据集,而不仅仅是相关事件。我们的数据集仍然不平衡,特征缺乏预测能力。 ROC 曲线对于不平衡的数据集并不理想,因为它们可以掩盖模型在预测其他类别时的不良表现。
为了解决数据不平衡的问题,我进行了调整,只关注与开放事件相关的数据。不幸的是,即使经过这些修改,我的模型也未能展现出预测能力。它产生了与随机模型相同的结果。我还尝试了一个简单的前馈模型,它显示出稍微好一点但仍然不能令人满意的结果。总之,如您所见,如果您为模型提供质量较差的数据,深度学习就没有任何魔力。 “垃圾进,垃圾出”的原则在这种情况下适用。此外,当处理高度不平衡的数据集并且缺乏具有强大预测能力的特征时,分类模型将倾向于预测构成数据集大部分的类别。
正如我之前提到的,了解我们的数据并确定可以帮助我们找到击败市场的方法的流程对我们来说至关重要。
今天的节目到此结束。我希望你发现它有见地和信息丰富。保重,待在家里,保持健康。
第六部分。强化学习。深度学习交易策略从开始到生产
第六部分。强化学习。深度学习交易策略从开始到生产
我是丹尼斯,欢迎收看“接近海藻交易”的另一集。在我们之前的节目中,我们一直在努力使用深度学习建立一个有利可图的交易策略。让我们回顾一下到目前为止的进展。
我们首先观察市场状况以寻找效率低下的地方。一旦确定,我们就创建了简单的规则并为我们的深度学习模型准备了数据。然而,在实施我们的直接方法后,我们发现它没有产生预期的结果。这使我们意识到我们需要重新考虑我们的方法并考虑替代策略。
在今天的节目中,我们将探索一个新的方向:强化学习。强化学习在各个领域都取得了巨大的成功,在国际象棋、Dota 和围棋等游戏中超越了人类的表现。它还用于控制机器人和自动驾驶汽车。那么,为什么不将其应用于交易呢?虽然我不能保证它会成功,但它是一个值得探索的有趣途径。
首先,让我们深入了解一下强化学习并熟悉关键定义。
强化学习可以描述为通过反复试验来解决最优控制问题的学习。简单来说,它涉及找到在给定环境状态下采取的最佳行动,以最大化最终的数字奖励。为了更好地理解这个概念,让我们用一个简单的类比来形象化它。
想象一位交易员坐在显示器前买卖股票。在这里,交易者代表代理人,而图表价格和经纪人构成环境。智能体观察环境的当前状态并采取行动,例如购买股票。作为回报,代理人会收到奖励,这可能是经纪人的费用。随着环境的变化,代理人可以购买更多股票、出售或什么都不做。在交易日结束时,代理人收到最终奖励,可以是正数也可以是负数。代理人的目标是最大化这个最终奖励。
在强化学习中,我们的目标是设计可以通过与环境交互来学习的代理。现在,让我们熟悉一下我们将在整个旅程中遇到的主要定义。
Agent:做出决策、执行动作、观察环境、接收反馈并旨在最大化奖励的算法。
环境:代理所在的世界。它包含可供我们的代理人做出决策的所有可用数据。
状态:智能体感知到的环境的配置。
奖励:代理人在采取行动后收到的反馈。它是代理寻求最大化的值。重要的是,在强化学习中,奖励并不一定意味着金钱或实物奖杯。它只是一个数值,也可以是负数,我们的目标是最大化这个值。
行动:代理在给定环境中能够做的任何事情。为简单起见,让我们考虑三种操作:买入、卖出或什么都不做。
情节:整个任务的完整运行。
这些是我们将在整个旅程中使用的主要定义。我们将在以后的视频中介绍其他重要术语。
通过对强化学习的介绍,我们将继续了解环境并在下一个视频中使用 TensorFlow 创建我们自己的环境。
感谢您今天加入我的行列,我期待与您进一步探索强化学习。再见!
第七部分。强化学习。交易环境。
第七部分。强化学习。交易环境。
我是 Denis,您正在观看“Close to AlgoTrading”。在上一集中,我们简要介绍了强化学习。今天,我们将深入探讨为我们的代理创建一个简单的交易环境。让我们探讨一下细节。
首先,我们需要考虑交易环境代表什么。它是完全基于价格数据,还是我们应该结合其他因素,如完整的订单簿、新闻,甚至来自 Twitter 的谣言?这个决定将塑造我们环境的复杂性。
接下来,我们需要确定我们的代理可以执行的操作。它应该仅限于“买入”和“卖出”操作,还是可以跳过某些步骤?定义动作空间对于我们代理的决策过程至关重要。
现在,让我们讨论目标以及我们将如何定义奖励。在现实世界中,交易环境具有连续的状态空间。但是,为简单起见,让我们尽可能让环境简单明了,以便我们了解其内部工作原理和实现。
首先,我们将生成一个仅包含 20 个值的随机游走过程,而不是使用真实价格数据。这些模拟的每日价格将作为我们的输入。这一集将从这个价格序列的中间开始,这意味着初始状态将包括 10 个历史价格。剩余的不可见价格将用零填充。每一步,一个新的价格都会被添加到数组中。当所有 20 个价格都对代理可见时,这一集将结束。因此,在剧集完成之前,我们总共有 10 个步骤。
除了价格数据外,状态还将包括有关我们未平仓头寸的信息。让我们使用 one-hot 编码来表示仓位:[0,0] 表示无开仓,[1,0] 表示多头仓位,[0,1] 表示空头仓位。
考虑到典型的交易行为,我们将在没有开仓的情况下包括“买入”和“卖出”。但是,如果已经有开仓,代理只能选择跳过或平仓。因此,在这种情况下,“卖出”或“买入”操作等同于“跳过”。
我们的代理人的目标是在 10 天的时间内使损益 (PnL) 最大化。因此,我们将奖励定义为每日 PnL。
清楚地了解我们环境的结构和行为后,我们现在可以进入实施阶段。如前所述,我们将使用 TensorFlow (tf-agent) 框架。 tf-agent 团队提供了有关为 tf-agent 开发合适环境的综合指南,我建议您查看该指南以更深入地了解代码。
要创建我们的环境,我们将从继承 PyEnvironment 类开始,因为它定义了所有 Python 环境必须实现的接口。在 Init 函数中,我们将初始化变量、设置初始状态,最重要的是,指定操作和观察规范。在我们的例子中,动作空间将由四个不同的动作组成,最小值和最大值分别设置为 0 和 3。观察规范会描述环境状态,价格从0开始,没有上限。价格的数据类型将为浮动。返回操作和观察规范对于与 tf-agent 的无缝集成至关重要。
下一个要实现的重要功能是重置。此函数会将环境重置为初始状态。确保此功能的正确实施对于环境的正常运行至关重要。
现在,让我们讨论最关键的功能:step。 step 函数接收一个动作作为输入参数,并负责管理环境的状态转换。在此函数中,我们将处理所有可能的操作并计算 PnL(奖励)。该函数返回一个time_step,它由observation(agent可以观察到的环境状态的一部分来选择下一步的动作),reward(agent的学习目标),step_type(表明这个时间步是否是序列中的第一、中间或最后)和折扣。
在 step 函数中,我们有两种不同的返回场景:一种用于中间步骤,另一种用于情节的最后一步。
创建环境后,必须对其进行验证以识别和修复任何错误。 util 包提供了一个名为 validate_py_environment 的函数,可用于此目的。此外,检查环境规范将有助于确保一切都按预期运行。
在我们的环境准备就绪后,最好使用不同的操作对其进行测试以调试和验证其行为。
我使用简单的 DQN tf-agent 进行了一些测试,结果如下。在 20,000 步之后,代理表现出可接受的性能。但是,请记住,我们只有一个时间序列供代理学习,因此相对简单。如果我们引入第二个时间序列并运行 20,000 步,结果可能不会那么乐观。但是在大约 100,000 步之后,代理的性能显着提高。