Индикатор: Синхронизация символа НЕ на котором установлен индикатор

 

Уважаемые разработчики!

Вот уже НЕСКОЛЬКО лет существует проблема, когда в индикаторе используется

ещё один (несколько) символов, и не появляется синхронизация серии другого символа

Код индикатора

//+------------------------------------------------------------------+
//|                                                     BG_forts.mq5 |
//|                                      Copyright 2017 prostotrader |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2017 prostotrader"
#property link      "https://www.mql5.com"
#property version   "1.00"
#property indicator_separate_window
#property indicator_buffers 1
#property indicator_plots   1
//
#property indicator_label1  "Si_price" 
#property indicator_type1   DRAW_LINE 
#property indicator_color1  clrYellow
#property indicator_style1  STYLE_SOLID 
#property indicator_width1  1  
//
input double BarPrice = 40;          //Бюджетная стоимость барреля в $ 
input string USDSpot = "USDRUB_TOM"; //USD спот
//
double PBuff[];
MqlRates rates[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
{
  if(StringFind(Symbol(), "BR-") < 0)
  {
    Alert("Индикатор должен быть на графике Brent!");
    return(INIT_FAILED);
  }
  if(!SymbolSelect(USDSpot, true))
  {
    Alert("Не выбран спот символ!");
    return(INIT_FAILED);
  }
//---
  IndicatorSetInteger(INDICATOR_DIGITS,0);
  IndicatorSetString(INDICATOR_SHORTNAME,"BG_forts");
  SetIndexBuffer(0,PBuff,INDICATOR_DATA);
  ArraySetAsSeries(PBuff,true);
  PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,EMPTY_VALUE);   
  return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
  if(reason==REASON_INITFAILED)
  {
    int window=ChartWindowFind(ChartID(),"BG_forts");
    ChartIndicatorDelete(ChartID(),window,"BG_forts");
  }
}  
//+------------------------------------------------------------------+
//| Custom indicator calc value function                             |
//+------------------------------------------------------------------+
double CalcValue()
{
  return(0); //TODO!
}
//+------------------------------------------------------------------+
//| 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(prev_calculated == 0)
  {
    ArrayInitialize(PBuff,EMPTY_VALUE);
    ResetLastError();
    int usd_bars = Bars(USDSpot, Period());
    if(usd_bars<=0)
    {
      int l_err = GetLastError();
      Print("Код ошибки: ", l_err);
      bool is_sync = bool(SeriesInfoInteger(USDSpot,Period(),SERIES_SYNCHRONIZED));
      Print("Не получены бары по символу " + USDSpot + "!");
      Print("Синхронизация серии: ", string(is_sync));
      return(prev_calculated);
    }
    else
    {
      ResetLastError();
      int res = CopyRates(USDSpot, Period(), 0, usd_bars, rates);
      if(res <=0)
      {
        int l_err = GetLastError();
        Print("Код ошибки: ", l_err);
        Print("Не получены данные по символу " + USDSpot + "!");
        return(prev_calculated);  
      }
      else
      {
        int bars_start = rates_total - prev_calculated;
      int mem_pos = res -1;
      for(int i = bars_start - 1; i >=0 ; i--)
      {
        for(int j = mem_pos; j >=0 ; j--)
        {
          if(time[i] == rates[j].time)
          {
            PBuff[i] = CalcValue();
            mem_pos = j;
            break;
          }
          else
          {
            if(i < (bars_start - 1)) PBuff[i] = PBuff[i+1];
          }
        }
      }
      }
    }
  }
  else
  {
   //TODO!
  }
  return(rates_total);
}
//+------------------------------------------------------------------+

Результат

2017.08.08 12:22:23.475 BG_forts (BR-9.17,H1)   Код ошибки: 4401
2017.08.08 12:22:23.475 BG_forts (BR-9.17,H1)   Не получены бары по символу USDRUB_TOM!
2017.08.08 12:22:23.475 BG_forts (BR-9.17,H1)   Синхронизация серии: false
2017.08.08 12:22:23.475 BG_forts (BR-9.17,H1)   Код ошибки: 4401
2017.08.08 12:22:23.475 BG_forts (BR-9.17,H1)   Не получены бары по символу USDRUB_TOM!
2017.08.08 12:22:23.475 BG_forts (BR-9.17,H1)   Синхронизация серии: false
2017.08.08 12:22:23.475 BG_forts (BR-9.17,H1)   Код ошибки: 4401
2017.08.08 12:22:23.475 BG_forts (BR-9.17,H1)   Не получены бары по символу USDRUB_TOM!
2017.08.08 12:22:23.475 BG_forts (BR-9.17,H1)   Синхронизация серии: false
2017.08.08 12:22:23.475 BG_forts (BR-9.17,H1)   Код ошибки: 4401
2017.08.08 12:22:23.475 BG_forts (BR-9.17,H1)   Не получены бары по символу USDRUB_TOM!
2017.08.08 12:22:23.475 BG_forts (BR-9.17,H1)   Синхронизация серии: false
2017.08.08 12:22:23.475 BG_forts (BR-9.17,H1)   Код ошибки: 4401
2017.08.08 12:22:23.475 BG_forts (BR-9.17,H1)   Не получены бары по символу USDRUB_TOM!
2017.08.08 12:22:23.475 BG_forts (BR-9.17,H1)   Синхронизация серии: false
2017.08.08 12:22:23.475 BG_forts (BR-9.17,H1)   Код ошибки: 4401
2017.08.08 12:22:23.475 BG_forts (BR-9.17,H1)   Не получены бары по символу USDRUB_TOM!
2017.08.08 12:22:23.475 BG_forts (BR-9.17,H1)   Синхронизация серии: false
2017.08.08 12:22:23.475 BG_forts (BR-9.17,H1)   Код ошибки: 4401
2017.08.08 12:22:23.475 BG_forts (BR-9.17,H1)   Не получены бары по символу USDRUB_TOM!
2017.08.08 12:22:23.475 BG_forts (BR-9.17,H1)   Синхронизация серии: false
2017.08.08 12:22:23.475 BG_forts (BR-9.17,H1)   Код ошибки: 4401
2017.08.08 12:22:23.475 BG_forts (BR-9.17,H1)   Не получены бары по символу USDRUB_TOM!
2017.08.08 12:22:23.475 BG_forts (BR-9.17,H1)   Синхронизация серии: false
2017.08.08 12:22:23.475 BG_forts (BR-9.17,H1)   Код ошибки: 4401
2017.08.08 12:22:23.475 BG_forts (BR-9.17,H1)   Не получены бары по символу USDRUB_TOM!
2017.08.08 12:22:23.475 BG_forts (BR-9.17,H1)   Синхронизация серии: false
2017.08.08 12:22:23.475 BG_forts (BR-9.17,H1)   Код ошибки: 4401
2017.08.08 12:22:23.475 BG_forts (BR-9.17,H1)   Не получены бары по символу USDRUB_TOM!
2017.08.08 12:22:23.475 BG_forts (BR-9.17,H1)   Синхронизация серии: false
2017.08.08 12:22:23.475 BG_forts (BR-9.17,H1)   Код ошибки: 4401
2017.08.08 12:22:23.475 BG_forts (BR-9.17,H1)   Не получены бары по символу USDRUB_TOM!
2017.08.08 12:22:23.475 BG_forts (BR-9.17,H1)   Синхронизация серии: false
2017.08.08 12:22:23.475 BG_forts (BR-9.17,H1)   Код ошибки: 4401
2017.08.08 12:22:23.475 BG_forts (BR-9.17,H1)   Не получены бары по символу USDRUB_TOM!
2017.08.08 12:22:23.475 BG_forts (BR-9.17,H1)   Синхронизация серии: false
2017.08.08 12:22:23.475 BG_forts (BR-9.17,H1)   Код ошибки: 4401
2017.08.08 12:22:23.475 BG_forts (BR-9.17,H1)   Не получены бары по символу USDRUB_TOM!
2017.08.08 12:22:23.475 BG_forts (BR-9.17,H1)   Синхронизация серии: false
2017.08.08 12:22:23.475 BG_forts (BR-9.17,H1)   Код ошибки: 4401
2017.08.08 12:22:23.475 BG_forts (BR-9.17,H1)   Не получены бары по символу USDRUB_TOM!
2017.08.08 12:22:23.475 BG_forts (BR-9.17,H1)   Синхронизация серии: false

По НЕСКОЛЬКУ минут не появляется сихронизация!!!

Когда же, наконец, решите эту проблему???

 
prostotrader:

По НЕСКОЛЬКУ минут не появляется сихронизация!!!

Когда же, наконец, решите эту проблему???

Лучше вынести блок синхронизации за определение момента первого запуска и, в случае отсутствия синхронизации - полностью пересчитать индикатор. Синхронизация иногда прерывается во время работы. Да, SERIES_SYNCHRONIZED, как по мне, лучше вообще не использовать. Ее результат иногда отличается от результата Bars(), особенно во время старта терминала/перехода на новый сервер.
 

Видимо, всех эта ситуация устраивает, те, кто не писали мультивалютные индикаторы в МТ, вас не поймут :)
https://www.mql5.com/ru/forum/212354

Я решаю ситуацию так :

1. во время старта индикатора запускаю таймер и он работает пока не подгрузятся данные всех символов, потом убиваю таймер и работает только OnCalculate
2. после этого обновляю значения только на последних барах каждого символа, для верности на последнем баре делаю цикл из 100 повторений для CopyRates для каждого символа, обычно за 100 запросов данные для последнего бара таки выбираются

int OnCalculate(const int bars, const int counted, const int start, const double &price[])
{
    Step();

    if (iIndex <= 0)
    {
        for (int k = 0; k < 100 && Step() <= 0; k++); // Method step is taking value of the last bar for 3 symbols, loop is over when we got all 3 prices
    }

    return bars;
}

void OnTimer()
{
    // iSeries[0] = EURUSD, iSeries[1] = GBPUSD, iSeries[2] = EURGBP
    // InpDepth = 1000 bars
    // This line is loading bars until all 3 symbols are completely loaded, CopyRates() goes to this method, in the simplest case it would be while (CopyRates(...) > 0)

    iDepth = iSets.getEqualSets(iSeries, PERIOD_CURRENT, NULL, InpDepth); 

    // Code below is here only to do some calculations on a per-bar basis

    if (iIndex == 0)
    {
        iIndex = iDepth - 1;
    }

    if (iDepth > 0 && Step() > 0) 
    {
        iIndex = MathMax(iIndex, iDepth - 1);

        if (Step() > 0) 
        {
            EventKillTimer();
            ChartRedraw(ChartID());
        }
    }
}
 
Alexey Kozitsyn:
Лучше вынести блок синхронизации за определение момента первого запуска и, в случае отсутствия синхронизации - полностью пересчитать индикатор. Синхронизация иногда прерывается во время работы. Да, SERIES_SYNCHRONIZED, как по мне, лучше вообще не использовать. Ее результат иногда отличается от результата Bars(), особенно во время старта терминала/перехода на новый сервер.

Вы не внимательно смотрели код, если нет синхронизации, то prev_calculated вседа будет равно "0" 

 
prostotrader:

Вы не внимательно смотрели код, если нет синхронизации, то prev_calculated вседа будет равно "0" 

Прочитайте еще раз то, что я написал. Синхронизация может прерваться после первого запуска! Т.е. после того, когда prev_calculated != 0.
 
Alexey Kozitsyn:
Прочитайте еще раз то, что я написал. Синхронизация может прерваться после первого запуска! Т.е. после того, когда prev_calculated != 0.

А я и не говорил, что prev_calculated != 0 мне нужна синхронизация.

 
prostotrader:

А я и не говорил, что prev_calculated != 0 мне нужна синхронизация.

Омг.. ок.
 
prostotrader:

Вы не внимательно смотрели код, если нет синхронизации, то prev_calculated вседа будет равно "0" 


Михаил в своем амплуа, как обычно, все у него того, один он ДыАртанья.

Надо проверку Bars() вытащить из под if(prev_calculated == 0)