Restringir "CopyTime" em Dias e Horários (No Limiar da Linguagem MQL5)

 

Oi pessoal! Já imagino que o que vá perguntar seja impossível de realizar com as funções padrão do MQL5, mas não custa nada perguntar se alguém já topou com uma solução alternativa.

CopyTime  é uma função prática, mas ela copia dados que não são interessantes para mim por culpa inclusive do servidor dos dados (e quem sabe do próprio mercado FOREX). Exemplo: sexta-feira (dia 18/12/2020) as velas foram até 23:50 (timeframe: M5), já nos outros dias até 23:55 iniciando o próximo dia às 00:00.

Meu EA é bem estranho em relação ao que o pessoal está acostumado, mas para resumir ele fecha blocos de tempo e divide esses blocos de tempo em "caixas" de 4, ou 5 ou 6 velas. Essa diferença nos finais de semana desloca o início desses blocos, o que não é interessante para mim. (faz meu EA ficar restrito a analisar a semana vigente e errar os cálculos quando analisa mais para trás).

Daí que eu gostaria de perguntar: existe uma maneira de copiar as velas para um Array apenas de segunda-feira a partir de 00:00 (horário do servidor, não importa o horário local) até sexta-feira em algum horário redondo, tipo 23:30 ao (invés de ir até 23:50)?

Imagino que talvez uma função NO LUGAR de CopyTime possa fazer o serviço. Algo pronto em alguma biblioteca, ou alguma função customizada? (pesquisei no fórum e acho que isso é uma questão que interessa outros programadores e, especificamente no meu caso, ainda não explorada em alguns aspectos)

 

ESTÁ VIVO!!! xD

Confesso que quebrei demais a cabeça com esse algoritmo. Confesso também que não conseguiria se não encontrasse diversas soluções para diversos problemas diferentes de diversas fontes. oO

MAS esse código está parecendo meio porco... sei lá, resolve o problema definitivamente, mas suspeito que existam maneiras melhores de fazê-lo. De qualquer maneira, transformando em função, considero superior em possibilidades em relação a CopyTime (ainda que faça uso dessa mesma função) porque permite maior controle sobre os limites dos horários das velas:

void OnStart()
  {
   datetime       dataInicial = D'2020.12.11 03:00';
   datetime       dataFinal = D'2020.12.21 23:55';
   datetime       dataFake = D'1984.04.01 00:00';
   datetime       copiaTempo_vetor[];
   int            numeroLinhas_vetorOriginal = 0;
   int            contadorExcesso_valoresVetor = 0;
   MqlDateTime    diaVerificado_estrutura;
   datetime       copiaTempo_vetorAlterado[];
   bool           valorDuplicado = false;
   int            indice = 0;
   datetime       copiaTempo_vetorDuplicado[];
   datetime       copiaTempo_vetorDuplicado2[];
   int            numeroLinhas_vetorFinal = 0;

   CopyTime(Symbol(), Period(), dataInicial, dataFinal, copiaTempo_vetor);

   ZeroMemory(copiaTempo_vetorAlterado);
   ArrayResize(copiaTempo_vetorAlterado, ArrayRange(copiaTempo_vetor, 0), 0);
   ZeroMemory(copiaTempo_vetorAlterado);

   numeroLinhas_vetorOriginal = ArrayRange(copiaTempo_vetorAlterado, 0);

//--- ELIMINA O QUE NÃO ENTRA NO CRITÉRIO
   for(int i = 0; i < numeroLinhas_vetorOriginal; i++)
     {
      TimeToStruct(copiaTempo_vetor[i], diaVerificado_estrutura);

      if((diaVerificado_estrutura.day_of_week >= 1 && diaVerificado_estrutura.day_of_week < 5) ||
         (diaVerificado_estrutura.day_of_week == 5 && diaVerificado_estrutura.hour < 23) ||
         (diaVerificado_estrutura.day_of_week == 5 && diaVerificado_estrutura.hour == 23 &&
          diaVerificado_estrutura.min <= 30))
        {
         copiaTempo_vetorAlterado[i] = copiaTempo_vetor[i];
        }
      else
        {
         //--- Conta quantos elementos não entraram no critério
         contadorExcesso_valoresVetor = contadorExcesso_valoresVetor + 1;
        }
     }

//--- SUBSTITUI VALORES NULOS POR VALOR INÚTIL REPETIDO
   for(int i = 0; i < numeroLinhas_vetorOriginal; i++)
     {
      if(copiaTempo_vetorAlterado[i] == NULL)
        {
         copiaTempo_vetorAlterado[i] = dataFake;
        }
     }

   ArrayResize(copiaTempo_vetorDuplicado, numeroLinhas_vetorOriginal);

//--- ELIMINA DUPLICADOS
   for(int i = 0; i < numeroLinhas_vetorOriginal; i++)
     {
      for(int j = 0; j < indice; j++)
        {
         if(copiaTempo_vetorAlterado[i] == copiaTempo_vetorDuplicado[j])
           {
            valorDuplicado = true;
            break;
           }
        }
      if(!valorDuplicado)
        {
         copiaTempo_vetorDuplicado[indice] = copiaTempo_vetorAlterado[i];
         indice++;
        }
      valorDuplicado = false; // restart
     }

//--- SUBSTITUI DATA FAKE PELO PRÓXIMO VALOR (DUPLICANDO O DITO CUJO)
   for(int i = 0; i < numeroLinhas_vetorOriginal; i++)
     {
      if(copiaTempo_vetorDuplicado[i] == dataFake && i != numeroLinhas_vetorOriginal)
        {
         copiaTempo_vetorDuplicado[i] = copiaTempo_vetorDuplicado[i + 1];
        }
     }

ArrayResize(copiaTempo_vetorDuplicado2, numeroLinhas_vetorOriginal, 0);

//--- ELIMINA DUPLICADOS NOVAMENTE
   indice = 0;
   for(int i = 0; i < numeroLinhas_vetorOriginal; i++)   // looping through the main array
     {
      for(int j = 0; j < indice; j++)   // looping through the target array where we know we have data. if we haven't found anything yet, this wont loop
        {
         if(copiaTempo_vetorDuplicado[i] == copiaTempo_vetorDuplicado2[j])   // if the target array contains the object, no need to continue further.
           {
            valorDuplicado = true;
            break; // break from this loop
           }
        }
      if(!valorDuplicado)   // if our value wasn't found in 'b' we will add this non-dublicate at index
        {
         copiaTempo_vetorDuplicado2[indice] = copiaTempo_vetorDuplicado[i];
         indice++;
        }
      valorDuplicado = false; // restart
     }

   numeroLinhas_vetorFinal = numeroLinhas_vetorOriginal - contadorExcesso_valoresVetor;

   ArrayResize(copiaTempo_vetorDuplicado2, numeroLinhas_vetorFinal, 0);

   Print("contadorExcesso_valoresVetor: ", contadorExcesso_valoresVetor);
   Print("numeroLinhas_vetorOriginal: ", numeroLinhas_vetorOriginal, " numeroLinhas_vetorFinal: ", numeroLinhas_vetorFinal);
   Print("copiaTempo_vetorDuplicado2:");
   ArrayPrint(copiaTempo_vetorDuplicado2);
  }

A beleza do código é no final do dia 11 e do dia 18 (sem aquelas "queridas" velas de 23:35, 23:40 etc.)

Experimentem e me digam o que acham.