Fragen von Anfängern MQL5 MT5 MetaTrader 5 - Seite 786

 

Bitte korrigieren Sie den Code, wenn es Ihnen nichts ausmacht.

Ich habe Code für das Scrollen offener Charts geschrieben, aber ich bin mit der Synchronisierung stecken geblieben. Ich kann nicht nach der Zeit der ersten sichtbaren Balken synchronisieren, es berücksichtigt keine verpassten Balken - es scrollt durch alle, ohne die Zeit zu berücksichtigen


//+------------------------------------------------------------------+
#property indicator_chart_window
#property indicator_plots 0


long     mass_id[];
datetime Time[1];
long     MassID;
string   MassSY;
int      Shift=0;

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnTimer()
  {
   int  _CHART_WIDTH_IN_BARS = (int)ChartGetInteger(0, CHART_WIDTH_IN_BARS);
   int  BarTimeVisible = iBarShift(Symbol(), 0, TIME(_CHART_WIDTH_IN_BARS));//Print(TIME(_CHART_WIDTH_IN_BARS));

   long ID=ArraySize(mass_id);
// Запомним время
   for(int i=0; i<ID; i++)
     {
      MassID = mass_id[i];
      Shift = BarTimeVisible - (int)ChartGetInteger(MassID, CHART_VISIBLE_BARS);
      if(GlobalVariableGet("FirstVisibleBar") != TIME((int)ChartGetInteger(MassID, CHART_FIRST_VISIBLE_BAR) + Shift))
        {
         GlobalVariableSet("FirstVisibleBar", TIME((int)ChartGetInteger(MassID, CHART_FIRST_VISIBLE_BAR) + Shift));
         break;
        }
     }

// Прокрутка графиков
   for(int i=0; i<ID; i++)
     {
      MassID = mass_id[i];
      MassSY = ChartSymbol(MassID);
      Shift = (BarTimeVisible -  (int)ChartGetInteger(MassID, CHART_VISIBLE_BARS));
      if(GlobalVariableGet("FirstVisibleBar") != TIME((int)ChartGetInteger(MassID, CHART_FIRST_VISIBLE_BAR) + Shift))
        {
         ChartNavigate(MassID, CHART_END, (_CHART_WIDTH_IN_BARS - iBarShift(Symbol(), 0, (datetime)GlobalVariableGet("FirstVisibleBar"))) - 2);
        }
     }
  }
  
  
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   ChartGetIDList(mass_id);
   EventSetMillisecondTimer(50);
//---
   return(INIT_SUCCEEDED);
  }

//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
int ChartGetIDList(long &aList[])
  {
   int i=0;
   long handle=0;
   long chartID=ChartNext(handle);
   while(chartID!=-1)
     {
      handle=chartID;
      i++;
      ArrayResize(aList,i);
      aList[i-1]=chartID;
      chartID=ChartNext(handle);
     }
   return(i);
  }

//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
int iBarShift(string symbol,ENUM_TIMEFRAMES timeframe,datetime time,bool exact=false)
  {
   datetime LastBAR;
   if(!SeriesInfoInteger(symbol,timeframe,SERIES_LASTBAR_DATE,LastBAR))
     {
      datetime opentimelastbar[1];
      if(CopyTime(symbol,timeframe,0,1,opentimelastbar)==1)
         LastBAR=opentimelastbar[0];
      else
         return(-1);
     }
//--- if time > LastBar we always return 0
   if(time>LastBAR)
      return(0);
//---
   int shift=Bars(symbol,timeframe,time,LastBAR);
   datetime checkcandle[1];

   if(CopyTime(symbol,timeframe,time,1,checkcandle)==1)
     {
      if(checkcandle[0]==time)
         return(shift-1);
      else if(exact && time>checkcandle[0]+PeriodSeconds(timeframe))
         return(-1);
      else
         return(shift);
     }
   return(-1);
  }

//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
datetime TIME(int index=0)
  {
   return(CopyTime(Symbol(),PERIOD_CURRENT,index,1,Time)?Time[0]:WRONG_VALUE);
  }
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
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[])
  {
//---

//--- return value of prev_calculated for next call
   return(rates_total);
  }
 
Vitaly Muzichenko:

Bitte korrigieren Sie den Code, wenn es Ihnen nichts ausmacht.

Ich habe Code für das Scrollen durch offene Charts geschrieben, aber ich bin mit der Synchronisierung stecken geblieben, ich kann nicht nach der Zeit der ersten sichtbaren Balken synchronisieren, es berücksichtigt keine verpassten Balken - es scrollt durch alle von ihnen, ohne Berücksichtigung der Zeit

Was sollte ich tun? Es wäre wahrscheinlich einfacher, von Grund auf neu zu schreiben, als es zu reparieren.

SyncChart
SyncChart
  • Stimmen: 12
  • 2016.09.16
  • o_o
  • www.mql5.com
Синхронизация показываемых баров на всех открытых в терминале графиках. Синхронизация графиков происходит по таймеру. Без DLL! Дополнительные возможности: опция синхронизации вертикальных...
 
fxsaber:

Was sollte ich tun? Es wäre wahrscheinlich einfacher, von Grund auf neu zu schreiben als zu bearbeiten.

Vielleicht von Grund auf, aber es müsste irgendwie zeitsynchronisiert werden


 
Vitaly Muzichenko:

Vielleicht von Anfang an, wenn es nur eine Zeitsynchronisation gäbe

Das Video ist sehr einfach gehalten. Sie sollte leicht zu lösen sein. Wenn ich Zeit habe, werde ich meine Version veröffentlichen.

 
fxsaber:

Das Video macht das alles sehr deutlich. Die Lösung sollte kurz und bündig sein. Wenn ich Zeit habe, werde ich meine Version veröffentlichen.

Ich habe nur nicht betont, dass das Blättern von jedem Diagramm aus funktioniert, nicht nur vom Hauptdiagramm aus.

Ich danke Ihnen!

 
Kommentare, die sich nicht auf dieses Thema beziehen, wurden nach "Fragen von MQL4 MT4 MetaTrader 4 Anfängern" verschoben.
 
Vitaly Muzichenko:

Ich habe nur nicht betont, dass das Blättern von jedem Diagramm aus funktioniert, nicht nur vom Hauptdiagramm aus.

// 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 = 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:

Vielen Dank für den vollständigen und umfassenden Code, ich werde ihn ausprobieren und später Bericht erstatten!

 
fxsaber:

Das Ergebnis ist auf dem Video zu sehen, allerdings ohne Ton. Ihr Code wurde verwendet, und meiner, aber ohne Zeitsynchronisation, im letzten Beitrag als Indikator gepostet

Wie kann man es so synchronisieren, dass, wenn der Balken nicht in das Zeitfenster fällt, d.h. nicht in die Handelszeit, er übersprungen und der letzte Handelsbalken verwendet wird?

Die Hauptaufgabe des Codes ist es, gut von dem Fenster mit der größten Anzahl von Balken, dh, Forex-Paare, scrollt es jetzt gut von dem Fenster mit der geringsten Anzahl von Balken auf diese Fenster überspringt Zeiträume fallen in Nicht-Handelszeit des Paares - das ist richtig und es sollte durch Logik sein.

Bitte: Ändern Sie es so, dass es möglich ist, die Devisenpaare von einem Fenster aus reibungslos zu drehen.

Ich danke Ihnen!

 
Vitaly Muzichenko:

Das Ergebnis ist auf dem Video zu sehen, allerdings ohne Ton. Ihr Code wurde verwendet, und meiner, aber ohne Zeitsynchronisation, im letzten Beitrag als Indikator gepostet

Wie kann man es so synchronisieren, dass, wenn der Balken nicht in das Zeitfenster fällt, d.h. nicht in die Handelszeit, er übersprungen und der letzte Handelsbalken verwendet wird?

Die Hauptaufgabe des Codes ist es, gut von dem Fenster mit der größten Anzahl von Balken zu scrollen, das heißt, Forex-Paare, es scrollt jetzt gut von dem Fenster mit der geringsten Anzahl von Balken auf diese Fenster, die Zeiträume fallen in Nicht-Handelszeit des Paares - das ist richtig und sollte logisch sein.

Bitte: Ändern Sie es so, dass es möglich ist, die Devisenpaare von einem Fenster aus reibungslos zu drehen.

Ich danke Ihnen!

Ich habe das Problem verstanden. Ich muss darüber nachdenken, um das Problem gut zu lösen.

In jedem Fall sind diese beiden Funktionen grundlegend.

// Возвращает правое время чарта
datetime GetChartTimeRight( const long chartID = 0 );

// Устанавливает правое время чарта
bool SetChartTimeRight( const datetime time, const long chartID = 0 );

Man muss mit ihnen spielen, um eine Lösung zu finden.