Esto es lo que puedes hacer con OpenCL directamente en MetaTrader 5 sin ninguna DLL - página 4

 
Alexey Volchanskiy:
Sí, estoy un poco familiarizado con la OCL, soy consciente de ello. No tienes que cargar todo el EA en el mapa, deja que carguen algunos fragmentos de código en paralelo, suelen ser un porcentaje de todo el código.
De esta manera, no se obtendrá un gran aumento de velocidad para los Asesores Expertos estándar. Todo estará limitado por el ancho de banda de los agentes.
 
Vitalie Postolache:
Entonces, ¿por qué veo sólo los núcleos de la CPU (Core i5, 8 núcleos - 8 agentes) al optimizar cuando tengo NVIDIA 780GTX?

¿Utilizas OpenCL en tu código?

Lo más probable es que pienses que cualquiera de tus códigos debe cargarse en la tarjeta gráfica. Lo cual no es cierto.

Recomiendo encarecidamente la lectura de nuestro artículo sobre OpenCL en MetaTrader 5 que explica en detalle su funcionamiento:

 

Para obtener una aceleración significativa, debe enviar todo el asesor a la GPU, pero para esto debe escribir su propio probador.

Aquí hay un ejemplo de tal probador, una red neuronal con lógica comercial, código OCL:

//————————————————————————————————————————————————————————————————————————————————————————————————
//Функция для ядра
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"
          
 

continuación del código:

          "    //Сумма произведений нейронов предыдущего слоя и их весов:                  \r\n"
           "    // (+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"
          );
}
//————————————————————————————————————————————————————————————————————————————————————————————————
 
Renat Fatkhullin:

Esta es una demostración no sólo de los cálculos de la GPU en el código MQL5, sino también de las capacidades gráficas del terminal:

Se adjunta el código fuente completo en forma de script. Se ha corregido el error en OpenCL 1.2.

¡Esto es genial! Haré gráficos en 3d, me serán útiles. Y la velocidad será buena para un megaproyecto. Iré hoy a probarlo).
 
Andrey Dik:

la continuación del código:

Por cierto, ¿es posible enviar el código a la OCL de alguna manera en forma de archivo, en lugar de como una partida? De lo contrario, parece un poco espeluznante.

 
Alexey Volchanskiy:

Por cierto, ¿es posible enviar el código a la OCL no como una hoja línea por línea, sino de alguna manera como un archivo? Parece un poco espeluznante.

El código OCL es sólo una cadena. Puedes leer el archivo en la variable de cadena y enviarlo a la GPU.
 
No me funciona(
 

Es importante señalar que ahora, a finales de 2016, ya es posible reivindicar la presencia de OpenCL en los sistemas de destino.

Incluso si no hay GPU, OpenCL se ejecutará en la CPU utilizando todos los núcleos. Este es el aspecto del conjunto de dispositivos:

OpenCL  Device #0: GPU Advanced Micro Devices, Inc. Hawaii with OpenCL 2.0 (44 units, 1080 MHz, 8192 Mb, version 2117.13 (VM), rating 1760)
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)

El terminal selecciona automáticamente el dispositivo más rápido en función de la clasificación de rendimiento. También es posible seleccionar manualmente cualquier dispositivo mediante la función CLContextCreate.

Por desgracia, olvídate de OpenCL en Windows XP. Y los sistemas operativos de 32 bits en general: estamos en el año 2017.

Más desagradable es la situación de Nvidia, que básicamente está saboteando el estándar OpenCL y no implementa OpenCL 2.0. Primero saboteó la implementación de OpenCL 1.2, ahora OpenCL 2.0. Lo hace para promover su propia implementación de CUDA, lo que perjudica a toda la comunidad.

Además, Nvidia baja deliberadamente la precisión de sus tarjetas para jugadores para limitar su uso en matemáticas y estimular la compra de tarjetas especializadas (Tesla).

En este contexto, AMD parece estar ganando no sólo por sus matemáticas claramente más rápidas (las granjas de mineros en AMD suelen estar construidas), sino también por su estrategia de estándares abiertos (se han abierto mucho y están empujando hacia el dominio público). La introducción de OpenCL 2.0 en las tarjetas de AMD ha hecho que esta especificación se acerque mucho a las capacidades de CUDA y ahora ya no tiene sentido preparar el terreno para CUDA.

 
Pronto permitiremos OpenCL en MQL5 Cloud Network al menos para las implementaciones de la CPU.
Распределенные вычисления в сети MQL5 Cloud Network
Распределенные вычисления в сети MQL5 Cloud Network
  • cloud.mql5.com
Заработать деньги, продавая мощности своего компьютера для сети распределенных вычислений MQL5 Cloud Network