초보자의 질문 MQL5 MT5 MetaTrader 5 - 페이지 786

 

괜찮으시다면 코드를 수정해주세요.

열린 차트를 스크롤하는 코드를 작성했지만 동기화가 멈췄습니다. 첫 번째 보이는 막대를 시간에 동기화할 수 없습니다. 누락된 막대를 고려하지 않습니다. 시간을 고려하지 않고 모두 회전합니다.


 //+------------------------------------------------------------------+
#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 :

괜찮으시다면 코드를 수정해주세요.

열린 차트를 스크롤하는 코드를 작성했지만 동기화가 멈췄습니다. 첫 번째 보이는 막대를 시간에 동기화할 수 없습니다. 누락된 막대를 고려하지 않습니다. 시간을 고려하지 않고 모두 회전합니다.

그리고 어떻게 해야 합니까? 처음부터 작성하는 것이 편집하는 것보다 쉬울 것입니다.

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

그리고 어떻게 해야 합니까? 처음부터 작성하는 것이 편집하는 것보다 쉬울 것입니다.

어쩌면 처음부터 어떻게 든 제 시간에 동기화 될 것입니다.


 
Vitaly Muzichenko :

어쩌면 처음부터 어떻게 든 제 시간에 동기화 될 것입니다.

비디오를 사용하면 모든 것이 매우 이해하기 쉽습니다. 간결하게 다루어야 합니다. 나는 자유로울 것이다 - 나는 나의 버전을 게시할 것이다.

 
fxsaber :

비디오를 사용하면 모든 것이 매우 이해하기 쉽습니다. 간결하게 다루어야 합니다. 나는 자유로울 것이다 - 나는 나의 버전을 게시할 것이다.

그러나 스크롤은 기본 차트뿐만 아니라 모든 차트에서 작동한다는 점을 강조하지 않았습니다.

고맙습니다!

 
이 주제와 관련이 없는 댓글은 " MQL4 MT4 MetaTrader 4 초보자의 질문 "으로 이동되었습니다.
 
Vitaly Muzichenko :

그러나 스크롤은 기본 차트뿐만 아니라 모든 차트에서 작동한다는 점을 강조하지 않았습니다.

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

완전하고 자세한 코드에 감사드립니다. 시도해 보고 결과에 대해 쓰겠습니다!

 
fxsaber :

결과는 비디오이지만 소리는 없습니다. 귀하의 코드가 사용되었으며 시간 동기화 없이 내 코드가 마지막 메시지에 표시기로 게시됩니다.

바가 시간대, 즉 비거래 시간에 속하지 않으면 건너뛰고 마지막 거래 시간을 사용하도록 동기화하는 방법.

코드의 주요 작업은 가장 많은 수의 막대 가 있는 창, 즉 외환 쌍에서 잘 스크롤하는 것입니다. 이제 가장 적은 수의 막대가 있는 창에서 해당 창에 해당하는 시간 섹션으로 스크롤됩니다. 이 페어 슬립의 비 거래 시간 - 논리적이어야 하므로 정확합니다.

요청: 창에서 Forex 쌍을 원활하게 회전할 수 있도록 수정하십시오.

고맙습니다!

 
Vitaly Muzichenko :

결과는 비디오이지만 소리는 없습니다. 귀하의 코드가 사용되었으며 시간 동기화 없이 내 코드가 마지막 메시지에 표시기로 게시됩니다.

바가 시간대, 즉 비거래 시간에 속하지 않으면 건너뛰고 마지막 거래 시간을 사용하도록 동기화하는 방법.

코드의 주요 작업은 가장 많은 수의 막대 가 있는 창, 즉 외환 쌍에서 잘 스크롤하는 것입니다. 이제 가장 적은 수의 막대가 있는 창에서 해당 창에 해당하는 시간 섹션으로 스크롤됩니다. 이 페어 슬립의 비 거래 시간 - 논리적이어야 하므로 정확합니다.

요청: 창에서 Forex 쌍을 원활하게 회전할 수 있도록 수정하십시오.

고맙습니다!

문제를 이해했습니다. 아름답게 결정하려면 생각해야 합니다.

어쨌든 이 두 가지 기능은

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

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

솔루션을 얻으려면 사용을 해야 합니다.