代码之家  ›  专栏  ›  技术社区  ›  Jaffer Wilson Dilip kumar

在MQL5中使用OpenCL-在自定义指示符代码中:

  •  0
  • Jaffer Wilson Dilip kumar  · 技术社区  · 7 年前

    我正在尝试使用OpenCL库修改指示器文件。

    但我不明白我怎么能做到这一点。我试图阅读和理解文档,但无法理解。

    这是我的代码:

    #include <MovingAverages.mqh>
    
    #property indicator_separate_window
    #property indicator_buffers 6
    #property indicator_plots   3
    #property indicator_type1   DRAW_LINE
    #property indicator_color1  Yellow//LightSeaGreen
    #property indicator_style1  STYLE_SOLID
    #property indicator_width1  1
    #property indicator_type2   DRAW_LINE
    #property indicator_color2  Lime//YellowGreen
    #property indicator_style2  STYLE_SOLID//STYLE_DOT
    #property indicator_width2  1
    #property indicator_type3   DRAW_LINE
    #property indicator_color3  Red//Wheat
    #property indicator_style3  STYLE_SOLID//STYLE_DOT
    #property indicator_width3  1
    #property indicator_label1  "ADX"
    #property indicator_label2  "+DI"
    #property indicator_label3  "-DI"
    //--- input parameters
    input int InpPeriodADX=14; // Period
    //---- buffers
    double    ExtADXBuffer[];
    double    ExtPDIBuffer[];
    double    ExtNDIBuffer[];
    double    ExtPDBuffer[];
    double    ExtNDBuffer[];
    double    ExtTmpBuffer[];
    //--- global variables
    int       ExtADXPeriod;
    
    //+------------------------------------------------------------------+
    //| Custom indicator initialization function                         |
    //+------------------------------------------------------------------+
    void OnInit()
      {
    //--- check for input parameters
       if(InpPeriodADX>=100 || InpPeriodADX<=0)
         {
          ExtADXPeriod=14;
          printf("Incorrect value for input variable Period_ADX=%d. Indicator will use value=%d for calculations.",InpPeriodADX,ExtADXPeriod);
         }
       else ExtADXPeriod=InpPeriodADX;
    //---- indicator buffers
       SetIndexBuffer(0,ExtADXBuffer);
       SetIndexBuffer(1,ExtPDIBuffer);
       SetIndexBuffer(2,ExtNDIBuffer);
       SetIndexBuffer(3,ExtPDBuffer,INDICATOR_CALCULATIONS);
       SetIndexBuffer(4,ExtNDBuffer,INDICATOR_CALCULATIONS);
       SetIndexBuffer(5,ExtTmpBuffer,INDICATOR_CALCULATIONS);
    //--- indicator digits
       IndicatorSetInteger(INDICATOR_DIGITS,2);
    //--- set draw begin
       PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,ExtADXPeriod<<1);
       PlotIndexSetInteger(1,PLOT_DRAW_BEGIN,ExtADXPeriod);
       PlotIndexSetInteger(2,PLOT_DRAW_BEGIN,ExtADXPeriod);
    //--- indicator short name
       string short_name="ADX("+string(ExtADXPeriod)+")";
       IndicatorSetString(INDICATOR_SHORTNAME,short_name);
    //--- change 1-st index label
       PlotIndexSetString(0,PLOT_LABEL,short_name);
    //---- end of initialization function
      }
    //+------------------------------------------------------------------+
    //| Custom indicator iteration function                              |
    //+------------------------------------------------------------------+
    int OnCalculate(const int rates_total,
                    const int prev_calculated,
                    const datetime &time[],
                    const double &open[],
                    const double &high[],
                    const double &low[],
                    const double &close[],
                    const long &tick_volume[],
                    const long &volume[],
                    const int &spread[])
      {
    //--- checking for bars count
       if(rates_total<ExtADXPeriod)
          return(0);
    //--- detect start position
       int start;
       if(prev_calculated>1) start=prev_calculated-1;
       else
         {
          start=1;
          ExtPDIBuffer[0]=0.0;
          ExtNDIBuffer[0]=0.0;
          ExtADXBuffer[0]=0.0;
         }
    //--- main cycle
       for(int i=start;i<rates_total && !IsStopped();i++)
         {
          //--- get some data
          double Hi    =high[i];
          double prevHi=high[i-1];
          double Lo    =low[i];
          double prevLo=low[i-1];
          double prevCl=close[i-1];
          //--- fill main positive and main negative buffers
          double dTmpP=Hi-prevHi;
          double dTmpN=prevLo-Lo;
          if(dTmpP<0.0)   dTmpP=0.0;
          if(dTmpN<0.0)   dTmpN=0.0;
          if(dTmpP>dTmpN) dTmpN=0.0;
          else
            {
             if(dTmpP<dTmpN) dTmpP=0.0;
             else
               {
                dTmpP=0.0;
                dTmpN=0.0;
               }
            }
          //--- define TR
          double tr=MathMax(MathMax(MathAbs(Hi-Lo),MathAbs(Hi-prevCl)),MathAbs(Lo-prevCl));
          //---
          if(tr!=0.0)
            {
             ExtPDBuffer[i]=100.0*dTmpP/tr;
             ExtNDBuffer[i]=100.0*dTmpN/tr;
            }
          else
            {
             ExtPDBuffer[i]=0.0;
             ExtNDBuffer[i]=0.0;
            }
          //--- fill smoothed positive and negative buffers
          ExtPDIBuffer[i]=ExponentialMA(i,ExtADXPeriod,ExtPDIBuffer[i-1],ExtPDBuffer);
          ExtNDIBuffer[i]=ExponentialMA(i,ExtADXPeriod,ExtNDIBuffer[i-1],ExtNDBuffer);
          //--- fill ADXTmp buffer
          double dTmp=ExtPDIBuffer[i]+ExtNDIBuffer[i];
          if(dTmp!=0.0)
             dTmp=100.0*MathAbs((ExtPDIBuffer[i]-ExtNDIBuffer[i])/dTmp);
          else
             dTmp=0.0;
          ExtTmpBuffer[i]=dTmp;
          //--- fill smoothed ADX buffer
          ExtADXBuffer[i]=ExponentialMA(i,ExtADXPeriod,ExtADXBuffer[i-1],ExtTmpBuffer);
    
    
    
         }
    
    //---- OnCalculate done. Return new prev_calculated.
    
       return(rates_total);
      }
    //+------------------------------------------------------------------+
    

    请帮助我用OpenCL修改上述内容,以便它能帮助我理解我可以用它做什么。

    1 回复  |  直到 7 年前
        1
  •  1
  •   user3666197    7 年前

    主要注释:

    不,先生,正如许多MQL4/5帖子已经发布的那样, [ CustomIndicator ] MQL4/5类型的代码除了最终尽可能同步地响应外部响应之外,其他任何东西都无法容纳 QUOTE -流事件处理,因此没有阻塞,没有GUI MMI交互,没有 Print() -ing,没有任何东西会减慢速度,更少地阻止所有的单线程(SPOF) [自定义指示器] 数据刷新/事件同步处理。

    OpenCL不是用于此目的的工具(如果没有其他原因,它会增加延迟)。


    OpenCL打开了利用异构计算资源的大门
    CPU+GPU+多个核心设备,并在它们之间组织计算作业的工作流。。。

    OpenCL程序用于在支持 OpenCL 1.1或更高版本 。现代视频卡包含数百个小型专用处理器,可以同时对传入的数据流执行简单的数学运算。这个 OpenCL 该语言组织并行计算,并为特定类别的任务提供更高的速度。

    如果要进入OpenCL领域,最好从简单、非顺序(因此,大多数技术指标,即在时域中卷积,无论如何都是不可能的)并行计算开始,因为异步、分布式合作需要掌握多个域:


    总是先测试现在 <COMPUTING RESOURCES> 可用:

    void OnStart() {
    
         uchar cDATA[1024];
         uint  aSIZE;
         int   aDevCOUNT = CLGetInfoInteger( 0, CL_DEVICE_COUNT );
    
         for ( int aDEVICE  = 0;
                   aDEVICE <  aDevCOUNT;
                   aDEVICE++
                   )
         {
             int clCONTEXT =  CLContextCreate( aDEVICE );
             if (clCONTEXT == -1 ) Print( "ERROR in CLContextCreate() for aDEVICE#", aDEVICE );
             string aDeviceNAME;
             CLGetInfoString( clCONTEXT,
                              CL_DEVICE_NAME,
                              aDeviceNAME
                              );   Print( "INF[", aDEVICE, "].NAME::  ", aDeviceNAME );
             CLGetDeviceInfo( clCONTEXT,
                              CL_DEVICE_VENDOR,
                              cDATA,
                              aSIZE
                              );   Print( "INF[", aDEVICE, "].VENDOR:: ", CharArrayToString( cDATA ) );
         }
      }
    
    推荐文章