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

Using OpenCL in MQL5 - in a Custom Indicator code:

我正在尝试使用 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 修改上面的内容,这样它会帮助我理解我可以用它做什么。

主要注释:

不,先生,正如许多 MQL4/5 帖子中已经发布的那样,[ CustomIndicator ] type-of-MQL4/5 代码是除了最终尽可能同步响应外部 QUOTE-stream 事件处理,所以没有阻塞,没有 GUI-MMI-interactions,没有 Print() -ing,无论如何都不会减慢速度,所有 [ CustomIndicator ] data-refresh / 事件 synchronous-processing.

中的 solo-thread ( SPOF ) 块越少

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


OpenCL 打开了利用异构计算资源的大门
CPU + GPU + manyCore-device(s) 并在它们之间组织 ComputingJOB 的工作流程...

OpenCL programs are used for performing computations on video cards that support OpenCL 1.1 or higher. Modern video cards contain hundreds of small specialized processors that can simultaneously perform simple mathematical operations with incoming data streams. The OpenCL language organizes parallel computing and provides greater speed for a certain class of tasks.

如果进入 OpenCL 领域,最好从简单的开始,non-sequential(所以大多数技术指标,在 TimeDOMAIN 中卷积无论如何都不在游戏中)concurrent-computing,异步,分布式co-operation 需要掌握多个域:


始终先测试当前<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 ) );
     }
  }