Scripts: sSyncScroll - página 2

 
De hecho, al intentar desplazar el gráfico hacia atrás y ver el historial, cuando llega un nuevo tick, el gráfico vuelve al principio. En este caso, ¿para qué lo necesito? Ya sé que cuando se dibuja la última vela en M1, es también la última vela para todos los demás TFs. Y sin este indicador en todas las ventanas las últimas velas se redibujan automáticamente.
 
Дима Джумок #:
De hecho, al intentar desplazar el gráfico hacia atrás y ver el historial, cuando llega un nuevo tick, el gráfico vuelve al principio. En este caso, ¿para qué lo necesito? Ya sé que cuando se dibuja la última vela en M1, es también la última vela para todos los demás TFs. Y sin este indicador en todas las ventanas las últimas velas se redibujan automáticamente.

Se rompió después de los siguientes cambios en el lenguaje, tengo otro aquí, también roto. Busque más, hay los que trabajan aquí.

 
Dmitry Fedoseev #:

Se rompió después de otro cambio en el idioma, tengo otro aquí, también roto. Busque más, hay algunos de trabajo aquí.

Dmitry, gracias por tu respuesta. Para mi pesar google da enlaces sólo a sus desarrollos. Foro también no me ofreció nada alternativo. Admiral Market ofrece una función de este tipo, pero sólo en su plataforma y no es MT5. Estimado fxsaber ofreció en 2017 su variante Simultaneous autoscrolling of charts for one instrument in different timeframes for MT5 - Technical Indicators and Forex Market Analysis - MQL5 Algo-Traders Forum (está el texto del indicador en el último comentario), pero no sé cómo convertirlo para el terminal MT5, así que no puedo determinar si es una variante que funciona. Si no te importa, por favor, convertirlo, tal vez está trabajando.

// Código MQL4&5
// Sincronización de todos los gráficos por hora correcta

sinput int TimerInterval = 1; // Intervalo de actualización en milisegundos

// Desactiva el desplazamiento automático en todos los gráficos
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();
}

// Devuelve true si no hay ninguna barra con este tiempo ("agujero")
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));
}

// Devuelve la barra de tiempo
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);
}

// Devuelve la hora del bar
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));
}

// Devuelve la barra derecha del gráfico
int ChartBarRight( const long chartID = 0 )
{
  return((int)(ChartGetInteger(chartID, CHART_FIRST_VISIBLE_BAR) - ChartGetInteger(chartID, CHART_WIDTH_IN_BARS) + 1));
}

// Devuelve la hora correcta del gráfico
datetime GetChartTimeRight( const long chartID = 0 )
{
  return(iBarShift(ChartSymbol(chartID), ChartPeriod(chartID), ChartBarRight(chartID)));
}

// Establece la hora del gráfico derecho, devuelve la hora establecida
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));
}

// Añadir un elemento al final de un array arbitrario
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;
}

// Obtiene la hora de la barra derecha de cada gráfico
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));
}

// Establece la hora correcta para todos los gráficos
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));
}

// Devuelve el gráfico que el tiempo de la barra derecha ha cambiado
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);
}

// Sincronizar todos los gráficos por tiempo correcto, devuelve el número de gráficos sincronizados
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, gracias por tu respuesta. Muy a mi pesar google sólo da enlaces a tus desarrollos. El foro tampoco me ofreció nada alternativo. Admiral Market ofrece una función de este tipo, pero sólo en su plataforma y no es MT5. Estimado fxsaber ofreció en 2017 su variante Simultaneous autoscrolling of charts for one instrument in different timeframes for MT5 - Technical Indicators and Forex Market Analysis - MQL5 Algo-Traders Forum (está el texto del indicador en el último comentario), pero no sé cómo convertirlo para el terminal MT5, así que no puedo determinar si es una variante que funciona. Si no te importa, por favor, convertirlo, tal vez está trabajando.

Entonces es mejor para arreglar su propio.

He descargado el mío ahora, funciona. Un inconveniente - si las sangrías no están habilitadas, la barra requerida en el gráfico de desplazamiento sobrepasa el borde y la línea no es visible. Habrá que corregirlo.

¿Qué ocurre en tu script, cómo es que no funciona? El script desactiva el desplazamiento automático con la llegada de un nuevo tick.

Este botón de la barra de herramientas debería pulsarse automáticamente en todos los gráficos cuando se adjunta el script:

 
¡Bomba! ¡Funciona! ¡Muchas gracias!