下载MetaTrader 5

请观看如何免费下载自动交易

有趣的脚本?
因此发布一个链接 -
让其他人评价

喜欢这个脚本? 在MetaTrader 5客户端尝试它

2016.03.29 12:45
程序库

随机震荡网络 - MetaTrader 4程序库

| Chinese English 日本語 Русский Español Deutsch Português

显示:
435
等级:
投票: 5
dpnn.dll (68 KB)

本随机震荡神经网络是以函数库的形式构建的, 用于MQL4开发的EA交易. 本函数库可以同时包含多个网络. 我曾经尝试让网络最大限度地独立, 但是我很快决定首先把一些功能放到外面进行管理以能够更好控制. 我就以这样的形式提供它. 这个网络的特点是, 它的大小能够根据情况动态改变. 网络可以通过基本(Primary)的训练然后在工作过程中还能得到训练. 在那时会有新的神经元产生, 也会有神经元调整或者死去. 针对每个类都会创建新的网络. 例如, 为了产生超买和超卖的信号, 您需要为第一种情况创建一个网络, 为第二种情况创建另外一个.

训练

网络的输入是规范化统一的向量. 输出是 [0..1] 的数字, 分别指示输入的向量是否属于此类型的网络. 同时, 如果在训练过程中, 网络没有以指定的可能性发现模式, 它会自动增加新的神经元用以记录. 如果是基本训练(Primary training), 我建议重复运行两到三次. 以便当时网络可以更好地学习发生的基本信息. 通常需要不超过5遍重复.

预测或者分类会更加准确

分类的目标是提交输入模式是否匹配网络的类型. 如果网络已经学会, 把与熊势趋势信号相反分类为牛势趋势, 则它的输出值必须接近为1. 我把这些工作留到将来, 要看EA的开发者在于它集成时的反馈再做决定.

操作网络的主要必需函数

CreateNet 函数用于创建网络.


double CreateNet(string NN, // 我们创建叫做 <NN> 的网络
int InputVectorSize, // 输入向量所需的神经元数量 <InputVectorSize>
double MinTV, // 神经元冲突的阈值
double MaxTV, // 独立的阈值
double MW, // 神经元衰弱的标准
int NL); // 神经元的生命周期 (柱数), 如果为0, 就一直存在

为了方便起见, 我决定称它们为nets. 我想提醒您, 您可以使用全部的神经元集合. 每个网络的设置在其创建时指定, 直到被删除都不会改变.

独立阈值是用来决定在训练过程中是否产生新的神经元的. 通常它等于0.95. 如果指定了比较低的值 (较小的独立程度), 网络会尝试更新, 这样不需要很多神经元就能应对大量的变数. 在这种情况下, 预测的精确性会下降. 如果 MaxTV 的值高, 网络会为几乎每个向量都创建新的神经元, 这样网络会变得很大. 网络会不断更新, 因而神经元不会产生冲突 (模式彼此间不会类似). MinTV 就是为了此目的而实现的, 我通常把它设为 2. MaxTV, MinTV 和 MW 参数值定义一次就够了. 之后如有必要, 优化程序会找到更好的参数值.

强者生存!这里也使用了同样的原则. 权重低于 MW 数值的虚弱神经元会被抛弃. 这样的神经元通常含有有害的信息, 应该死去而不是用来产生奇怪的信号.

如有必要, 您可以杀死老的神经元以去除这些"陈规陋习". 为此您应该制定神经元的生命周期柱数 (NL). 当新的神经元创建时, 它的创建时间会记录下来, 在未来您可以通过此标记删除它. 所以当把任何类型的数据输入到网络时, 时间因素是必需的.

您可以使用 DestroyNet 函数来删除网络. 这非常简单. 不要忘记删除不必要的网络, 否则它们会一直占用计算机的内存直到MetaTrader被关闭.


int DestroyNet(string NN); // 删除<NetName> 网络, 返回剩余的网络数量

我没有实现网络名称独特性的检查, 您可以创建很多同名的网络. 这些网络会通过序列号加以区分.

string NetName(int i); // 返回根据序列号取得的网络名称
int GetNetsNumber(); // 返回库中的网络总数
int NetNumber(string NetName); // 返回库中叫做 <NetName> 的网络的序列号

您应该使用TrainNet 函数来训练网络. 正确的答案可能是需要进行下单. 例如, 我们以 1 为买入信号, 而已 -1 为卖出信号. 但是因为买入和卖出是使用不同的网络, 所以在网络内不作考虑. 我们所需的是当前时间或者柱的创建时间.

double TrainNet(string NetName,
double& iX[], // InputVectorSize 大小的输入的规范化向量
int T, // 正确答案
datetime sT); // 向量创建的时间

在训练的过程中, 您可以决定网络识别了模式还是把它当成了新的类型. 为此可以使用SizeOfNet函数.

int SizeOfNet(string NetName); // 返回高斯神经元的数量

您应该使用 GetPredict函数读取回应. 它的参数与TrainNet一致. 如果您输入了与训练时同样的向量, 那么答案将是1.

double GetPredict(string NetName, // 取得 [0..1] 的数值以判断输入向量是否属于此类
double& iX[],
datetime sT);

这些函数在网络的内部使用中是必需的. 可以如例子中那样使用它们.

void Shrink(string NetName);
void WReset(string NetName);
void AEqual(string NetName);
void CW(string NetName);
void KillWeaks(string NetName);
void KillOlds(string NetName,datetime sT);

使用实例

init() 函数的代码实例


Print("已创建网络的编号: ",CreateNet("OverBought",24,0.2,0.95,0.001,Period()*60*1000)); // 创建卖出信号的网络
Print("已创建网络的编号: ",CreateNet("OverSold",24,0.2,0.95,0.001,Period()*60*1000)); // 创建买入信号的网络

//~~
Print("开始初始训练 ...");
for (int R = 1; R <= Repetitions; R++) // 基本训练过程
{ // 在历史数据上
WReset("OverBought"); // 权重清零
InitialTraining("OverBought",HistoryBars,-1); // 运行训练
Shrink("OverBought"); // 更新网络
AEqual("OverBought"); // 把所有权重设为1
CW("OverBought"); // 计算权重
KillWeaks("OverBought"); // 杀死衰弱神经元
CW("OverBought"); // 计算权重

WReset("OverSold"); // 权重值清零
InitialTraining("OverSold",HistoryBars,1); // 运行训练
AEqual("OverSold"); // 把所有权重设为1
Shrink("OverSold"); // 更新网络
CW("OverSold"); // 计算权重
KillWeaks("OverSold"); // 杀死虚弱神经元
CW("OverSold"); // 计算权重
FlushReport("OverSold",R); // 把报告写到文件中

}

start() 函数的代码实例


KillOlds("OverBought",iTime(Symbol(),0,1)); // 去掉老旧神经元
PostTraining("OverBought",-1); // 在过程中继续训练
Shrink("OverBought"); // 更新网络
AEqual("OverBought"); // 把所有权重设为1
CW("OverBought"); // 计算权重
KillWeaks("OverBought"); // 去掉老旧神经元
CW("OverBought"); // 计算权重

KillOlds("OverSold",iTime(Symbol(),0,1));
PostTraining("OverSold",1); // 在过程中继续训练
AEqual("OverSold"); // 把所有权重设为1
Shrink("OverSold"); // 更新网络
CW("OverSold"); // 计算权重
KillWeaks("OverSold"); // 去掉老旧神经元
CW("OverSold"); // 计算权重

//--------------------------------------------------------------------
double OverBought = Predict("OverBought");
double OverSold = Predict("OverSold");
Out = (OverBought - OverSold)/(OverBought+OverSold);

deinit() 函数的代码实例


Print("Destroying net=>",Destroy ("OverBought")); // 删除我们增加的网络
Print("Destroying net=>",Destroy ("OverSold")); // 删除我们增加的网络

已经成功检查了网络的工作能力. 好的结果依赖于创建输入向量的方法. 在训练过程中, 应该输入那些事先知道分类结果的向量数据, 认识到这点很重要. 简单来说, 如果网络是用于卖出信号的, 那么选择用来训练的柱应该确实是用于卖出信号的. 否则网络会收集相反的信号而您得不到想要的结果.

我想请您讨论以下的问题:

1. 输入向量的构建 - 现在我使用了24个参数 (移动平均之间的差异), 统一规范化到24个柱. 也就是说我计算了24x24的矩阵. 然后我对它规范化并取得最后的值.

2. 确定 "正确答案" - 也就是说, 何时输出信号是信号. 我现在使用的是AMA. 所以我就知道了只要2个柱以后就会有信号.

就是这样.

本文译自 MetaQuotes Software Corp. 撰写的俄文原文
官方代码: https://www.mql5.com/ru/code/8514

加速震荡(AC) 加速震荡(AC)

加速/减速技术指标(AC)用于衡量当前驱动力的加速和减速。

平均趋向指数(ADX) 平均趋向指数(ADX)

平均趋向指数指标(ADX)用来帮助判断市场是否存在趋势。

60 EMA profit 60 EMA profit

直观显示60EMA均线交易系统的赢利和亏损。

Ticks Volume 指标 Ticks Volume 指标

在期货市场上,交易量的数据会有一天的延迟,为了解决这个问题,许多分析员使用 tick volume 指标 (tick volume,订单交易量).