Пожалуйста помогите или объясните популярно как сделать индикатор трендовой линии

 

Добрый день,

пожалуйста помогите написать индикатор, который на графике цены рисует уровень поддержки и сопротивления (инструмент трендовая линия) параллельно горизонтальной шкале времени. Уровень начинает строится от появляющегося экстремума от цены High или Low, сначала в виде луча слева направо. Луч должен превратиться в отрезок на той свече, на которой цена её закрытия будет выше (для сопротивления) или ниже (для поддержки).

Луч должен начинать строиться только в том случае если другой ближайший действительный уровень в виде луча находится на расстоянии более 100 пунктов 

 
Лучше 1 раз увидеть
 

Может, так: 

// Копирование HLine в Line
int fHLine2Line(string OldName,string NewName="Прежний",string Text="Прежний",int Action=0){
   int Error, Type=ObjectType(OldName);
   bool Ray;
   datetime Time0;
   double Price0;
   if( Type!=OBJ_HLINE ){
      if( ПечататьПредупреждения ) Print("***   "+OldName+" недопустимый тип: "+Type);
      return(MyError);
   }
   if( NewName=="Прежний" ) NewName=OldName;
   if( NewName==OldName ) Action=2;                // Удалять оригинал
   if( ObjectFind(OldName)==0 ){                   // Копирование OldName в NewName
      double Price1=ObjectGet(OldName,OBJPROP_PRICE1);
      datetime Time1=ObjectGet(OldName,OBJPROP_TIME1);
      if( Time1==Time[LastBar-1] ){
         Time1 =0;
         Price1=0;
      }
      if( Price1<=Zero ){
         if( ПечататьПредупреждения ) Print("***   "+OldName+" не задана цена");
         return(MyError);
      }
      double Price2=ObjectGet(OldName,OBJPROP_PRICE2);
      datetime Time2=ObjectGet(OldName,OBJPROP_TIME2);
      if( Time2==Time[LastBar-1] ){
         Time2 =0;
         Price2=0;
      }
      double Price3=ObjectGet(OldName,OBJPROP_PRICE3);
      datetime Time3=ObjectGet(OldName,OBJPROP_TIME3);
      if( Time3==Time[LastBar-1] ){
         Time3 =0;
         Price3=0;
      }
      if( (MathAbs(Price1-Price2)>Zero && Price2>Zero )
       || (MathAbs(Price1-Price3)>Zero && Price3>Zero ) ){
         if( ПечататьПредупреждения ) Print("***   "+OldName+" цены в точках уровня не совпадают");
         return(MyError);
      }
      if( Price3>Zero ){
         Ray=false;                                // Задан отрезок 2(1)-3
         if( Price2>Zero ){                        // Отрезок 2-3
            Time0 =Time1;
            Price0=Price1;
            Time1 =Time2;                          // Начало отрезка
            Price1=Price2;
         }
         Time2=Time3;                              // Конец отрезка
         Price2=Price3;
         Time3=Time0;                              // Промежуточная точка
         Price3=Price0;
         if( РежимОтладки && ПечататьПредупреждения ) Print("*     "+OldName+" заданы цены отрезка: "
                                 +DoubleToStr(Price1,Digits)+" / "+TimeToStr(Time1)
                                 +" ... "+DoubleToStr(Price3,Digits)+" / "+TimeToStr(Time3)
                                 +" ... "+DoubleToStr(Price2,Digits)+" / "+TimeToStr(Time2));
      }
      else{
         if( Price2>Zero ){
            Ray=true;                              // Задан луч 2-1
            Time0 =Time1;
            Price0=Price1;
            Time1 =Time2;                          // Начало луча
            Price1=Price2;
            Time2 =Time0;                          // Промежуточная точка
            Price2=Price0;
            if( РежимОтладки && ПечататьПредупреждения ) Print("*     "+OldName+" заданы цены луча: "
                                    +DoubleToStr(Price1,Digits)+" / "+TimeToStr(Time1)
                                    +" ... "+DoubleToStr(Price2,Digits)+" / "+TimeToStr(Time2));
         }
         else{                                     // Задан уровень 1
            if( РежимОтладки && ПечататьПредупреждения ) Print("*     "+OldName+" задана только цена уровня: "
                                    +DoubleToStr(Price1,Digits)+" / "+TimeToStr(Time1));
            Error=fObjectCopy(OldName,NewName,Text,Action);
            return(Error);
      }  }
      bool  Фон      =ObjectGet(OldName,OBJPROP_BACK);
      color Цвет     =ObjectGet(OldName,OBJPROP_COLOR);
      int   Стиль    =ObjectGet(OldName,OBJPROP_STYLE);
      int   Видимость=ObjectGet(OldName,OBJPROP_TIMEFRAMES);
      int   Размер   =ObjectGet(OldName,OBJPROP_WIDTH);
      if( Text=="Прежний" ) Text=ObjectDescription(OldName);
      if( Action==1 ){                             // Спрятать оригинал
         if( !ObjectSet(OldName,OBJPROP_TIMEFRAMES,EMPTY) ){
            Error=GetLastError();
            if( !РежимОтладки ) PlaySound("alert.wav");
            Print("***** "+OldName+" - ошибка при задании невидимости "+Error);
      }  }
      if( Action==2 ) Error=fObjectDelete(OldName);// Удалить оригинал
      Error=fObjectDelete(NewName);                // Удалить копию
      if( ObjectCreate(NewName,OBJ_TREND,0,Time1,Price1,Time2,Price2,Time3,Price3) ) {
         if( !ObjectSetText(NewName,Text)
          || !ObjectSet(NewName,OBJPROP_RAY,Ray)
          || !ObjectSet(NewName,OBJPROP_BACK,Фон)
          || !ObjectSet(NewName,OBJPROP_COLOR,Цвет)
          || !ObjectSet(NewName,OBJPROP_STYLE,Стиль)
          || !ObjectSet(NewName,OBJPROP_TIMEFRAMES,Видимость)
          || !ObjectSet(NewName,OBJPROP_WIDTH,Размер) ){
            Error=GetLastError();
            if( !РежимОтладки ) PlaySound("alert.wav");
            Print("***** "+NewName+" - ошибка модификации параметров "+Error);
      }  }
      else{
         Error=GetLastError();
         if( !РежимОтладки ) PlaySound("alert.wav");
         Print("***** "+OldName+" - Копия "+NewName+" не создана, ошибка "+Error);
   }  }
   else{
      Error=MyError;
      if( ПечататьПредупреждения ) Print("***   "+OldName+" - Объект для копирования не найден!");
   }
   return(Error);
}
 
poruchik:
Лучше 1 раз увидеть

добрый день

Вижу вы мастер, а я не слишком продвинут в этом. Подскажите пожалуйста, мне ваш текст скопировать и создать новый индикатор? или как поступить?

Заранее благодарен

С уважением, Рушан 

 
tara:

Может, так: 

 

 

добрый день

Вижу вы мастер, а я не слишком продвинут в этом. Подскажите пожалуйста, мне ваш текст скопировать и создать новый индикатор? или как поступить?

Заранее благодарен

С уважением, Рушан 

 

Добрый день всем. Ребята, помогите пожалуйста разобраться и исправить ошибку в индикаторе. Программа строит прямые линии (уровни) на графике цены по определённому алгоритму и задаваемым параметрам. Но к сожалению не всегда правильно закрывает эти лучи - в тех случаях когда цена открытия и закрытия находятся ниже (выше) этих лучей они не закрываются. Я могу пояснить скрин-шотами. Пожалуйста помогите разобраться.

Вот текст программы.

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

//|                                                    trendline.mq4 |

//|                                                                  |

//|                                                                  |

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

#property copyright ""

#property link      ""

#property version   "1.20"

#property strict

#property indicator_chart_window

#property indicator_buffers 2

#property indicator_color1 Red

#property indicator_color2 Blue


//--- input parameters

input int      maxbars=1488;//Количество свечей для расчёта

input color    o_color=clrGold; //Цвет неактивного уровня 

input color    a_color=clrOrange; //Цвет активного уровня 

input int   dist=150; //Расстояние до ближайшего луча

input bool mark=false; //Метки экстремумов

double extr_high[];

double extr_low[];


color    old_color=o_color;

color    active_color=a_color;


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

//| Custom indicator initialization function                         |

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

int OnInit()

  {

//--- indicator buffers mapping

   IndicatorShortName("trendline");

   IndicatorDigits(5);

   IndicatorBuffers(2); 

    

   SetIndexDrawBegin(0, 0);

   SetIndexBuffer(0, extr_high);

   if (mark) SetIndexStyle(0, DRAW_ARROW); else SetIndexStyle(0, DRAW_NONE);

   SetIndexArrow(0, 117);

   SetIndexEmptyValue(0,0.0);

   SetIndexLabel(0,"extr high");   


   SetIndexDrawBegin(1, 0);

   SetIndexBuffer(1, extr_low);

   if (mark) SetIndexStyle(1, DRAW_ARROW); else SetIndexStyle(1, DRAW_NONE);  

   SetIndexArrow(1, 117);

   SetIndexEmptyValue(1,0.0);

   SetIndexLabel(1,"extr low");   

   

   if (old_color==active_color)active_color++;

    

//---

   return(INIT_SUCCEEDED);

  }

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

//| Custom indicator iteration function                              |

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

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[])

  {

//---

   ObjectsDeleteAll(0,"tr_",0,OBJ_TREND);

   for (int i=1;i<maxbars;i++)

     {

       extr_high[i]=0;

       extr_low[i]=0;

       if (High[i]>High[i-1])

         {

           if (High[i]>High[i+1]) extr_high[i]=High[i];

           if (High[i]==High[i+1] && High[i]>High[i+2])extr_high[i]=High[i];        

         }

       if (Low[i]<Low[i-1])

         {

           if (Low[i]<Low[i+1]) extr_low[i]=Low[i];

           if (Low[i]==Low[i+1] && Low[i]>Low[i+2])extr_low[i]=Low[i];        

         }         

     }

   for (int i=maxbars;i>0;i--)

     {

       for (int j=0;j<ObjectsTotal();j++)

         {

           if (ObjectType(ObjectName(j))==OBJ_TREND

               && StringSubstr(ObjectName(j),0,3)=="tr_"

               && ObjectGet(ObjectName(j),OBJPROP_COLOR)==active_color) 

             {

               if (Open[i]<ObjectGet(ObjectName(j),OBJPROP_PRICE1) && ObjectGet(ObjectName(j),OBJPROP_PRICE1)<Close[i] && ObjectGet(ObjectName(j),OBJPROP_TIME1 != Time[i]))

                 {

                   ObjectMove(0,ObjectName(j),1,Time[i],ObjectGet(ObjectName(j),OBJPROP_PRICE1));

                   ObjectSet(ObjectName(j),OBJPROP_COLOR,old_color);    

                   ObjectSet(ObjectName(j),OBJPROP_RAY,false);


                 }

               if (Open[i]>ObjectGet(ObjectName(j),OBJPROP_PRICE1) && ObjectGet(ObjectName(j),OBJPROP_PRICE1)>Close[i] && ObjectGet(ObjectName(j),OBJPROP_TIME1 != Time[i]))

                 {

                   ObjectMove(0,ObjectName(j),1,Time[i],ObjectGet(ObjectName(j),OBJPROP_PRICE1));

                   ObjectSet(ObjectName(j),OBJPROP_COLOR,old_color);    

                   ObjectSet(ObjectName(j),OBJPROP_RAY,false);    

                 }                 

             }

         }      

     

     

       if (extr_high[i]!=0)

         {

           bool dist_check=true;

           for (int j=0;j<ObjectsTotal();j++)

             {

               if (ObjectType(ObjectName(j))==OBJ_TREND

                   && StringSubstr(ObjectName(j),0,3)=="tr_"

                   && ObjectGet(ObjectName(j),OBJPROP_COLOR)==active_color) 

                 {

                   if (extr_high[i]!=0 && MathAbs(ObjectGet(ObjectName(j),OBJPROP_PRICE1)-extr_high[i])<dist/MathPow(10,Digits)) dist_check = false;

                 }

             }

           if (dist_check)

             {

               ObjectCreate("tr_H"+Time[i],OBJ_TREND, 0, Time[i],extr_high[i],Time[0],extr_high[i]);

               ObjectSet("tr_H"+Time[i],OBJPROP_COLOR,active_color);

               ObjectSet("tr_H"+Time[i],OBJPROP_RAY,true);                            

             }  

         }    


     

     if (extr_low[i]!=0)

         {

           bool dist_check=true;

           for (int j=0;j<ObjectsTotal();j++)

             {

               if (ObjectType(ObjectName(j))==OBJ_TREND

                   && StringSubstr(ObjectName(j),0,3)=="tr_"

                   && ObjectGet(ObjectName(j),OBJPROP_COLOR)==active_color) 

                 {

                   if (extr_low[i]!=0 && MathAbs(ObjectGet(ObjectName(j),OBJPROP_PRICE1)-extr_low[i])<dist/MathPow(10,Digits)) dist_check = false;

                 }

             }

           if (dist_check)

             {

               ObjectCreate("tr_L"+Time[i],OBJ_TREND, 0, Time[i],extr_low[i],Time[0],extr_low[i]);

               ObjectSet("tr_L"+Time[i],OBJPROP_COLOR,active_color);

               ObjectSet("tr_L"+Time[i],OBJPROP_RAY,true);                                                   

             }  

         }   

         

            

     }     

     

     

     

     


     

//--- return value of prev_calculated for next call

   return(rates_total);

  }

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

Файлы:
Причина обращения: