//+-------------------------------------------------------------------+
//|                                MF_Pivot AXEL 0-2255.mq4           |
//|                                Copyright © YuraZ-VAF-Zhunko-Nestor|
//|                                MF YURAZ     yzh@mail.ru           |
//|                                MF VAF  vazh-af@inbox.ru           |
//|                                MF ZHUNKO zhunko@mail.ru           |
//|                                MF NESTOR a_nesterchuk@mail.ru     |
//+-------------------------------------------------------------------+
//| Идикатор разработан по материалам АКАДЕМИИ МФ.                    |
//| ИСПРАВЛЕННАЯ ВЕРСИЯ.                                              |
//| Совпадает с точностью 5п с уровнями DJ от Axel Rudolph !          |
//| Берет данные с M1.                                                |
//|                          ВНИМАЕНИЕ!                               |
//| Если ваше ДЦ даёт не точные котировки - PIVOT не будет совпадать. |
//+-------------------------------------------------------------------+
//|                    ИЗМЕНЕНИЯ и ДОПОЛНЕНИЯ.                        |
//| 1.Дополнения в версии MF_Pivot AXEL 0-101 от 06.09.2006 .         |
//| 1.1.Возможно перемещение всей надписи по экрану координатами XY   |
//| 1.2.Введены настройки по умолчанию.                               |
//| 1.3.Введена настройка цвета текста.                               |
//| 2.Дополнения в версии MF_Pivot AXEL 0-102 от 08.09.2006 .         |
//| 2.1.Исправлена ошибка отрисовки линии в некоторых терминалах.     |
//| 3.Дополнения в версии MF_Pivot AXEL 0-103 от 09.09.2006 .         |
//| 3.1.Изменён переключатель вывода текста на логический.            |
//| 3.2.Изменены названия внешних переменных.                         |
//| 3.3.Введены отсутствующие коментарии в исходник.                  |
//| 3.4.Изменена настройка разницы времени между МТ4 и GMT.           |
//| 4.Дополнения в версии MF_Pivot AXEL 0-113 от 14.09.2006 .         |
//| 4.1.Введна нечувствителенность к пропущенным барам.               |
//| 5.Дополнения в версии MF_Pivot AXEL 0-114 от 17.09.2006 .         |
//| 5.1.Упрощены настройки времени конца периода расчёта и времени    |
//|     начала отрисовки линии.                                       |
//| 5.2.На валютных парах, содержащих JPY, в текстовой строке цифровое|
//|     значение после запятой содержит два знака. На остальных       |
//|     валютных парах - четыре.                                      |
//| 6.Дополнения в версии MF_Pivot AXEL 0-214 от 18.09.2006 .         |
//| 6.1 Доработка вывода количества знаков для валютных пар в         |
//|     текстовом отображении.                                        |
//| 7.Дополнения в версии MF_Pivot AXEL 0-224 от 19.09.2006 .         |
//| 7.1.Устранена ошибка начала расчёта в понедельник.                |
//| 8.Дополнения в версии MF_Pivot AXEL 0-225 от 24.09.2006 .         |
//| 8.1.Устранена ошибка начала расчёта в азиатскую сессию.           |
//| 8.2.При отсутствии данных для расчёта вместо "99999999,0000"      |
//|     выводится "0,0000".                                           |
//| 9.Дополнения в версии MF_Pivot AXEL 0-2254 от 06.10.2006 .        |
//| 9.1.Корректное отображение показаний в зависимости от изменения   |
//|     параметров старта расчёта.                                    |
//| 9.2.Оптимизация кода преобразований.                              |
//| 9.3.Изменение алгоритма расчёта минимумов и максимумов сессий.    |
//| 10.Дополнения в версии MF_Pivot AXEL 0-2255 от 06.11.2006         |
//| 10.1.Переход на вычисление по вышеидущему тайм-фрейму для дней, у |
//|      которых отсутствует полная история на младших тайм-фреймах.  |
//| 10.2.Подкорректирован алгоритм расчета пивота на европейскую      |
//|      сессию в зимнее время.                                       |
//| 10.3.Оптимизирована загрузка компьютера. Вычисление значения      |
//|      только при появлении новой свечи, а не с каждым тиком.       |
//| 11.  Дополнения в версии MF_Pivot AXEL 0-3255 от 25.08.2007       |     
//| 11.1.Добавлена функция автоматического определения                |
//|      летнего зимнего времени                                      |
//+-------------------------------------------------------------------+
#property copyright "Copyright © 2006 YuraZ-VAF-Zhunko-Nestor"
#property link      "yzh@mail.ru ; vazh-af@inbox.ru ; zhunko@mail.ru ; a_nesterchuk@mail.ru"


#property indicator_chart_window 
#property indicator_buffers 1
//Цвет по умолчанию.
#property indicator_color1 Gold
//Стиль по умолчанию.
#property indicator_style1 STYLE_DASH
//Толщина линии по умолчанию.
#property indicator_width1 1
//----Локализация---------------------------------------------------------------------------------------------------------------------------------
extern int    Дней = 30;                       // Количество расчитываемых дней.
extern int    Время_ДЦ = 0;                    // Разница во времени между МТ4 и GMT.
//----Настройка длины периода расчёта-------------------------------------------------------------------------------------------------------------
extern double Asia_период_расчёта_час   = 9 ; // Период расчёта в часах для Азии.
extern double Europe_период_расчёта_час =  9 ; // Период расчёта в часах для Европы.
extern double USA_период_расчёта_час    =  9 ; // Период расчёта в часах для Америки.
//----Настройка времени конца периода расчёта и времени начала отрисовки линии--------------------------------------------------------------------
extern string Start_ASIA          = "00:00" ;  // Время конца периода расчёта для Азии по GMT.
                                               // Время начала отрисовки линии "PIVOT DJ ASIA" (учитываются только часы, минуты отбрасываются).
extern string Start_EUROPE_Winter = "06:00" ;  // Время конца периода расчёта для Европы по GMT.
                                               // Время начала отрисовки линии "PIVOT DJ EUROPE" (учитываются только часы, минуты отбрасываются).
extern string Start_USA_Winter    = "12:00" ;  // Время конца периода расчёта для Америки по GMT.
                                               // Время начала отрисовки линии "PIVOT DJ USA" (учитываются только часы, минуты отбрасываются).
//----Настройка отображения-----------------------------------------------------------------------------------------------------------------------
extern int    Угол         =   0   ;    // Расположение индикатора : 0 = сверху слева, 1 = сверху справа, 2 = снизу слева, 3 = снизу справа.
extern int    XD           = 250   ;    // Смещение от угла по X.
extern int    YD           =   0   ;    // Смещение от угла по Y.
extern bool   TEXT_Visible = true  ;    // true - отображать текст; false - не отображать текст.
extern color  TextColor    = White ;    // Цвет текста.


//================================================================================================================================================
double nClose   = 0 ;
double nPivot   = 0 ; 
double nMaxHigh = 0 ; 
double nMinLow  = 0 ;
//---------------------------------------------------------------
static bool   Time_Summer = false;             // true - летнее время / false - зимнее время.
//---------------------------------------------------------------
double    PBuffer[];
//---------------------------------------------------------------
static string ss1 = "Asia DJ Pivot"    ;
static string ss2 = "Europe DJ Pivot"  ;
static string ss3 = "Usa DJ Pivot"     ;
//===============================================================
datetime t;
int init() 
 {
  t=0;
  if ( TEXT_Visible == true )
   {
    ObjectCreate(ss1, OBJ_LABEL, 0, 0, 0);   
    ObjectSet(ss1, OBJPROP_XDISTANCE, XD);
    ObjectSet(ss1, OBJPROP_YDISTANCE, YD);
    ObjectSet(ss1, OBJPROP_CORNER, Угол);

    ObjectCreate(ss2, OBJ_LABEL, 0, 0, 0);   
    ObjectSet(ss2, OBJPROP_XDISTANCE, XD);
    ObjectSet(ss2, OBJPROP_YDISTANCE, 10+YD);
    ObjectSet(ss2, OBJPROP_CORNER, Угол);

    ObjectCreate(ss3, OBJ_LABEL, 0, 0, 0);   
    ObjectSet(ss3, OBJPROP_XDISTANCE, XD);
    ObjectSet(ss3, OBJPROP_YDISTANCE, 20+YD);
    ObjectSet(ss3, OBJPROP_CORNER, Угол);
   }
    SetIndexStyle(0,DRAW_LINE);
    SetIndexBuffer(0,PBuffer);
  return(0); 
 }
//===============================================================
int deinit() 
{ 
if ( TEXT_Visible == true )
 {
  ObjectDelete(ss1);
  ObjectDelete(ss2);
  ObjectDelete(ss3);
 }
return(0); 
} 
//===============================================================
 void funPivot(int pDay, int pMonth, int pYear,  double PeriodHour, double hourMT4, double minuteMT4)
  { 
   datetime dTimeMT4end;
   datetime dTimeMT4begin;
   
   string sTimeMT4 = StringConcatenate(DoubleToStr( pYear, 0),".",DoubleToStr( pMonth , 0),".",DoubleToStr( pDay , 0)," ",
                     DoubleToStr( hourMT4, 0),":",DoubleToStr( minuteMT4, 0) ) ; 
                    
   dTimeMT4end = StrToTime(sTimeMT4); 
   dTimeMT4begin = dTimeMT4end - PeriodHour*3600+60  ;  
   
   if (TimeDayOfWeek (dTimeMT4begin) ==0)
   dTimeMT4begin = dTimeMT4begin - 172800;

//which period to use depends on the history presence.

   int i=PERIOD_M1;
   int j =iBarShift(NULL,i,dTimeMT4begin,true);

   if (j == -1)
    i=PERIOD_M5;
    j=iBarShift(NULL,i,dTimeMT4begin,true);

   if (j == -1)
    i=PERIOD_M15;

   int      shiftend=iBarShift(NULL,i,dTimeMT4end);
   int      shiftbegin=iBarShift(NULL,i,dTimeMT4begin);
      
   nMinLow =iLow(NULL,i,Lowest ( NULL, i, MODE_LOW, shiftbegin-shiftend, shiftend));
   nMaxHigh= iHigh(NULL,i,Highest( NULL, i, MODE_HIGH, shiftbegin-shiftend, shiftend)); 
   nClose=iClose(NULL,i,shiftend);
   nPivot = (nMaxHigh+nMinLow+nClose)/3;
   
   return; 
  } 
//================================================================
int start() 
 {
  if(t==Time[0]) return(0);
  t=Time[0];
    
  int mDay;
  int mMonth ;
  int mYear  ;
  string mYearMonthDay;
//----------------------------------------------------------------
  static double PeriodHour_ ; // = Asia_период_расчёта_час;
  static double hourMT4_    ; // = Asia_конец_периода_MT4_час; 
  static double minuteMT4_  ; // = Asia_конец_периода_MT4_мин; 

  static double nPivotEurope; // = nPivot; 
  static double nMaxHighE   ; // = nMaxHigh; 
  static double nMinLowE    ; // = nMinLow; 
  static double nCloseE     ; // = nClose; 

  static double nPivotUSA   ; // = nPivot; 
  static double nMaxHighU   ; // = nMaxHigh; 
  static double nMinLowU    ; // = nMinLow; 
  static double nCloseU     ; // = nClose; 

  static double nPivotASIA  ; // = nPivot; 
  static double nMaxHighA   ; // = nMaxHigh; 
  static double nMinLowA    ; // = nMinLow; 
  static double nCloseA     ; // = nClose; 
//-----------------------------------------------------------------
  datetime  mDatBegin;

// время берется с бара для правильной работы  в советниках - при тестированнии TimeCurrent() - имела проблему
  Time_Summer = TimeWinter(iTime(Symbol(),PERIOD_M15,0)); // достаточный ТФ для определения лета или зима 

//  if (Bars != IndicatorCounted())
   {
    if (Дней == 0 )
     {
      deinit();
      return(0);
     }
  else
     {
      mDatBegin = StrToTime(StringConcatenate(TimeToStr(CurTime(),TIME_DATE)," 00:00")) - ((Дней-1) * 86400);
     }
//==================================================================
  for ( ; mDatBegin < CurTime();  mDatBegin += 86400 )
   {
    mYear  = TimeYear( mDatBegin);
    mMonth = TimeMonth( mDatBegin);
    mDay   = TimeDay( mDatBegin);
    mYearMonthDay = StringConcatenate(DoubleToStr (mYear,0) , "." , DoubleToStr (mMonth, 0) , "." , DoubleToStr (mDay , 0));
//----------------------------------------------------------------------------------------------------------------------------------------------------------------
    Start_ASIA=StringTrimRight(StringTrimLeft(Start_ASIA));
    Start_EUROPE_Winter=StringTrimRight(StringTrimLeft(Start_EUROPE_Winter));
    Start_USA_Winter=StringTrimRight(StringTrimLeft(Start_USA_Winter));
    
    if (Time_Summer==true) int TWS =1;
    else TWS=0;
    
    int  Asia_end_MT4_hour           = StrToDouble(StringSubstr(Start_ASIA, 0, 2)) + Время_ДЦ;
    int  Asia_end_MT4_min            = StrToDouble(StringSubstr(Start_ASIA, 3, 2)) ;
                                    
    int  Europe_end_MT4_hour_pivot   = StrToDouble (StringSubstr(Start_EUROPE_Winter, 0, 2)) + Время_ДЦ-1+TWS;
    int  Europe_end_MT4_hour_session = StrToDouble (StringSubstr(Start_EUROPE_Winter, 0, 2)) + Время_ДЦ - TWS;
    int  Europe_end_MT4_min          = StrToDouble (StringSubstr(Start_EUROPE_Winter, 3, 2)) ;
                                    
    int  USA_end_MT4_hour_pivot      = StrToDouble (StringSubstr(Start_USA_Winter, 0, 2)) + Время_ДЦ - TWS;
    int  USA_end_MT4_hour_session    = StrToDouble (StringSubstr(Start_USA_Winter, 0, 2)) + Время_ДЦ - TWS;
    int  USA_end_MT4_min             = StrToDouble (StringSubstr(Start_USA_Winter, 3, 2)) ;
//----------------------------------------------------------------------------------------------------------------------------------------------------------------*/
    PeriodHour_  = Asia_период_расчёта_час;
    hourMT4_     = Asia_end_MT4_hour;
    minuteMT4_   = Asia_end_MT4_min;
    funPivot( mDay, mMonth ,mYear ,PeriodHour_, hourMT4_, minuteMT4_);
    nPivotASIA   = nPivot;
    nMaxHighA    = nMaxHigh;
    nMinLowA     = nMinLow;
    nCloseA      = nClose;
//----------------------------------------------
    PeriodHour_  = Europe_период_расчёта_час;
    hourMT4_     = Europe_end_MT4_hour_pivot;
    minuteMT4_   = Europe_end_MT4_min;
    funPivot(mDay, mMonth,mYear,PeriodHour_, hourMT4_, minuteMT4_);
    nPivotEurope = nPivot;
    nMaxHighE    = nMaxHigh;
    nMinLowE     = nMinLow;
    nCloseE      = nClose;
//----------------------------------------------
    PeriodHour_  = USA_период_расчёта_час;
    hourMT4_     = USA_end_MT4_hour_pivot;
    minuteMT4_   = USA_end_MT4_min;
    funPivot(mDay, mMonth,mYear,PeriodHour_, hourMT4_, minuteMT4_);
    nPivotUSA    = nPivot;
    nMaxHighU    = nMaxHigh;
    nMinLowU     = nMinLow;
    nCloseU      = nClose;
//----------------------------------------------
    string DC_ASIA   = StringConcatenate(mYearMonthDay , " " , Asia_end_MT4_hour, ":00");   
    string DC_EUROPE = StringConcatenate(mYearMonthDay , " " , Europe_end_MT4_hour_session, ":00");   
    string DC_USA    = StringConcatenate(mYearMonthDay , " " , USA_end_MT4_hour_session, ":00");   
   
    int pPivotBARA = iBarShift (NULL,0,StrToTime (DC_ASIA)); 
    int pPivotBARE = iBarShift (NULL,0,StrToTime (DC_EUROPE));  
    int pPivotBARU = iBarShift (NULL,0,StrToTime (DC_USA));

      int j;

      if ( nPivotASIA !=0 )
         {
          for (j = 0  ; j < pPivotBARA; j++)
            PBuffer[j] = nPivotASIA ;
         }  
      if ( nPivotEurope !=0)
         {
          for (j = 0  ; j < pPivotBARE; j++)
            PBuffer[j] = nPivotEurope ;
         }

      if (nPivotUSA !=0 )
         {
          for (j = 0 ; j < pPivotBARU; j++)
            PBuffer[j] = nPivotUSA ;
         }
    }

   if (TEXT_Visible == true )
    {
     string sPivotASIA    =  StringConcatenate("PivotAsia     =",DoubleToStr(nPivotASIA  ,Digits)," High="+DoubleToStr(nMaxHighA,Digits)," Low=",DoubleToStr(nMinLowA,Digits)," Close=",DoubleToStr(nCloseA,Digits)) ; 
     string sPivotEUROPE  =  StringConcatenate("PivotEurope="   ,DoubleToStr(nPivotEurope,Digits)," High="+DoubleToStr(nMaxHighE,Digits)," Low=",DoubleToStr(nMinLowE,Digits)," Close=",DoubleToStr(nCloseE,Digits)) ;
     string sPivotUSA     =  StringConcatenate("PivotUSA    ="  ,DoubleToStr(nPivotUSA   ,Digits)," High="+DoubleToStr(nMaxHighU,Digits)," Low=",DoubleToStr(nMinLowU,Digits)," Close="+DoubleToStr(nCloseU,Digits)) ; 

     ObjectSetText(ss1, sPivotASIA   , 8, "Arial", TextColor); 
     ObjectSetText(ss2, sPivotEUROPE , 8, "Arial", TextColor); 
     ObjectSetText(ss3, sPivotUSA    , 8, "Arial", TextColor); 
    }
 }
return(0);
}


////////////////////////////////////////////////////////////// 
//
// YURAZ yzh mail ru
//
// функция вернет 
// true   -  летнее время
// false  -  зимнее время
// 
//  переход на зимнее в ночь  последнего воскресенья ОКТЯБРЯ
//  переход на летнее в ночь  последнего воскресенья МАРТА
// 
bool TimeWinter(datetime dt) 
{
   int i;

   if (   TimeMonth(dt) >= 11 || TimeMonth(dt) <= 2 ) // ЗИМА
   {
      return(false); //    мгновенно вернем зимнее
   }
   if (   TimeMonth(dt) >= 4 && TimeMonth(dt) <= 9) // ЛЕТО
   {
      return(true); //    мгновенно вернем  Лето
   }

// делать нечего идем определять 
   datetime tSeek;
   string sTIM;
   if ( TimeMonth(dt) == 10 ) // октябрь
   {
      if ( TimeDay(dt) >= 20 ) // ночью в последее воскресенье октября - переход на зимнее время
      {
         tSeek = StrToTime( StringTrimRight(StringTrimLeft(DoubleToStr(TimeYear(dt),0)))+".10.31");  // установим последний день октября
         // ищем первое воскресенье с конца
         for ( i = 31; i >= 20; i-- )
         {
            if ( TimeDayOfWeek(tSeek) == 0 ) 
            {
               break;   // нашли последнее воскресеньне октября
            }
            tSeek = tSeek - 86400; // еще один день
         }
         if ( dt >= tSeek  ) // уже зимнее время
         {
            return(false); // да зима
         }
      }
      return(true);
   }
   if ( TimeMonth(dt) == 3 ) // март
   {
      if ( TimeDay(dt) >= 20 ) // ночью в последее воскресенье МАРТА - переход на ЛЕТНЕЕ время
      {
         tSeek = StrToTime( StringTrimRight(StringTrimLeft(DoubleToStr(TimeYear(dt),0)))+".03.31");  // установим последний день марта
        
         for ( i = 31; i >= 20; i-- )
         {
            if ( TimeDayOfWeek(tSeek) == 0 ) // ищем первое воскресенье с конца
            {
               break; // нашли последнее воскресеньне марта
            }
            tSeek = tSeek - 86400; // еще один день
         }
         if ( dt >= tSeek  ) // уже летнее время
         {
            return(true); //  уже лето 
         }
      }
      return(false);
   }
}

//+------------------------------------------------------------------+