327 lines
28 KiB
MQL5
327 lines
28 KiB
MQL5
//+------------------------------------------------------------------+
|
|
//| teste-regressao.mq5 |
|
|
//| Copyright 2020, OS Corp. |
|
|
//| http://www.os.org |
|
|
//+------------------------------------------------------------------+
|
|
#property copyright "Copyright 2020, OS Corp."
|
|
#property link "http://www.os.org"
|
|
#property version "1.001"
|
|
|
|
#include <Math\Alglib\dataanalysis.mqh>
|
|
#include <Math\Stat\Math.mqh>
|
|
#include <Graphics\Graphic.mqh>
|
|
#include <Trade\SymbolInfo.mqh>
|
|
|
|
#include <oslib\osc\est\CStat.mqh>
|
|
|
|
|
|
enum ENUM_TDN_TIPO_EXEC{
|
|
TEX_NOW_MINUS_MINUTE , // NOW_MINUS_MINUTE execucao continua. tempo atual menos qtd minutos configurados.
|
|
TEX_FROM_TO , // FROM_TO execucao unica, no intervalo informado.
|
|
TEX_FROM_TO_INTERV_CUM , // FROM_TO_INTERV_CUM execucao unica, no intervalo informado com incremento de minutos configurados (acumulativa).
|
|
TEX_FROM_TO_INTERV_DESL, // FROM_TO_INTERV_DESL execucao unica, no intervalo informado com incremento de minutos configurados (deslizante).
|
|
};
|
|
|
|
enum ENUM_TDN_TIPO_DADO{
|
|
TDA_PRICE , // TDA_PRICE distribuicao do preco.
|
|
TDA_PRICE_RET, // TDA_PRICE_RET distribuicao do retorno.
|
|
TDA_VOLUME , // TDA_VOLUME distribuicao do volume.
|
|
};
|
|
|
|
enum ENUM_TDN_TIPO_PESO{
|
|
TPE_VOLUME , // TPE_VOLUME ponderado pelo volume.
|
|
TPE_1 , // TPE_1 nao ponderado.
|
|
};
|
|
|
|
|
|
|
|
#property script_show_inputs
|
|
input string IN_SYMBOL = "VAZIO";
|
|
input int IN_WINDOW_MINUTO = 15 ;
|
|
input double IN_SLIP_MINUTO = 1 ; // SLIP quanto exec unica e janela deslizante
|
|
input int IN_REFRESH_IN_MILIS = 200;
|
|
input ENUM_TDN_TIPO_EXEC IN_TIPO_EXEC = TEX_FROM_TO_INTERV_CUM;
|
|
input ENUM_TDN_TIPO_DADO IN_TIPO_DADO = TDA_PRICE;
|
|
input ENUM_TDN_TIPO_PESO IN_TIPO_PESO = TPE_VOLUME;
|
|
input datetime IN_1X_DT_INI = D'2020.10.30 09:30:00';
|
|
input datetime IN_1X_DT_FIM = D'2020.10.30 17:54:00';
|
|
//+------------------------------------------------------------------+
|
|
//| Script program start function |
|
|
//+------------------------------------------------------------------+
|
|
|
|
void OnStart(){
|
|
|
|
// resolvendo o ticker...
|
|
string symbol_str;
|
|
if( IN_SYMBOL =="VAZIO"){ symbol_str = _Symbol; }else{symbol_str=IN_SYMBOL;}
|
|
CSymbolInfo cSymb;
|
|
cSymb.Name(symbol_str);
|
|
|
|
// resolvendo o tamanho do tick e a quantidade de digitos...
|
|
double tickSize;
|
|
int digits ;
|
|
if( IN_TIPO_DADO==TDA_PRICE || IN_TIPO_DADO==TDA_PRICE_RET ){
|
|
tickSize = cSymb.TickSize();
|
|
digits = cSymb.Digits();
|
|
Print(__FUNCTION__, " ticksize=",tickSize, " digitos=", digits);
|
|
}else{
|
|
tickSize = 1;
|
|
digits = 0;
|
|
}
|
|
|
|
// processando...
|
|
switch(IN_TIPO_EXEC){
|
|
// processando em loop com os ultimos IN_WINDOW_MINUTO...
|
|
case TEX_NOW_MINUS_MINUTE:
|
|
{
|
|
while(true){
|
|
processar(IN_WINDOW_MINUTO,symbol_str,cSymb.TickSize(),cSymb.Digits(),IN_TIPO_DADO,IN_TIPO_PESO );
|
|
Sleep(IN_REFRESH_IN_MILIS);
|
|
}
|
|
}
|
|
break;
|
|
|
|
// processando uma unica vez com os ticks do intervalo de datas informado...
|
|
case TEX_FROM_TO:
|
|
processar(symbol_str, IN_1X_DT_INI, IN_1X_DT_FIM,cSymb.TickSize(),cSymb.Digits(),IN_TIPO_DADO,IN_TIPO_PESO); break;
|
|
|
|
// processa uma vez o intervalo de dadas com janela acumulativa. Acumula a cada IN_WINDOW_MINUTO e refresh a cada IN_REFRESH_IN_MILIS;
|
|
case TEX_FROM_TO_INTERV_CUM:
|
|
processarIntervaloAcumulativo(symbol_str, IN_1X_DT_INI, IN_1X_DT_FIM, cSymb.TickSize(),cSymb.Digits(), IN_WINDOW_MINUTO, IN_REFRESH_IN_MILIS,IN_TIPO_DADO,IN_TIPO_PESO); break;
|
|
|
|
// processa uma vez o intervalo de datas com janela deslizante. Janela a cada IN_WINDOW_MINUTO e refresh a cada IN_REFRESH_IN_MILIS;
|
|
case TEX_FROM_TO_INTERV_DESL:
|
|
processarIntervaloDeslizante(symbol_str, IN_1X_DT_INI, IN_1X_DT_FIM, cSymb.TickSize(),cSymb.Digits(), IN_WINDOW_MINUTO, IN_SLIP_MINUTO, IN_REFRESH_IN_MILIS,IN_TIPO_DADO,IN_TIPO_PESO); break;
|
|
}
|
|
}
|
|
|
|
bool processarIntervaloDeslizante(string symb, datetime from, datetime to, double tickSize, int digits, int minutosAcum, double slip, int refresInMillis,ENUM_TDN_TIPO_DADO tpDado, ENUM_TDN_TIPO_PESO tpPeso){
|
|
|
|
datetime dtIni = from;
|
|
datetime dtFim = from + minutosAcum*60;
|
|
while( dtFim <= to ){
|
|
processar(symb, dtIni, dtFim, tickSize, digits, tpDado, tpPeso );
|
|
dtIni = dtIni + (int)(slip*60);
|
|
dtFim = dtIni + minutosAcum*60;
|
|
Sleep(refresInMillis);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool processarIntervaloAcumulativo(string symb, datetime from, datetime to, double tickSize, int digits, int minutosAcum, int refresInMillis,ENUM_TDN_TIPO_DADO tpDado, ENUM_TDN_TIPO_PESO tpPeso){
|
|
|
|
datetime dtFimAcum = from + minutosAcum*60;
|
|
while( dtFimAcum <= to ){
|
|
processar(symb, from, dtFimAcum, tickSize, digits, tpDado, tpPeso );
|
|
dtFimAcum = dtFimAcum + minutosAcum*60;
|
|
Sleep(refresInMillis);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool processar(int qtdMinutos, string symb, double tickSize, int digits,ENUM_TDN_TIPO_DADO tpDado, ENUM_TDN_TIPO_PESO tpPeso){
|
|
//datetime from = D'2020.07.01 10:05:00';
|
|
//datetime to = D'2020.07.01 10:15:00';
|
|
datetime to = TimeCurrent();
|
|
datetime from = to-qtdMinutos*60;
|
|
return processar(symb, from, to, tickSize, digits, tpDado, tpPeso);
|
|
}
|
|
|
|
bool processar(string symb, datetime from, datetime to, double tickSize, int digits, ENUM_TDN_TIPO_DADO tpDado, ENUM_TDN_TIPO_PESO tpPeso){
|
|
|
|
CStat stat;
|
|
|
|
// Print(":-| ",__FUNCTION__,": Copiando ticks...");
|
|
MqlTick ticks[];
|
|
int qtdTicks = CopyTicksRange(symb, ticks, COPY_TICKS_TRADE, from*1000, to*1000);
|
|
if( qtdTicks < 2){
|
|
Print(":-| ",__FUNCTION__,": ", qtdTicks," Copiados. LastError:",GetLastError());
|
|
return false;
|
|
}
|
|
|
|
// Print(":-| ",__FUNCTION__,": Inicializando os arrays de precos e volumes last...");
|
|
double last [];
|
|
double vol [], volSel[], volBuy[];
|
|
double price[];
|
|
ArrayResize(last ,qtdTicks);
|
|
ArrayResize(vol ,qtdTicks);
|
|
ArrayResize(volSel,qtdTicks);
|
|
ArrayResize(volBuy,qtdTicks);
|
|
for(int i=1; i<qtdTicks; i++){
|
|
// selecionando somente quando muda o preco...
|
|
last[i]= (tpDado==TDA_PRICE ) ? (int) ticks[i].last :
|
|
// (tpDado==TDA_PRICE_RET ) ? (int) (ticks[i].last - ticks[i-1].last):
|
|
(int)MathAbs( log(ticks[i].volume) ) ;
|
|
vol [i]= (tpPeso==TPE_VOLUME) ? (int)ticks[i].volume : 1 ;
|
|
|
|
//if( ((ticks[i].flags&TICK_FLAG_BUY )==TICK_FLAG_BUY ) ) volBuy[i]=(int)ticks[i].volume;
|
|
//if( ((ticks[i].flags&TICK_FLAG_SELL)==TICK_FLAG_SELL ) ) volSel[i]=(int)ticks[i].volume;
|
|
}
|
|
|
|
// Print(":-| ",__FUNCTION__,": Chamando a funcao que calcula a distribuicao...");
|
|
double freq[];
|
|
stat.calcDist(last,vol,freq,price);
|
|
|
|
// Print(":-| ",__FUNCTION__,": Plotando grafico da distribuicao...");
|
|
//GraphPlot (price,dist,CURVE_HISTOGRAM);
|
|
|
|
double mean =0; // [out] Variável para a média (1º momento)
|
|
double variance=0; // [out] Variável para a variância (2º momento)
|
|
double skewness=0; // [out] Variável para a assimetria (3º momento)
|
|
double kurtosis=0; // [out] Variável para a curtose (4º momento)
|
|
double dpadrao =0; // desvio padrao
|
|
double cv =0; // coeficiente de variacao
|
|
|
|
//if( MathMoments( last , // [in] Array com dados
|
|
// mean , // [out] Variável para a média(1º momento)
|
|
// variance, // [out] Variável para a variância (2º momento)
|
|
// skewness, // [out] Variável para a assimetria (3º momento)
|
|
// kurtosis) ) {
|
|
// dpadrao = MathSqrt(variance);
|
|
|
|
if( stat.describe(last, vol, mean, variance, skewness, kurtosis, dpadrao, cv ) ){
|
|
|
|
|
|
// Print(":-| ",__FUNCTION__,": mean:" ,mean ,
|
|
// " \nvariance:" ,variance,
|
|
// " \nskewness(assimetria):",skewness,
|
|
// " \nkurtosis:" ,kurtosis,
|
|
// " \ndpadrao:" ,dpadrao
|
|
// );
|
|
}else{
|
|
Print(":-( ",__FUNCTION__,": ERRO calculando momentos!!");
|
|
}
|
|
|
|
CGraphic graphic;
|
|
|
|
string name = "distrib";
|
|
int chart = 0;
|
|
if(ObjectFind(chart,name)<0) graphic.Create(chart,name,0,0,0,700,267);
|
|
else graphic.Attach(chart,name);
|
|
|
|
// X: precos, Y:frequencias
|
|
CCurve *curve=graphic.CurveAdd(price,freq,CURVE_HISTOGRAM);
|
|
curve.Name("volume");
|
|
|
|
// bolinha com a media...
|
|
double meanx[]; // desvio padrao
|
|
double meany[]; // frequencia absoluta do desvio padrao
|
|
ArrayResize(meanx,1);
|
|
ArrayResize(meany,1);
|
|
meanx[0] = normalizePrice(mean,tickSize,digits);
|
|
meany[0] = freq[ ArraySearchSerial(price,meanx[0]) ];
|
|
CCurve *curveMedia=graphic.CurveAdd(meanx,meany,CURVE_HISTOGRAM);
|
|
curveMedia.Name("mean:"+DoubleToString(mean,digits));
|
|
curveMedia.HistogramWidth(2);
|
|
curveMedia.PointsFill(true);
|
|
curveMedia.Color(clrGold);
|
|
|
|
// bolinha com o desvio padrao acima e abaixo da media...
|
|
double dpx[]; // desvio padrao
|
|
double dpy[]; // frequencia absoluta do desvio padrao
|
|
ArrayResize(dpx,4);
|
|
ArrayResize(dpy,4);
|
|
|
|
dpx[0] = normalizePrice(mean-dpadrao*1.5,tickSize,digits);
|
|
dpx[1] = normalizePrice(mean-dpadrao*1.0,tickSize,digits);
|
|
dpx[2] = normalizePrice(mean+dpadrao*1.0,tickSize,digits);
|
|
dpx[3] = normalizePrice(mean+dpadrao*1.5,tickSize,digits);
|
|
|
|
dpy[0] = freq[ ArraySearchSerial(price,dpx[0]) ];
|
|
dpy[1] = freq[ ArraySearchSerial(price,dpx[1]) ];
|
|
dpy[2] = freq[ ArraySearchSerial(price,dpx[2]) ];
|
|
dpy[3] = freq[ ArraySearchSerial(price,dpx[3]) ];
|
|
|
|
//dpx[0] = m_cSymb.NormalizePrice(mean+dpadrao);
|
|
//dpx[1] = m_cSymb.NormalizePrice(mean-dpadrao);
|
|
//dpy[0] = dist[ ArraySearchSerial(price,dpx[0]) ];
|
|
//dpy[1] = dist[ ArraySearchSerial(price,dpx[1]) ];
|
|
CCurve *curveDpadraoP=graphic.CurveAdd(dpx,dpy,CURVE_HISTOGRAM);
|
|
curveDpadraoP.Name("dpadrao:"+DoubleToString(dpadrao,digits));
|
|
curveDpadraoP.HistogramWidth(2);
|
|
curveDpadraoP.PointsFill(true);
|
|
//curveDpadraoP.PointsColor(clrBlack);
|
|
curveDpadraoP.Color(clrBlack);
|
|
|
|
// bolinha com o preco atual...
|
|
double patux[]; // preco atual
|
|
double qatuy[]; // frequencia absoluta do preco atual
|
|
ArrayResize(patux,1);
|
|
ArrayResize(qatuy,1);
|
|
patux[0] = normalizePrice( last[qtdTicks-1], tickSize,digits);
|
|
qatuy[0] = freq[ ArraySearchSerial(price,patux[0]) ];
|
|
CCurve *curveUltPreco=graphic.CurveAdd(patux,qatuy,CURVE_HISTOGRAM);
|
|
curveUltPreco.Name("price:"+DoubleToString(patux[0],digits));
|
|
curveUltPreco.HistogramWidth(2);
|
|
curveUltPreco.PointsFill(true);
|
|
curveUltPreco.Color(ColorToARGB(clrRed,255));
|
|
|
|
//graphic.YAxis().AutoScale(false);
|
|
//double cv = dpadrao/mean; // coeficiente de variacao...
|
|
graphic.BackgroundMain( "["+symb + " " + to +
|
|
"] [" + IntegerToString(IN_WINDOW_MINUTO) + "min" +
|
|
"] [skew " + DoubleToString(skewness,3) +
|
|
"] [kurt " + DoubleToString(kurtosis,3) +
|
|
"] [cv " + DoubleToString(cv ,5) +
|
|
"]");
|
|
graphic.BackgroundMainSize(15);
|
|
graphic.XAxis().Name("preco");
|
|
graphic.XAxis().NameSize(12);
|
|
graphic.YAxis().Name("volume");
|
|
graphic.YAxis().NameSize(12);
|
|
graphic.YAxis().Min(0);
|
|
//graphic.YAxis().ValuesWidth(15);
|
|
graphic.CurvePlotAll();
|
|
graphic.Update();
|
|
//return true;
|
|
|
|
// Print(":-| ",__FUNCTION__,": Retirando os valores com zero do array...");
|
|
double x[];
|
|
int j=0;
|
|
for(int i=0; i<ArraySize(freq); i++){
|
|
|
|
if(ArraySize(x)<j+1){ArrayResize(x,j+1);}
|
|
|
|
if(freq[i] != 0){
|
|
x[j++] = freq[i];
|
|
}
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
// retorna o indice da primeira ocorrencia de V no array A ou -1 se não encontrar.
|
|
int ArraySearchSerial(const double &a[], const double v){
|
|
|
|
int size = ArraySize(a);
|
|
|
|
//for(int i=0; i<size; i++){ if(a[i]==v) return i; if(a[i]>v) break; }
|
|
for(int i=0; i<size; i++){ if(a[i]==v) return i; }
|
|
|
|
ArrayPrint(a);
|
|
Print(__FUNCTION__, "ind nao encontrado valor ",v, " em vetor de tamanho ", size);
|
|
return 0;
|
|
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
|
//GraphPlot( is, estimate, is, rets, CURVE_POINTS,"nome_teste");
|
|
//GraphPlot( is, estimate, is, rets, CURVE_POINTS,"nome_teste");
|
|
//GraphPlot( estimate, CURVE_POINTS,"nome_teste");
|
|
//GraphPlot( rets , CURVE_LINES,"nome_teste");
|
|
//GraphPlot( retacum , CURVE_LINES,"nome_teste");
|
|
//GraphPlot( is, retacum , CURVE_LINES,"nome_teste");
|
|
//GraphPlot( is, retacum , is, estimate , CURVE_LINES,"nome_teste");
|
|
//GraphPlot( is, retacum , is, estimateAr , CURVE_LINES,"nome_teste");
|
|
//GraphPlot( estimateArAcum, CURVE_LINES,"nome_teste");
|
|
//GraphPlot( is, estimateAr, is, estimateArAcum, CURVE_LINES,"nome_teste");
|
|
|
|
double normalizePrice(const double price, const double tickSize, const int digits )
|
|
{
|
|
if(tickSize!=0)
|
|
return(NormalizeDouble(MathRound(price/tickSize)*tickSize,digits));
|
|
//---
|
|
return(NormalizeDouble(price,digits));
|
|
}
|