Баг в функции SymbolInfoDouble() ??? - страница 4

 
denkir:
Евгений, barabashkakvn скорее прав, чем не прав... нужно флиртовать с окружением МТ. Если в Ините что-то не выдаётся, то скорее всего окружение не подготовлено... нужно безусловно его подготовить при попытке получить какую-то инфу...

Я человек уже достаточно взрослый, флиртовал-то по-молодости только )) да и то с девушками... с программами не доводилось.

Ну что мне от окружения-то, ежели функция на 10-й запрос только выдает правильный ответ? что там неподготовленного? если бы только на запуске терминала или при переключении счета/сервера, то понятное дело.

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

В реализации Tick Value 100% ошибка. Доказывать не собираюсь, и так много времени потратил, пока внаглую цикл не сделал. Заметь цикл без RefreshRates, синхронизации и т.п., а тупо вызов функции.

Володя всегда прав, на то он и модератор ))

 

В общем вот, что обнаружил: http://forum.mql4.com/ru/8336/page2#83875

Renat 12.06.2008 20:27 | 

Это не грабли, а принципиальный момент. Полностью рыночное окружение можно распознать только по приходу тика. 

 

Сейчас не проверим это - выходные и тиков нет. Будем посмотреть завтра.

грабли в init() - MQL4 форум
  • www.mql5.com
грабли в init() - MQL4 форум
 

Ну дык оттуда и цитата Рената

В отличие от индикатора, функция init() эксперта(!) гарантированно вызывается при наличии всего полного рыночного окружения. Функция init() у эксперта вызывается не в момент прикрепления эксперта к графику, а после прихода первого ценового тика.

Я как раз эксперт и пишу, а не индикатор, поэтому рыночное окружение при OnInit уже готово (должно быть) по его словам.

На счет OnInit и первого тика, это не правда ИМХО, т.к. сейчас рынок закрыт, тиков нет, а OnInit вызывается. Другое дело что событие тика может быть послано MT4 самому себе для искусственного запуска OnInit. Это я еще понять могу.

Так что дело вовсе не в окружении. 

Вот еще

Извините, тут я некорректно выразился. Функция init() эксперта вызывается не с приходом первого тика, а после загрузки рыночного окружения (списка символов и последних цен bid/ask, но без гарантии полной подгрузки исторических данных). 

 Так что окружение готово уже. Ренату вроде доверяю.

 

Значится так. Похоже удалось найти причину выскакивания числа вида -1.#IND. Это не число или это бесконечность. Пришлось ввести проверку - и я таки дождался получения верного значения. Иногда, правда, приходится ждать несколько секунд.

int OnInit()
  {
   Comment("Init");

// Symbols initialization

   string symbol;
   int st,i,digits;
   double tick_value;
   double v_ask,v_bid;

   st=SymbolsTotal(false);

// enable all market symbols
   for(i=0; i<st; i++)
     {
      symbol=SymbolName(i,false);
      SymbolSelect(symbol,true);
     }

// disable unused symbols
   st=SymbolsTotal(true);
   for(i=st-1; i>=0; i--)
     {
      symbol=SymbolName(i,true);
      if(
         symbol != "EURUSD" &&
         symbol != "EURGBP" &&
         symbol != "GBPUSD" &&
         symbol != "GBPJPY" &&
         symbol != "USDJPY"
         )
        {
         SymbolSelect(symbol,false);
        }
     }

   st=SymbolsTotal(true);
   for(i=0; i<st; i++)
     {
      symbol=SymbolName(i,true);
/*
      //--- 1.дождаться окончания процесса перестройки таймсерии
      static int count;
      while(!SeriesInfoInteger(symbol,Period(),SERIES_SYNCHRONIZED) && !IsStopped())
        {
         Sleep(500);
         count++;
         Comment(count,"; ",symbol);
        }
*/
      //Sleep(5000);
      digits=SymbolInfoInteger(symbol,SYMBOL_DIGITS);
      static int count;
      tick_value=SymbolInfoDouble(symbol,SYMBOL_TRADE_TICK_VALUE);
      //--- проверяем корректность действительного числа
      while(!MathIsValidNumber(tick_value))
        {
         Sleep(500);
         tick_value=SymbolInfoDouble(symbol,SYMBOL_TRADE_TICK_VALUE);
         count++;
         Comment(count,"; ",symbol);
         Print("tick_value=",tick_value,"; ",symbol);
        }
      v_ask = SymbolInfoDouble(symbol, SYMBOL_ASK);
      v_bid = SymbolInfoDouble(symbol, SYMBOL_BID);

      Print("Symbol: ",symbol,", digits:",digits,", Ask:",v_ask,", Bid:",v_bid,", TickValue:",tick_value);
     }

   return (INIT_SUCCEEDED);
  }

апр

 

Как воочию убедится, что проверка на корректность числа работает (напомню вся тема про МТ4):

  • Оставить один открытый с проверяемым советником.
  • В обзоре рынка через правую кнопку мышки "Удалить все символы".
  • Перезагрузить MetaTrader 4. 
Чтобы обнаружить ошибку иногда нужно перезагрузить раза два.

 
barabashkakvn:

Как воочию убедится, что проверка на корректность числа работает (напомню вся тема про МТ4):

  • Оставить один открытый с проверяемым советником.
  • В обзоре рынка через правую кнопку мышки "Удалить все символы".
  • Перезагрузить MetaTrader 4. 
Чтобы обнаружить ошибку иногда нужно перезагрузить раза два.

Никогда не пользовался MathIsValidNumber()... Попробую вместо своей проверки.

Но вопрос таки остается. Какого художника SymbolInfoDouble выдает такие значения и даже не генерит ошибку чтобы обработать GetLastError... 

В доках и намека нет на подобную ситуацию.

В плане бреда - а давайте любая функция будет такое вытворять, скажем OrderSend... не важно открыла ордер или нет, вернет когда захочет -1.#IND вместо номера тикета и не сгенерирует ошибку.

Я к тому что это ситуация не нормальная, выходит за рамки процесса информационного взаимодействия. )))

Володя, ты согласен? 

 
elugovoy:

Но вопрос таки остается. Какого художника SymbolInfoDouble выдает такие значения и даже не генерит ошибку чтобы обработать GetLastError... 

В доках и намека нет на подобную ситуацию.

В плане бреда - а давайте любая функция будет такое вытворять, скажем OrderSend... не важно открыла ордер или нет, вернет когда захочет -1.#IND вместо номера тикета и не сгенерирует ошибку.

Я к тому что это ситуация не нормальная, выходит за рамки процесса информационного взаимодействия. )))

Тезка, да конечно исправят, остается надеяться что поскорей. Не в первой прокладки лепить:) Главное что мы этот, мягко говоря недочет, уже знаем. Тестим далее, полет нормальный...
 

Подозреваю 2 ситуации при расчете TICK VALUE внутри терминала.

1. Деление на 0

2. Неверное обращение к индексу массива символов.

3. Вряд ли хотели вернуть "-1" в виде строки и не указали ASCIIZ типа "-1\x00"... хотя я уже ничему не удивляюсь.

Хотя по докам обязана вернуться ошибка:

  • 5040 – invalid string parameter for specifying a symbol name,
  • 4301 – unknown symbol (financial instrument),
  • 4302 – symbol is not selected in "Market Watch" (not found in the list of available ones),
  • 4303 – invalid identifier of a symbol property.
  •  
    svds75:
    Тезка, да конечно исправят, остается надеяться что поскорей. Не в первой прокладки лепить:) Главное что мы этот, мягко говоря недочет, уже знаем. Тестим далее, полет нормальный...

    Жека, к тому времени как исправят, мы уже налепим таких обработок MathIsValidNumber на каждое число полученное от каждой функции терминала ))

    И там уже пусть терминал возвращает хоть черта лысого, нас фиг проберешь этим )) 

     
    elugovoy:

    Жека, к тому времени как исправят, мы уже налепим таких обработок MathIsValidNumber на каждое число полученное от каждой функции терминала ))

    И там уже пусть терминал возвращает хоть черта лысого, нас фиг проберешь этим )) 

    А вот дружков чур не трогать :).
    Причина обращения: