스크립트: sSyncScroll - 페이지 2

 
실제로 차트를 뒤로 스크롤하여 기록을 보려고 할 때 새 틱이 도착하면 차트가 맨 처음으로 돌아갑니다. 이 경우 왜 필요한가요? M1에 마지막 캔들을 그릴 때 다른 모든 TF의 마지막 캔들이기도 하다는 것을 이미 알고 있습니다. 그리고 모든 창에서 이 표시기가 없으면 마지막 캔들 스틱이 자동으로 다시 그려집니다.
 
Дима Джумок #:
실제로 차트를 뒤로 스크롤하여 기록을 보려고 할 때 새 틱이 도착하면 차트가 맨 처음으로 돌아갑니다. 이 경우 왜 필요한가요? M1에 마지막 캔들을 그릴 때 다른 모든 TF의 마지막 캔들이기도 하다는 것을 이미 알고 있습니다. 그리고 모든 창에서 이 표시기가 없으면 마지막 캔들 스틱이 자동으로 다시 그려집니다.

다음 언어 변경 후 깨졌고 여기에도 깨진 다른 하나가 있습니다. 더 찾아보세요. 여기에 작동하는 것이 있습니다.

 
Dmitry Fedoseev #:

언어가 또 변경된 후 고장 났고 여기 다른 언어도 고장났습니다. 더 찾아보세요. 여기 작동하는 것이 몇 개 있습니다.

드미트리, 답장 해 주셔서 감사합니다. 유감스럽게도 Google은 귀하의 개발에 대한 링크 만 제공합니다. 포럼에서도 대안을 제공하지 않았습니다. Admiral Market은 이러한 기능을 제공하지만 플랫폼에서만 제공되며 MT5가 아닙니다. 친애하는 fxsaber는 2017 년에 MT5 - 기술 지표 및 외환 시장 분석 - MQL5 Algo-Traders 포럼 (마지막 댓글에 지표 텍스트가 있음)에 대해 다른 시간대의 한 상품에 대한 차트 동시 자동 스크롤 변형을 제공했지만 MT5 터미널로 변환하는 방법을 모르기 때문에 작동하는 변형인지 여부를 확인할 수 없습니다. 괜찮으시다면 변환해 주시면 작동할 수도 있습니다.

// MQL4&5 코드
// 모든 차트를 적절한 시간별로 동기화하기

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();
}

// 이 시간("구멍")이 있는 막대가 없으면 참을 반환합니다.
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 = 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));
}

// 임의의 배열 끝에 엘리먼트를 추가합니다.
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
Профиль трейдера
 
Дима Джумок #:

드미트리, 답장해 주셔서 감사합니다. 유감스럽게도 Google은 귀하의 개발에 대한 링크 만 제공합니다. 포럼에서도 대안을 제시하지 않았습니다. Admiral Market은 이러한 기능을 제공하지만 플랫폼에서만 제공되며 MT5가 아닙니다. 친애하는 fxsaber는 2017 년에 MT5 - 기술 지표 및 외환 시장 분석 - MQL5 Algo-Traders 포럼 (마지막 댓글에 지표 텍스트가 있음)에 대해 다른 시간대의 한 상품에 대한 차트 동시 자동 스크롤 변형을 제공했지만 MT5 터미널 용으로 변환하는 방법을 모르기 때문에 작동하는 변형인지 확인할 수 없습니다. 괜찮으시다면 변환해 주시면 작동할 수도 있습니다.

그렇다면 직접 수정하는 것이 좋습니다.

지금 다운로드했는데 작동합니다. 한 가지 불편한 점은 들여쓰기가 활성화되어 있지 않으면 스크롤 차트에서 필요한 막대가 가장자리를 넘어가서 선이 보이지 않는다는 것입니다. 이 문제는 수정해야 합니다.

무슨 문제가 있는 건가요, 어떻게 작동하지 않나요? 스크립트에서 새 체크 표시가 도착하면 자동 스크롤을 비활성화합니다.

스크립트가 첨부되면 모든 차트에서 툴바의 이 버튼이 자동으로 눌러져야 합니다:

 
폭탄! 작동합니다! 정말 감사합니다!