Мультивалютный советник МТ5, значение bid текущего тика различается в обзоре рынка и по функции SymbolInfoTick (и SymbolInfoDouble) , если советник не на графике этого символа

 

Здравствуйте.

Вопрос такой:

Мультивалютный советник. Запущен на графике символа "Б". В обзоре рынка значение BID для символа "А" текущего тика одно, а полученное SymbolInfoTick для символа "А" другое (старое). Если советник переставить на график символа "А", то каждый тик всё совпадает со значением в обзоре рынка для символа "А".

Я долго не мог понять, почему мультивалютник неправильно торгует и такой подлянки ждал в последнюю очередь. Это можно как то решить или мультивалютнику RIP, делать 100500 советников на каждый символ? Советник анализирует тики и такие косяки не допустимы. Может можно как-то брать значения прямо из обзора рынка, раз SymbolInfoTick и SymbolInfoDouble дают такой косяк?

 
Konstantin Efremov:

Здравствуйте.

Вопрос такой:

Мультивалютный советник. Запущен на графике символа "Б". В обзоре рынка значение BID для символа "А" текущего тика одно, а полученное SymbolInfoTick для символа "А" другое (старое). Если советник переставить на график символа "А", то каждый тик всё совпадает со значением в обзоре рынка для символа "А".

Я долго не мог понять, почему мультивалютник неправильно торгует и такой подлянки ждал в последнюю очередь. Это можно как то решить или мультивалютнику RIP, делать 100500 советников на каждый символ? Советник анализирует тики и такие косяки не допустимы. Может можно как-то брать значения прямо из обзора рынка, раз SymbolInfoTick и SymbolInfoDouble дают такой косяк?

Код где?
 
Artyom Trishkin:
Код где?
                  MqlTick last_tick;
                  SymbolInfoTick(PairA,last_tick);
                  Print(DoubleToString(last_tick.bid,(int)SymbolInfoInteger(PairA,SYMBOL_DIGITS)));

Стоит на графике пары "Б". Имеем, текущая котировка bid 3105.76, а по SymbolInfoTick получаем предыдущую 3106.92


А что в коде можно увидеть? Я вроде ситуацию подробно расписал


Вот, добавил перед значением тика время обновления цен. Почему так? 

Print("time: "+last_tick.time+"   "+DoubleToString(last_tick.bid,(int)SymbolInfoInteger(PairA,SYMBOL_DIGITS)));


Я, конечно, в шоке от такого. Нормально так, пытаться торговать на неправильных данных. Притом в тестере данные правильные, а в онлайне такое! Конечно будет слив. Хорошо что наткнулся чисто случайно, теперь всё придется переделывать. Но самое главное, не получится сделать мультивалютную систему, а это кошмар и бред. Позор!
 
Konstantin Efremov:
Artyom Trishkin:
Код где?

Стоит на графике пары "Б". Имеем, текущая котировка bid 3105.76, а по SymbolInfoTick получаем предыдущую 3106.92


А что в коде можно увидеть? Я вроде ситуацию подробно расписал


Вот, добавил перед значением тика время обновления цен. Почему так? 


Я, конечно, в шоке от такого. Нормально так, пытаться торговать на неправильных данных. Притом в тестере данные правильные, а в онлайне такое! Конечно будет слив. Хорошо что наткнулся чисто случайно, теперь всё придется переделывать. Но самое главное, не получится сделать мультивалютную систему, а это кошмар и бред. Позор!

В таймере проходите по массиву нужных символов и получайте от них данные. Если на текущем символе тика нет, то вы и на остальных символах не получите никаких данных.

 
Artyom Trishkin:

В таймере проходите по массиву нужных символов и получайте от них данные. Если на текущем символе тика нет, то вы и на остальных символах не получите никаких данных.

Еще раз повторю, в обзоре рынка цена меняется, в SymbolInfoTick нет, как её не получай, если советник не стоит на графике этого символа

 
Рынок какой? Есть возможность открыть стаканы по данным инструментам? Если есть такая возможность = берем тики  при изменение стакана нужного инструмента.
 
Volokola:
Рынок какой? Есть возможность открыть стаканы по данным инструментам? Если есть такая возможность = берем тики  при изменение стакана нужного инструмента.

Причем здесь стакан? Еще раз - если советник стоит на графике того инструмента, по которому берем тики с помощью SymbolInfoTick - то всё нормально. Если советник стоит на графике другого инструмента, то происходит косяк с получением тиков, описанный выше.

То есть это отрабатывает нормально:

SymbolInfoTick(_Symbol,last_tick);


А это косячит:

SymbolInfoTick(-другой_символ-,last_tick);
 
Konstantin Efremov:

Здравствуйте.

Вопрос такой:

Мультивалютный советник. Запущен на графике символа "Б". В обзоре рынка значение BID для символа "А" текущего тика одно, а полученное SymbolInfoTick для символа "А" другое (старое). Если советник переставить на график символа "А", то каждый тик всё совпадает со значением в обзоре рынка для символа "А".

Я долго не мог понять, почему мультивалютник неправильно торгует и такой подлянки ждал в последнюю очередь. Это можно как то решить или мультивалютнику RIP, делать 100500 советников на каждый символ? Советник анализирует тики и такие косяки не допустимы. Может можно как-то брать значения прямо из обзора рынка, раз SymbolInfoTick и SymbolInfoDouble дают такой косяк?

Предоставьте, пожалуйста полный код  опишите последовательность действий для воспроизведения (сколько графиков открыто, на каком сервере подключение, на каком символе запущен советник и с какого символа пытается получить данные ...).

 
Konstantin Efremov:

Причем здесь стакан? Еще раз - если советник стоит на графике того инструмента, по которому берем тики с помощью SymbolInfoTick - то всё нормально. Если советник стоит на графике другого инструмента, то происходит косяк с получением тиков, описанный выше.

То есть это отрабатывает нормально:


А это косячит:

Ищите ошибку у себя. Вот код:

#property version   "1.00"
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
input string inpSymbol="GBPUSD";
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
   if(inpSymbol==_Symbol)
     {
      Print(__FUNCTION__,": ОШИБКА! Рабочий символ '"+inpSymbol+"' должен отличаться от символа графика '"+_Symbol+"'");
      //---
      return( INIT_PARAMETERS_INCORRECT );
     }
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---

  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   int digits=(int)SymbolInfoInteger(inpSymbol,SYMBOL_DIGITS);
//---
   MqlTick tick;
//---
   SymbolInfoTick(inpSymbol,tick);
//---
   Print(__FUNCTION__,": tick.bid = "+DoubleToString(tick.bid,digits)+", tick.ask = "+DoubleToString(tick.ask,digits)+", tick.time = "+TimeToString(tick.time,TIME_SECONDS));
  }
//+------------------------------------------------------------------+

Вот результат его отработки:

2019.02.01 10:30:25.526 test_SymbolInfoTick (EURUSD,M5) OnTick: tick.bid = 1.30987, tick.ask = 1.30990, tick.time = 05:30:25
2019.02.01 10:30:33.115 test_SymbolInfoTick (EURUSD,M5) OnTick: tick.bid = 1.30986, tick.ask = 1.30990, tick.time = 05:30:32
2019.02.01 10:30:33.289 test_SymbolInfoTick (EURUSD,M5) OnTick: tick.bid = 1.30986, tick.ask = 1.30987, tick.time = 05:30:33
2019.02.01 10:30:33.310 test_SymbolInfoTick (EURUSD,M5) OnTick: tick.bid = 1.30986, tick.ask = 1.30987, tick.time = 05:30:33
2019.02.01 10:30:33.344 test_SymbolInfoTick (EURUSD,M5) OnTick: tick.bid = 1.30985, tick.ask = 1.30986, tick.time = 05:30:33
2019.02.01 10:30:33.498 test_SymbolInfoTick (EURUSD,M5) OnTick: tick.bid = 1.30985, tick.ask = 1.30986, tick.time = 05:30:33
2019.02.01 10:30:33.532 test_SymbolInfoTick (EURUSD,M5) OnTick: tick.bid = 1.30985, tick.ask = 1.30986, tick.time = 05:30:33
2019.02.01 10:30:36.783 test_SymbolInfoTick (EURUSD,M5) OnTick: tick.bid = 1.30984, tick.ask = 1.30985, tick.time = 05:30:33
2019.02.01 10:30:36.804 test_SymbolInfoTick (EURUSD,M5) OnTick: tick.bid = 1.30984, tick.ask = 1.30985, tick.time = 05:30:33
2019.02.01 10:30:36.817 test_SymbolInfoTick (EURUSD,M5) OnTick: tick.bid = 1.30982, tick.ask = 1.30985, tick.time = 05:30:36
2019.02.01 10:30:36.957 test_SymbolInfoTick (EURUSD,M5) OnTick: tick.bid = 1.30982, tick.ask = 1.30983, tick.time = 05:30:36
2019.02.01 10:30:37.296 test_SymbolInfoTick (EURUSD,M5) OnTick: tick.bid = 1.30979, tick.ask = 1.30981, tick.time = 05:30:37
2019.02.01 10:30:37.317 test_SymbolInfoTick (EURUSD,M5) OnTick: tick.bid = 1.30979, tick.ask = 1.30981, tick.time = 05:30:37

Тики идут. Билд 1940.

 
Konstantin Efremov:

Вот, добавил перед значением тика время обновления цен. Почему так? 


Я, конечно, в шоке от такого. Нормально так, пытаться торговать на неправильных данных. Притом в тестере данные правильные, а в онлайне такое! Конечно будет слив. Хорошо что наткнулся чисто случайно, теперь всё придется переделывать. Но самое главное, не получится сделать мультивалютную систему, а это кошмар и бред. Позор!

Так потому, что вы запрашиваете данные с одной пары (первой), а OnTick() выполняется на другой паре (второй). И выполняется чаще на второй. Тик по первой паре просто не успевает прийти в этот момент и, логично, выдается последний тик, который равен предыдущему.

Вот расширенный пример:

#property version   "1.00"
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
input string inpSymbol="GBPUSD";
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
   if(inpSymbol==_Symbol)
     {
      Print(__FUNCTION__,": ОШИБКА! Рабочий символ '"+inpSymbol+"' должен отличаться от символа графика '"+_Symbol+"'");
      //---
      return( INIT_PARAMETERS_INCORRECT );
     }
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---

  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   int digits=(int)SymbolInfoInteger(inpSymbol,SYMBOL_DIGITS);
   //---
   double bid = SymbolInfoDouble( inpSymbol, SYMBOL_BID );
//---
   MqlTick tick;
//---
   SymbolInfoTick(inpSymbol,tick);
   //---
   string equal = "?";
   //--- Сравниваем цену бид из обзора рынка и из тика
   if( bid != tick.bid )
        equal = "НЕТ";
   else
        equal = "ДА!";
//---
   Print(__FUNCTION__,": tick.bid = "+DoubleToString(tick.bid,digits)+", tick.ask = "+DoubleToString(tick.ask,digits)+", tick.time = "+TimeToString(tick.time,TIME_SECONDS)+
                                                 ", tick.time_msc = ",tick.time_msc,", BID = "+DoubleToString( bid, digits )+", биды равны: "+equal );
  }
//+------------------------------------------------------------------+

И результат:

2019.02.01 10:45:42.193 test_SymbolInfoTick (EURUSD,M5) OnTick: tick.bid = 1.30981, tick.ask = 1.30986, tick.time = 05:45:42, tick.time_msc = 1548999942045, BID = 1.30981, биды равны: ДА!
2019.02.01 10:45:42.245 test_SymbolInfoTick (EURUSD,M5) OnTick: tick.bid = 1.30981, tick.ask = 1.30986, tick.time = 05:45:42, tick.time_msc = 1548999942045, BID = 1.30981, биды равны: ДА!
2019.02.01 10:45:42.379 test_SymbolInfoTick (EURUSD,M5) OnTick: tick.bid = 1.30981, tick.ask = 1.30986, tick.time = 05:45:42, tick.time_msc = 1548999942182, BID = 1.30981, биды равны: ДА!
2019.02.01 10:45:42.572 test_SymbolInfoTick (EURUSD,M5) OnTick: tick.bid = 1.30981, tick.ask = 1.30986, tick.time = 05:45:42, tick.time_msc = 1548999942182, BID = 1.30981, биды равны: ДА!
2019.02.01 10:45:47.419 test_SymbolInfoTick (EURUSD,M5) OnTick: tick.bid = 1.30982, tick.ask = 1.30985, tick.time = 05:45:47, tick.time_msc = 1548999947220, BID = 1.30982, биды равны: ДА!
2019.02.01 10:45:47.836 test_SymbolInfoTick (EURUSD,M5) OnTick: tick.bid = 1.30981, tick.ask = 1.30986, tick.time = 05:45:47, tick.time_msc = 1548999947608, BID = 1.30981, биды равны: ДА!
 
Alexey Kozitsyn:

Так потому, что вы запрашиваете данные с одной пары, а OnTick() выполняется на другой паре. И выполняется чаще. Тик по другой паре просто не успевает прийти в этот момент и, логично, выдается последний тик, который равен предыдущему.


Вот это может быть! Спасибо, буду думать как обойти. Попробую через таймер.


UPD: Да, сделал задержку перед получением значения тика и всё получилось, тики получает корректно. Спасибо огромное, Алексей!

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