Корректировка времени точки привязки с младшего таймфрейма!

 

Доброго времени суток, уважаемые форумчане! Подскажите, пожалуйста, как скорректировать время точки привязки (например трендовой линии) с младшего таймфрейма? При нанесении граф объекта на график, например на D1, при переходе на более младший таймфрейм точка привязки оказывается смещена на время открытия бара D1! Пытался накидать функцию, но что-то не очень получилось!

//+------------------------------------------------------------------+
//| Корректировка точек привязки (время) граф объектов по младшим     |
//| таймфреймам                                                      |
//+------------------------------------------------------------------+
bool TimeAnchorPointsCorrection(const ENUM_TIMEFRAMES &tf_mass_l[],const string name)
{
   #ifdef TimeAnchorPointsCorrection_DEBUG
      Print(__FUNCSIG__);
   #endif
   //---
   datetime time1,time2;
   double price1,price2,low,high;
   int timeframe = _Period, massIndex = IndexInTimeframeMass(tf_mass_l, timeframe);
   bool correct1 = true, correct2 = true;
   //---
   if(!ObjectGetInteger(0,name,OBJPROP_TIME,0,time1) || !ObjectGetInteger(0,name,OBJPROP_TIME,1,time2) || 
   !ObjectGetDouble(0,name,OBJPROP_PRICE,0,price1) || !ObjectGetDouble(0,name,OBJPROP_PRICE,1,price2)){
      #ifdef TimeAnchorPointsCorrection_DEBUG
      Print("Error #",IntegerToString(GetLastError()),", in attempt to receive properties of an object!");
      #endif
      return false;}
   else{
      #ifdef TimeAnchorPointsCorrection_DEBUG
         Print("Parameters of an object are successfully received: price 1 ",DoubleToStr(price1,_Digits),", price 2 ",DoubleToStr(price2,_Digits),
         ", time 1 ",time1,", time 2 ",time2);
      #endif}
   //---
   price1=ND(price1);
   HighLowByTime(high,low,time1);
   if(price1==high){
      int x = massIndex;
      while(x>0){
         x--;
         int index=iBarShift(_Symbol,tf_mass_l[x],time1,true);
         if(index>0){
            while(index>0 && iHigh(_Symbol,tf_mass_l[x],index) > 0.0 && price1!=ND(iHigh(_Symbol,tf_mass_l[x],index))){
               index--;}
            time1=iTime(_Symbol,tf_mass_l[x],index);}
         else{
            #ifdef TimeAnchorPointsCorrection_DEBUG
               Print("Adjustment of point #1 is ended on a timeframe - ",TimeframeToStr(tf_mass_l[x]));
            #endif
            break;}}}
   else if(price1==low){
      int x=massIndex;
      while(x>0){
         x--;
         int index=iBarShift(_Symbol,tf_mass_l[x],time1,true);
         if(index>0){
            while(index>0 && iLow(_Symbol,tf_mass_l[x],index) > 0.0 && price1!=ND(iLow(_Symbol,tf_mass_l[x],index))){
               index--;}
            time1=iTime(_Symbol,tf_mass_l[x],index);}
         else{
            #ifdef TimeAnchorPointsCorrection_DEBUG
               Print("Adjustment of point #1 is ended on a timeframe - ",TimeframeToStr(tf_mass_l[x]));
            #endif
            break;}}}
   else{
      correct1=false;
      #ifdef TimeAnchorPointsCorrection_DEBUG
         Print("Anchor point #1 is put not on extremum");
      #endif}
   //---
   price2=ND(price2);
   HighLowByTime(high,low,time2);
   if(price2==high){
      int x = massIndex;
      while(x>0){
         x--;
         int index=iBarShift(_Symbol,tf_mass_l[x],time2,true);
         if(index>0){
            while(index>0 && iHigh(_Symbol,tf_mass_l[x],index) > 0.0 && price2!=ND(iHigh(_Symbol,tf_mass_l[x],index))){
               index--;}
            time2=iTime(_Symbol,tf_mass_l[x],index);}
         else{
            #ifdef TimeAnchorPointsCorrection_DEBUG
               Print("Adjustment of point #2 is ended on a timeframe - ",TimeframeToStr(tf_mass_l[x]));
            #endif
            break;}}}
   else if(price2==low){
      int x=massIndex;
      while(x>0){
         x--;
         int index=iBarShift(_Symbol,tf_mass_l[x],time2,true);
         if(index>0){
            while(index>0 && iLow(_Symbol,tf_mass_l[x],index) > 0.0 && price2!=ND(iLow(_Symbol,tf_mass_l[x],index))){
               index--;}
            time2=iTime(_Symbol,tf_mass_l[x],index);}
         else{
            #ifdef TimeAnchorPointsCorrection_DEBUG
               Print("Adjustment of point #2 is ended on a timeframe - ",TimeframeToStr(tf_mass_l[x]));
            #endif
            break;}}}
   else{
      correct2=false;
      #ifdef TimeAnchorPointsCorrection_DEBUG
         Print("Anchor point #2 is put not on extremum");
      #endif}
   //---
   if(correct1){
      if(!ObjectSetInteger(0,name,OBJPROP_TIME,0,time1)){
         #ifdef TimeAnchorPointsCorrection_DEBUG
            Print("Error #",IntegerToString(GetLastError()),", in attempt to change properties (time 1) of an object: \"",name,"\"!");
         #endif}}
   if(correct2){
      if(!ObjectSetInteger(0,name,OBJPROP_TIME,1,time2)){
         #ifdef TimeAnchorPointsCorrection_DEBUG
            Print("Error #",IntegerToString(GetLastError()),", in attempt to change properties (time 2) of an object: \"",name,"\"!");
         #endif}}
   //---
   return true;
}
//+------------------------------------------------------------------+
//| Индекс лоу хай по времени                                        |
//+------------------------------------------------------------------+
bool HighLowByTime(double &high,double &low,const datetime time)
{
   int index=iBarShift(_Symbol,_Period,time,true);
   if(index<0){
      return false;}
   //---
   high = ND(High[index]);
   low  = ND(Low[index]);
   //---
   return true;
}
//+------------------------------------------------------------------+
//| Поиск индекса массива таймфреймов соответствующего передаваемому |
//| периоду                                                          |
//+------------------------------------------------------------------+
int IndexInTimeframeMass(const ENUM_TIMEFRAMES &tf_mass_l[],const int locPeriod)
{
   int x=ArraySize(tf_mass_l)-1;
   for(; x>=0; x--){
      if(locPeriod==tf_mass_l[x]){
         break;}}
   //---
   #ifdef IndexInTimeframeMass_DEBUG
      Print("TF mass index: ",x,", TF ",TimeframeToStr(tf_mass_l[x]));
   #endif
   //---
   return x;
}
//+------------------------------------------------------------------+
//| Округление                                                       |
//+------------------------------------------------------------------+
double ND(const double value,int _digits=0)
{
   if(_digits == 0)
      _digits = _Digits;
   //---
   return NormalizeDouble(value, _digits);
}
 
Viktor Glovluk:

Доброго времени суток, уважаемые форумчане! Подскажите, пожалуйста, как скорректировать время точки привязки (например трендовой линии) с младшего таймфрейма? При нанесении граф объекта на график, например на D1, при переходе на более младший таймфрейм точка привязки оказывается смещена на время открытия бара D1! Пытался накидать функцию, но что-то не очень получилось!

У меня в программе для МТ4 это решено так:

//--------------------------------------------------------
// Определение времени и hl на минимально возможном таймфрейме. Начало.
//--------------------------------------------------------
// hl=1 - цена на максимуме, hl=2 - цена на минимуме
datetime hl_minTF(int &hl, int &minTF, datetime dt, double price, int dtPeriod)
  {
   datetime end, tfdelta=dtPeriod*60;
   datetime end_save, dtx_save;
   datetime dtx=dt;
   datetime save_dt=dt, return_time=dt;
   double   save_price=price;
   double   cena=0, dopusk=1.0003; 
   int      shift=0,i, j, k=-1, m=-1;
   double   mindopusk, maxdopusk;

   minTF=20;
   hl=0;
   shift=iBarShift(_Symbol,dtPeriod,dt,true);
   dtx_save=iTime(_Symbol,dtPeriod,shift);

   if (shift>=0)
     {
      if (price>=iHigh(_Symbol,dtPeriod,shift) || price>(iHigh(_Symbol,dtPeriod,shift)+iLow(_Symbol,dtPeriod,shift))/2)
        {
         hl=1; 
         price=iHigh(_Symbol,dtPeriod,shift);
         cena=0;
        }
      else // if (price<=iLow(_Symbol,dtPeriod,shift))
        {
         hl=2;
         price=iLow(_Symbol,dtPeriod,shift);
         cena=1000000;
        }

      mindopusk=price/dopusk;
      maxdopusk=price*dopusk;

      // поиск времени экстремума на минимально возможном таймфрейме для определения точного времени экстремума
      if (hl>0)
        {
         end=dtx+tfdelta;
         end_save=end;

         for (i=20;i>=0;i--)
           {
            if (iBars(_Symbol,tf[i])>0 && tf[i]<=dtPeriod)
              {
               shift=iBarShift(_Symbol,tf[i],dtx,false); // ,true);
//               0 1 2 3 4 5 6  7  8  9  10 11 12  13  14  15  16  17  18   19    20 
//int    tf[21]={1,2,3,4,5,6,10,12,15,20,30,60,120,180,240,360,480,720,1440,10080,43200}; 

               if (iTime(_Symbol,tf[i],shift)<dtx_save-tfdelta || iTime(_Symbol,tf[i],shift)>end_save)
                 {
                  break;
                 }

               if (shift>=0)
                 {
                  if (hl==1)
                    {
                     cena=0;
                     for (j=shift; iTime(_Symbol,tf[i],j)<=end && j>=0; j--)
                       {
                        if (cena<iHigh(_Symbol,tf[i],j) && iTime(_Symbol,tf[i],j)>0) {cena=iHigh(_Symbol,tf[i],j); k=j; dt=iTime(_Symbol,tf[i],j);}

                        if (cena>maxdopusk)
                          {
                           return_time=iTime(_Symbol,tf[minTF],m);
                           if (return_time<save_dt && cena<save_price)
                             {
                              return_time=save_dt;
                             }

                           return (return_time);
                          }
                       }
                    }
                  else
                    {
                     cena=10000000;
                     for (j=shift; iTime(_Symbol,tf[i],j)<=end && j>=0; j--)
                       {
                        if (cena>iLow(_Symbol,tf[i],j) && iTime(_Symbol,tf[i],j)>0) {cena=iLow(_Symbol,tf[i],j); k=j; dt=iTime(_Symbol,tf[i],j);}

                        if (cena<mindopusk)
                          {
                           return_time=iTime(_Symbol,tf[minTF],m);
                           if (return_time<save_dt && cena>save_price)
                             {
                              return_time=save_dt;
                             }

                           return (return_time);
                          }
                       }
                    }

                  if (cena<=maxdopusk || cena>=mindopusk)
                    {
                     m=k; 
                     minTF=i;
                     dtx=iTime(_Symbol,tf[i],k);
                     tfdelta=tf[i]*60;
                     if (dt<save_dt) dt=save_dt;
                     end=iTime(_Symbol,tf[i],k)+tfdelta;
                    }
                 }
              }
//            ResetLastError();
           }
        }
      else
        {
         return(save_dt);
        }
     }
   else
     {
      return(save_dt);
     }

   return(dt); 
  }
//--------------------------------------------------------
// Определение времени и hl на минимально возможном таймфрейме. Конец.
//--------------------------------------------------------
 

Как-то так, Get функции, думаю сами напишете?

datetime GetM1Time(datetime fTime,double fPrice,ENUM_APPLIED_PRICE fPriceType){
   int shiftCur=iBarShift(NULL,0,fTime,true);
   if (shiftCur<0) return 0;
   datetime timeEnd=shiftCur==0?TimeCurrent()/60*60:
                                iTime(NULL,0,shiftCur)-60;
   if ((long)timeEnd<0) return 0;
   MqlRates rates[];
   ArraySetAsSeries(rates,true);
   ResetLastError();
   int size=CopyRates(NULL,PERIOD_M1,fTime,timeEnd,rates);
   if (GetLastError()!=0) return 0;
   for (int i=0;i<size;i++)
      switch(fPriceType){
         case PRICE_HIGH:     if (rates[i].high==fPrice) return rates[i].time;               else break;
         case PRICE_LOW:      if (rates[i].low==fPrice) return rates[i].time;                else break;
         case PRICE_CLOSE:    if (rates[i].close==fPrice) return rates[i].time;              else break;
         case PRICE_OPEN:     if (rates[i].open==fPrice) return rates[i].time;               else break;
         case PRICE_MEDIAN:   if (GetPriceMedian(rates[i])==fPrice) return rates[i].time;    else break;
         case PRICE_TYPICAL:  if (GetPriceTypical(rates[i])==fPrice) return rates[i].time;   else break;
         case PRICE_WEIGHTED: if (GetPriceWeight(rates[i])==fPrice) return rates[i].time;}
   return 0;}
Причина обращения: