Особенности языка mql5, тонкости и приёмы работы - страница 94

Nikolai Semko
6312
Nikolai Semko  
Konstantin:

а как вы видите практическое применение GetMicrosecondCount что оно вам портит всю работу программы в текущем варианте ? опишите практическое применение

я к примеру ни в С++ ни тут не вижу вариантов, кроме тех, что описал Ренат, т.е. замер времени исполнения кода с точность в mcs

т.е. я не понимаю вашего упорства если честно

Область применения этой функции весьма обширна, если есть полет фантазии.
Я уже говорил выше от мультитаймере, который позволяет запускать несколько таймеров с разными периодами одновременно.
Об этом также уже писал fxsaber .
Микросекундная функция в сравнении с миллисекундной удобна не только для теста скорости выполнения, но и для снятия различной телеметрической информации в процессе работы советников.
Если точность такой телеметрии в 16 мс ( точнее 1/64 с = 15625 микросекунд) - то это весьма большая погрешность. 

Nikolai Semko
6312
Nikolai Semko  
Aleksey Vyazmikin:

Настроено, но не помогает - не понимаю причину. Правда сервер у меня ntp2.stratum2.ru

Если Вы для счетчика таких больших промежутков времени используете GetTickCount, то проблем быть не должно.
Проблемы будут если Вы используете GetMicrosecondCount.
Если использование микросекундной функции - это принципиальный момент, то лучше тогда использовать этот вариант функции.

Информация для принятия к сведению:

Примерное время выполнения функций:

- GetTickCount - ~ 2 нс

- GetMicrosecondCount - ~ 30 нс

RealMicrosecondCount - ~ 40 нс

Aleksey Vyazmikin
15832
Aleksey Vyazmikin  
Nikolai Semko:

Если Вы для счетчика таких больших промежутков времени используете GetTickCount, то проблем быть не должно.
Проблемы будут если Вы используете GetMicrosecondCount.
Если использование микросекундной функции - это принципиальный момент, то лучше тогда использовать этот вариант функции.

Информация для принятия к сведению:

Примерное время выполнения функций:

- GetTickCount - ~ 2 нс

- GetMicrosecondCount - ~ 30 нс

RealMicrosecondCount - ~ 40 нс

Я использую чужой код, там как то вообще нет этих функций, но эффект рассинхронизации возникает.

#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]);   
}
Alexey Navoykov
4552
Alexey Navoykov  
Slava:
Какова вероятность изменения локального времени компьютера между двумя вызовами GetMicrosecondsCount, используемых для замера времени в микросекундах?

Это зависит, в первую очередь, от заданного периода синхронизации системного времени с временем интернета. У меня например задана синхронизация раз в сутки, и за это время набегает более 1 с расхождения.  У кого-то синхронизируется раз в час, или ещё чаще.  Вот и прикидывайте вероятность.

Alexey Navoykov
4552
Alexey Navoykov  
Nikolai Semko:

...так как уже знаю о такой особенности работы GetMicrosecondCount() и что эта функции более чем на порядок медленее GetTickCount.

Полагаю, такая медлительность связана с тем, что помимо получения нативного PerfomanceCount там дополнительно дёргается локальное время, вот и приходится оплачивать эту медвежью услугу.  Если бы сравнивалась скорость непосредственно PerfomanceCount и GetTickCount, то разница была бы гораздо меньше.

Хотя, честно говоря, мне не очень понятны эти разговоры о скорости выполнения, когда речь идёт о 2-20 наносекундах.  Эту разницу реально ощутить только гоняя практически пустой цикл (с данной функцией) на сотне миллионов итераций.  Это само по себе неправильно спроектированное решение. 

Alexey Navoykov
4552
Alexey Navoykov  
Renat Fatkhullin:

И да, вас точно также взорвет чистая WinAPI функция (что GetTickCount, что QueryPerformanceCounter), когда вы подсунете лом в бензопилу, поменяв дату даже на секунды. Вообще нет никакой защиты, о якобы наличии которой вы говорите. Высосанная из пальца как проблема, так и якобы решение.

Так что все верно - таков WinAPI и такова реальность.

Вы ошибаетесь.  Я же вот здесь специально привёл код с использованием WinApi.  Запустите, поменяйте часы в процессе, и посмотрите на результат.

Не очень понятно, как с вами вести какой-либо диалог, если ваши аргументы основаны на домыслах.  И даже не считаете нужным ознакомиться с ходом обсуждения темы.

Konstantin
744
Konstantin  
Nikolai Semko:

Область применения этой функции весьма обширна, если есть полет фантазии.
Я уже говорил выше от мультитаймере, который позволяет запускать несколько таймеров с разными периодами одновременно.
Об этом также уже писал fxsaber .
Микросекундная функция в сравнении с миллисекундной удобна не только для теста скорости выполнения, но и для снятия различной телеметрической информации в процессе работы советников.
Если точность такой телеметрии в 16 мс ( точнее 1/64 с = 15625 микросекунд) - то это весьма большая погрешность. 

я замеряю постоянно скорость исполнения, о чем писал Ренат, проблем ни когда не видел, вы похоже накручиваете из пустого, либо не хотите написанное ранее изменить, так бывает когда как говорится наго...шь и потом понимаешь что писалось все зря, без обид, но тот же приведенный вами мультитаймер спокойно реализовывается без всяких погрешностей, но за это придется платить, Ренат выше так же давал описание в ответе на мой вопрос

Nikolai Semko
6312
Nikolai Semko  
Konstantin:
Уста  Истинны немы для непосвященных.
Konstantin
744
Konstantin  
Nikolai Semko:
Уста  Истинны немы для непосвященных.

ну так то да ))

Slava
Модератор
13395
Slava  
Alexey Navoykov:

Это зависит, в первую очередь, от заданного периода синхронизации системного времени с временем интернета. У меня например задана синхронизация раз в сутки, и за это время набегает более 1 с расхождения.  У кого-то синхронизируется раз в час, или ещё чаще.  Вот и прикидывайте вероятность.

Вы вопрос точно весь прочитали?

...между двумя вызовами GetMicrosecondsCount...