下载MetaTrader 5

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

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

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

2014.02.07 08:08
EA

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

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

显示:
783
等级:
投票: 13

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

本版本的代码专门用于和MQL5 市场中的免费版支持矢量学习工具结合做演示.

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

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

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

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

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

代码:

//+------------------------------------------------------------------+
//|                                                 Schnick_Demo.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_demo.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;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
   double inputs[];           //用于创建训练输入的空双精度型数组
   bool   outputs[];          //用于创建训练输入的空布林型数组
   int N_TrainingPoints=5000; //定义需要生成的训练样本数量
   int N_TestPoints=5000;     //定义测试中使用的样本数量

   genTrainingData(inputs,outputs,N_TrainingPoints); //生成用于训练 svm的输入和输出

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

   insertRandomErrors(inputs,outputs,500);  //接收最初的输入/输出, 向数据中生成和插入错误

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

   double t1=testSVM(handle1,N_TestPoints); //测试训练好的svm并把结果保存到t1
   double t2=testSVM(handle2,N_TestPoints); //测试训练好的svm并把结果保存到t2

   Print("SVM 精确度为",NormalizeDouble(t1,2),"% (使用不含错误的训练输入/输出)");
   Print("SVM 精确度为",NormalizeDouble(t2,2),"% (使用含有错误的训练输入/输出)");
   deinitSVMachine(); //清除SVM训练中使用的内存以免内存泄漏
   return(0);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//--- OnDeinit()中不执行函数
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//--- OnTick()中不执行函数   
  }
//+------------------------------------------------------------------+
//| 本函数接收观察动物的观察属性, 
//| 并基于我们选择的标准, 返回
//| 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); //如果高度在参数范围之外 > 返回(false)
   if(weight   < 40    || weight   > 50)    return(false); //如果体重在参数范围之外 > 返回(false)
   if(N_legs   < 8     || N_legs   > 10)    return(false); //如果 N_Legs 在参数范围之外 > 返回(false)
   if(N_eyes   < 3     || N_eyes   > 4)     return(false); //如果 N_eyes 在参数范围之外 > 返回(false)
   if(L_arm    < 400   || L_arm    > 450)   return(false); //如果 L_arm  在参数范围之外 > 返回(false)
   if(av_speed < 2     || av_speed > 2.5)   return(false); //如果 av_speed 在参数范围之外 > 返回(false)
   if(f_call   < 11000 || f_call   > 15000) return(false); //如果 f_call 在参数范围之外 > 返回(false)
   return(true);                                           //否则 > 返回(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 Software Corp.从英文翻译成
官方代码: https://www.mql5.com/en/code/1370

Schnick [支持矢量机器学习工具测试器] Schnick [支持矢量机器学习工具测试器]

本脚本用于演示矢量机器在解决分类类型难题中的强大作用.

VIP_DSR VIP_DSR

MetaTrader 的动态支持/阻力指标

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

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

使用环形缓冲区绘制ER的类 使用环形缓冲区绘制ER的类

本类使用环形缓冲区算法绘制效率比率技术指标(Efficiency Ratio, ER).