Укажите новый бар

Willbur  

Мне интересно, как указать, когда новый бар видит свет.
В первую очередь я беспокоюсь о производительности. На некоторых символах я видел тики каждые 20 мс. Не так много времени для реакции.

Одна из идей - rates.tick_volume

Mqlrates rates[1];

OnInit()
    {
    if(CopyRates(_Symbol,_Period,0,1,rates) < 1)
       if(rates[0].tick_volume == 1)
          {
          ... deal with new bar ...
          }

Другой идеей может быть проверка, было ли увеличено количество баров.

OnInit()
  {
  if(BarsOld < Bars(_Symbol,_Period))
     {
     BarsOld = Bars(_Symbol,_Period);
     ... deal with new bar ...
     }

Я проверил также OnChartEvent, но не нашел способа отличить новые бары от других.

Спасибо за вашу оценку

WIllbur

Alain Verleyen  

Бары и объем ненадежны для обнаружения нового бара.

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

The "New Bar" Event Handler
The "New Bar" Event Handler
  • 2010.10.11
  • Konstantin Gruzdev
  • www.mql5.com
MQL5 programming language is capable of solving problems on a brand new level. Even those tasks, that already have such solutions, thanks to object oriented programming can rise to a higher level. In this article we take a specially simple example of checking new bar on a chart, that was transformed into rather powerful and versatile tool. What tool? Find out in this article.
Willbur  

Спасибо, Ален,

очень интересно... именно то, что я предполагал... В 10 раз быстрее... хммм...

Значит: TimeCurrent() работает быстро и синхронно с границами баров?

Почему .... хммм ...

Мне нужно время, чтобы подумать об этом.

Willbur

Willbur  

Хорошо - для людей, которые любят подобные вещи: Мое исследование по этому вопросу.

Я написал предложение в файл в каждом событии "OnTick".

TimeLocal (PC CLock), TimeCurrent(), используя SymbolInfoTick() некоторую информацию о последнем пришедшем тике и - используя CopyRates() - некоторую информацию о текущем Баре.


Пример из "USD/JPY" - Период - "M1":

Сейчас 19:43:01 на PC-часах, когда приходит первый тик 43-й минуты, в это же время возникает новый бар.
Не считая того, что тик-объем не равен 1, это нормальный ход вещей.



Иногда это не так просто - как в данном случае:

ПК показывает уже 19:42:00, когда пришли еще три тика бара 41мин. Они все еще имеют временную метку 19:41:59.

Сейчас мир делает глубокий вдох - 8.150 мс полной неподвижности.

Затем - компьютер показывает уже 19:42:09 - наступает первый тик нового бара - бара длительностью 42 минуты.
Тик отмечен 19:42:07 и - поскольку это бар 19:42, который приходит с ним - временная метка бара 19:42:00.


Теперь .... хммм ....

1. Всегда ли TimeCurrent() равен временной метке тика?

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

2. Всегда ли last_tick опережает открытие нового бара?

(будет продолжено)

Alain Verleyen  

TimeCurrent() - это время последнего тика с сервера, от вашего кода зависит, будет ли это время от символа вашего графика или нет.

Я не понимаю вашу проблему с "последним тиком", вы должны показать код, который выдал этот результат.

Willbur  

Привет Ален

Я проверяю TimeCurrent() в OnTick(), что должно гарантировать, что он принадлежит символу, с которым я имею дело.

Ну, это должен быть мой "Новый идентификатор бара" - маленький и быстрый - что вы думаете?

//---  New Bar           
bool   NewBar = false;
long   currPeriodSeconds;
double currPeriodProgress = 0;

int OnInit(void)  //-----------------------------------------------
{
      currPeriodSeconds = PeriodSeconds();
      return(INIT_SUCCEEDED);
}

void OnTick()  //--------------------------------------------------
{
      if(MathMod(TimeCurrent(),currPeriodSeconds) < currPeriodProgress)
           NewBar = true;
      else NewBar = false;
     

      currPeriodProgress = MathMod(TimeCurrent(),currPeriodSeconds);

Я собираюсь проверить его с помощью этого секвенса:

//---  Just for testing
int    ExtHdlFile1=0;
       MqlRates rates[1];
        
//---  New Bar           
bool   NewBar = false;
long   currPeriodSeconds;
double currPeriodProgress = 0;

int OnInit(void) // -------------------------------------------------------
{
      currPeriodSeconds = PeriodSeconds();

      ExtHdlFile1=FileOpen("NewBarTest.csv",FILE_READ|FILE_WRITE|FILE_CSV);
      FileSeek (ExtHdlFile1,0,SEEK_END); 
      FileWrite(ExtHdlFile1,  "TimeLocal",
                              "TimeCurrent",
                              "rates[0].time",
                              "rates[0].tick");
      return(INIT_SUCCEEDED);
}

void OnTick() // -----------------------------------------------------------
{
      if(MathMod(TimeCurrent(),currPeriodSeconds) < currPeriodProgress)
           NewBar = true;
      else NewBar = false;
     
      currPeriodProgress = MathMod(TimeCurrent(),currPeriodSeconds);

//--- lets check this

      if(NewBar)
         {
         // last Time Stamp of old Bar
         FileWrite(ExtHdlFile1, " ",
                                " ",
                                TimeToString(rates[0].time, TIME_MINUTES|TIME_SECONDS),
                                IntegerToString(rates[0].tick_volume));
         // get the new bar                     
         if(CopyRates(Symbol(),Period(),0,1,rates)!= 1) return;
         // first Time Stamp of new Bar       
         FileWrite(ExtHdlFile1,TimeToString(TimeLocal(),TIME_MINUTES|TIME_SECONDS),
                               TimeToString(TimeCurrent(), TIME_MINUTES|TIME_SECONDS),
                               TimeToString(rates[0].time, TIME_MINUTES|TIME_SECONDS),
                               IntegerToString(rates[0].tick_volume));
         }

      if(CopyRates(Symbol(),Period(),0,1,rates)!= 1) return; // != clean code - just a test
}

void OnDeinit(const int reason)
{
      FileClose(ExtHdlFile1);
      return;
}

Alain Verleyen  
Willbur:

Привет Ален

Я проверяю TimeCurrent() в OnTick(), что должно гарантировать, что он принадлежит символу, с которым я имею дело.

Ну, это должен быть мой "Новый идентификатор бара" - маленький и быстрый - что вы думаете?

Интересно, но я не думаю, что это универсально (работает во всех случаях)... Я проверю, сейчас нет времени.
Willbur  

Вот моя окончательная версия.

На самом деле я немного волнуюсь, потому что это так просто.

Ален: Было бы хорошо, если бы вы дали благословение.

// -----------------------------------------------------------------------
bool NewBar(void)
{
bool iNewBar = false;
static double currPeriodProgress = 0;

   if(MathMod(TimeCurrent(),PeriodSeconds()) < currPeriodProgress) iNewBar = true;

   currPeriodProgress = MathMod(TimeCurrent(),PeriodSeconds());

   return(iNewBar);
}
// ------------------------------------------------------------------------
void OnTick()
{
    if(NewBar())     PlaySound("tick.wav");


Приветствую вас из Кельна
Вилбур

Doerk Hilger  

Самый простой способ:

static datetime tlastbar=0;

datetime tnewbar=iTime(NULL,PERIOD_CURRENT,0);

bool isnewbar=tnewbar!=tlastbar;

tlastbar=tnewbar;

Причина обращения: