请观看如何免费下载自动交易
请在Telegram上找到我们!
加入我们粉丝页
有趣的脚本?
因此发布一个链接 -
让其他人评价
喜欢这个脚本? 在MetaTrader 5客户端尝试它
脚本

Schnick [支持矢量机器学习工具测试器] - MetaTrader 5脚本

显示:
2270
等级:
(24)
已发布:
2014.02.07 08:04
已更新:
2016.11.22 07:33
schnick.mq5 (11.03 KB) 预览
MQL5自由职业者 需要基于此代码的EA交易或指标吗?请在自由职业者服务中订购 进入自由职业者服务

本脚本是发布于MQL5网站上的"机器学习: 支持矢量机器是如何应用于交易(Machine Learning: How Support Vector Machines can be used in Trading)"文章的一部分.

想像一下这个假想场景, 您是一位研究人员, 专门研究只能在北极深处发现的稀有动物, 叫做Shnick. 因为这种动物非常遥远, 只能找到很少的部分(就算5000左右吧). 作为研究者, 您被这个问题困扰...怎样识别Schnick?

您所拥有的只是一些以往研究者提出的研究报告, 他们也只看到过一只. 在这些研究报告中, 作者提出了一些他们看到的Schnick的某些特征, 例如, 身高, 体重, 有几条腿, 等等. 但是所有这些特征在不同的报告中都有所不同并且没有可识别的模式….

我们怎样才能使用这些数据识别像 schnick 这样的新动物呢?

一个可能解决我们困难的方案就是使用支持向量机器来识别数据中的模式, 并且创建一个框架可以用于把动物分类为或者是schnick或者不是schnick. 第一步是创建一系列数据用于训练您的支持向量机器以识别schnick. 训练数据是一系列输入和机器输出, 它们是为了支持矢量机器分析和展开模板.

本脚本用于演示支持矢量机器在解决分类类型问题中的强大作用, 它使用了MQL5 市场上的支持矢量学习工具. 此假想问题以及脚本的完整描述在文章"机器学习: 怎样在交易中使用支持矢量机器(Machine Learning: How Support Vector Machines can be used in Trading)"之中. 该文章包含了怎样使用脚本以及怎样为评估市场趋势而深入理解机器学习的指导.

代码:

//+------------------------------------------------------------------+
//|                                                      Schnick.mq5 |
//|                        Copyright 2011, MetaQuotes Software Corp. |
//|                                              http://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2011, MetaQuotes Software Corp."
#property link      "http://www.mql5.com"
#property version   "1.00"
//+------------------------------------------------------------------+
//| 本脚本演示了支持矢量机器学习工具
//|                     的强大能力
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
//| 下列语句用于引入
//| 支持矢量机器库 'svMachineTool.ex5'
//+------------------------------------------------------------------+
#import "svMachineTool.ex5"
enum ENUM_TRADE {BUY,SELL};
enum ENUM_OPTION {OP_MEMORY,OP_MAXCYCLES,OP_TOLERANCE};
int  initSVMachine(void);
void setIndicatorHandles(int handle,int &indicatorHandles[],int offset,int N);
void setParameter(int handle,ENUM_OPTION option,double value);
bool genOutputs(int handle,ENUM_TRADE trade,int StopLoss,int TakeProfit,double duration);
bool genInputs(int handle);
bool setInputs(int handle,double &Inputs[],int nInputs);
bool setOutputs(int handle,bool &Outputs[]);
bool training(int handle);
bool classify(int handle);
bool classify(int handle,int offset);
bool classify(int handle,double &iput[]);
void deinitSVMachine(void);
#import
//--- 在 svm 中需要输入参数的数量
int N_Inputs=7;
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnStart()
  {
   double inputs[];           //用于创建训练输入的空白双精度数组
   bool   outputs[];          //用于创建训练输入的空白布林型数组
   int N_TrainingPoints=5000; //定义需要生成的训练样本数
   int N_TestPoints=5000;     //定义测试时的训练样本数

   genTrainingData(inputs,outputs,N_TrainingPoints); //为训练 svm 创建输入和输出

   int handle1=initSVMachine();             //初始化新的支持矢量机器并返回句柄
   setInputs(handle1,inputs,7);             //把输入传给 (不含错误) 支持矢量工具
   setOutputs(handle1,outputs);             //把输出传给 (不含错误) 支持矢量工具
   setParameter(handle1,OP_TOLERANCE,0.01); //设置容错参数为 <5%
   training(handle1);                       //使用输入/输出训练支持矢量机器

   insertRandomErrors(inputs,outputs,500);  //接受初始输入/输出并在数据中加入随机错误

   int handle2=initSVMachine();             //初始化新支持矢量机器并返回一个句柄
   setInputs(handle2,inputs,7);             //把输入传给 (不含错误) 支持矢量机器
   setOutputs(handle2,outputs);             //把输出传给 (不含错误) 支持矢量机器
   setParameter(handle2,OP_TOLERANCE,0.01); //把容错参数设为 <5%
   training(handle2);                       //使用输入/输出训练支持矢量机器

   double t1=testSVM(handle1,N_TestPoints); //测试训练过的支持矢量机器并把结果保存为 t1
   double t2=testSVM(handle2,N_TestPoints); //测试训练过的支持矢量机器并把结果保存为 t2

   Print("SVM 精确度为 ",NormalizeDouble(t1,2),"% (使用不含错误的输入/输出训练)");
   Print("SVM 精确度为 ",NormalizeDouble(t2,2),"% (使用含有错误的输入/输出训练)");
   deinitSVMachine(); //清理生成 SVM  使用的内存以避免内存泄漏
  }
//+------------------------------------------------------------------+
//| 本函数从观察到的动物接受观察属性 
//| 并且基于我们的选择, 返回 
//| true/false 指出它是否为 schnick
//+------------------------------------------------------------------+
bool isItASchnick(double height,double weight,double N_legs,double N_eyes,double L_arm,double av_speed,double f_call)
  {
   if(height   < 1000  || height   > 1100)  return(false); //If the height is outside the parameters > return(false)
   if(weight   < 40    || weight   > 50)    return(false); //If the weight is outside the parameters > return(false)
   if(N_legs   < 8     || N_legs   > 10)    return(false); //If the N_Legs is outside the parameters > return(false)
   if(N_eyes   < 3     || N_eyes   > 4)     return(false); //If the N_eyes is outside the parameters > return(false)
   if(L_arm    < 400   || L_arm    > 450)   return(false); //If the L_arm  is outside the parameters > return(false)
   if(av_speed < 2     || av_speed > 2.5)   return(false); //If the av_speed is outside the parameters > return(false)
   if(f_call   < 11000 || f_call   > 15000) return(false); //If the f_call is outside the parameters > return(false)
   return(true);                                           //Otherwise > return(true)
  }
//+------------------------------------------------------------------+
//| 本函数接受空白的双精度数组和布林型数组
//| 并生成用于训练SVM的输入/输出
//+------------------------------------------------------------------+ 
void genTrainingData(double &inputs[],bool &outputs[],int N)
  {
   double in[];                    //创建一个空双精度数组准备用于
                                   //临时保存生成的输入
   ArrayResize(in,N_Inputs);       //把in[]数组改为N_Inputs大小
   ArrayResize(inputs,N*N_Inputs); //把inputs[]数组改为N*N_Inputs大小 
   ArrayResize(outputs,N);         //把outputs[]数组改为N大小 
   for(int i=0;i<N;i++)
     {
      in[0]=    randBetween(980,1120);    //高度的随机输入
      in[1]=    randBetween(38,52);       //体重的随机输入
      in[2]=    randBetween(7,11);        //N_legs的随机输入
      in[3]=    randBetween(3,4.2);       //N_eyes的随机输入
      in[4]=    randBetween(380,450);     //L_arms的随机输入
      in[5]=    randBetween(2,2.6);       //av_speed的随机输入
      in[6]=    randBetween(10500,15500); //f_call的随机输入

      //--- 把新生成的随机输入复制到训练输入数组中
      ArrayCopy(inputs,in,i*N_Inputs,0,N_Inputs);
      //--- 评估随机输入以确定它是否为schnick
      outputs[i]=isItASchnick(in[0],in[1],in[2],in[3],in[4],in[5],in[6]);
     }
  }
//+------------------------------------------------------------------+
//| 本函数接收训练好的SVM的句柄并测试
//| 它是否能够对新的随机输入进行分类
//+------------------------------------------------------------------+ 
double testSVM(int handle,int N)
  {
   double in[];
   int atrue=0;
   int afalse=0;
   int N_correct=0;
   bool Predicted_Output;
   bool Actual_Output;
   ArrayResize(in,N_Inputs);
   for(int i=0;i<N;i++)
     {
      in[0]=    randBetween(980,1120);    //高度的随机输入
      in[1]=    randBetween(38,52);       //体重的随机输入
      in[2]=    randBetween(7,11);        //N_legs的随机输入
      in[3]=    randBetween(3,4.2);       //N_eyes的随机输入
      in[4]=    randBetween(380,450);     //L_arms的随机输入
      in[5]=    randBetween(2,2.6);       //av_speed的随机输入
      in[6]=    randBetween(10500,15500); //f_call的随机输入

      //--- 使用 isItASchnick 函数以确定实际想要的输出
      Actual_Output=isItASchnick(in[0],in[1],in[2],in[3],in[4],in[5],in[6]);
      //--- 使用训练好的SVM返回预测的输出.
      Predicted_Output=classify(handle,in);
      if(Actual_Output==Predicted_Output)
        {
         N_correct++; //本语句对正确的输出预测进行计数.
        }
     }
//--- 返回训练好的SVM的正确百分率
   return(100*((double)N_correct/(double)N));
  }
//+------------------------------------------------------------------+
//| 本函数接收生成的正确的输入和输出 
//| 并在数据中插入N个随机错误
//+------------------------------------------------------------------+ 
void insertRandomErrors(double &inputs[],bool &outputs[],int N)
  {
   int nTrainingPoints=ArraySize(outputs); //计算训练点的数量
   int index;                              //创建一个新整数 'index'
   bool randomOutput;                      //创建新布林类型数 'randomOutput'
   double in[];                            //创建新的双精度型数组用于
                                           //临时保存生成的输入
   ArrayResize(in,N_Inputs);               //把 in[] 数组改为 N_Inputs大小
   for(int i=0;i<N;i++)
     {
      in[0]=    randBetween(980,1120);    //高度的随机输入
      in[1]=    randBetween(38,52);       //体重的随机输入
      in[2]=    randBetween(7,11);        //N_legs的随机输入
      in[3]=    randBetween(3,4.2);       //N_eyes的随机输入
      in[4]=    randBetween(380,450);     //L_arms的随机输入
      in[5]=    randBetween(2,2.6);       //av_speed的随机输入
      in[6]=    randBetween(10500,15500); //f_call的随机输入

      //--- 随机选择训练输入并插入错误
      index=(int)MathRound(randBetween(0,nTrainingPoints-1));
      //--- 随机生成布林类型输出用于创建错误
      if(randBetween(0,1)>0.5) randomOutput=true;
      else                     randomOutput=false;

      //--- 把新生成的随机输入复制到训练输入数组中
      ArrayCopy(inputs,in,index*N_Inputs,0,N_Inputs);
      //--- 把新生成的随机输出复制到训练输出数组中
      outputs[index]=randomOutput;
     }
  }
//+------------------------------------------------------------------+
//| 本函数用于在t1和t2之间产生随机数值
//+------------------------------------------------------------------+ 
double randBetween(double t1,double t2)
  {
   return((t2-t1)*((double)MathRand()/(double)32767)+t1);
  }
//+------------------------------------------------------------------+

由MetaQuotes Ltd译自英文
原代码: https://www.mql5.com/en/code/1369

VIP_DSR VIP_DSR

MetaTrader 的动态支持/阻力指标

使用环形缓冲区绘制 OsCD 指标的类 使用环形缓冲区绘制 OsCD 指标的类

本类设计为使用环形缓冲区算法计算技术指标振荡移动平均 (Moving Average of Oscillator, OsMA).

Schnick [支持矢量机器学习工具测试期 - 演示] Schnick [支持矢量机器学习工具测试期 - 演示]

本脚本用于演示矢量机器在解决分类类型难题中的强大作用. 本版本的代码专门用于和MQL5市场中的免费版支持矢量学习工具做演示.

使用环形缓冲区绘制随机振荡指标的类 使用环形缓冲区绘制随机振荡指标的类

本类设计为使用环形缓冲区计算技术指标随机振荡指标 (Stochastic Oscillator).