İşte herhangi bir DLL olmadan doğrudan MetaTrader 5 terminalinde OpenCL ile yapabilecekleriniz - sayfa 4
Ticaret fırsatlarını kaçırıyorsunuz:
- Ücretsiz ticaret uygulamaları
- İşlem kopyalama için 8.000'den fazla sinyal
- Finansal piyasaları keşfetmek için ekonomik haberler
Kayıt
Giriş yap
Gizlilik ve Veri Koruma Politikasını ve MQL5.com Kullanım Şartlarını kabul edersiniz
Hesabınız yoksa, lütfen kaydolun
Evet, OCL'ye biraz aşinayım, farkındayım. Bu nedenle, tüm danışmanı haritaya yüklemeniz gerekmez, paralel kodun bölümlerinin yüklenmesine izin verin, kural olarak bunlar tüm kodun yüzdeleridir.
NVIDIA 780GTX mevcutsa neden optimizasyon sırasında yalnızca CPU çekirdeklerini görüyorum (Core i5, 8 çekirdek - 8 aracılar)?
Kodunuzda OpenCL kullanıyor musunuz?
Büyük olasılıkla, kodlarınızın herhangi birinin grafik kartına yüklenmesi gerektiğini düşünüyorsunuz. Ne doğru değil.
Her şeyin nasıl çalıştığının ayrıntılı olarak açıklandığı MetaTrader 5'teki OpenCL ile ilgili makalelerimizi okumanızı şiddetle tavsiye ederim:
Önemli bir ivme elde etmek için tüm danışmanı GPU'ya göndermeniz gerekir, ancak bunun için kendi test cihazınızı yazmanız gerekir.
İşte böyle bir test cihazının bir örneği, ticaret mantığı olan bir sinir ağı , OCL kodu:
//Функция для ядра
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"
kodun devamı:
" // (+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"
);
}
//————————————————————————————————————————————————————————————————————————————————————————————————
Bu, yalnızca MQL5 kodundaki GPU üzerindeki hesaplamaların değil, aynı zamanda terminalin grafik yeteneklerinin bir gösterimidir:
Bir komut dosyası biçimindeki tam kaynak kodu ektedir. OpenCL 1.2'deki hata düzeltildi.
kodun devamı:
Bu arada, kodu OCL'ye satır sayfası olarak değil de bir şekilde dosya olarak göndermek mümkün müdür? Ve bu korkutucu görünüyor.
Bu arada, kodu OCL'ye satır sayfası olarak değil de bir şekilde dosya olarak göndermek mümkün müdür? Ve bu korkutucu görünüyor.
2016'nın sonunda, hedef sistemlerde OpenCL'nin varlığına bahis yapmanın zaten mümkün olduğunu belirtmek önemlidir.
GPU olmasa bile, OpenCL tüm çekirdekleri kullanarak CPU üzerinde çalışacaktır. Cihaz seti şöyle görünür:
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 )
Terminal, performans derecesine göre en hızlı cihazı otomatik olarak seçer. CLContextCreate işlevi aracılığıyla herhangi bir cihazı manuel olarak da seçebilirsiniz.
Ne yazık ki, Windows XP'de OpenCL'yi unutmanız gerekiyor. Ve genel olarak, yaklaşık 32 bit işletim sistemleri - 2017 burunda.
Daha da sıkıntılı olan ise OpenCL standardını sabote eden ve OpenCL 2.0'ı uygulamayan Nvidia'dır. Önce OpenCL 1.2'nin, şimdi ise OpenCL 2.0'ın uygulanmasını sabote etti. Bunu, tüm topluluğa zarar veren kendi CUDA uygulamasını desteklemek için yapıyor.
Ayrıca Nvidia, matematikte kullanımlarını sınırlamak ve özel kartların (Tesla) satın alınmasını teşvik etmek için oyun kartlarının doğruluğunu kasıtlı olarak düşürür.
Bu arka plana karşı, AMD yalnızca açıkça daha hızlı matematik hesaplamaları (AMD'deki madenci çiftlikleri genellikle toplar) nedeniyle değil, aynı zamanda açık standart stratejileri (çok fazla açtılar ve halka tanıttılar) nedeniyle avantajlı görünüyor. AMD kartlarında OpenCL 2.0'ın piyasaya sürülmesi, bu özelliği CUDA'nın yeteneklerine çok yaklaştırdı ve artık CUDA'ya güvenmenin hiçbir anlamı yok.