Using OpenCL in MQL5 - in a Custom Indicator code:

Using OpenCL in MQL5 - in a Custom Indicator code:

Manage alerts

Loading saved threads...

Jaffer Wilson · External communityPost link
External question — Stack Overflow Stack Exchange Author: Jaffer Wilson Original post: https://stackoverflow.com/questions/49606977 License: CC BY-SA 3.0 — https://creativecommons.org/licenses/by-sa/3.0/ Adaptation: HTML converted to plain text; contact email addresses removed. I am trying to modify an indicator file using the OpenCL library. But I couldn't understand how I can make that possible. I tried to read and understand the Documentation but could not. Here is my code: #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); } //+------------------------------------------------------------------+ Kindly, help me modify the above with OpenCL, so that it will help me understand what I can do with it.
Quote
Report
user3666197 · External communityPost link
External answer — Stack Overflow Stack Exchange Author: user3666197 Original post: https://stackoverflow.com/a/49612154 License: CC BY-SA 4.0 — https://creativecommons.org/licenses/by-sa/4.0/ Adaptation: HTML converted to plain text; contact email addresses removed. A Principal Note: No, as was posted in many MQL4/5 posts already, [ CustomIndicator ] type-of-MQL4/5 code is no place for anything else but ultimately as synchronously responsive as possible external QUOTE -stream event processing, so no blocking, no GUI-MMI-interactions, no Print() -ing, nothing that may anyhow slow down, the less block a solo-thread ( SPOF ) of all [ CustomIndicator ] data-refresh / event synchronous-processing. OpenCL is not a tool for this ( if for no other reason, for it adds latency ). OpenCL opens gates to harness heterogeneous computing resourcesCPU + GPU + manyCore-device(s) and organises ComputingJOBs' workflows among them ... 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. If going into OpenCL territory, best start with simple, non-sequential ( so most of the Technical Indicators, that convolve in TimeDOMAIN are out of the game anyways ) concurrent-computing, as asynchronous, distributed co-operation requires mastering multiple domains: Always first test the present <COMPUTING RESOURCES> available: 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 ) ); } }
Quote
Report

Post Reply

Quoted from Forex.com.bd-Editorial External question — Stack Overflow Stack Exchange Author: Jaffer Wilson Source score (net votes, not local likes): 0 Original post: https://stackoverflow.com/questions/49606977 License: CC BY-SA 3.0 — https://creativecommons.org/licenses/by-sa/3.0/ Adaptation: HTML converted to plain text; contact email addresses removed. I am trying to modify an indicator file using the OpenCL library. But I couldn't understand how I can make that possible. I tried to read and understand the Documentation but could not. Here is my code: #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); } //+------------------------------------------------------------------+ Kindly, help me modify the above with OpenCL, so that it will help me understand what I can do with it.

Cancel quote

Checking account access…