oslib/svc/run/cls-run.mqh
super.admin 07f69c4478 convert
2025-05-30 16:15:18 +02:00

203 lines
No EOL
19 KiB
MQL5

//+------------------------------------------------------------------+
//| oss-run.mq5 |
//| Copyright 2020, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2018, OS Corp."
#property link "http://www.os.org"
#property version "1.00"
//+------------------------------------------------------------------+
//| Classe para contabilizar estatisticas de mudanca de precos. |
//+------------------------------------------------------------------+
struct Run{
ushort len;
ushort repeticoes;
uint qtdPositivas;
uint qtdNegativas;
};
class OscRun{
public:
void calcRuns(const MqlTick &pVetTicks[], const int pQtdTicks, const int pLenChunk, const double pTickSize, int &run1[], int &run2[]);
void calcRuns(const double &pVetPrice[], const int pQtdTicks, const int pLenChunk, const double pTickSize, int &run1[], int &run2[]);
string toString(const int &run1[], const int &run2[], int lenChunk);
double calcIndice(const int &run1[], const int &run2[]);
};
//+--------------------------------------------------------------------------------------------------------------+
//| pVetTicks : vetor de ticks que serao processados |
//| pQtdTicks : quantidade de ticks a processar |
//| pLenChunk : tamanho inicial do chunk em ticks |
//| pTickSize : tamanho do tick |
//| run1 : vetor de runs positivas. retorno por referencia. |
//| run2 : vetor de runs negativas. retorno por referencia. |
//| OBS : Em run1 e run2, a posicao do vetor eh quantas vezes a run se repetiu seguidamente e o valor na |
//| : posicao eh quantas vezes a repeticao se concretizou. |
//| Ex : run1{0,10,8,0,0,2} significa que |
//| : houve 10 ocorrencias de repeticoes de 1(uma ) run; |
//| : houve 08 ocorrencias de repeticoes de 2(duas ) runs seguidas |
//| : houve 02 ocorrencias de repeticoes de 5(cinco) runs seguidas; |
//+--------------------------------------------------------------------------------------------------------------+
void OscRun::calcRuns(const MqlTick &pVetTicks[], const int pQtdTicks, const int pLenChunk, const double pTickSize, int &run1[], int &run2[]){
double price[];
int size = ArraySize(pVetTicks);
//ArrayResize(price,pQtdTicks);
ArrayResize(price,size);
for(int i=0; i<size; i++){ price[i]=pVetTicks[i].ask;}
calcRuns(price, pQtdTicks, pLenChunk, pTickSize, run1, run2);
}
//+--------------------------------------------------------------------------------------------------------------+
//| pVetPrice : vetor de precos que serah processado |
//| pQtdTicks : quantidade de ticks a processar |
//| pLenChunk : tamanho inicial do chunk em ticks |
//| pTickSize : tamanho do tick |
//| run1 : vetor de runs positivas. retorno por referencia. |
//| run2 : vetor de runs negativas. retorno por referencia. |
//| OBS : Em run1 e run2, a posicao do vetor eh quantas vezes a run se repetiu seguidamente e o valor na |
//| : posicao eh quantas vezes a repeticao se concretizou. |
//| Ex : run1{0,10,8,0,0,2} significa que |
//| : houve 10 ocorrencias de repeticoes de 1(uma ) run; |
//| : houve 08 ocorrencias de repeticoes de 2(duas ) runs seguidas |
//| : houve 02 ocorrencias de repeticoes de 5(cinco) runs seguidas; |
//+--------------------------------------------------------------------------------------------------------------+
void OscRun::calcRuns(const double &pVetPrice[], const int pQtdTicks, const int pLenChunk, const double pTickSize, int &run1[], int &run2[]){
int run[] ; //vetor de mudancas de precos
int ir = 0 ; //indice do vetor run
int lenChunk = pLenChunk; //chunk eh o tamanho da run medido em ticks...
int chunk = 0;
int vp = 0;
int p = 0; //preco normalizado para unidade de ticks;
int pAnt = 0; //preco anterior normalizado para unidade de ticks;
int dp = 0; //quantidade de ticks entre p e pAnt;
int qtdRuns1 = 0;
int qtdRuns2 = 0;
int lenVetPrice = ArraySize(pVetPrice);
ArrayResize(run1,10,10);
ArrayResize(run2,10,10);
ArrayInitialize(run1,0);
ArrayInitialize(run2,0);
ArrayResize(run,10,10);
ArrayInitialize(run,0);
// varrendo o array de ticks(precos) e montando o array de runs (run)...
for( int i=1; i<pQtdTicks && i<lenVetPrice; i++ ){
// delta p (dp) eh a quantidade de ticks entre p e pAnt...
dp = (int)( (pVetPrice[i] - pVetPrice[i-1] ) / pTickSize );
//dp = (int)( (pVetTicks[i].ask - pVetTicks[i-1].ask) / pTickSize );
p = pAnt + dp;
if( p == pAnt ){ continue; }
chunk = chunk+dp;
//Print("pAnt=",pAnt," p=",p," dp=",dp, " chunkP=",chunkP, "chunkN=",chunkN);
if( ArraySize(run)<= ir ) ArrayResize(run,ir+10,10);
if( chunk>= lenChunk ){ run[ir++] = 1; chunk=0; }
if( chunk<= -lenChunk ){ run[ir++] = -1; chunk=0; }
pAnt = p;
}
//ArrayPrint(run);
// montando os vetores de quantidade de runs...
int pos=0; int neg =0;
int r =0; int rAnt=0;
ArrayInitialize(run1,0);
ArrayInitialize(run2,0);
for( int i=0; i<ArraySize(run); i++ ){
// ajutando tamanho de run1 e run2, caso tenham ficado pequenos...
if( ArraySize(run1) == pos+1 ){
ArrayResize(run1,ArraySize(run1)+10, 10);
for(int t=pos+1; t<ArraySize(run1); t++){run1[t]=0;} // array cresceu, inicializa os campos novos com zeros...
}
if( ArraySize(run2) == neg+1 ){
ArrayResize(run2,ArraySize(run2)+10, 10);
for(int t=neg+1; t<ArraySize(run2); t++){run2[t]=0;}
}
// saindo do laco se os valores nao sao chunks...
if( run[i] != 1 && run[i] != -1) break;
// preeenchendo run1 e run2...
if(i==0){
if(run[i]>0){pos++;}else{neg++;}
}else{
if(run[i]==run[i-1]){
// igual ao valor anterior, acumulamos
if(run[i]>0){pos++;}else{neg++;}
}else{
// diferente do valor anterior, salvamos o acumulado anterior no vetor e voltamos a acumular...
if(run[i-1]>0){run1[pos]++; pos=0; neg++;}else
{run2[neg]++; neg=0; pos++;}
}
}
}
// complemento apos o final do laco
if( pos>0 )run1[pos]++;
if( neg>0 )run2[neg]++;
return;
}
string OscRun::toString(const int &run1[], const int &run2[], int lenChunk){
int qtdRuns1=0;
int qtdRuns2=0;
string strRun = IntegerToString(lenChunk) + "[POS";
// Calculando e apresentando o vetor de runs positivas...
strRun += "[POS" ;
for(int i=0; i<ArraySize(run1); i++){
if(run1[i]==0){continue;}
strRun+=(" "+IntegerToString(i)+":"+IntegerToString(run1[i]) );
qtdRuns1+=(i*run1[i]);
}
strRun+=("] " + IntegerToString(qtdRuns1)+"\n");
// Calculando e apresentando o vetor de runs negativas...
strRun+=IntegerToString(lenChunk);
strRun+="[NEG";
for( int i=0; i<ArraySize(run2); i++ ){
if(run2[i]==0){continue;}
strRun+=(" "+IntegerToString(i)+":"+IntegerToString(run2[i]) );
qtdRuns2+=(i*run2[i]);
}
if(qtdRuns1+qtdRuns2 > 0){
strRun+=("] " + IntegerToString(qtdRuns2)+ " " + DoubleToString(((double)(qtdRuns1-qtdRuns2)/(double)(qtdRuns1+qtdRuns2))*100.0, 0) +"%\n");
}else{
strRun+=("] " + IntegerToString(qtdRuns2)+ "0%\n");
}
return strRun;
}
double OscRun::calcIndice(const int &run1[], const int &run2[]){
int qtdRuns1=0;
int qtdRuns2=0;
// Calculando o indice do vetor de runs positivas...
for(int i=0; i<ArraySize(run1); i++){
if(run1[i]==0){continue;}
qtdRuns1+=(i*run1[i]);
}
// Calculando e apresentando o vetor de runs negativas...
for( int i=0; i<ArraySize(run2); i++ ){
if(run2[i]==0){continue;}
qtdRuns2+=(i*run2[i]);
}
if(qtdRuns1+qtdRuns2 == 0) return 0;
return (double)(qtdRuns1-qtdRuns2)/(double)(qtdRuns1+qtdRuns2);
}
//+------------------------------------------------------------------+