创建任何交易系统的目的都是为了能够预测金融产品的市场行为,如一个货币对。预测的目标可以是不同的。我们在此限定为预测货币的走势,或者更准确的说是预测货币报价的涨(多头)跌(空头)。
要预测货币价格走势,交易者通常在图标上附加一些指标,以期找到一种可用于预测的模式。
本文探讨使用R统计分析系统中的Rattle包,来自动选取相关模式进行价格行为预测。
我们使用R这一理想的金融市场预测工具,来对货币对价格行为进行预测。话说,R主要是一种给有经验的统计人员使用的编程语言,对许多交易者来说较难掌握。R语言的复杂性在于,用于预测的工具非常多并且分散在许多R的基本功能工具包中。
Rattle(简单易学的R语言分析工具)集成了一系列R语言包,对于交易系统开发者来说非常重要,但初学者用起来并不容易。你不必了解掌握R语言就能开始使用Rattle包。对Rattle报的使用将用R语言来编写,将可以被用于开发真实的交易系统。然而,在这个阶段就需要对R语言有所了解。
任何情况下,在交易系统设计的阶段,Rattle是不可替代的工具。它能够让新手快速的看到各种策略想法的结果并且使用之。
Rattle (Williams, 2009) 是一个开源的软件包,它是R的一部分(R开发小组,2011)。因为它是免费软件,Rattle的R语言源代码没有使用限制。Rattle源代码用C语言编写,鼓励用户学习、测试及扩展代码。
本文的计算结果都是基于EURUSD, GBPUSD, USDCHF, USDJPY, EURGBP, USDCAD这六个货币对在H1时间框架下从 10.01.2011 到 24.12.2013 的收盘价。这组数据有超过18000个K线组成,因此计算结果是可靠的。基于上面货币对的数据集用于搜寻预测多空的模式。
原始报价数据集在文件kot60_110101_131231_UA.txt中。
2.1. 创建目标变量
首先我们要准确的确定我们要预测的对象。虽然看上去很简单,但是选择正确的预测目标以及用于预测的数据集合是非常关键的。
预测趋势的目的是基于进行趋势交易的期望。
根据“趋势”的定义,所谓上升趋势就是后续的价格比前面K线的价格高,反之则为下降趋势。因此,有必要根据趋势的定义来进行货币对的价格预测。如果EURUSD的初始价格是1.3500,预测价格是1.3550,那么这是上升趋势则立即买入。
而然,订单为“买”和“卖”,预测是针对价格水平的。例如,价格水平在交易系统中用于预测突破。为了实现趋势交易的想法,需进行一次额外的价格对比。显然,我们预测的东西和想要做的交易不是一回事。
然而,如果交易系统被设计为趋势跟随,那么模型就用于预测趋势。模型必须经过训练来识别趋势,目标变量只有两个值“买”和“卖”。在代码中目标变量为“1”和“-1”。
使用源数据集计算金融标的价格的模型和将源数据集进行分类的模型之间有根本的区别。第一种类型属于回归模型,第二种属于聚类模型。
回归类型的预测模型用于计算一些未来的值。当未来来到时,我们将预测值和实际值进行对比。
聚类类型的预测模型用于计算预测时一组接收到的源数据将被归于哪个类别。就是“多”和“空”两种类型。如其他聚类类型一样,这两个类型没有任何特定的值。因此,“多”类型无法和“空”类型进行对比。虽然为了简化起见我们将“多”编码成“1”,“空”编码成“0”,但这并不是说“多”比“空”大。为了强调这点,对于这种定性的变量,R和Rattle中定义了一种特定的分类变量。
多和空作为目标变量并不存在,这就是和下面描述的独立变量之间的主要区别。这和我们将要预测当下并不存在的将来事件相吻合。我们很容易基于历史数据绘制趋势,因为我们已知道将来和过去的关系。
在历史数据中标识趋势,我们用ZigZag指标。对于历史数据来说这是一个很好的指标,但对于实时数据就没有用了,因为经常会对前一个极点进行重绘。历史数据是静态的,因此我们能用这个指标画出非常漂亮的趋势线。
参数“反转点之间的间距”为0.0035的ZigZag指标用于计算目标变量。图. 1 为结果。
图 1. ZigZag指标
现在指标值被转化为“多” = 1 和 “空” = 0。
结果显示在图2上。
图 2. 分类形式的ZigZag指标
让我们对目标值做最后的操作。如果我们将ZigZag指标左移,则当前K线将对应ZigZag指标的未来值。本文中平移1根K线,相当于用一小时前的数据来预测。
可以平移更多的K线,相应于预测更多的K线。本方法有别于其他预测方法,在累积预测误差下,前一个值可用于预测多个未来值。
本文中提出的模型及一般分类模型不累积误差。在分类模型中,提前预测2根K线有它自身的预测误差,和任何提前预测1根k线的方法都没有关系。
2.2. 创建独立变量
因为它们来自于外部模型,因此称作独立变量或者预测器。他们是外部的可测变量或者基于外部变量计算的变量。任何经济和金融数据包括货币汇率都是独立变量,因为它们的值是市场行为的结果。技术指标的值也是这类变量,因为它们是基于报价计算的。
独立变量的选择和目标变量的选择一样重要。事实上,模型的成功与否取决于独立变量的选择。模型开发的绝大多数时间都是用在分析和选择独立参数组上。
源文件kot60_110101_131231_UA中的变量包含六种货币的报价、时间和日期,能用于预测。
从本方法的角度看,时间和日期信息更为有用。时间和日期一直被尝试用于交易系统的设计中。在我们的模型中,一些基于时间和星期的隐藏的货币报价信息能够被分类模型自动识别出来。这里唯一需要做的就是将这两个变量转换成类型形式。时间变换为24个分类,日期变换为5个分类变量对应一周中的星期几。
除了用于预测的原始因子,我们还将创造在我看来能够揭示源报价中存在的趋势的额外预测因子。我们将使用众所周知的指标来创建额外预测因子。
下面的指标将被引用:5,10 和 15; MACD(12,26,9),周期为 14,21,28 的RSI指标。在它们之上,我们将使用报价的增量和移动平均。所有这些转换都将被应用于六个货币对的报价。
ZigZag指标将被包含在独立变量中,用于辅助目的。它不会用于模型的开发,因为对应右侧远方K线的指标值是未知的。
因此,我们得到88个独立变量,一个目标变量和一个辅助变量(ZigZag)。每一个变量的数据量为18083跟K线。
此数据集为R工作空间格式,能够在本文的附件TC.RData中找到。这个数据集能够通过如下方式使用:
Rattle包提供一系列预处理工具,或智能数据处理 - 数据挖掘。
3.1. 输入参数预览
执行上述命令后,让我们看看接下来能够干什么。
结果见图 3。
图 3. Rattle首页
我们从Data页切换到Log页,在Rattle中开发模型。
Rattle的首页是Data。由命名不难看出此页加载数据,用于后续操作。
我们对Spreadsheets和R Dataset两个按钮尤其感兴趣。
Spreadsheets按钮可用于上传Excel文件。如果读者想测试他们的想法,可以用他们自己的Excel文件在Rattle中做测试。
要重现本文所述或者使用本文附件原始数据执行一些额外任务,请使用R Dataset按钮。此按钮将文件以R格式加载。文件叫做"Working Directory" 或 "Work file"。它们的后缀名为.RData。文件能够上传到R,并点击此按钮后变为可用。
上传我们准备好的文件,得图4上半部分以及图5的下半部分。
图 4. 源文件的上半部分
图. 5. 源文件下半部分
3.2. 带独立变量的目标变量相关性
注意。“Run”按钮起关键作用。所有的操作都准备好了但并未执行。要执行任请按“Run”按钮。要重复执行本文中的操作,每次都要按下此按钮。
图4显示了变量列表,他们的特性及这些变量的用途。因为我们不想在模型中使用ZigZag指标,我们就将其设置为Ignore。
其他变量都被用作存储输入参数,除了最后一个,用作目标变量。
“Partition”按钮在证实模型结果的授信水平上发挥重要作用。数据集在需要的时候可以用这个按钮分割为三个部分。用于训练、验证和测试模型的数据集的比例在此阶段确认。
在下一阶段,确定生成伪随机数的种子。例如,从源数据集中随机选择70%的源数据用作训练数据集。另外两个15%(如我们的情况)也是随机的K线序列。
因此,改变源数据集的生成种子,就能够获取无限多的训练和其他数据集。
图. 6. 变量的相关性
在接收到的表中找到名称为ZZ.35的列。下表样例取自此列。
变量 | ZZ.35 |
---|---|
RSI_cad.14 | -0.0104122177 |
JPY.dif2 | -0.0088412685 |
EUR.dif3 | -0.0052379279 |
CHF.dif3 | -0.0049692265 |
GBP.dif3 | -0.0047409208 |
GBP.dif1 | 0.0044691430 |
MA_cad.15.dif1 | -0.0039004722 |
JPY.dif1 | -0.0023831247 |
GBP.dif2 | -0.0015356091 |
EUR.dif2 | -0.0013759749 |
CHF.dif2 | -0.0012447101 |
EUR.dif1 | 0.0005863149 |
MA_cad.10.dif1 | 0.0023981433 |
CHF.dif1 | 0.0024543973 |
MA_gbp.5.dif1 | 0.0043757197 |
MA_cad.5.dif1 | 0.0075424397 |
MA_gbp.10.dif1 | 0.0094964069 |
EURGBP.dif1 | 0.0095990416 |
CAD.dif1 | 0.0110571043 |
表1 变量相关性
如我们所见,有很多变量同ZZ.35的相关性小于0.01. 小于0.1的相关性无法得出独立变量对于目标变量产生影响的结论。
在这一阶段我们要注意这个事实,用它来对模型进行恰当的评估。
在分类模型中,预测因子对于目标变量的影响程度起到关键作用。在相关性低的水平,预测因子被认为是模型中的噪声,需要重新训练。当模型考虑细节和预测因子对于目标变量的非显著性时,就需要重新训练。
不存在建议的相关性水平。通常使用统计数字 – 5%。实际上是不正确的。移除模型中被认为是噪声的预测因子,可以减小预测误差。移除模型中的非噪声因子,会导致预测误差的增加。因此,模型的预测因子列表需通过实验来确立。
3.3. 尺度
某些模型,如支持向量机(SVM),对预测因子的跨度非常敏感,如下说明。例如,货币对EURUSD的数据在0.5内变动,而USDJPY的数据在数十单位内变动。要去排除测因子不同尺度的影响,需要将他们在Transform页中归一化到同一尺度下。最好将预测因子的波动都限定在0-1之间。
要进行尺度缩放,选择Transform/Rescale/Scale [0-1]。之后我们勾选左右变量并按下“Run”按钮。
3.4. 转换成分类形式
转换成分类形式就是说将数字化的变量值转换成一些分类因子。RSI指标是第一个被转换为多级因子的指标。当其值接近0或者100时被认为趋势即将反转。
要将RSI指标值变换为分类形式,选择:Transform/Recode/KMeans。之后,将因子等级设为8. 勾选所有RSI指标并按 "Run"。
当设置ZZ.35变量为Ignore后,我们进入开发模型阶段。
下面的模型在Rattle中:
除了分类模型的基本区别之外,(我们不仅仅讨论Rattle中提供的)他们都有下述特点。
让我们选择一个含字符串的训练序列(共18030个),包含预测因子(88个)以及目标变量值("long"和"short")。
任何的分类算法都是为了解决一个问题,即从对应于“多”的预测因子组合值中将对应于“空”的预测因子组合值分离出来。这就是模型的训练阶段。
紧随其后的就是模型的验证。
由于我们将源数据集分成三部分,我们使用另一个数据集并考虑将预测因子的组合同在训练阶段的数据进行比较。如果可归类于“多”或“空”,则任何预测因子的组合都会被建立。于验证数据集包含那些已知的值,其结果与实际数据进行比较。实际的多空头寸和预测值之间的比就是预测误差。
如果结果不满足我们的要求,就返回到智能数据分析阶段来改进结果。不幸的是,这一阶段的预测质量完全取决于交易者的经验。对源数据集进行改变,然后再重新开发模型。
如果从训练和验证数据集上获得的结果令人满意,那么我们到测试数据集上验证模型,测试数据集是还没有使用过的。
高质量的模型不仅预测误差要小,不同数据集在此误差下的预测值的差异也要小。这说明该模型的鲁棒性及无需重新训练或者如交易者所称的超调。
本文将仅详细探讨一个随机森林模型。
5.1. 总结
交易算法如下。一组指标加入到货币对的报价中,通过分析当前报价和指标数据来做出交易决定。
在最简单的交易系统“移动平均”系统中,如果当前价格高于移动平均价格则买入,低于则卖出。可以添加额外的数据如RSI指标数据。结果,交易者得到一个决策树。在树的叶子节点是货币对的报价,移动平均值和RSI指标。树根仅包含两个值 — “买”和“卖”。
上述建立决策树的过程在分类树模型中自动执行。最终仅有一颗树,或者按交易者的话说,一种模式。
单一树的算法无法建立精确的模型,但多样性会带来不稳定,这一现象在建立独立的决策树时能见到。
读者可以在Rattle中的树形模型中自行验证这一说法。本模型实现上述建立树的算法。
随机森林模型中包含了许多分类树(模式),不仅仅是一个。因此,随机森林具有更高的抗数据变化和坑干扰能力(对目标变量的影响很小)。
所使用的随机森林算法的随机性表现在随机选择表中的行(观测值)和预测因子。和独立树状分类器相比,这种随机选择能够有效的抗噪声,异常值和避免重新训练。
也可能显著的提升计算效率。要建立一个独立决策树,模型的开发者可以从训练数据集中随机选取一组观察数据。此外,当构建树过程中的每个节点时,在确定数据集的最佳分割比例时,仅考虑所有可用变量的一小部分。这样的话对计算性能的要求就大为降低了。
因此,有理由开发相信随机森林树模型是个很好的选择。经常需要对数据进行预处理,因为需要对数据进行归一化以及滤除一些异常值。无需选择变量,因为算法会有效的选择自己的变量集。使用两组随机数据集(观察和预测因子)建立了许多决策树,因此每棵树都是一个有效的独立模型。此模型无需在测试数据集上重新训练。
随机森林算法通常会产生100到500棵树。当最终模型确定后,每棵树做出的决策和整体做出的决策是一致的。树集最终的决策将是占多数的树的决策。如果100颗树中有51颗为“多”,则“多”值将被接受,虽然可信度不高。
5.2. 算法
5.2.1. 用数据集给出一个例子
通过使用引导聚合或者在样本生成过程中引入随机性,随机决策树的构建算法会生成很多决策树。引导聚合的思想是将观察值的随机样本聚集起来打包。许多数据包以随机的方式生成,包含从训练数据集的观察数据中选中的数据。
随机聚合到数据包中。也就是说每个观察数据都有机会出现在特定的包中。样本大小往往和完整的数据集一样。实践表明三分之二的观察数据将被包含在包中(含重复的),三分之一将不会被包含。每一个观察数据集都将被用作训练数据来构建决策树。另外部分的数据将被作为独立样本用于评估最终结果。
5.2.2. 预测因子的选择
用于分隔数据集的预测因子的选择,是生成随机决策树的第二个基本的元素。在创建独立决策节点的每一步中,例如,在树的每个分离点上,通常只会选择随机的很少的预测因子。仅考虑分离点上选择的预测因子。使用不同的预测因子集来构建树的每一个节点。
5.2.3. 随机性
生成数据和变量的随机集合,他们接收由数据子集确定的不同的决策树。这样能够将树的组合作为不同能力层次协同运作的专家团队,来获得最可靠的预测结果。
采样生成还有另一个有意的优点 - 计算效率。当分割数据集时仅考虑所有预测因子的一小部分,能够大大减少所需的计算资源。
创建每一颗决策树,生成随机树的算法通常不会削减决策树。可以将一个带超调树的随机森林开发为一个非常好的预测模型,其在新的数据上有良好的表现。
5.2.4. 合成计算
当将许多决策树作为一个模型对待时,在形成最终决策上,每颗树的重要程度相等。结果由简单多数原则决定。也就是说占比51%和占比99%将产生一样的结果,例如“多”。
Rattle的计算只是部分,因为用户最终得到的结果为某种类型。如果在R中使用该模型,那么就能能得到类型概率形式的结果。
5.3. 开发一个随机森林模型
要创建一个模型,选择Model/Forest。使用我们的源数据计算模型将会花费几分钟的时间。
我将把计算结果分为几个部分逐一说明。
让我们来回顾一下图7的结果。
图. 7. 随机森林模型调整后结果的上半部分。
这幅图上的一些信息必须突出说明下。
此处TREND是目标变量。
本模型生成了500颗树。在树的每个分裂节点上,使用9个预测因子(变量)。另外,Errors按钮和OOB ROC使我们特别感兴趣的。
预测误差看上去像这样:
OOB 误差估计:15.97%
混和矩阵:
0 | 1 | class.error | |
---|---|---|---|
0 | 4960 | 1163 | 0.1899396 |
1 | 858 | 5677 | 0.1312930 |
表 2. 训练集的误差矩阵列表
应该被理解为“包外错误率15.97%”。
预测结果的错误率非常明显。搞清楚错误率是如何获得非常重要,或者准确的说,是否“袋外”获得。仅仅部分训练数据用于构建此模型。此模型自己创造70%源数据集。约60%训练数据集用于构建此模型,其余40%不被使用。这40%的数据被称为“袋外”。15.97%的预测误差是由这些数据得到。
继续。
偶然性表和误差矩阵说明如下。
顶行包含预测的空和多头寸。左边一列是真实的多空头寸,来自历史数据上的ZigZag指标。
坐标(0,0)上的值4960,是预测正确的做空和做多的头寸数量。下一个值1163是空被预测为了多的头寸数量。
坐标(1,0)上的值858,是多被预测为了空的头寸数量。值5677是预测正确的做多头寸数量。
然后让我们来看看模型结果。
下面是包含模型所有变量的大表中的一些行。这是一个重要变量列表。
0 | 1 | MeanDecreaseAccuracy | MeanDecreaseGini | |
---|---|---|---|---|
MA_eur.5.dif1 | 42.97 | 41.85 | 54.86 | 321.86 |
EUR.dif3 | 37.21 | 46.38 | 51.80 | 177.34 |
RSI_eur.14 | 37.70 | 40.11 | 50.75 | 254.61 |
EUR.dif2 | 24.66 | 31.64 | 38.24 | 110.83 |
MA_eur.10.dif1 | 22.94 | 25.39 | 31.48 | 193.08 |
CHF.dif3 | 22.91 | 23.42 | 30.15 | 73.36 |
MA_chf.5.dif1 | 21.81 | 23.24 | 29.56 | 135.34 |
表 3. 随机森林模型中变量重要性
变量的重要性有一些评估方式。此处“重要性”反应在特定变量对目标变量的影响程度。影响越大,此变量越发“重要”。
此表提供数据依据,用于从模型中剔除最不重要的值。在特定的统计和特定分类下,模型越简单越好,只要模型准确率变化不大。
在Model标签页中,Errors按钮是最后一个重要的。按下它我们得到如图.8。
图. 8. 模型误差和树数量的关系
模型效率的评估在Evaluate标签页中,在Rattle中提供了相关选项。
我们应该使用误差矩阵,原先被称为似然表,在模型效率评估可选项列表中。
当你从Model标签页来到Evaluate标签页,最新创建的模型将被自动标记。和Rattle中的一般运作原则相符:我们创建并设立一个模型然后在Evaluate标签页中研究其效率。
要评估模型,必须确定用于执行检验的数据集。Rattle界面中下一行选项是可选的源数据集。
Data的前四个选项对应于分割Data标签页中的数据集。选项为Training(训练), Validation(检验), Test(测试) 和 Full(整个数据集)。将数据集分割为训练集,效验集和测试集已经讨论过了。
第一个选项是在训练集上验证模型。通常这并不是好主意。在训练数据集上评估模型的问题在于,模型本身就是从训练集上建立的。模型会取得很好的结果,因为一开始我们就是基于此创建的。模型因被用于之前未知的数据。
需要一种方法来保证模型在新数据上的表现。同时,我们得到一个实际的模型误差评级,它反映了模型和实际数据的预测间的差异。此误差评级是针对未知数据而非训练数据,这是最好的评估模型效率的方法。
我们使用效验数据集在模型创建和配置阶段来评估其效率。因此当模型创建后,其效果将在验证数据集上被检验。模型创建中的某些配置项可以改变。我们将基于验证数据集的新模型的效率和旧模型进行比较。在这个意义上验证数据集用于最终模型的开发。然而,如果依赖于验证数据集,仍将存在对模型效率评估的偏差。
测试数据集从头至尾不参与模型的创建。一但我们基于训练和检验数据集确定“最佳”模型后,我们就能够在测试数据集上评估模型的效率。这是针对新数据的模型效率的评估。第四个选项是使用完整数据集来评估模型。完整数据集包括训练,检验和测试数据集。这个选项仅用于满足好奇心,显然无法获取准确的模型数据。
还有一种可能就是源数据通过采样获取。如果Score选项作为评估类型选中的话。这种情况下会打开一个可输入附加数据的窗口。
误差矩阵将用于预测目标变量。
误差矩阵对比展现实际结果和预测结果。有两个表。第一个以绝对数量的形式展现结果,第二个以百分比形式展现结果。
误差矩阵能在Rattle中的Evaluate(评估)标签页中找到。按“Run”按钮将在选定的数据集上,用已选模型来预测此数据集上每个观测值的结果。然后预测值和实际观测值进行比较。
图.9代表先前计算的随机森林树的误差矩阵。
图. 9. 随机森林模型的评估结果
图表显示平均误差为0.167,例如16.7%。在训练阶段预测误差为15.97%。我们可以认为两者相等。
让我们在测试数据集上计算误差。结果如下:
在TC[测试]上的随机森林树模型的误差矩阵(计数):
预测 | 预测 | |
---|---|---|
实际 | 0 | 1 |
0 | 1016 | 256 |
1 | 193 | 1248 |
表 4. 绝对数量形式的随机森林树误差矩阵(测试数据集)
在TC[测试]上的随机森林树模型的误差矩阵(百分比):
预测 | 预测 | ||
---|---|---|---|
实际 | 0 | 1 | 误差 |
0 | 0.37 | 0.09 | 0.20 |
1 | 0.07 | 0.46 | 0.13 |
表 5. 绝对数量形式的随机森林树误差矩阵(测试数据集)
总误差:0.1654994,平均分类误差:0.1649244
预测误差为16.4%。
这三个数字大致相等,模型结果是可以接受的。
请注意,由Rattle计算生成的模型,必须要在MetaTrader4或MetaTrader5的策略测试器中检验其效率。然后应该在模拟账户做测试并用小额交易量在实盘帐户上做测试。只有所有测试都完成后我们才能得到模型的最终效果。
当我们研究预测因子和随机变量ZZ.35的相关性时,我们发现大量的预测因子和目标变量的相关性都很弱。
让我们剔除相关系数小于0.01的预测因子。在Data标签页中将相关预测因子设置为Ignore,然后在Model标签页中重新计算随机森林模型。
我们获得如下结果:
虽然误差没有显著减少,但是不同数据集上的预测误差差异下降了。这是模型稳定的标志。
你可以继续根据相关系数表格来剔除预测因子。使用由模型计算而得的预测因子重要性表格,能够改进模型的效率,例如,预测误差下降。
直到剔除一个预测因子后模型的效率显著恶化后,结束剔除预测因子的工作。当你在一个给定数量的预测因子下获得了一个最小且最有效的模型后,就可以随时停止优化了。
理论上,使用Rattle交易的方法如下:在Excel中为Rattle准备的输入数据可以通过一些外部工具获取。在交易市场关闭后,交易者将获取到的价格数据并存入源文件中。几分钟后,下一天的预测已经做好,并且第二天开盘后即可使用。
对于日内交易,MetaTrader4或者类似交易终端是必须的。
要在Rattle中进行自动化或半自动化交易,需要下列组织构成:
在Rattle中训练六种可用模型的方法已经在上面介绍过了。R中的分类模型有150个之多,但是Rattle无法使用他们。
R和MetaTrader4终端交互的类库可以在代码库中找到:mt4R for new MQL4。
对应于训练后模型的R代码在日志(Log标签页)中。所有模型发开相关的操作都以R代码的形式出现,这就是可用于实盘交易的。
无论是交易新手和有经验的交易者都会发现,本文对于交易系统的初步评价以及选择都非常有用。
使用Rattle开发一个人工智能交易系统的主要挑战是如何正确选择相应的目标变量以及预测因子。有经验的交易者已经有这方面的知识了,初学者则需要Rattle方面的必要经验。
本社区仅针对特定人员开放
查看需注册登录并通过风险意识测评
5秒后跳转登录页面...
移动端课程