Características da linguagem mql5, subtilezas e técnicas - página 94

 
Konstantin:

e como você vê a aplicação prática do GetMicrosecondCount que estraga todo o trabalho do programa na versão atual? descreva a aplicação prática

por exemplo, não vejo nenhuma variante nem em c++ nem aqui, exceto as descritas por Renat, ou seja, medir o tempo de execução do código com precisão em mcs

Não entendo a sua persistência, francamente falando...

O escopo desta função é bastante extenso, se você tiver um vôo de fantasia.
Já mencionei acima o multitimer que permite executar vários temporizadores com períodos diferentes ao mesmo tempo.
É também sobre isto que o fxsaber já escreveu.
A função microssegundo em comparação com a função milissegundo é útil não só para testes de velocidade, mas também para obter várias informações de telemetria durante o tempo de execução dos Expert Advisors.
Se a precisão dessa telemetria for de 16 ms (mais precisamente 1/64 s = 15625 microssegundos) - este é um erro muito grande.

 
Aleksey Vyazmikin:

Configurado, mas não ajuda - não entendo a razão. É verdade, meu servidor é ntp2.stratum2.ru

Se você usa GetTickCount por intervalos tão longos, você não deve ter nenhum problema.
Os problemas ocorrerão se você usar o GetMicrosecondCount.
Se usar a função microssegundo é uma questão de princípio, é melhor usar esta variante da função.

Informações a ter em conta:

Tempo aproximado de execução das funções:

- GetTickCount - ~ 2 ns

- GetMicrosecondCount - ~ 30 ns

-RealMicrosecondCount - ~ 40 ns

 
Nikolai Semko:

Se você estiver usando GetTickCount por intervalos tão longos, você não deve ter problemas.
Os problemas ocorrerão se você usar GetMicrosecondCount.
Se usar a função microssegundo é uma questão de princípio, é melhor usar esta variante da função.

Informações a serem tomadas em conta:

Tempo aproximado de execução das funções:

- GetTickCount - ~ 2 ns

- GetMicrosecondCount - ~ 30 ns

-RealMicrosecondCount - ~ 40 ns

Eu estou usando o código de outra pessoa e não há nenhuma função desse tipo lá, exceto esse efeito de dessincronização que ocorre.

#property indicator_chart_window
#property indicator_buffers 1
#property indicator_plots   1

input color ValuesPositiveColor = MediumSeaGreen; // Color for positive timer values
input color ValuesNegativeColor = PaleVioletRed;  // Color for negative timer values
input int   TimeFontSize        = 10;             // Font size for timer
input int   TimerShift          = 7;              // Timer shift

#define  clockName "CandleTimer"
int  atrHandle;
int ObjComplite=0;
int  OnInit()                   { atrHandle = iATR(NULL,0,30); EventSetTimer(1);  return(0); }
void OnDeinit(const int reason) { EventKillTimer(); }
void OnTimer( )                 { refreshClock();  }
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[])
{
   //refreshClock();
   return(rates_total);
}
void refreshClock()
{
   static bool inRefresh = false;
           if (inRefresh) return;
               inRefresh = true;
                              ShowClock(); ChartRedraw();
               inRefresh=false;
}

//------------------------------------------------------------------
//
//------------------------------------------------------------------
void ShowClock()
{
   int periodMinutes = periodToMinutes(Period());
   int shift         = periodMinutes*TimerShift*60;
   int currentTime   = (int)TimeCurrent();
   int localTime     = (int)TimeLocal();
   int barTime       = (int)iTime(Symbol(),PERIOD_CURRENT,0);//iTime();
   int diff          = (int)MathMax(round((currentTime-localTime)/3600.0)*3600,-24*3600);

      color  theColor;
      string time = getTime(barTime+periodMinutes*60-localTime-diff,theColor);
             time = (TerminalInfoInteger(TERMINAL_CONNECTED)) ? time : time+" x";

      if(ObjComplite==0)if(ObjectFind(0,clockName) < 0)
      {            
         ObjectCreate(0,clockName,OBJ_TEXT,0,barTime+shift,0);
         ObjComplite=1;
      }   
         ObjectSetString(0,clockName,OBJPROP_TEXT,time);
         ObjectSetString(0,clockName,OBJPROP_FONT,"Arial");
         ObjectSetInteger(0,clockName,OBJPROP_FONTSIZE,TimeFontSize);
         ObjectSetInteger(0,clockName,OBJPROP_COLOR,theColor);

      
         if (ChartGetInteger(0,CHART_SHIFT,0)==0 && (shift >=0))
               ObjectSetInteger(0,clockName,OBJPROP_TIME,barTime-shift*3);
         else  ObjectSetInteger(0,clockName,OBJPROP_TIME,barTime+shift);

      double price[]; if (CopyClose(Symbol(),0,0,1,price)<=0) return;
      double atr[];   if (CopyBuffer(atrHandle,0,0,1,atr)<=0) return;
             price[0] += 3.0*atr[0]/4.0;
             
      bool visible = ((ChartGetInteger(0,CHART_VISIBLE_BARS,0)-ChartGetInteger(0,CHART_FIRST_VISIBLE_BAR,0)) > 0);
      if ( visible && price[0]>=ChartGetDouble(0,CHART_PRICE_MAX,0))
            ObjectSetDouble(0,clockName,OBJPROP_PRICE,price[0]-1.5*atr[0]);
      else  ObjectSetDouble(0,clockName,OBJPROP_PRICE,price[0]);
}

//------------------------------------------------------------------
//
//------------------------------------------------------------------
string getTime(int times, color& theColor)
{
   string stime = "";
   int    seconds;
   int    minutes;
   int    hours;
   
   if (times < 0) {
         theColor = ValuesNegativeColor; times = (int)fabs(times); }
   else  theColor = ValuesPositiveColor;
   seconds = (times%60);
   hours   = (times-times%3600)/3600;
   minutes = (times-seconds)/60-hours*60;
   
   if (hours>0)
   if (minutes < 10)
         stime = stime+(string)hours+":0";
   else  stime = stime+(string)hours+":";
         stime = stime+(string)minutes;
   if (seconds < 10)
         stime = stime+":0"+(string)seconds;
   else  stime = stime+":" +(string)seconds;
   return(stime);
}


int periodToMinutes(int period)
{
   int i;
   static int _per[]={1,2,3,4,5,6,10,12,15,20,30,0x4001,0x4002,0x4003,0x4004,0x4006,0x4008,0x400c,0x4018,0x8001,0xc001};
   static int _min[]={1,2,3,4,5,6,10,12,15,20,30,60,120,180,240,360,480,720,1440,10080,43200};

   if (period==PERIOD_CURRENT) 
       period = Period();   
            for(i=0;i<20;i++) if(period==_per[i]) break;
   return(_min[i]);   
}
 
Slava:
Qual é a probabilidade de alterar o tempo do computador local entre duas chamadas para GetMicrosecondsCount usadas para medir o tempo em microssegundos?

Isto depende, antes de mais nada, do período definido de sincronização da hora do sistema com a hora da Internet. Por exemplo, eu defino a sincronização uma vez por dia, e durante esse tempo há mais de 1 s de diferença. Alguém sincroniza uma vez por hora, ou até mais vezes. Então, calcule a probabilidade.

 
Nikolai Semko:

...porque eu já sei sobre tal recurso do GetMicrosecondCount() e que essa função é mais lenta que o GetTickCount.

Suponho que esta lentidão se deve ao fato de que além de ter uma PerfomanceCount nativa, além disso, ela se torna uma bobagem na hora local, então temos que pagar por este serviço em baixa. Se comparássemos a velocidade da PerfomanceCount e GetTickCount diretamente, a diferença seria muito menor.

Embora, francamente falando, eu realmente não entendo toda essa conversa sobre velocidade de execução quando estamos falando de 2-20 nanossegundos. Essa diferença só pode ser sentida ao executar um loop quase vazio (com essa função) para uma centena de milhões de iterações. É uma solução mal desenhada em si mesma.

 
Renat Fatkhullin:

E sim, você será igualmente surpreendido por uma função WinAPI pura (GetTickCount ou QueryPerformanceCounter) quando você colocar uma sucata na motosserra, alterando a data mesmo por segundos. Não há nenhuma protecção que estás a falar em supostamente ter. Sugado do seu dedo como um problema e alegada solução.

Então tudo é verdade - é assim que o WinAPI é e isto é a realidade.

Você está errado, eu citei especificamente o código aqui usando o WinApi. Execute-o, mude o relógio no processo, e veja o resultado.

Não é muito claro como conduzir qualquer diálogo com você, se seus argumentos são baseados em especulações. E você nem mesmo considera necessário se familiarizar com a discussão do assunto.

 
Nikolai Semko:

O campo de aplicação desta função é bastante extenso, se você tiver um vôo de fantasia.
Já mencionei acima sobre o temporizador múltiplo, que permite executar vários temporizadores com períodos diferentes ao mesmo tempo.
É também sobre isto que o fxsaber já escreveu.
A função microssegundo em comparação com a função milissegundo é útil não só para testes de velocidade, mas também para obter várias informações de telemetria durante o tempo de execução dos Expert Advisors.
Se tal telemetria for precisa até 16 ms (mais precisamente 1/64 s = 15625 microssegundos), é um erro bastante grande.

Eu meço constantemente a velocidade de execução, como Renat escreveu, eu nunca vi nenhum problema, você parece acabar do nada, ou não quer mudar o que foi escrito antes, isso acontece quando você recebe tudo em vão, sem ofensa, mas o mesmo multitimer que você mencionou pode ser facilmente implementado sem erros, mas você tem que pagar por isso, Renat também deu uma descrição em resposta à minha pergunta acima

 
Konstantin:
A boca da Verdade é muda para os não-iniciados.
 
Nikolai Semko:
A boca da Verdade é muda para os não-iniciados.

bem, sim ))

 
Alexey Navoykov:

Depende, antes de mais nada, do período definido de sincronização do tempo do sistema com o tempo de internet. Por exemplo, eu defino a sincronização uma vez por dia, e durante esse tempo há mais de 1 segundo de divergência. Alguém a tem uma vez por hora, ou até mais vezes. Aqui você pode estimar a probabilidade.

Tens a certeza que leste a pergunta toda?

...entre duas chamadas para a GetMicrosecondsCount...

Razão: