Скрипты: sSyncScroll

 

sSyncScroll:

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

Автор: Дмитрий

Скрипт для синхронной прокрутки графиков.

 

Дмитрий, спасибо огромное за скрипт!

Может есть возможность сделать Ваш скрипт также и в виде индикатора, чтобы был постоянно на графиках и не пропадал при переключении таймфреймов.

С уважением, Эдуард.

 

Уважаемый Дмитрий, спасибо Вам за этот скрипт. И у меня вопрос есть.

Дмитрий, а также уважаемые знатоки,

Не подскажете ли, как сделать, чтобы этот скрипт смещал графики не через 4 свечи за 1 шаг, а через 1 свечу за 1 шаг? Например, у меня открыты 5-минутки, и если я жму стрелку вправо, то с 8:00 сразу перескакиваю на 8:20.

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

Спасибо большое. 

 
Finik:

Уважаемый Дмитрий, спасибо Вам за этот скрипт. И у меня вопрос есть.

Дмитрий, а также уважаемые знатоки,

Не подскажете ли, как сделать, чтобы этот скрипт смещал графики не через 4 свечи за 1 шаг, а через 1 свечу за 1 шаг? Например, у меня открыты 5-минутки, и если я жму стрелку вправо, то с 8:00 сразу перескакиваю на 8:20.

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

Спасибо большое. 

А он вообще работает? Мне недавно писали что и этот сломался.
 
Finik:

Дмитрий, а также уважаемые знатоки,

Не подскажете ли, как сделать, чтобы этот скрипт смещал графики не через 4 свечи за 1 шаг, а через 1 свечу за 1 шаг? Например, у меня открыты 5-минутки, и если я жму стрелку вправо, то с 8:00 сразу перескакиваю на 8:20.

F12 и Shift+F12
 
Andrey Khatimlianskii:
F12 и Shift+F12
Спасибо
 
При приходе новой котировки смещает график вправо. При этом смещение графика при приходе новых тиков отключено. Его сам скрипт отключает. Могу попробовать починить, но дайте пожалуйста наводку, какая именно часть кода за это отвечает. В MQL 5 я новичок
 
Действительно, при попытке прокрутить график назад и посмотреть историю, при приходе нового тика график возвращается в самое начало. В таком случае нах он нужен? Я и так знаю, что при рисовании последней свечи на М1, это же является и последней свечёй для всех остальных ТФ. И без этого индикатора во всех окнах последние свечи перерисовываются автоматически.
 
Дима Джумок #:
Действительно, при попытке прокрутить график назад и посмотреть историю, при приходе нового тика график возвращается в самое начало. В таком случае нах он нужен? Я и так знаю, что при рисовании последней свечи на М1, это же является и последней свечёй для всех остальных ТФ. И без этого индикатора во всех окнах последние свечи перерисовываются автоматически.

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

 
Dmitry Fedoseev #:

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

Дмитрий, благодарю вас за ответ. К моему сожалению гугл даёт ссылки только на ваши разработки. Форум так же ничего альтернативного мне не предложил. Адмирал Маркет предлагает такую функцию но только на их платформе и это не МТ5. Уважаемый  fxsaber  предлагал в 2017 году свой вариант  Одновременная автопрокрутка графиков по одному инструменту в разных таймфреймах для МТ5 - Технические индикаторы и анализ рынка Форекс - Форум алго-трейдеров MQL5  (там в последнем комментарии находится текст индикатора), но я не умею преобразовать его для терминала МТ5, поэтому не могу определить рабочий ли там вариант. Если вас не затруднит преобразуйте пожалуйста его, возможно он рабочий.

// MQL4&5-code
// Синхронизация всех чартов по правому времени

sinput int TimerInterval = 1; // Интервал обновления в миллисекундах

// Отрубает на всех чартах автоскролл и сдвиг
bool AutoShiftOff( void )
{
  long handle = ChartFirst();

  while (handle != INVALID_HANDLE)
  {
    ChartSetInteger(handle, CHART_SHIFT, false);
    ChartSetInteger(handle, CHART_AUTOSCROLL, false);

    handle = ChartNext(handle);
  }

  return(true);
}

const bool Init = EventSetMillisecondTimer(TimerInterval) && AutoShiftOff();

void OnTimer()
{
  SyncCharts();
}

// Возвращает true, если нет бара с таким временем ("дырка")
bool IsHole( const string Symb, const ENUM_TIMEFRAMES TimeFrame, const datetime time )
{
  return(Bars(Symb, TimeFrame, SeriesInfoInteger(_Symbol, PERIOD_CURRENT, SERIES_FIRSTDATE), time) +
         Bars(Symb, TimeFrame, time, SeriesInfoInteger(_Symbol, PERIOD_CURRENT, SERIES_LASTBAR_DATE)) ==
         SeriesInfoInteger(_Symbol, PERIOD_CURRENT, SERIES_BARS_COUNT));
}

// Возвращает бар по времени
int iBarShift( const string Symb, const ENUM_TIMEFRAMES TimeFrame, datetime time )
{
  int Res = -1;
  datetime LastBar;

  time -= time % PeriodSeconds(TimeFrame);

  if (SeriesInfoInteger(Symb, TimeFrame, SERIES_LASTBAR_DATE, LastBar))
  {
    if (time > LastBar)
      Res = (int)((LastBar - time) / PeriodSeconds(TimeFrame));
    else
    {
      const int Shift = Bars(Symb, TimeFrame, time, LastBar);

      if (Shift > 0)
      {
        Res = Shift - 1;

        if (IsHole(Symb, TimeFrame, time))
          Res++;
      }
    }
  }

  return(Res);
}

// Возвращает время по бару
datetime iBarShift( const string Symb, const ENUM_TIMEFRAMES TimeFrame = PERIOD_CURRENT, const int Pos = 0 )
{
  datetime Tmp[1];

  CopyTime(Symb, TimeFrame, (Pos < 0) ? 0 : Pos, 1, Tmp);

  return(Tmp[0] - ((Pos < 0) ? Pos * PeriodSeconds(TimeFrame) : 0));
}

// Возвращает правый бар чарта
int ChartBarRight( const long chartID = 0 )
{
  return((int)(ChartGetInteger(chartID, CHART_FIRST_VISIBLE_BAR) - ChartGetInteger(chartID, CHART_WIDTH_IN_BARS) + 1));
}

// Возвращает правое время чарта
datetime GetChartTimeRight( const long chartID = 0 )
{
  return(iBarShift(ChartSymbol(chartID), ChartPeriod(chartID), ChartBarRight(chartID)));
}

// Устанавливает правое время чарта, возвращает установленное время
datetime SetChartTimeRight( datetime time, const long chartID = 0, const ulong MaxTime = 1e5 )
{
  const string Symb = ChartSymbol(chartID);
  const ENUM_TIMEFRAMES period = ChartPeriod(chartID);

  const int Pos = iBarShift(Symb, period, time);
  const int PrevPos = ChartBarRight(chartID);

  if ((Pos != PrevPos) && ChartNavigate(chartID, CHART_END, -1 - Pos))
  {
    const ulong StartTime = GetMicrosecondCount();
    int NewPos = ChartBarRight(chartID);

    while (((NewPos != Pos)|| (NewPos == PrevPos)) && (GetMicrosecondCount() - StartTime < MaxTime) && !IsStopped())
    {
      Sleep(0);
      
      NewPos = ChartBarRight(chartID);
    }
  }

  return(GetChartTimeRight(chartID));
}

// Добавление элемента в конец произвольного массива
template <typename T>
void AddArrayElement( T &Array[], const T Value, const int Reserve = 0 )
{
  const int Size = ArraySize(Array);

  ArrayResize(Array, Size + 1, Reserve);

  Array[Size] = Value;
}

// Получает время правого бара каждого чарта
int GetChartsTimeRight( datetime &RightTime[], long &Handles[] )
{
  ArrayFree(RightTime);
  ArrayFree(Handles);

  long handle = ChartFirst();

  while (handle != INVALID_HANDLE)
  {
    AddArrayElement(RightTime, GetChartTimeRight(handle));
    AddArrayElement(Handles, handle);

    handle = ChartNext(handle);
  }

  return(ArraySize(RightTime));
}

// Устанавливает правое время на все чарты
int SetChartsTimeRight( const datetime time, datetime &RightTime[], const long ExcludeHandle = 0 )
{
  ArrayFree(RightTime);

  long handle = ChartFirst();

  while (handle != INVALID_HANDLE)
  {
    AddArrayElement(RightTime, (ExcludeHandle == handle) ? GetChartTimeRight(handle) : SetChartTimeRight(time, handle));

    handle = ChartNext(handle);
  }

  return(ArraySize(RightTime));
}

// Возвращает чарт, что время правого бара которого изменилось
long GetChangeChart( const datetime &PrevRightTime[])
{
  datetime Handles[];
  datetime RightTime[];

  long Res = ArraySize(PrevRightTime) ? 0 : ChartID();

  for (int i = MathMin(ArraySize(PrevRightTime), GetChartsTimeRight(RightTime, Handles)) - 1; i >= 0; i--)
    if (RightTime[i] != PrevRightTime[i])
    {
      Res = Handles[i];

      break;
    }

  return(Res);
}

// Синхронизация всех чартов по правому времени, возвращает количество синхронизированных чартов
int SyncCharts()
{
  static datetime PrevRightTime[];

  const long handle = GetChangeChart(PrevRightTime);

  return(handle ? SetChartsTimeRight(GetChartTimeRight(handle), PrevRightTime, handle) : 0);
}
fxsaber
fxsaber
  • 2023.01.17
  • www.mql5.com
Профиль трейдера
 
Дима Джумок #:

Дмитрий, благодарю вас за ответ. К моему сожалению гугл даёт ссылки только на ваши разработки. Форум так же ничего альтернативного мне не предложил. Адмирал Маркет предлагает такую функцию но только на их платформе и это не МТ5. Уважаемый  fxsaber  предлагал в 2017 году свой вариант  Одновременная автопрокрутка графиков по одному инструменту в разных таймфреймах для МТ5 - Технические индикаторы и анализ рынка Форекс - Форум алго-трейдеров MQL5  (там в последнем комментарии находится текст индикатора), но я не умею преобразовать его для терминала МТ5, поэтому не могу определить рабочий ли там вариант. Если вас не затруднит преобразуйте пожалуйста его, возможно он рабочий.

Тогда уж лучше свой исправить. 

Скачал свой сейчас, он работает. Одно неудобство - если отступы не включены, нужный бар на прокручиваемом графике выходит за край и линию не видно. Вот это надо будет поправить.

А что у вас происходит, как оно не работает? В скрипте сделано отключение автопрокрутки с приходом нового тика. 

Вот эта кнопка на панели инструментов должна автоматически отжиматься на всех графиках при присоединении скрипта:

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