ФОРТС Прошу помощи - страница 6

Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий
Dmitriy Skub
11773
Dmitriy Skub  
Serj_Che:
Для чего вы в OnCalculate повторяете то что было в OnInit? Это такое заклинание?)

Это простая магия копи/паста))

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

Поэтому, проверку нужно делать и (или только) в калькулейте и не начинать основные расчеты, пока все нужные данные не появятся - то есть проверять до готовности на каждом тике.

Sergey Chalyshev
7754
Sergey Chalyshev  
Dima_S:

Это простая магия копи/паста))

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

Поэтому, проверку нужно делать и (или только) в калькулейте и не начинать основные расчеты, пока все нужные данные не появятся - то есть проверять до готовности на каждом тике.

О чем и речь, функция OnInit в индикаторе бутафория, или разработчики халтурят.

Копи/паст великая вещь, сам грешу ))

Mikhail Filimonov
5306
Mikhail Filimonov  

Покричали, обозвали чукчей, а проблема-то не решена!

//+------------------------------------------------------------------+
//|                                                         Test.mq5 |
//|                        Copyright 2014, MetaQuotes Software Corp. |
//|                                              http://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2014, MetaQuotes Software Corp."
#property link      "http://www.mql5.com"
#property version   "1.00"
#property indicator_separate_window
#property indicator_buffers 1
#property indicator_plots   1
//
bool is_failed = false;
datetime start_time;
datetime end_time;
int mix_bars, rts_bars, si_bars;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
    start_time = StringToTime( "2015.03.17" );
    end_time = TimeCurrent();
//--- indicator buffers mapping
  mix_bars = GetBars( "MIX-6.15" , PERIOD_CURRENT, start_time, end_time ); 
  if ( mix_bars < 1 )
  {
    is_failed = true;
    Print( "Init failed. MIX-6.15 ");
  }
  rts_bars = GetBars( "RTS-6.15" , PERIOD_CURRENT, start_time, end_time ); 
  if ( rts_bars < 1 )
  {
    is_failed = true;
    Print( "Init failed. RTS-6.15 ");
  }
  si_bars = GetBars( "Si-6.15" , PERIOD_CURRENT, start_time, end_time ); 
  if ( si_bars < 1 )
  {
    is_failed = true;
    Print( "Init failed. Si-6.15 ");
  }
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Custom indicator Get bars function                               |
//+------------------------------------------------------------------+
int GetBars( string symbol, ENUM_TIMEFRAMES period, const datetime start_date, const datetime end_date )
{
  if ( !SymbolInfoInteger( symbol, SYMBOL_SELECT ) )
  {
    ResetLastError();
//---    
    if ( GetLastError() != ERR_MARKET_UNKNOWN_SYMBOL )
    {
      SymbolSelect( symbol, true );
    }
    else
    {
      Print( "GetBars: Неизвестный символ - ", symbol );
      return( 0 );
    }    
  }
//---  
  if ( MQL5InfoInteger( MQL5_PROGRAM_TYPE ) == PROGRAM_INDICATOR && Period() == period && Symbol() == symbol )
  {
    Print( "GetBars: Не пройдена проверка типа программы!" );
    return( 0 );
  }  
//---
  if ( SymbolIsSynchronized( symbol ) )
  {
    return( Bars( symbol, period, start_date, end_date ) );
  }
  else
  {
    long first_date = 0;
    datetime times[1];
//---    
    if ( SeriesInfoInteger( symbol, PERIOD_M1, SERIES_TERMINAL_FIRSTDATE, first_date ) )
    {
      if ( first_date > 0 )
      {
//--- force timeseries build
        CopyTime( symbol, period, datetime( first_date ) + PeriodSeconds( period ), 1, times );
//--- check date
        if ( SeriesInfoInteger( symbol, period, SERIES_FIRSTDATE, first_date ) )
//---        
        if ( first_date > 0 && first_date <= long( start_date ) )
        {
          return( Bars( symbol, period, start_date, end_date ) );
        } 
      }
    }
    Print( "Необходима загрузка истории с сервера!");
  }       
//---  
  return( 0 );
}  
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
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[])
  {
//---
   if ( is_failed )
   {
     Print( "Sorry! Get Bars failed." );
   }
   else Print( "Bingo! We done.");
//--- return value of prev_calculated for next call
   return(rates_total);
  }

 Закачку истории не написал ещё, НО данные есть в терминале, а НЕ БЕРУТСЯ из него с первого раза!

 

2015.03.26 20:49:01.641 Test (MIX-6.15,M1)      Необходима загрузка истории с сервера!
2015.03.26 20:49:01.641 Test (MIX-6.15,M1)      Init failed. RTS-6.15 
2015.03.26 20:49:01.641 Test (MIX-6.15,M1)      Необходима загрузка истории с сервера!
2015.03.26 20:49:01.641 Test (MIX-6.15,M1)      Init failed. Si-6.15 
2015.03.26 20:49:01.641 Test (MIX-6.15,M1)      Sorry! Get Bars failed.
Andrey Miguzov
1976
Andrey Miguzov  
Serj_Che:

Ок, интересно! 

Индикаторы работают в своем потоке, советники в своем. Если конечно не одноядерный камень. 

Всё происходит ровно так, как и написано в документации. :)

Набросал для проверки индикатор и эксперта + результат на видео.

1) Сначала бросаю на график эксперта, у которого внутри OnTick есть функция,  работающая в течение 20 секунд.

Результат – чат продолжает работать и отображать всё как надо.  Стакан тоже работает как надо.

2) Потом бросаем на график индикатор, у которого внутри OnCalculate есть функция,  работающая в течение 20 секунд.

Результат – чат подвисает. Причем соседний чат с тем же символом, на котором установлен другой период тоже подвисает. Стакан продолжает работать как надо. После того как функция отработала – всё возвращается на круги своя.

3) На видео этого нет - но если на один чат набросить индикатор (поставьте 60 сек), а на другой эксперта - эксперт не начинает работать пока не отглючит индикатор на другом чате!!! 

Видео прикрепил отдельно - в браузере у меня тормозит. 

Sergey Chalyshev
7754
Sergey Chalyshev  
MigVRN:

Всё происходит ровно так, как и написано в документации. :)

Набросал для проверки индикатор и эксперта + результат на видео.

1) Сначала бросаю на график эксперта, у которого внутри OnTick есть функция,  работающая в течение 20 секунд.

Результат – чат продолжает работать и отображать всё как надо.  Стакан тоже работает как надо.

2) Потом бросаем на график индикатор, у которого внутри OnCalculate есть функция,  работающая в течение 20 секунд.

Результат – чат подвисает. Причем соседний чат с тем же символом, на котором установлен другой период тоже подвисает. Стакан продолжает работать как надо. После того как функция отработала – всё возвращается на круги своя.

3) На видео этого нет - но если на один чат набросить индикатор (поставьте 60 сек), а на другой эксперта - эксперт не начинает работать пока не отглючит индикатор на другом чате!!! 

Видео прикрепил отдельно - в браузере у меня тормозит. 

Спасибо, видео не получается посмотреть, поизучаю.

Vladimir Karputov
Модератор
169149
Vladimir Karputov  

Если Пытаетесь получить данные из торгового окружения при работе из индикатора, то даже не пытайтесь задавать запросы в OnInit(). Проводите запросы и проверки ответа в OnCalculate(). При получении данных или с чужого инструмента или с другого таймфрейма практически гарантировано, что Вам не удастся даже в OnCalculate() с первого раза получить данные. Поэтому проводите проверку возврата значений. Если значения не получены, пробуйте получить данные на следующем тике в OnCalculate().


Так же уже интересен ответ сервисдеска - код который был предоставлен.

Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий

ФОРТС Прошу помощи

alexvd, 2015.03.26 15:48

Вам в сервисдеске дали исходник. Попробуйте поместить ваш последний код в функцию Test().

Уже спортивный интерес - автор продолжает писать свой код и игнорирует код сервисдеска?

Andrey Miguzov
1976
Andrey Miguzov  
barabashkakvn:

Если Пытаетесь получить данные из торгового окружения при работе из индикатора, то даже не пытайтесь задавать запросы в OnInit(). Проводите запросы и проверки ответа в OnCalculate(). При получении данных или с чужого инструмента или с другого таймфрейма практически гарантировано, что Вам не удастся даже в OnCalculate() с первого раза получить данные. Поэтому проводите проверку возврата значений. Если значения не получены, пробуйте получить данные на следующем тике в OnCalculate().

+++ и так до победного. Т.е если данных нет - return;
Vladimir Karputov
Модератор
169149
Vladimir Karputov  
MigVRN:
+++ и так до победного. Т.е если данных нет - return;
Это смотря, что запрашивать. И сколько делать запросов - это уже целиком зависит от предпочтений писателя кода.
Mikhail Filimonov
5306
Mikhail Filimonov  
barabashkakvn:
Это смотря, что запрашивать. И сколько делать запросов - это уже целиком зависит от предпочтений писателя кода.

Вы понимаете, что

если есть данные в терминале, то функция

SeriesInfoInteger( symbol, PERIOD_M1, SERIES_TERMINAL_FIRSTDATE, first_date )

 Не должна возвращать FALSE?

 

P/S код СД ТОЖЕ НЕ РАБОТАЕТ С ПЕРВОГО РАЗА! 

Mikhail Filimonov
5306
Mikhail Filimonov  

ЕЩЁ РАЗ.

из справки:

SeriesInfoInteger

Возвращает информацию о состоянии исторических данных. Существует 2 варианта функции.

Второй вариант: 

bool  SeriesInfoInteger(
   string                     symbol_name,     // имя символа
   ENUM_TIMEFRAMES            timeframe,       // период
   ENUM_SERIES_INFO_INTEGER   prop_id,         // идентификатор свойства
   long&                      long_var         // переменная для получения информации
   );

 

SERIES_TERMINAL_FIRSTDATE

Самая первая дата в истории по символу в клиентском терминале независимо от периода

datetime

 

НЕ ДОЛЖНА ФУНКЦИЯ ВОЗВРАЩАТЬ FALSE, ЕСЛИ ЕСТЬ ДАННЫЕ В ТЕРМИНАЛЕ!!! 

Откуда бы Вы её не вызывали! 

Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий