Discussion of article "Using OpenCL to test candlestick patterns"

 

New article Using OpenCL to test candlestick patterns has been published:

The article describes the algorithm for implementing the OpenCL candlestick patterns tester in the "1 minute OHLC" mode. We will also compare its speed with the built-in strategy tester launched in the fast and slow optimization modes.

We need to rely on something to make sure that the implementation of the tester on OpenCL works correctly. First, we will develop an MQL5 EA. Then we will compare its results of testing and optimizing using a regular tester with the ones obtained by the OpenCL tester.

The test object is a simple EA trading the following candlestick patterns.
  • Bearish pin bar
  • Bullish pin bar
  • Bearish engulfing
  • Bullish engulfing

The strategy is simple:

  • Bearish pin bar or bearish engulfing  — sell
  • Bullish pin bar or bullish engulfing — buy
  • The number of simultaneously opened positions — unlimited
  • Maximum position holding time — limited, user-defined
  • Take Profit and Stop Loss levels — fixed, user-defined

The presence of the pattern is to be checked on fully closed bars. In other words, we search for a pattern on three previous bars as soon as a new one appears.

Pattern detection conditions are as follows:

Pin bar

Author: Serhii Shevchuk

 

Author, Thank you for the article! I think you chose this particular TC for demonstration for a reason, as it parallels perfectly. However, this is a very narrow niche.

In the article you have very much moved away from universality towards particularity. It is clear that the goal is to demonstrate potential possibilities. But there is little to apply it to your own needs.

I would like to see examples of translating different MQL-code into OpenCL-code. Perhaps this is contained in the articles linked to in the beginning of your article.

 
Custom symbols can help get rid of swaps and commissions when comparing testers' results.
 
Is the OCLDefines.mqh file missing only for me? :-)
 
Denis Kirichenko:
Is the OCLDefines.mqh file missing only for me? :-)

Thanks for your attention) We'll fix it, but I understand, already from Monday. Here is the source:

//+------------------------------------------------------------------+
//| defines|
//+------------------------------------------------------------------+
//--- setting a runtime error
#define  SET_ERR(c) do {m_last_error.function = __FUNCTION__; \
      m_last_error.line =__LINE__; \
      m_last_error.code=::GetLastError(); m_last_error.comment=c;} while(0)
//--- setting a runtime error by passing the function name and line number through the parameter
#define  SET_ERRx(c,f,l) do {m_last_error.function = f; m_last_error.line = l; \
      m_last_error.code=::GetLastError(); m_last_error.comment=c;} while(0)
//--- setting a user error
#define  SET_UERR(err,c) do {m_last_error.function = __FUNCTION__; \
      m_last_error.line =__LINE__; \
      m_last_error.code=ERR_USER_ERROR_FIRST+err; m_last_error.comment=c;} while(0)
//--- setting a user error by passing the function name and line number through the parameter
#define  SET_UERRx(err,c,f,l) do {m_last_error.function = f; m_last_error.line = l; \
      m_last_error.code=ERR_USER_ERROR_FIRST+err; m_last_error.comment=c;} while(0)
//--- function calls for working with OpenCL
#define _BufferFromArray(buffer_index,data,data_array_offset,data_array_count,flags) \
      if(BufferFromArray(buffer_index,data,data_array_offset,data_array_count,flags,__FUNCTION__,__LINE__)==false) return false
#define _BufferCreate(buffer_index,size_in_bytes,flags) \
      if(BufferCreate(buffer_index,size_in_bytes,flags,__FUNCTION__,__LINE__)==false) return false
#define _BufferRead(buffer_index,data,cl_buffer_offset,data_array_offset,data_array_count) \
      if(BufferRead(buffer_index,data,cl_buffer_offset,data_array_offset,data_array_count,__FUNCTION__,__LINE__)==false) return false
#define _BufferWrite(buffer_index,data,cl_buffer_offset,data_array_offset,data_array_count) \
      if(BufferWrite(buffer_index,data,cl_buffer_offset,data_array_offset,data_array_count,__FUNCTION__,__LINE__)==false) return false
#define _Execute(kernel_index,work_dim,work_offset,work_size) \
      if(Execute(kernel_index,work_dim,work_offset,work_size,__FUNCTION__,__LINE__)==false) return false
#define _SetArgument(kernel_index,arg_index,value) \
      if(SetArgument(kernel_index,arg_index,value,__FUNCTION__,__LINE__)==false) return false
#define _SetArgumentBuffer(kernel_index,arg_index,buffer_index) \
      if(SetArgumentBuffer(kernel_index,arg_index,buffer_index,__FUNCTION__,__LINE__)==false) return false
#define _KernelCreate(k,src) \
      if(KernelCreate(k,src,__FUNCTION__,__LINE__)==false) break

//--- User errors 
#define  UERR_NONE                0     // No error
#define  UERR_NO_OCL              1     // COpenCL object does not exist
#define  UERR_GET_MEMORY_SIZE     2     // Error getting memory size
#define  UERR_KERNEL_CREATE       3     // Error creating a kernel
#define  UERR_SET_BUF_COUNT       4     // Error setting the number of buffers
#define  UERR_DOUBLE_NOT_SUPP     5     // Not supported by double
#define  UERR_BUFFER_CREATE       6     // Buffer creation error
#define  UERR_BUFFER_FROM_ARRAY   7     // Error creating buffer from array
#define  UERR_BUFFER_READ         8     // Buffer read error
#define  UERR_BUFFER_WRITE        9     // Buffer write error
#define  UERR_SET_ARGUMENT        10    // Argument setting error
#define  UERR_SET_ARGUMENT_BUFFER 11    // Error setting buffer as argument
#define  UERR_EXECUTE             12    // Kernel execution error
#define  UERR_NO_ENOUGH_MEM       13    // No free memory

//--- Tester errors
#define  UERR_TESTER_ERROR_FIRST  256
#define  SET_UERRt(err,c)         SET_UERR(UERR_TESTER_ERROR_FIRST+err,c)
//+------------------------------------------------------------------+
 
fxsaber:
Custom symbols can help get rid of swaps and commissions when comparing testers results.

Yes, but that's even further away from the real world. Unless it's for debugging.

 
The article is really impressive. It is a pity that this is the case when one does not want to compare the amount of mental expenditure and useful output.
 

Congratulations, you have written a great article!

The code from the article will be quoted and you have raised the bar very high for your colleagues who are going to write articles on parallel computing in trading.

 
fxsaber:

In the article, you have very much moved away from the universal towards the particular.

That's just the beginning. Universality is ahead. The hidden message of the article is that everything is not so simple. You cannot just convert serial code into parallel code. You need to write in parallel from the beginning.

If the community is interested, I will post my further developments in this direction.

 
Serhii Shevchuk:

This is just the beginning. Versatility is ahead. The hidden message of the article is that not everything is so simple. You cannot just convert serial code into parallel code. You need to write parallel code from the beginning.

If the community is interested, I will post my further developments in this direction.

the community is very interested, "Afftar fishi ischo!!!1111".

a very important topic in terms of accelerating optimisation/testing, especially for machine learning algorithms

 

Very useful article!

Of course, I would like to see more simple examples of translation of ordinary MQL code into OpenCL code, in the form of ready functions with comments for dummies.

And another question, how long does it take to transfer/prepare data for a video card, I heard an opinion that OpenCL for a video card makes no sense to use for real trading because of the time loss on data transfer for processing, is it really so?