//============================================================================================= MQL5 === // LibreFEI v1.006 (MQL5) // Главный модуль обработки событий // Librecoin(c)2014-2017 //============================================================================================= MQL5 === // REVIEWS //------------------------------------------------------------------------------------------------------ // Fourier Extrapolator Adaptive - экстраполятор фурье творческая переработка. //============================================================================================= MQL5 === // IDEAS //------------------------------------------------------------------------------------------------------ // 12.12.2017 Идея: расчетную часть выполнить с использованием OpenCL //============================================================================================= MQL5 === // PROPERTY //------------------------------------------------------------------------------------------------------ #property strict #define ver "1.006" #property copyright "Librecoin(c)2014-2017, gpwr(c)2008-2010" #property link "https://www.mql5.com/ru/users/kirillovyv" #property description "**************************************************" #property description " Indicator LibreFEI v"+ver+" Lite (MQL5)" #property description " Extrapolator by trigonometric (multitone) model" #property description " From Russia with Love! :-)" #property description " https://www.mql5.com/ru/users/kirillovyv" #property description " Based from: gpwr(c)2008-2010, neoclassic(c)2009" #property description "**************************************************" #property version ver const string vers = "LibreFEI v"+ver; //Version //----- indicator property #property indicator_chart_window #property indicator_buffers 4 #property indicator_plots 2 #resource "Kernels/Prog01_02B.cl" as string CL_Source//Код кернел-программ можно подключать как ресурс // //============================================================================================= MQL5 === // INTERFACE //------------------------------------------------------------------------------------------------------ input int Npast = 650; //Past bars, to which trigonometric series is fitted input int Nfut = 20; //Predicted future bars input int Nharm = 9; //Min Narmonics in model input double FreqTOL = 0.0000001; //Tolerance of frequency calculations input int StartBar = 15; //С какого бара начинаем input int MSTimerSet = 500; //Установка таймера xxx миллисекунд input int nTickDelay = 5; //Интервал пропуска тиков для тестирования input ulong IterLimit = 60; //Iteration limit для Freq input bool CommentOn = false; //Вывод комментариев на экран input bool PrintOn = false; //Печать комментариев в журнал input bool OCLSelector = true; //Использовать OpenCL //============================================================================================= MQL5 === OCLSelector // Global variable definition //------------------------------------------------------------------------------------------------------ bool TimeInterrupt; int nTickSumm; //----- indicator buffers double pv[]; //0 Отображаемый буфер истории PAST double fv[]; //1 Отображаемый буфер прогноза FUTURE double pc[]; //2 Расчетный буфер истории PAST double fc[]; //3 Расчетный буфер прогноза FUTURE //----- Буфер расчетного параметра double xc[]; //Буфер расчетного параметра (Close()) //----- Включатель отладочной печати bool PrintDebugSelector=true; //----- Хендлы для объектов OpenCL int h_CL_Context=INVALID_HANDLE; //Хендл контекста int h_CL_Program=INVALID_HANDLE; //Хендл программы int h_CL_Kernel=INVALID_HANDLE; //Хендл кернела int h_CL_Buffers[]; //Хендлы буферов // //============================================================================================= MQL5 === // OnInit() - Custom indicator initialization function //------------------------------------------------------------------------------------------------------ int OnInit() { //----- initialize global variables TimeInterrupt=true; nTickSumm=0; //----- indicator parametrs IndicatorSetInteger(INDICATOR_DIGITS,_Digits); IndicatorSetString(INDICATOR_SHORTNAME,"LibreFEI"); //----- indicator buffers mapping //Прошлое - буфер отображения PAST ArraySetAsSeries(pv,true); ArrayInitialize(pv,EMPTY_VALUE); SetIndexBuffer(0,pv,INDICATOR_DATA); PlotIndexSetString(0,PLOT_LABEL,"Past"); PlotIndexSetInteger(0,PLOT_DRAW_TYPE,DRAW_LINE); PlotIndexSetInteger(0,PLOT_LINE_STYLE,STYLE_SOLID); PlotIndexSetInteger(0,PLOT_LINE_WIDTH,2); PlotIndexSetInteger(0,PLOT_LINE_COLOR,clrBlue); //Будущее - буфер отображения FUTURE ArraySetAsSeries(fv,true); ArrayInitialize(fv,EMPTY_VALUE); SetIndexBuffer(1,fv,INDICATOR_DATA); PlotIndexSetString(1,PLOT_LABEL,"Future"); PlotIndexSetInteger(1,PLOT_DRAW_TYPE,DRAW_LINE); PlotIndexSetInteger(1,PLOT_LINE_STYLE,STYLE_SOLID); PlotIndexSetInteger(1,PLOT_LINE_WIDTH,2); PlotIndexSetInteger(1,PLOT_LINE_COLOR,clrRed); PlotIndexSetInteger(1,PLOT_SHIFT,Nfut); //future data vector i=0..Nfut; Nfut corresponds to bar=StartBar //Прошлое - буфер расчета PAST - разобраться с AsSeries(), сделать false ArraySetAsSeries(pc,false); ArrayInitialize(pc,EMPTY_VALUE); SetIndexBuffer(2,pc,INDICATOR_CALCULATIONS); //Будущее - буфер расчета FUTURE ArraySetAsSeries(fc,true);//false ArrayInitialize(fc,EMPTY_VALUE); SetIndexBuffer(3,fc,INDICATOR_CALCULATIONS); //Буфер расчетного параметра ArraySetAsSeries(xc,false);//Всегда! ArrayResize(xc,Npast+1); //----- Настройки таймера и глобальных счетчиков {if(!MQLInfoInteger(MQL_TESTER))//Не тестирование { int err=-1; int count=50; {while((err!=0)&&(count>0)) { ResetLastError(); EventSetMillisecondTimer(MSTimerSet); //Установка таймера XXX миллисекунд err=GetLastError(); {if(err!=0) { Sleep(50); }}//if(err!=0) count--; }}//while((err!=0)&&(count>0)) }}//if(!MQLInfoInteger(MQL_TESTER)) //----- Подготовительные операции OpenCL {if(OCLSelector) { //----- Включатель отладочной печати PrintDebugSelector=true; //----- Хендлы для объектов OpenCL h_CL_Context=INVALID_HANDLE; //Хендл контекста h_CL_Program=INVALID_HANDLE; //Хендл программы h_CL_Kernel=INVALID_HANDLE; //Хендл кернела //----- Определение числа буферов под переменные ArrayResize(h_CL_Buffers,5);//x,ipc,im,ic,is ArrayFill(h_CL_Buffers,0,ArraySize(h_CL_Buffers),INVALID_HANDLE); //----- Создание контекста (среды) для программы OpenCL (выбор девайса) ResetLastError(); {if((h_CL_Context=CLContextCreate(CL_USE_ANY))==INVALID_HANDLE) //CL_USE_ANY - использовать любое доступное устройство с поддержкой OpenCL { Print("OpenCL not found, error:",GetLastError()); ShutDown(h_CL_Context,h_CL_Program,h_CL_Kernel,h_CL_Buffers); return(INIT_FAILED); }else{ Print("OpenCL found, Хендл на контекст OpenCL:",h_CL_Context," Error:",GetLastError()); }}//if((h_CL_Context=CLContextCreate(CL_USE_ANY))==INVALID_HANDLE) //----- Создание в контексте программы на основе кода в строке CL_Source string BuildLog=""; //Лог компиляции ResetLastError(); {if((h_CL_Program=CLProgramCreate(h_CL_Context,CL_Source,BuildLog))==INVALID_HANDLE)//В третьем параметре - лог компиляции { Print("OpenCL program create failed, error:",GetLastError()," BuildLog=",BuildLog); ShutDown(h_CL_Context,h_CL_Program,h_CL_Kernel,h_CL_Buffers,BuildLog,PrintDebugSelector); return(INIT_FAILED); }else{ Print("OpenCL program create, Хендл программы OpenCL:",h_CL_Program," Error:",GetLastError()); }}//if((h_CL_Program=CLProgramCreate(h_CL_Context,CL_Source,BuildLog))==INVALID_HANDLE) //----- Создание кернела для расчета значений функции от двух переменных string CL_Kernel_Name="TrigFit_OCL"; //Задание имени кернела - задать вручную ResetLastError(); {if((h_CL_Kernel=CLKernelCreate(h_CL_Program,CL_Kernel_Name))==INVALID_HANDLE) //Имя функции должно соответствовать имени в программной строке CL_Source { Print("OpenCL kernel create failed, error:",GetLastError()); ShutDown(h_CL_Context,h_CL_Program,h_CL_Kernel,h_CL_Buffers); return(INIT_FAILED); }else{ Print("OpenCL kernel create, Хендл кернела OpenCL:",h_CL_Kernel," Error:",GetLastError()); }}//if((h_CL_Kernel=CLKernelCreate(h_CL_Program,"Exch"))==INVALID_HANDLE) //----- Создание буферов //----- Создание буфера[0] OpenCL для значений x[] ResetLastError(); {if((h_CL_Buffers[0]=CLBufferCreate(h_CL_Context,Npast*sizeof(double),CL_MEM_READ_WRITE))==INVALID_HANDLE)//__global double *x, { Print("OpenCL buffer create failed, error:",GetLastError()); ShutDown(h_CL_Context,h_CL_Program,h_CL_Kernel,h_CL_Buffers); return(INIT_FAILED); }else{ Print("OpenCL buffer create, Хендл буфера OpenCL:",h_CL_Buffers[0]," Error:",GetLastError()); }}//if((h_CL_Buffer=CLBufferCreate(h_CL_Context,ArraySize(x)*sizeof(double),CL_MEM_READ_WRITE))==INVALID_HANDLE) //----- Создание буфера[1] OpenCL для значений ipc[] - переделать, только при изменении размерности массива ResetLastError(); {if((h_CL_Buffers[1]=CLBufferCreate(h_CL_Context,Npast*sizeof(double),CL_MEM_READ_WRITE))==INVALID_HANDLE)//__global double *ipc, { Print("OpenCL buffer create failed, error:",GetLastError()); ShutDown(h_CL_Context,h_CL_Program,h_CL_Kernel,h_CL_Buffers); return(INIT_FAILED); }else{ Print("OpenCL buffer create, Хендл буфера OpenCL:",h_CL_Buffers[1]," Error:",GetLastError()); }}//if((h_CL_Buffer=CLBufferCreate(h_CL_Context,ArraySize(x)*sizeof(double),CL_MEM_READ_WRITE))==INVALID_HANDLE) //----- Создание буфера[2] OpenCL для значений im[] ResetLastError(); {if((h_CL_Buffers[2]=CLBufferCreate(h_CL_Context,sizeof(double),CL_MEM_READ_WRITE))==INVALID_HANDLE)//__global double *m, { Print("OpenCL buffer create failed, error:",GetLastError()); ShutDown(h_CL_Context,h_CL_Program,h_CL_Kernel,h_CL_Buffers); return(INIT_FAILED); }else{ Print("OpenCL buffer create, Хендл буфера OpenCL:",h_CL_Buffers[2]," Error:",GetLastError()); }}//if((h_CL_Buffer=CLBufferCreate(h_CL_Context,ArraySize(x)*sizeof(double),CL_MEM_READ_WRITE))==INVALID_HANDLE) //----- Создание буфера[3] OpenCL для значений ic[] ResetLastError(); {if((h_CL_Buffers[3]=CLBufferCreate(h_CL_Context,sizeof(double),CL_MEM_READ_WRITE))==INVALID_HANDLE)//__global double *c, { Print("OpenCL buffer create failed, error:",GetLastError()); ShutDown(h_CL_Context,h_CL_Program,h_CL_Kernel,h_CL_Buffers); return(INIT_FAILED); }else{ Print("OpenCL buffer create, Хендл буфера OpenCL:",h_CL_Buffers[3]," Error:",GetLastError()); }}//if((h_CL_Buffer=CLBufferCreate(h_CL_Context,ArraySize(x)*sizeof(double),CL_MEM_READ_WRITE))==INVALID_HANDLE) //----- Создание буфера[4] OpenCL для значений is[] ResetLastError(); {if((h_CL_Buffers[4]=CLBufferCreate(h_CL_Context,sizeof(double),CL_MEM_READ_WRITE))==INVALID_HANDLE)//__global double *s, { Print("OpenCL buffer create failed, error:",GetLastError()); ShutDown(h_CL_Context,h_CL_Program,h_CL_Kernel,h_CL_Buffers); return(INIT_FAILED); }else{ Print("OpenCL buffer create, Хендл буфера OpenCL:",h_CL_Buffers[4]," Error:",GetLastError()); }}//if((h_CL_Buffer=CLBufferCreate(h_CL_Context,ArraySize(x)*sizeof(double),CL_MEM_READ_WRITE))==INVALID_HANDLE) }else{ }}//if(OCLSelector) //----- Выход тут return(INIT_SUCCEEDED); }//OnInit() // //============================================================================================= MQL5 === // OnDeinit() - Custom indicator iteration function | //------------------------------------------------------------------------------------------------------ void OnDeinit(const int reason){ Comment(""); return; }//OnDeinit() // //============================================================================================= MQL5 === // OnTimer() //------------------------------------------------------------------------------------------------------ void OnTimer(){ TimeInterrupt=true; nTickSumm=0; }//OnTimer() // //============================================================================================= MQL5 === // OnCalculate() - 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[]) { //----- Check for insufficient data {if(rates_totalFreqTOL)&&(IterCountFreqTOL) w=MathArccos(beta/2.0); ////----- Сравнение расчетов //double m1,c1,s1; //m1=m;c1=c;s1=s; //TrigFitOCL(x,ipc,n,w,m,c,s); //Print("1. m=",DoubleToString(m,8)," c=",DoubleToString(c,8)," s=",DoubleToString(s,8)); //m=m1;c=c1;s=s1; //TrigFit(x,ipc,n,w,m,c,s); //Print("2. m=",DoubleToString(m,8)," c=",DoubleToString(c,8)," s=",DoubleToString(s,8)); {if(OCLSelector) { TrigFitOCL(x,ipc,n,w,m,c,s); }else{ TrigFit(x,ipc,n,w,m,c,s); }}//if(OCLSelector) }//Freq() // //============================================================================================= MQL5 === // TrigFitOCL() - Least-squares fitting of trigonometric series //------------------------------------------------------------------------------------------------------ void TrigFitOCL(double& x[],double& ipc[],int n,double w,double& m,double& c,double& s) { //----- Транзитные переменные double im[1];//2 для m double ic[1];//3 для c double is[1];//4 для s im[0]=m; ic[0]=c; is[0]=s; //----- Устанавливаем в качестве 0-го параметра функции OpenCL (кернела) буфер по хендлу h_CL_Buffers[0] ResetLastError(); {if(!CLSetKernelArgMem(h_CL_Kernel,0,h_CL_Buffers[0])) { Print("OpenCL set buffer failed, error:",GetLastError()); ShutDown(h_CL_Context,h_CL_Program,h_CL_Kernel,h_CL_Buffers); return; }else{ //Print("OpenCL set buffer, Error:",GetLastError()); }}//if(CLSetKernelArgMem(h_CL_Kernel,0,h_CL_Buffer)) //----- Устанавливаем в качестве 1-го параметра функции OpenCL (кернела) буфер по хендлу h_CL_Buffers[1] ResetLastError(); {if(!CLSetKernelArgMem(h_CL_Kernel,1,h_CL_Buffers[1])) { Print("OpenCL set buffer failed, error:",GetLastError()); ShutDown(h_CL_Context,h_CL_Program,h_CL_Kernel,h_CL_Buffers); return; }else{ //Print("OpenCL set buffer, Error:",GetLastError()); }}//if(CLSetKernelArgMem(h_CL_Kernel,0,h_CL_Buffer_ipc)) //----- Устанавливаем в качестве 2-го параметра функции OpenCL (кернела) значение переменной n ResetLastError(); {if(!CLSetKernelArg(h_CL_Kernel,2,n)) { Print("OpenCL set buffer failed, error:",GetLastError()); ShutDown(h_CL_Context,h_CL_Program,h_CL_Kernel,h_CL_Buffers); return; }else{ //Print("OpenCL set buffer, Error:",GetLastError()); }}//if(CLSetKernelArgMem(h_CL_Kernel,0,h_CL_Buffer_ipc)) //----- Устанавливаем в качестве 3-го параметра функции OpenCL (кернела) значение переменной w ResetLastError(); {if(!CLSetKernelArg(h_CL_Kernel,3,w)) { Print("OpenCL set buffer failed, error:",GetLastError()); ShutDown(h_CL_Context,h_CL_Program,h_CL_Kernel,h_CL_Buffers); return; }else{ //Print("OpenCL set buffer, Error:",GetLastError()); }}//if(CLSetKernelArgMem(h_CL_Kernel,0,h_CL_Buffer_ipc)) //----- Устанавливаем в качестве 4-го параметра функции OpenCL (кернела) буфер по хендлу h_CL_Buffers[2] ResetLastError(); {if(!CLSetKernelArgMem(h_CL_Kernel,4,h_CL_Buffers[2])) { Print("OpenCL set buffer failed, error:",GetLastError()); ShutDown(h_CL_Context,h_CL_Program,h_CL_Kernel,h_CL_Buffers); return; }else{ //Print("OpenCL set buffer, Error:",GetLastError()); }}//if(CLSetKernelArgMem(h_CL_Kernel,0,h_CL_Buffer_ipc)) //----- Устанавливаем в качестве 5-го параметра функции OpenCL (кернела) буфер по хендлу h_CL_Buffers[3] ResetLastError(); {if(!CLSetKernelArgMem(h_CL_Kernel,5,h_CL_Buffers[3])) { Print("OpenCL set buffer failed, error:",GetLastError()); ShutDown(h_CL_Context,h_CL_Program,h_CL_Kernel,h_CL_Buffers); return; }else{ //Print("OpenCL set buffer, Error:",GetLastError()); }}//if(CLSetKernelArgMem(h_CL_Kernel,0,h_CL_Buffer_ipc)) //----- Устанавливаем в качестве 6-го параметра функции OpenCL (кернела) буфер по хендлу h_CL_Buffers[4] ResetLastError(); {if(!CLSetKernelArgMem(h_CL_Kernel,6,h_CL_Buffers[4])) { Print("OpenCL set buffer failed, error:",GetLastError()); ShutDown(h_CL_Context,h_CL_Program,h_CL_Kernel,h_CL_Buffers); return; }else{ //Print("OpenCL set buffer, Error:",GetLastError()); }}//if(!CLSetKernelArgMem(h_CL_Kernel,6,h_CL_Buffers[4])) //----- Записываем исходные значения x[] в буфер по хендлу h_CL_Buffers[0] ResetLastError(); uint nElementsWrite=CLBufferWrite(h_CL_Buffers[0],x,0,0,n); {if(nElementsWrite<(uint)n) { Print("OpenCL buffer x write failed, nElementsWrite=",nElementsWrite," error:",GetLastError()); ShutDown(h_CL_Context,h_CL_Program,h_CL_Kernel,h_CL_Buffers); return; }else{ //Print("OpenCL buffer write, nElementsWrite=",nElementsWrite," error:",GetLastError()); }}//if(nElementsWrite<=0) //----- Записываем исходные значения ipc[] в буфер по хендлу h_CL_Buffers[1] ResetLastError(); nElementsWrite=CLBufferWrite(h_CL_Buffers[1],ipc,0,0,n); {if(nElementsWrite<(uint)n) { Print("OpenCL buffer ipc write failed, nElementsWrite=",nElementsWrite," error:",GetLastError()); ShutDown(h_CL_Context,h_CL_Program,h_CL_Kernel,h_CL_Buffers); return; }else{ //Print("OpenCL buffer write, nElementsWrite=",nElementsWrite," error:",GetLastError()); }}//if(nElementsWrite<=0) //----- Записываем исходное значение m в буфер по хендлу h_CL_Buffers[2] ResetLastError(); nElementsWrite=CLBufferWrite(h_CL_Buffers[2],im,0,0,1); {if(nElementsWrite<1) { Print("OpenCL buffer write failed, nElementsWrite=",nElementsWrite," error:",GetLastError()); ShutDown(h_CL_Context,h_CL_Program,h_CL_Kernel,h_CL_Buffers); return; }else{ //Print("OpenCL buffer write, nElementsWrite=",nElementsWrite," error:",GetLastError()); }}//if(nElementsWrite<=0) //----- Записываем исходное значение c в буфер по хендлу h_CL_Buffers[3] ResetLastError(); nElementsWrite=CLBufferWrite(h_CL_Buffers[3],ic,0,0,1); {if(nElementsWrite<1) { Print("OpenCL buffer write failed, nElementsWrite=",nElementsWrite," error:",GetLastError()); ShutDown(h_CL_Context,h_CL_Program,h_CL_Kernel,h_CL_Buffers); return; }else{ //Print("OpenCL buffer write, nElementsWrite=",nElementsWrite," error:",GetLastError()); }}//if(nElementsWrite<=0) //----- Записываем исходное значение s в буфер по хендлу h_CL_Buffers[4] ResetLastError(); nElementsWrite=CLBufferWrite(h_CL_Buffers[4],is,0,0,1); {if(nElementsWrite<1) { Print("OpenCL buffer write failed, nElementsWrite=",nElementsWrite," error:",GetLastError()); ShutDown(h_CL_Context,h_CL_Program,h_CL_Kernel,h_CL_Buffers); return; }else{ //Print("OpenCL buffer write, nElementsWrite=",nElementsWrite," error:",GetLastError()); }}//if(nElementsWrite<=0) //----- Запускаем выполнение кернела ResetLastError(); {if(!CLExecute(h_CL_Kernel)) { Print("OpenCL execute failed, error:",GetLastError()); ShutDown(h_CL_Context,h_CL_Program,h_CL_Kernel,h_CL_Buffers); return; }else{ //Print("OpenCL execute, error:",GetLastError()); }}//if(!CLExecute(h_CL_Kernel)) //----- Считываем полученные значения в массивы //Print("Из буфера прочитано ",CLBufferRead(h_CL_Buffers[0],x,0,0,5)," элементов"); CLBufferRead(h_CL_Buffers[0],x,0,0,n); //Print("Из буфера прочитано ",CLBufferRead(h_CL_Buffers[1],ipc,0,0,3)," элементов"); CLBufferRead(h_CL_Buffers[1],ipc,0,0,n); //Print("Из буфера прочитано ",CLBufferRead(h_CL_Buffers[2],im,0,0,1)," элементов"); CLBufferRead(h_CL_Buffers[2],im,0,0,1); m=im[0]; //Print("Из буфера прочитано ",CLBufferRead(h_CL_Buffers[3],ic,0,0,1)," элементов"); CLBufferRead(h_CL_Buffers[3],ic,0,0,1); c=ic[0]; //Print("Из буфера прочитано ",CLBufferRead(h_CL_Buffers[4],is,0,0,1)," элементов"); CLBufferRead(h_CL_Buffers[4],is,0,0,1); s=is[0]; return; }//TrigFitOCL() // //============================================================================================= MQL5 === // TrigFit() - Least-squares fitting of trigonometric series //------------------------------------------------------------------------------------------------------ void TrigFit( double &x[], double &ipc[], int n, double w, double &m, double &c, double &s ) { //c=ipc[0]; double Sc =0.0; double Ss =0.0; double Scc=0.0; double Sss=0.0; double Scs=0.0; double Sx =0.0; double Sxc=0.0; double Sxs=0.0; {for(int i=0;i