//+------------------------------------------------------------------+ //| teste-dist-tick.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 #include #include #include #include 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_PRICE_RETX, // TDA_PRICE_RETX distribuicao do retorno X. 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 = 5 ; input double IN_SLIP_MINUTO = 1 ; // SLIP quanto exec unica e janela deslizante input int IN_REFRESH_IN_MILIS = 10 ; input ENUM_TDN_TIPO_EXEC IN_TIPO_EXEC = TEX_FROM_TO_INTERV_DESL; input ENUM_TDN_TIPO_DADO IN_TIPO_DADO = TDA_PRICE_RET; input ENUM_TDN_TIPO_PESO IN_TIPO_PESO = TPE_VOLUME; input datetime IN_1X_DT_INI = D'2020.10.30 09:00: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); //double tickSize = cSymb.TickSize(); //int digits = cSymb.Digits(); // 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,tickSize,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,tickSize,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, tickSize,digits, IN_SLIP_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, tickSize,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); } processar(symb, dtIni, dtFim, tickSize, digits, tpDado, tpPeso, true ); 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); } processar(symb, from, dtFimAcum, tickSize, digits, tpDado, tpPeso, true ); return true; } bool processar(int qtdMinutos, string symb, double tickSize, int digits,ENUM_TDN_TIPO_DADO tpDado, ENUM_TDN_TIPO_PESO tpPeso){ 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, bool print=false){ 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[]; ArrayResize(last ,qtdTicks); ArrayResize(vol ,qtdTicks); ArrayResize(volSel,qtdTicks); ArrayResize(volBuy,qtdTicks); if( tpDado==TDA_PRICE_RETX ){ last[0] = 0; vol [0] = 0; for(int i=1; i0) && (ticks[i].last - ticks[i-1].last)>0 ) || MathAbs(ticks[i].last - ticks[i-1].last)>5 ){ last[i] = (ticks[i].last - ticks[i-1].last); vol [i] = ticks[i].volume ; }else{ last[i] = 0; vol [i] = ticks[i].volume; } } }else{ for(int i=1; iv) break; } for(int i=0; i