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

 

Добрый день, Антон!

По Вашему совету ( LoadServerData() вызывает SeriesInfoInteger( a_symbol, PERIOD_M1, SERIES_SERVER_FIRSTDATE),

т.е. читается "первая дата в истории по символу на сервере независимо от периода".

Сам по себе этот запрос фактически не считается запросом истории, т.е. не вызывает построения кэша,

не предотвращает выгрузку данных символа. Имеет смысл либо запросить SERIES_FIRSTDATE, либо число баров таймсерии.),

 

я добавил новую функцию в индикатор, чтобы предотвратить выгрузку данных символа:

//+------------------------------------------------------------------+
// Custom indicator Book Event function                              |
//+------------------------------------------------------------------+
void OnBookEvent( const string &symbol )
{
  if ( ( ( symbol == _Symbol ) || ( symbol == sec_symbol ) ) && ( !IsStopped() ) )
  {
    GetBars( sec_symbol, time_frame );
  }  
}

 

//+------------------------------------------------------------------+
// Custom indicator Check timer function                             |
//+------------------------------------------------------------------+
bool CheckTimer( const uint start_value, const uint per_value )
{
  uint end_value = GetTickCount();
  
  if ( end_value < start_value )
  {
    if ( ( start_value - end_value ) >= per_value ) return( true );
  } 
  else
  {
    if ( ( end_value - start_value ) >= per_value ) return( true );
  }
  return( false );
}
//+------------------------------------------------------------------+
//| Custom indicator Get local data function                         |
//+------------------------------------------------------------------+
int GetLocalData( const string a_symbol, ENUM_TIMEFRAMES a_period )
{
  long first_date;
  int fail_cnt = 0;
//---  
  while ( ( fail_cnt < 3 ) && !IsStopped() )
  {
    first_date = long( SeriesInfoInteger( a_symbol, PERIOD_M1, SERIES_TERMINAL_FIRSTDATE ) );
//---    
    if ( first_date > 0 )
    {
      int f_cnt = 0;
      datetime times[1];
      long a_bars = 0;
//---  
      while ( ( f_cnt < 5 ) && !IsStopped() )
      {
        if ( bool( SeriesInfoInteger( a_symbol, PERIOD_M1, SERIES_BARS_COUNT, a_bars ) ) )
        {
          if ( a_bars > 0 )
          {
            if ( bool( SeriesInfoInteger( a_symbol, a_period, SERIES_BARS_COUNT, a_bars ) ) )
              if ( a_bars > 0 ) return( int( a_bars ) );
          }
        }
        else
        {
//--- force timeseries build
          CopyTime( a_symbol, a_period, 0, 1, times );
          uint start_tick = GetTickCount();
//---        
          while ( !CheckTimer( start_tick, 5 ) )
          {
            f_cnt--;
            f_cnt++;
          }  
        }
        f_cnt++;
      } 
  //    Print( "GetLocalData: Таймсерия не построена!" );
    }
    else
    {
      uint start_tick = GetTickCount();
//---        
      while ( !CheckTimer( start_tick, 5 ) )
      {
        fail_cnt--;
        fail_cnt++;
      }
    }
//---   
    fail_cnt++;
  }
//  Print( "GetLocalData: Нет данных в терминале!" );
  return( 0 );
}
//+------------------------------------------------------------------+
//| Custom indicator Get server data function                        |
//+------------------------------------------------------------------+
int LoadServerData( const string a_symbol, ENUM_TIMEFRAMES period )
{
  int fail_cnt = 0;
//---
  while ( ( fail_cnt < 5 ) && !IsStopped() )
  {   
    long first_date = long( SeriesInfoInteger( a_symbol, PERIOD_M1, SERIES_SERVER_FIRSTDATE ) );
//---
    if ( first_date > 0 )
    {
      if ( SymbolIsSynchronized( a_symbol ) )
      {
  //      Print( "LoadServerData: Первая дата на сервере есть. Пробуем получить локальные данные..." );
        return( GetLocalData( a_symbol, period ) );
      }  
    }
    else
    {
      uint start_tick = GetTickCount();
//---        
      while ( !CheckTimer( start_tick, 10 ) )
      {
        fail_cnt--;
        fail_cnt++;
      }
    }    
    fail_cnt++;
  }
 // Print( "LoadServerData: Первой даты на сервере нет!" );
  return( 0 );  
}
//+------------------------------------------------------------------+
//| Custom indicator Get bars function                               |
//+------------------------------------------------------------------+
int GetBars( string symbol, ENUM_TIMEFRAMES period )
{
  if ( !IsStopped() )
  {
    int a_bars = Bars( symbol, period );
//---
    if ( a_bars > 0 )
    {
      return( a_bars ); 
    }
    else
    {
  //    Print( "GetBars: Бары не получены проверяем синхронизации..." );
//---Check symbol is synchronized  
      if ( SymbolIsSynchronized( symbol ) )
      {
    //    Print( "GetBars: Символ сихронизирован. Проверяем таймсерию..." );
//---Check series is synchronized
        if ( bool( SeriesInfoInteger( symbol, period, SERIES_SYNCHRONIZED ) ) )
        {
     //     Print( "GetBars: Серия синхронизирована. Пробуем получить бары..." );
          a_bars = Bars( symbol, period );  
//---           
          if ( a_bars > 0 )
          {
            return( a_bars );
          }
          else
          {
            return( GetLocalData( symbol, period ) );
          }  
        }
        else
        {
      //    Print( "GetBars: Серия не сихронизирована. Пробуем получить данные из терминала..." );
          return( GetLocalData( symbol, period ) );
        }    
      }  
      else
      {
    //    Print( "GetBars: Символ не синхронизирован. Пробуем получить данные с сервера..." );
        return( LoadServerData( symbol, period ) );
      }  
    }   
  }  
  return( 0 );
}

 

 Функция OnBookEvent() срабатывает на символах BR-8.15 и BR-9.15 достаточно часто,

но результат тот же:

2015.07.23 20:48:13.449 Spread (BR-8.15,M1)     OnCalculate: Не получены бары по символу BR-9.15
2015.07.23 20:48:13.449 Spread (BR-8.15,M1)     OnCalculate: Не получены бары по символу BR-9.15
2015.07.23 20:48:13.449 Spread (BR-8.15,M1)     OnCalculate: Не получены бары по символу BR-9.15
2015.07.23 20:48:13.449 Spread (BR-8.15,M1)     OnCalculate: Не получены бары по символу BR-9.15
2015.07.23 20:48:13.449 Spread (BR-8.15,M1)     OnCalculate: Не получены бары по символу BR-9.15

 

Так в чём же дело?

Почему невозможно получить Бары? 

 
Михаил:

 Функция OnBookEvent() срабатывает на символах BR-8.15 и BR-9.15 достаточно часто,

но результат тот же:

Так в чём же дело?

Почему невозможно получить Бары? 

Периодичность "достаточно часто" не внушает доверия. Лучше для отладки добавить вывод в лог из функции GetBars().

Если есть желание разобраться, то открывайте заявку в сервисдеске. Приложите полноценный пример кода, попробуем воспроизвести проблему.

 
Anton:

Периодичность "достаточно часто" не внушает доверия. Лучше для отладки добавить вывод в лог из функции GetBars().

Если есть желание разобраться, то открывайте заявку в сервисдеске. Приложите полноценный пример кода, попробуем воспроизвести проблему.

Хорошо. Заявка: ОшибкиMetaTrader 5 ClientОткрытаНачата: 2015.07.24 18:28#1267768

 

P/S "Достаточно часто" - это от 10 до 100 срабатываний OnBookEvent() по двум высоколиквидным инструментам в МИНУТУ. 

 

Ур-рра!

Support Team 2015.07.29 16:29

Проблему воспроизвел. Действительно данные символа иногда выгружались из памяти даже при наличии периодических запросов. Ошибка будет исправлена. 

Спасибо! 

 
Михаил:

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


Сейчас Демо-сервер выдаёт Билд 1159 от 22 июня 2015 года. И в нём мультивалютные индикаторы тоже работают ужасно. Нужно несколько раз периоды переключить или индикатор перезапустить, чтобы он правильно отрисовался. А через некоторое время он опять не получает данные серий. В журнал постоянно пишет

Данные символа "Si-12.15" не синхронизированы с торговым сервером.

Разработчикам:

Неужели нельзя сделать функции, не для проверки синхронизированы данные или нет, а непосредственно для синхронизации и не выгружать эти данные из памяти?

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

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

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

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

SynchronizeSymbol("RTS-12.15");
SynchronizeSymbol("BR-10.15");
SynchronizeSymbol("Si-12.15");
 
demonsn:

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


Сейчас Демо-сервер выдаёт Билд 1159 от 22 июня 2015 года. И в нём мультивалютные индикаторы тоже работают ужасно. Нужно несколько раз периоды переключить или индикатор перезапустить, чтобы он правильно отрисовался. А через некоторое время он опять не получает данные серий. В журнал постоянно пишет

Разработчикам:

Неужели нельзя сделать функции, не для проверки синхронизированы данные или нет, а непосредственно для синхронизации и не выгружать эти данные из памяти?

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

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

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

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

Добрый день!

Разработчики ответили, что поправят в новом билде.

Когда он выйдет, пока не известно.

 
Обещанного три года ждут )
 

ФОРТС. Столкнулся с проблемой, функции OrderCheck() и OrderCalcMargin() иногда (!) неправильно определяют требуемое ГО для сделки и в итоге возвращают FALSE.

При требуемом ГО  для RTS-12.15 (SYMBOL_MARGIN_INITIAL) в 12 500 руб. функция требует аж 143 105 рубля!

При этом вручную всё отлично открывается.

Как вызываю:

MqlTradeRequest MtRequest = {0}; 

MqlTradeRequest.action = TRADE_ACTION_DEAL;
MqlTradeRequest.magic  = 0;
MqlTradeRequest.order  = 0;
MqlTradeRequest.symbol = "RTS-12.15";
MqlTradeRequest.volume = 1.00;
MqlTradeRequest.price  = 86470;
MqlTradeRequest.stoplimit = 0;
MqlTradeRequest.sl = 0;
MqlTradeRequest.tp = 0;
MqlTradeRequest.deviation = 50;
MqlTradeRequest.type = ORDER_TYPE_SELL;
MqlTradeRequest.type_filling = ORDER_FILLING_FOK;
MqlTradeRequest.type_time = gtc;
MqlTradeRequest.expiration = 0;
MqlTradeRequest.comment = NULL;

MqlTradeCheckResult MtCheckResult = {0};

OrderCheck(MtRequest,MtCheckResult);

Получаю в ответ False и такую структуру:

MqlTradeCheckResult.retcode:      10019 (There is not enough money to complete the request)
MqlTradeCheckResult.balance:      132727.37
MqlTradeCheckResult.equity:       130772.91
MqlTradeCheckResult.profit:       0.00
MqlTradeCheckResult.margin:       143104.55
MqlTradeCheckResult.margin_free: -12331.64
MqlTradeCheckResult.margin_level: 91.38
MqlTradeCheckResult.comment:      No money

 

Попробуйте так:

  MqlTradeRequest MtRequest = {0}; 
  MqlTradeCheckResult MtCheckResult = {0};
//---
  MtRequest.action = TRADE_ACTION_DEAL;
  MtRequest.magic  = 7777777777;
  MtRequest.symbol = "RTS-12.15";
  MtRequest.volume = 1.00;
  MtRequest.price  = 86470;
  MtRequest.type = ORDER_TYPE_SELL;
  MtRequest.type_filling = ORDER_FILLING_FOK;
  MtRequest.type_time = ORDER_TIME_DAY;
//---
 if ( OrderCheck( MtRequest, MtCheckResult ) )
 {
   Print( "retcode = ", MtCheckResult.retcode );
   Print( "balance = ", MtCheckResult.balance );
   Print( "equity = ",  MtCheckResult.equity );
   Print( "profit = ", MtCheckResult.profit );
   Print( "margin = ", MtCheckResult.margin );
   Print( "margin_free = ", MtCheckResult.margin_free  );
   Print( "margin_level = ", MtCheckResult.margin_level );
 }

 Вот мой результат:

2015.10.22 15:38:39.520 LastPrice (RTS-12.15,M1)        margin_level = 979.8676728569379
2015.10.22 15:38:39.334 LastPrice (RTS-12.15,M1)        margin_free = 112198.35
2015.10.22 15:38:39.151 LastPrice (RTS-12.15,M1)        margin = 12751.73
2015.10.22 15:38:38.973 LastPrice (RTS-12.15,M1)        profit = 0.0
2015.10.22 15:38:38.797 LastPrice (RTS-12.15,M1)        equity = 124950.08
2015.10.22 15:38:38.623 LastPrice (RTS-12.15,M1)        balance = 124950.08
2015.10.22 15:38:38.397 LastPrice (RTS-12.15,M1)        retcode = 0
 
Спасибо. Добавил ваш вариант как параллельную проверку. Теперь бы отловить нужный момент.