
神经网络实验(第 6 部分):自给自足的价格预测工具 — 感知器
概述
感知器是一种机器学习技术,可用于预测市场价格。对于那些努力获得价格预测的交易者和投资者来说,这是一个实用的工具。
一般概念
感知器是一个简单的神经网络,由一个或多个神经元组成,这些神经元接受输入数据,进行处理,并提供输出。 它由弗兰克·罗森布拉特(Frank Rosenblatt)于 1957 年开发,此后在各个领域得到了广泛的应用,包括金融分析和股票市场预测。
感知器可解决分类和回归问题,包括价格预测。 在最简单的情况下,感知器由单个神经元组成,该神经元接受多个输入变量,并产生单个输出信号。 例如,为了预测外汇市场的价格,您可以采用以下输入数据:汇率,交易量,消费者价格指数、和其它因素。 数据处理完毕之后,神经元生成一个输出信号,其为货币对的预测。
感知器工作原理
感知器的操作基于监督学习原理。 这意味着感知器依据历史数据进行训练,从而判定各种市场因素和价格之间的关系。 该数据用于调整神经元的权重,从而判定每个输入因子对预测股票价格的重要性。
感知器可以在学习和预测模式下运行。 在训练模式下,感知器将外汇市场中的历史数据和实际价格作为输入,然后以最小化预测误差的方式调整其权重。
运用感知器预测外汇价格的益处
- 使用感知器预测外汇价格有若干优点。 首先,感知器能够适应市场的变化,并根据新的数据调整其预测。 这使得它比传统的数据分析方法,如统计分析和时间序列等更有效,后者不能始终适应市场变化。
- 其次,感知器可以处理大量输入数据,这令其可参考影响价格的许众不同因素。 由此可导致比传统数据分析方法更准确的价格预测。
- 第三,感知器可以依据大量数据进行训练,这允许它基于大量历史数据进行训练和价格预测。
然而,运用感知器来预测价格也有一些缺点。 首先,感知器可能很容易受到数据中的峰值或误差的影响,这可能导致价格预测不准确。 其次,训练感知器需要大量的历史数据。 如果历史数据不能充分代表当前的市场情况,那么感知器预测可能不准确。
此外,当感知器对历史数据过于敏感而无法适应新的市场变化时,可能会出现过度拟合的问题。 为了应对这个问题,可以使用各种监管技术,例如 L1 和 L2 正则化,这有助于控制神经元权重,并防止过度拟合。
感知器可以与其它预测方法,如自回归模型(ARIMA) 或指数平滑结合使用,从而获得更准确、更可靠的预测。 例如,您可以使用感知器来预测长期价格趋势,并使用 ARIMA 或指数平滑来预测短期价格趋势。请记住,用于训练感知器的历史数据可能与当前的市场条件并不匹配。 在这种情况下,预测结果可能并不准确。 因此,应定期更新模型,以便充分反映市场变化。
优化感知器的参数
感知器是最简单的神经网络类型之一,它由输入层、隐藏层和输出层组成。 它可用于各种任务,例如分类、回归或图像处理。 不过,为了令感知器有效工作,必须正确为其选择参数。
感知器参数是定义其结构和行为的数值。 它们包括隐藏层的数量,每层中的神经元数量,激活函数,学习率、等等。 正确调整的参数令感知器获得最佳结果。
此处是一些可以优化的感知器参数:
Number of hidden layers
隐藏层的数量决定了模型的复杂性。 如果模型太简单,那么它可能无法胜任任务;如果它太复杂,则可能发生过度拟合。 因此,应根据要解决的问题以最优方式选择隐藏层的数量。
Number of neurons in each layer
每层中神经元的数量也会影响模型的复杂性。 大量的神经元可以提高预测的准确性,但同时会增加训练时间。 神经元的数量应该针对特定任务进行优化。
以下示例事关 Number of hidden layers,Number of neurons in each layer。 此处用到了 NeuralNets 函数库:
int OnInit() { // set the number of neurons in the input, hidden and output layers int n_inputs = 2; int n_hidden = 3; int n_outputs = 1; // create a perceptron object CNeuralNet ann; // add layers ann.AddLayer(n_inputs); ann.AddLayer(n_hidden, CNeuralNet::TANH); ann.AddLayer(n_outputs, CNeuralNet::TANH); // set learning parameters ann.SetLearningRate(0.1); ann.SetMomentum(0.9); ann.SetMaxEpochs(1000); ann.SetDesiredAccuracy(90); // create arrays to store input and target values double inputs[][2] = {{0,0}, {0,1}, {1,0}, {1,1}}; double targets[] = {0, 1, 1, 0}; // train the perceptron ann.Train((double*)inputs, targets, 4); // test the perceptron double output; ann.Compute((double*)inputs[0], output); Print("0 XOR 0 = ", output); ann.Compute((double*)inputs[1], output); Print("0 XOR 1 = ", output); ann.Compute((double*)inputs[2], output); Print("1 XOR 0 = ", output); ann.Compute((double*)inputs[3], output); Print("1 XOR 1 = ", output); }
在这个例子中,我们创建了一个含有两个输入神经元、三个隐藏神经元、和一个输出神经元的感知器。 我们还设置训练参数,例如训练速率、矩和最大世代。 接下来,创建存储输入和目标值的数组,并依据该数据训练感知器。 在四个不同的输入上测试感知器后,在屏幕上显示结果。
Activation function
激活函数判定神经元应如何响应输入。 有许多激活函数,例如 sigmoid、ReLU、和双曲正切。 激活函数的选择还应取决于所要解决的问题。
下面是选择不同激活函数的示例:
int OnInit() { // set the number of neurons in the input and output layers int n_inputs = 2; int n_outputs = 1; // create a perceptron object CNeuralNet ann; // add layers ann.AddLayer(n_inputs); ann.AddLayer(3, CNeuralNet::TANH); ann.AddLayer(n_outputs, CNeuralNet::SIGMOID); // set learning parameters ann.SetLearningRate(0.1); ann.SetMomentum(0.9); ann.SetMaxEpochs(1000); ann.SetDesiredAccuracy(90); // create arrays to store input and target values double inputs[][2] = {{0,0}, {0,1}, {1,0}, {1,1}}; double targets[] = {0, 1, 1, 0}; // train the perceptron ann.Train((double*)inputs, targets, 4); // test the perceptron double output; ann.Compute((double*)inputs[0], output); Print("0 XOR 0 = ", output); ann.Compute((double*)inputs[1], output); Print("0 XOR 1 = ", output); ann.Compute((double*)inputs[2], output); Print("1 XOR 0 = ", output); ann.Compute((double*)inputs[3], output); Print("1 XOR 1 = ", output); }
在这个例子中,我们添加一个由三个神经元组成的隐藏层,并为隐藏层选择 “tanh” 激活函数,为输出层选择 “sigmoid”。
Training rate
训练率决定了神经网络改变其权重的速度。 训练率太高会导致溢出,而该数值太低可能会导致训练时间过长。 您需要选择最适合特定任务的训练率。
Regularization
监管是一种用于防止过度拟合的方法。 它包括向误差函数添加附加项,从而惩罚模型的权重过大。 监管减少了预测的盲目扩散,提高了模型的普适能力。
Weight initialization
权重初始化是感知器中每个神经元的权重初始设置。 不正确的初始化权重可能会导致模型收敛到误差函数的局部最小值,而非全局最小值。 因此,有必要选择正确的方法来初始化权重。
Batch size
批量规模决定了在一个训练迭代中将用到多少个数据样本。 批量规模太小可能会减慢学习过程,而批量规模太大会导致内存溢出。 针对特定任务选择最适合的批量规模。
Optimizer
优化器是一种算法,用于在训练期间更新模型的权重。 有许多优化器,例如随机梯度下降,Adam 和 RMSprop。 每个优化器都有其优点和缺点,最佳优化器的选择取决于任务。
通常,感知器的最佳参数取决于所要解决的问题。 有必要尝试不同的参数值,以便找到特定任务的最优集合。 机器学习是迭代改进模型的过程,正确调整的参数是获得更好结果的关键。
将指标和价格传递给感知器进行市场分析
指标是用于分析市场并帮助识别趋势、入场和离场时机、以及支撑位和阻力位的数学方程式。 可以在感知器中用于分析外汇市场的一些最常见指标包括:
- 移动平均线;
- 相对强弱指数(RSI);
- 随机振荡器;
- MACD(移动平均收敛扩散)。
将收盘价和指标传递给感知器,可令模型参考市场分析的各个方面,并创建更准确的价格预测。 例如,模型可利用移动平均线来判定整体市场趋势,然后利用随机振荡器来判定入场切入点。
不过,将大量指标传递给感知器可能会导致数据冗余问题。 数据冗余会导致模型过度拟合,以及普适能力低下。 因此,有必要针对特定的市场分析任务选择最明显的指标。
此外,数据传输到感知器需要相应的数据预处理。 例如,如果数据包含缺失值,则需要解决此问题,例如,用平均值填充缺失值、或删除含有缺失值的行。
有必要为感知器选择最优参数,如此模型就能够最好地训练和预测价格。 需要优化的一些主要参数包括:
- The number of neurons in the hidden layer;
- Neuron activation function;
- Number of learning epochs;
- The size of data mini batches for training.
最佳参数的选择可以通过反复试验,或使用优化算法(如遗传算法,或基于梯度的优化方法)来完成。
示例和实际应用
在此,我们将研究一个基于简单感知器的 EA 示例,该感知器将两条移动平均线指标之间的距离作为输入传递。 传递周期为 1 和 24 的两条移动平均线指标之间的距离。 类型为指数移动平均线,应用收盘价,但首先把这些数值转换为点数的常规化数值。
在输入里取蜡烛序号 1、4、7、10(4 个参数)上的距离。 在感知器输出中,我们得到两个值 — 开仓买入,和开仓卖出。 这些条件不是标准条件。 它们只是作为感知器的一个例子给出。 我们当前的示例将尽可能简单。
在此,我将提供优化和前向验证测试的所有参数,以免在文本中重复:- 外汇市场;
- 货币对 EURUSD;
- 时间帧 H1;
- 止损 300,止盈 600; 在 EA 里止盈设为 止损的两倍;
- "仅开盘价","快速(基于遗传算法)",以及 "最大复杂准则" 优化和测试模式; 常重要的是使用“最大复杂准则”模式,与“最大盈利能力”相比,它展示出更稳定和有利可图的结果;
- 优化范围 3 年。 从 2019.04.19 至 2022.04.19。 3 年并非是一个可靠的准则。 您可以自行试验此参数;
- 前向验证测试范围为 1 年。 从 2022.04.19 至 2023.04.19。
- 初始本金 10000 单位;
- 杠杆 1:500。
优化:
EA 优化参数:
EA 优化结果:
以下是前向验证测试结果前 5 名:
结束语
总之,感知器是外汇市场价格预测的强大工具。 它可以单独使用,也可与其它数据分析方法结合使用。 然而,为了在运用感知器预测外汇价格时获得最佳结果,必须意识到其局限性,并考虑历史数据的关联场景。 还必须在外汇交易方面具有一定的知识和经验,并了解与外汇交易相关的高风险。
感谢您的关注!
本文由MetaQuotes Ltd译自俄文
原文地址: https://www.mql5.com/ru/articles/12515



嗨,罗曼、
两篇好文章!我刚刚第一次读了这两篇文章。
由于我还没有研究过代码,我很想知道 CNeuralNet 对象是否是您之前 Perceptron 计算的重构? 它看起来非常有趣,因为最初的角度和扇形方法在我的前瞻性测试中惨遭失败。 我使用欧元兑美元 H4 从 1/1/2020 到 1/1/0203 作为我的训练,并使用 1/1/2023 到 5/1/2023 作为我的前瞻性测试。该角度失败的原因是,在 1/2/2023左右的第一次下跌中,有停顿的延长趋势触发了该角度,但没有反转和止损并使账户破产,而您的测试完全遵循了这次下跌。 扇形方法在正向测试中没有进行任何交易。
注意安全,我期待着你的下一篇文章。
科达角
附注
我刚刚看了您的两个源文件,有一些问题。
根据您之前的 Perceptron 文章中的源代码,似乎缺少了一些部分。
提供的 EA 似乎是您的优化 EA。但是,它并没有使用我期望看到的 CNeuralNet 对象。
前向测试 EA 丢失了,因为附加 EA 没有使用 GA 优化运行的结果作为权重数组(如 EURUSD 数组)的输入。
还是我错过了您的感知器理念中的逻辑变化?
嗨,罗曼、
两篇好文章!我刚刚第一次读到这两篇文章。
由于我还没有研究过代码,我很想知道 CNeuralNet 对象是否是您之前 Perceptron 计算的重构? 它看起来非常有趣,因为最初的角度和扇形方法在我的前瞻性测试中惨遭失败。 我使用欧元兑美元 H4 从 1/1/2020 到 1/1/0203 作为我的训练,并使用 1/1/2023 到 5/1/2023 作为我的前瞻性测试。角度法失败的原因是,在 1/2023 年 1 月 2 日前后的第一次下跌中,有停顿的延长趋势触发了角度法,但并没有反转和止损并使账户破产,而您的测试则完全遵循了这次下跌。 扇形方法在前瞻性测试中没有进行任何交易。
注意安全,我期待着你的下一篇文章。
科达角
附注
我刚刚看了您的两个源文件,有一些问题。
根据您之前发表的 Perceptron 文章中的源代码,似乎缺少了一些部分。
提供的 EA 似乎是您的优化 EA。但是,它并没有使用我期望看到的 CNeuralNet 对象。
由于附加 EA 没有使用 GA 优化运行的结果作为权重数组(如 EURUSD 数组)的输入,因此缺少了前向测试 EA。
还是我错过了您的感知器理念中的逻辑变化?
你好,我的朋友。我不太理解您的意思,所以请您循序渐进地表达您的想法。优化取决于设置中使用的感知器的影响深度。每一对都有自己的结论。这也取决于通过的次数,因为它们的值是无限的。
你好,罗曼、
我很感谢您的快速回复。 我想我明白 GA 优化的原理,即在相同的时间框架内,每次运行的结果都可能不同,而且结果会因开始日期、测试时间和每对货币对的不同而不同。 但我没想到的是,当 3 年的训练运行产生 50%的利润时,EA 会在 5 天内失败,失去整个起始仓位,或者在实际运行期间不进行任何交易。
我的最终目标是开发一种波段交易感知器 EA,它的训练时间固定,在训练期最后一天之后只运行一个月。 然后,它将以相同的时间长度重新训练,但启动期将在一个月之后,然后运行第二个月的实际数据,就像滚动均线一样。我这样做的依据是我的假设,即外汇市场会逐渐改变方向,任何 "训练有素 "的网络在训练后的头几个月都会是最准确的,然后会随着市场条件的不断变化而逐渐失去准确性。 我还知道,可能会有一些开创性的市场变化会直接影响任何 "训练有素 "网络的准确性。 这种类型的变化会对所有未来的变化产生重大影响。
据我观察,角度感知器很擅长在反转发生之前感知反转的开始,但不幸的是,它也很擅长检测趋势的停顿,并在预期反转发生时进行交易,而在本案例中,反转并没有发生。由于趋势仍在继续,在实际测试运行开始时,由于大的止损单导致起始仓位亏损,从而造成重大损失。 我认为部分问题在于 100 感知器循环需要根据账户余额进行自适应调整,以降低交易总数。
在您以前的帖子中,您发布了一个用于优化的 EA (opt) 和第二个用于交易测试的 EA (trade)。 在这篇帖子中,只有一个:我的感觉是,这个 EA 可以直接用于运行 GA 优化,与您之前的 OPT 版本相对应。 但是,没有包含用于前瞻性测试的 Trade 版本。 如果这是有意为之,我可以调整这个 EA,加载 GA 结果,生成用于前瞻性测试的 EA。
除了 EA 之外,您还发布了一个类对象 NeualNet 作为包含文件,我还没有查看过。 让我感到惊讶的是 Perceptron_MA_4 EA 并没有使用这个包含文件。 我原本以为会有一个优化 EA 版本,其中包含 CNeuralNet 类,并且还使用了您发布的第 5 部分中的一种规范化技术。此外,还有一个单独的贸易版本用于前瞻性测试。 我认为创建类对象是一个非常好的方向。 作为一个对象,在 EA 中同时使用多个不同的感知器变得非常容易,例如用于交易、止损或止盈设置,或者甚至可以创建一个自适应交易策略,使用替代策略来应对平淡市场的趋势。 是的,我知道多个对象会占用大量的训练处理时间。
您好。如果您在特定任务上需要帮助,请写信给我,我会尽力提供帮助。 请私信我。
已发表文章:神经网络实验(第 6 部分):感知器作为自给自足的价格预测工具:
作者:Roman Poshtar