Here's what you can do with OpenCL directly in MetaTrader 5 without any DLLs - page 4
You are missing trading opportunities:
- Free trading apps
- Over 8,000 signals for copying
- Economic news for exploring financial markets
Registration
Log in
You agree to website policy and terms of use
If you do not have an account, please register
Yes, I'm a bit familiar with OCL, I'm aware of that. You don't have to load the whole EA into the map, let them load some parallel code fragments, they are usually a percentage of the whole code.
So, why do I see only CPU cores (Core i5, 8 cores - 8 agents) when optimizing when I have NVIDIA 780GTX?
Do you use OpenCL in your code?
Most likely you think that any of your code should load on the graphics card. Which is not true.
I highly recommend reading our article on OpenCL in MetaTrader 5 where everything is explained in detail how it works:
In order to get a significant acceleration, you need to send the entire adviser to the GPU, but for this you need to write your own tester.
Here is an example of such a tester, a neural network with trading logic, OCL code:
//Функция для ядра
string GPU_kernel( int hl1NeuronCount,
int hl2NeuronCount,
int sampleCount,
int signalCount)
{
return
(
"#define HL1Count " + ( string )hl1NeuronCount + " \r\n"
"#define HL2Count " + ( string )hl2NeuronCount + " \r\n"
//------------------------------------------------------------------------------------
"#define NeuronSensitivity " + ( string )NeuronSensitivity_P + " \r\n"
//------------------------------------------------------------------------------------
"#define sampleCount " + ( string )sampleCount + " \r\n"
//------------------------------------------------------------------------------------
"#define signalCount " + ( string )signalCount + " \r\n"
//------------------------------------------------------------------------------------
"#define StrArrSaSize " + ( string )( sizeof (ArrSample) / sizeof ( float )) + "\r\n"
"typedef struct{float C[StrArrSaSize];} ArrSa; \r\n"
//------------------------------------------------------------------------------------
"#define StrArrWeSize " + ( string )( sizeof (ArrWe) / sizeof ( float )) + " \r\n"
"typedef struct{float C[StrArrWeSize];} ArrWe; \r\n"
//------------------------------------------------------------------------------------
"#define StrArrCrSize " + ( string )( sizeof (ArrCr) / sizeof ( float )) + " \r\n"
"typedef struct{float C[StrArrCrSize];}ArrCr; \r\n"
//------------------------------------------------------------------------------------
"#define Spread " + ( string )(Spread_P * Point ()) + " \r\n"
//------------------------------------------------------------------------------------
"#define Point " + ( string ) Point () + " \r\n"
"#define SL " + ( string )(StopLoss_P * Point ()) + " \r\n"
"#define TP " + ( string )(TakeProfit_P * Point ()) + " \r\n"
//------------------------------------------------------------------------------------
" \r\n"
"__kernel void Work(__global ArrSa *Sample, \r\n"
" __global ArrWe *Weights, \r\n"
" __global ArrCr *Result) \r\n"
"{ \r\n"
" int thread = get_global_id(0); \r\n"
" \r\n"
" //------------------Переменные нейронной сети---------------------------------\r\n"
" float nHL1 [HL1Count]; // Нейроны первого скрытого слоя \r\n"
" float nHL2 [HL2Count]; // Нейроны второго скрытого слоя \r\n"
" ArrWe parametr = Weights[thread]; // Параметры системы \r\n"
" int cnt_W = 0; // счетчик весов \r\n"
" float out = 0.0; // выход сети \r\n"
" \r\n"
" //-------------------Переменные для торговли----------------------------------\r\n"
" float temp = 0.0; // для временного хранения чего нибудь \r\n"
" \r\n"
" //---параметры цены \r\n"
" float priceASK = 0.0; // текущая Ask цена \r\n"
" float priceBID = 0.0; // текущая Bid цена \r\n"
" float pricePrevHighASK = 0.0; // максимум предыдущей свечи Ask \r\n"
" float pricePrevHighBID = 0.0; // максимум предыдущей свечи Bid \r\n"
" float pricePrevLowASK = 0.0; // минимум предыдущей свечи Ask \r\n"
" float pricePrevLowBID = 0.0; // минимум предыдущей свечи Bid \r\n"
" \r\n"
" float posType = 0.0; // тип сделки: \r\n"
" // 1.0 - buy, \r\n"
" //-1.0 - sell; \r\n"
" // 0.0 - нет открытой сделки \r\n"
" float posPriceClose = 0.0; \r\n"
" float posPriceClosePrevHi = 0.0; \r\n"
" float posPriceClosePrevLo = 0.0; \r\n"
" \r\n"
" //-----------------Текущие показатели позиции---------------------------------\r\n"
" float posPriceSL = 0.0; // цена StopLoss открытой сделки \r\n"
" float posPriceTP = 0.0; // цена TakeProfit открытой сделки \r\n"
" \r\n"
" //--------------------Статистика торговли-------------------------------------\r\n"
" int StTradeProfitCount = 0; // кол-во приб. сделок \r\n"
" int StTradeLossCount = 0; // кол-во уб. сделок \r\n"
" \r\n"
" int StTradeLossSeries = 0; // текущая серия убыточных ордеров \r\n"
" int StTradeMaxLossSer = 0; // самая длинная серия уб.ордеров \r\n"
" \r\n"
" //-----------------------Тут прогон по истории--------------------------------\r\n"
" for(int hist = 0;hist < sampleCount;hist++) \r\n"
" { \r\n"
" cnt_W = 0; \r\n"
" //---------------Обработаем первый скрытый слой-----------------------------\r\n"
" //Добавим смещение точек насыщения нейрона: (+b) \r\n"
" for(int u = 0;u < HL1Count;u++) \r\n"
" { \r\n"
" nHL1[u] = parametr.C[cnt_W]; \r\n"
" cnt_W++; \r\n"
" } \r\n"
" \r\n"
" //Сумма произведений нейронов предыдущего слоя и их весов: \r\n"
" // (+w1*x1+...+wn*xn) для каждого нейрона \r\n"
" for(int u = 0;u < HL1Count;u++) \r\n"
" { \r\n"
" for(int i = 0;i < signalCount;i++) \r\n"
" { \r\n"
" nHL1[u] += Sample[hist].C[i + 3] * parametr.C[cnt_W]; \r\n"
" cnt_W++; \r\n"
" } \r\n"
" } \r\n"
" \r\n"
" //Посчитаем функцию активации для каждого скрытого нейрона \r\n"
" for(int u = 0;u < HL1Count;u++) \r\n"
" { \r\n"
" nHL1[u] = 5.0 * nHL1[u] / (1.0 + fabs(4.02 * nHL1[u])); \r\n"
" } \r\n"
" \r\n"
" //---------------Обработаем второй скрытый слой-----------------------------\r\n"
" //Добавим смещение точек насыщения нейрона: (+b) \r\n"
" for(int u = 0;u < HL2Count;u++) \r\n"
" { \r\n"
" nHL2[u] = parametr.C[cnt_W]; \r\n"
" cnt_W++; \r\n"
" } \r\n"
" \r\n"
code continuation:
" // (+w1*x1+...+wn*xn) для каждого нейрона \r\n"
" for(int u = 0;u < HL2Count;u++) \r\n"
" { \r\n"
" for(int i = 0;i < HL1Count;i++) \r\n"
" { \r\n"
" nHL2[u] += nHL1[i] * parametr.C[cnt_W]; \r\n"
" cnt_W++; \r\n"
" } \r\n"
" } \r\n"
" \r\n"
" //Посчитаем функцию активации для каждого скрытого нейрона \r\n"
" for(int u = 0;u < HL2Count;u++) \r\n"
" { \r\n"
" nHL2[u] = 5.0 * nHL2[u] / (1.0 + fabs(4.02 * nHL2[u])); \r\n"
" } \r\n"
" \r\n"
" //-----------------Обработаем выходной слой---------------------------------\r\n"
" //Добавим смещение точек насыщения нейрона: (+b) \r\n"
" out = parametr.C[cnt_W]; \r\n"
" cnt_W++; \r\n"
" \r\n"
" //Сумма произведений нейронов предыдущего слоя и их весов: \r\n"
" // (+w1*x1+...+wn*xn) для каждого нейрона \r\n"
" for(int i = 0;i < HL2Count;i++) \r\n"
" { \r\n"
" out += nHL2[i] * parametr.C[cnt_W]; \r\n"
" cnt_W++; \r\n"
" } \r\n"
" //==========================================================================\r\n"
" \r\n"
" \r\n"
" //==========================================================================\r\n"
" priceASK = Sample[hist].C[0] + Spread; \r\n"
" priceBID = Sample[hist].C[0]; \r\n"
" \r\n"
" pricePrevHighASK = Sample[hist].C[1] + Spread; \r\n"
" pricePrevHighBID = Sample[hist].C[1]; \r\n"
" \r\n"
" pricePrevLowASK = Sample[hist].C[2] + Spread; \r\n"
" pricePrevLowBID = Sample[hist].C[2]; \r\n"
" \r\n"
" //-----------------проверка условий на выход из рынка-----------------------\r\n"
" // если есть открытая поза \r\n"
" if(posType != 0.0) \r\n"
" { \r\n"
" if(posType == 1.0) \r\n"
" { \r\n"
" posPriceClose = priceBID; \r\n"
" posPriceClosePrevHi = pricePrevHighBID; \r\n"
" posPriceClosePrevLo = pricePrevLowBID; \r\n"
" } \r\n"
" else \r\n"
" { \r\n"
" posPriceClose = priceASK; \r\n"
" posPriceClosePrevHi = pricePrevHighASK; \r\n"
" posPriceClosePrevLo = pricePrevLowASK; \r\n"
" } \r\n"
" \r\n"
" \r\n"
" // может уже сработал SL? \r\n"
" if(posType * (posPriceSL - posPriceClose) >= 0.0 || \r\n"
" posType * (posPriceSL - posPriceClosePrevLo) >= 0.0) \r\n"
" { \r\n"
" // на одну убыточную сделку больше \r\n"
" StTradeLossCount++; \r\n"
" // текущая серия убыточных сделок увеличилась \r\n"
" StTradeLossSeries++; \r\n"
" // если серия уб. сделок больше чем в истори, то запомним \r\n"
" StTradeMaxLossSer = (StTradeMaxLossSer < StTradeLossSeries) ? \r\n"
" StTradeLossSeries : StTradeMaxLossSer; \r\n"
" // позиция закрыта \r\n"
" posType = 0.0; \r\n"
" } \r\n"
" // нет, SL не сработал \r\n"
" else \r\n"
" { \r\n"
" // может уже сработал TP? \r\n"
" if(posType * (posPriceClose - posPriceTP) >= 0.0 || \r\n"
" posType * (posPriceClosePrevHi - posPriceTP) >= 0.0) \r\n"
" { \r\n"
" // на одну прибыльную сделку больше \r\n"
" StTradeProfitCount++; \r\n"
" // текущая серия убыточных сделок закончилась \r\n"
" StTradeLossSeries = 0; \r\n"
" // позиция закрыта \r\n"
" posType = 0.0; \r\n"
" } \r\n"
" } \r\n"
" \r\n"
" } \r\n"
" //--------------------------------------------------------------------------\r\n"
" \r\n"
" \r\n"
" //-----------------проверка сигнала на вход в рынок-------------------------\r\n"
" // если нет открытых поз проверим возможность открытия \r\n"
" if(posType == 0.0 && hist < (sampleCount - 1)) \r\n"
" { \r\n"
" // если есть сигнал на покупку \r\n"
" if(NeuronSensitivity < out) \r\n"
" { \r\n"
" posPriceTP = priceASK + TP; \r\n"
" posPriceSL = priceASK - SL; \r\n"
" posType = 1.0; \r\n"
" } \r\n"
" // если есть сигнал на продажу \r\n"
" if(out < -NeuronSensitivity) \r\n"
" { \r\n"
" posPriceSL = priceBID + SL; \r\n"
" posPriceTP = priceBID - TP; \r\n"
" posType = -1.0; \r\n"
" } \r\n"
" } \r\n"
" } \r\n"
" \r\n"
" \r\n"
" //----------------------------------------------------------------------------\r\n"
" float Profit = ((float)StTradeProfitCount*TP)-((float)StTradeLossCount*SL); \r\n"
" Result[thread].C[0] = Profit; \r\n"
" Result[thread].C[1] = -StTradeMaxLossSer; \r\n"
"} \r\n"
);
}
//————————————————————————————————————————————————————————————————————————————————————————————————
This is a demonstration not only of GPU calculations in the MQL5 code, but also of the graphical capabilities of the terminal:
The full source code as a script is attached. The bug on OpenCL 1.2 has been fixed.
the continuation of the code:
By the way, is it possible to send code to OCL somehow in the form of a file, rather than as a line item? Otherwise it looks a bit creepy.
By the way, is it possible to send code to OCL not as a line-by-line sheet, but somehow as a file? It looks a bit creepy.
It is important to note that now, at the end of 2016, it is already possible to lay claim to the presence of OpenCL in the target systems.
Even if there is no GPU, OpenCL will run on CPU using all cores. This is what the device set looks like:
OpenCL Device #1: CPU GenuineIntel Intel(R) Xeon(R) CPU E5-2690 v3 @ 2.60 GHz with OpenCL 1.2 (24 units, 2598 MHz, 32680 Mb, version 2117.13 (sse2,avx), rating 85)
The terminal automatically selects the fastest device based on the performance rating. It is also possible to manually select any device via the CLContextCreate function.
Unfortunately, forget about OpenCL on Windows XP. And 32-bit operating systems in general - it's the year 2017.
More unpleasant is the situation with Nvidia, which is essentially sabotaging the OpenCL standard and not implementing OpenCL 2.0. First it sabotaged the implementation of OpenCL 1.2, now OpenCL 2.0. It is doing this to promote its own implementation of CUDA, which hurts the whole community.
Besides, Nvidia deliberately lowers accuracy in its gamer cards to limit their use in mathematics and to stimulate purchases of specialized cards (Tesla).
Against this backdrop AMD looks to be winning not only because of their clearly faster maths (mining farms on AMD are usually built), but also for their open standards strategy(they have very much opened up and are pushing into the public domain). The introduction of OpenCL 2.0 in AMD cards has brought this specification very close to CUDA capabilities and now there is no point in laying the groundwork for CUDA at all.