Scripts: sSyncScroll - page 2

 
Indeed, when trying to scroll the chart back and view the history, when a new tick arrives, the chart returns to the very beginning. In this case, why do I need it? I already know that when drawing the last candle on M1, it is also the last candle for all other TFs. And without this indicator in all windows the last candlesticks are redrawn automatically.
 
Дима Джумок #:
Indeed, when trying to scroll the chart back and view the history, when a new tick arrives, the chart returns to the very beginning. In this case, why do I need it? I already know that when drawing the last candle on M1, it is also the last candle for all other TFs. And without this indicator in all windows the last candlesticks are redrawn automatically.

It broke after the next changes in the language, I have another one here, also broken. Look for more, there are working ones here.

 
Dmitry Fedoseev #:

It broke after another change in the language, I have another one here, also broken. Look for more, there are some working ones here.

Dmitry, thank you for your reply. To my regret google gives links only to your developments. Forum also did not offer me anything alternative. Admiral Market offers such a function but only on their platform and it is not MT5. Dear fxsaber offered in 2017 his variant Simultaneous autoscrolling of charts for one instrument in different timeframes for MT5 - Technical Indicators and Forex Market Analysis - MQL5 Algo-Traders Forum (there is the indicator text in the last comment), but I don't know how to convert it for MT5 terminal, so I can't determine if it is a working variant. If you don't mind, please convert it, maybe it is working.

// MQL4&5-code
// Synchronisation of all charts by right time

sinput int TimerInterval = 1; // Update interval in milliseconds

// Disables autoscroll and shift on all charts
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();
}

// Returns true if there is no bar with this time ("hole")
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));
}

// Returns the time bar
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);
}

// Returns the bar time
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));
}

// Returns the right chart bar
int ChartBarRight( const long chartID = 0 )
{
  return((int)(ChartGetInteger(chartID, CHART_FIRST_VISIBLE_BAR) - ChartGetInteger(chartID, CHART_WIDTH_IN_BARS) + 1));
}

// Returns the right chart time
datetime GetChartTimeRight( const long chartID = 0 )
{
  return(iBarShift(ChartSymbol(chartID), ChartPeriod(chartID), ChartBarRight(chartID)));
}

// Sets the right chart time, returns the set time
datetime SetChartTimeRight( datetime time, const long chartID = 0, const ulong MaxTime = 1 e5 )
{
  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));
}

// Add an element to the end of an arbitrary array
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;
}

// Gets the time of the right bar of each chart
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));
}

// Sets the right time for all charts
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));
}

// Returns the chart that the time of the right bar has changed
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);
}

// Synchronise all charts by right time, returns the number of charts synchronised
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
Профиль трейдера
 
Дима Джумок #:

Dmitry, thank you for your reply. To my regret google gives links only to your developments. The forum also did not offer me anything alternative. Admiral Market offers such a function but only on their platform and it is not MT5. Dear fxsaber offered in 2017 his variant Simultaneous autoscrolling of charts for one instrument in different timeframes for MT5 - Technical Indicators and Forex Market Analysis - MQL5 Algo-Traders Forum (there is the indicator text in the last comment), but I don't know how to convert it for MT5 terminal, so I can't determine if it is a working variant. If you don't mind, please convert it, maybe it is working.

Then it's better to fix your own.

I downloaded mine now, it works. One inconvenience - if indents are not enabled, the required bar on the scrolling chart goes over the edge and the line is not visible. This will have to be corrected.

What do you have going on, how is it not working? The script disables auto-scrolling with the arrival of a new tick.

This button on the toolbar should be automatically pressed on all charts when the script is attached:

 
Bombshell! It works! Thank you so much!