LibreOCL/Lesson01/Part02/Prog01_02A/Prog01_02A.mq5
super.admin 10c769ed25 convert
2025-05-30 15:03:43 +02:00

367 lines
No EOL
30 KiB
MQL5

//============================================================================================= MQL5 ===
// LibreFEI v1.005 (MQL5)
// Главный модуль обработки событий
// Librecoin(c)2014-2017
//============================================================================================= MQL5 ===
// REVIEWS
//------------------------------------------------------------------------------------------------------
// Fourier Extrapolator Adaptive - экстраполятор фурье творческая переработка.
//============================================================================================= MQL5 ===
// IDEAS
//------------------------------------------------------------------------------------------------------
// 12.12.2017 Идея: расчетную часть выполнить с использованием OpenCL
//============================================================================================= MQL5 ===
// PROPERTY
//------------------------------------------------------------------------------------------------------
#define ver "1.005"
#property copyright "Librecoin(c)2014-2017, gpwr(c)2008-2010"
#property link "https://www.mql5.com/ru/users/kirillovyv"
#property strict
#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
//============================================================================================= 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; //Печать комментариев в журнал
//============================================================================================= MQL5 ===
// 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[]; //Буфер расчетного параметра
//
//datetime xTime = D'2017.09.13 21:57:59';//Время начала вывода протоколов
//datetime xTimeStop = D'2017.09.13 23:55:55';//Время окончания вывода протоколов
//
//============================================================================================= 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
ArraySetAsSeries(pc,true);
ArrayInitialize(pc,EMPTY_VALUE);
SetIndexBuffer(2,pc,INDICATOR_CALCULATIONS);
//Будущее - буфер расчета FUTURE
ArraySetAsSeries(fc,true);//false
ArrayInitialize(fc,EMPTY_VALUE);
SetIndexBuffer(3,fc,INDICATOR_CALCULATIONS);
//Буфер расчетного параметра
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))
//-----
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_total<Npast+StartBar+1)
{
{if(PrintOn)
{
Print("Error: not enough bars in history!"
+" Total="+IntegerToString(rates_total)
+" needed="+IntegerToString(Npast+StartBar+1));
}}//if(PrintOn)
return(0);
}}//if(rates_total<Npast)
//----- Проверка необходимости пересчета по тикам
{if(MQLInfoInteger(MQL_TESTER))
{
nTickSumm++;
{if(MathMod(nTickSumm,nTickDelay)<1.0)
{
nTickSumm=0;
TimeInterrupt=true;
}}//if(MathMod(nTickSumm,7)<1.0)
}}//if(MQLInfoInteger(MQL_TESTER))
//----- Проверка необходимости пересчета по таймеру
{if(rates_total<=prev_calculated)//размер входных таймсерий меньше или равен, чем ранее обработано (обычно размер входных на предшествующем тике)
{//Изменений нет - проверяем таймер
{if(!TimeInterrupt)//если нет прерывания от msec таймера
{
return(rates_total); //Сваливаем, ибо нет изменений и прерывания таймера
}else{//есть прерывание таймера - сбрасываем и выполняем расчет
TimeInterrupt=false;
}}//if(!TimeInterrupt)
}}//if(rates_total<=prev_calculated)
//----- Определение серийности массивов данных
ArraySetAsSeries(open,true);
ArraySetAsSeries(close,true);
ArraySetAsSeries(high,true);
ArraySetAsSeries(low,true);
ArraySetAsSeries(spread,true);
//----- Заполнение исходного массива для расчета
{for(int i=0;i<Npast+1;i++)
{
xc[i]=close[i+StartBar];
}}//for(int i=0;Npast+1;i++)
Calc_Fourier(xc,pc,fc,Npast,Nharm);
//----- Перекладка массивов для отображения
//Заполнение исходного массива для расчета прогноза
{for(int i=0;i<Npast;i++)
{
xc[i]=close[i];
}}//for(int i=0;i<Npast;i++)
//----- Расчет и вывод индикаторных буферов и справочной информации
{if(CommentOn)
{
Comment( "LibreFEI"+" "+
string(TimeCurrent())+" "+
"ST="+IntegerToString(StartBar)+" "+
"NF="+IntegerToString(Nfut)+" "+
"NP="+IntegerToString(Npast)+" "+
"NH="+IntegerToString(Nharm)+" "
);
}}//if(CommentOn)
{if(PrintOn)
{
Print( string(TimeCurrent())+" "+
"NP="+IntegerToString(Npast)+" "+
"NH="+IntegerToString(Nharm)+" "
);
}}//if(PrintOn)
PlotIndexSetInteger(0,PLOT_DRAW_TYPE,DRAW_NONE); //pv
PlotIndexSetInteger(1,PLOT_DRAW_TYPE,DRAW_NONE); //fv
PlotIndexSetInteger(2,PLOT_DRAW_TYPE,DRAW_NONE);
PlotIndexSetInteger(3,PLOT_DRAW_TYPE,DRAW_NONE);
ArrayInitialize(pv,EMPTY_VALUE);
ArrayInitialize(fv,EMPTY_VALUE);
ArrayCopy(pv,pc,0,0,Npast+StartBar+1);
{for(int i=0;i<=Nfut;i++)
{
fv[Nfut-i]=fc[i];
}}//for(int i=0;i<=Nfut;i++)
PlotIndexSetInteger(0,PLOT_DRAW_TYPE,DRAW_LINE); //pv
PlotIndexSetInteger(1,PLOT_DRAW_TYPE,DRAW_LINE); //fv
PlotIndexSetInteger(2,PLOT_DRAW_TYPE,DRAW_LINE);
PlotIndexSetInteger(3,PLOT_DRAW_TYPE,DRAW_LINE);
ChartRedraw(ChartID());
//-----
return(rates_total);
}//OnCalculate()
//
//============================================================================================= MQL5 ===
// Calc_Fourier() - Calc_Fourier
//------------------------------------------------------------------------------------------------------
void Calc_Fourier(double &x[],double &p[],double &f[],int iNpast,int iNharm){
//-----
//----- initialize indicator buffers to EMPTY_VALUE
ArrayInitialize(p,EMPTY_VALUE);
ArrayInitialize(f,EMPTY_VALUE);
//----- Find average of past values
double av=0.0;
//Заполнение исходного массива для расчета и накопление суммы для вычисления среднего
{for(int i=0;i<iNpast;i++)
{
av=av+x[i];
}}//for(int i=0;i<Npast;i++)
//Расчет среднего
av=av/iNpast;
//----- initialize model outputs
{for(int i=0;i<iNpast;i++)
{
p[i]=av; //Прошлое заполняем средним значением от [0] на максимальную глубину
}}//for(int i=0;i<iNpast;i++)
{for(int i=0;i<=Nfut;i++)
{
f[i]=av; //Будущее заполняем средним значением от [0] на глубину Nfut
}}//for(int i=0;i<iNpast;i++)
//----- fit trigonometric model and calculate predictions
double w,m,c,s;
{for(int harm=1;harm<=iNharm;harm++)//Nharmm - раз прогоняемся в цикле
{
Freq(x,p,iNpast,w,m,c,s);
double mcc=0.0;
double ss=0.0;
{for(int i=0;i<iNpast;i++)
{
mcc=m+c*MathCos(w*i);
ss=s*MathSin(w*i);
p[i]+=mcc+ss;
{if(i<=Nfut)
{
f[i]+=mcc-ss;
}}//if(i<=Nfut)
}}//for(int i=0;i<iNpast;i++)
}}//for(int harm=1;harm<=Nharmm;harm++)
return;
}//Calc_Fourier()
//
//============================================================================================= MQL5 ===
// Freq() - Quinn and Fernandes algorithm for finding frequency
//------------------------------------------------------------------------------------------------------
void Freq(double& x[],double& ipc[],int n,double& w,double& m,double& c,double& s)
{
double z[];
ArrayResize(z,n);
double alpha=0.0;
double beta=2.0;
z[0]=x[0]-ipc[0];
ulong IterCount=0;
{while((MathAbs(alpha-beta)>FreqTOL)&&(IterCount<IterLimit))
{
alpha=beta;
z[1]=x[1]-ipc[1]+alpha*z[0];
double num=z[0]*z[1];
double den=z[0]*z[0];
{for(int i=2;i<n;i++)
{
z[i]=x[i]-ipc[i]+alpha*z[i-1]-z[i-2];
num+=z[i-1]*(z[i]+z[i-2]);
den+=z[i-1]*z[i-1];
}}//for(int i=2;i<n;i++)
beta=num/den;
IterCount++;
}}//while(MathAbs(alpha-beta)>FreqTOL)
w=MathArccos(beta/2.0);
TrigFit(x,ipc,n,w,m,c,s);
}//Freq()
//
//============================================================================================= MQL5 ===
// TrigFit() - Least-squares fitting of trigonometric series
//------------------------------------------------------------------------------------------------------
void TrigFit(double& x[],double& ipc[],int n,double w,double& m,double& c,double& s)
{
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<n;i++)
{
double cos_w_i=MathCos(w*i);
double sin_w_i=MathSin(w*i);
double dx=x[i]-ipc[i];
Sc +=cos_w_i;
Ss +=sin_w_i;
Scc+=cos_w_i*cos_w_i;
Sss+=sin_w_i*sin_w_i;
Scs+=cos_w_i*sin_w_i;
Sx +=dx;
Sxc+=dx*cos_w_i;
Sxs+=dx*sin_w_i;
}}//for(int i=0;i<n;i++)
Sc /=n;
Ss /=n;
Scc/=n;
Sss/=n;
Scs/=n;
Sx /=n;
Sxc/=n;
Sxs/=n;
{if(w==0.0)
{
m=Sx;
c=0.0;
s=0.0;
}else{
// calculating a, b, and m
double den=MathPow(Scs-Sc*Ss,2)-(Scc-Sc*Sc)*(Sss-Ss*Ss);
c=((Sxs-Sx*Ss)*(Scs-Sc*Ss)-(Sxc-Sx*Sc)*(Sss-Ss*Ss))/den;
s=((Sxc-Sx*Sc)*(Scs-Sc*Ss)-(Sxs-Sx*Ss)*(Scc-Sc*Sc))/den;
m=Sx-c*Sc-s*Ss;
}}//if(w==0.0)
return;
}//TrigFit()
//