//+------------------------------------------------------------------+
//|                                          Barishpoltz Channel.mq4 |
//|                                                        SaiborEye |
//|                                                                  |
//+------------------------------------------------------------------+
#property copyright "SaiborEye"
#property link      ""
 /*
Вариант индикатора, использующего фракталы  при  построении  и  отображение 
скользящих    каналов    Баришпольца.     Данный     релиз     предназначен 
для прикладной оценки возможности отказа от ручного построения, выявления и 
коррекции слабых мест,  предложения  по  вводу  дополнительных   параметров
 */
#property indicator_chart_window
#property indicator_buffers 3
#property indicator_color1 Gold
#property indicator_color2 Coral
#property indicator_color3 Aquamarine
//---- input parameters
extern int       RightLevel=3;//    Отступ от правой границы графика (Номер бара, 0 - последний, не сформировавшийся)
extern int       BetweenPeaks=2;//  Минимальное расстояние между экстремумами (количество баров)
extern int       MaxLength=600;//   Максимальная разрешенная длина канала (количество баров)

//---- buffers
double ExtMapBuffer1[];
double ExtMapBuffer2[];
double ExtMapBuffer3[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
//---- indicators
   SetIndexStyle(0,DRAW_SECTION);
   SetIndexBuffer(0,ExtMapBuffer1);
   SetIndexEmptyValue(0,0.0);
   SetIndexLabel(0,"Top Border");
   SetIndexStyle(1,DRAW_SECTION);
   SetIndexBuffer(1,ExtMapBuffer2);
   SetIndexEmptyValue(1,0.0);
   SetIndexLabel(1,"Bottom Border");
   SetIndexStyle(2,DRAW_ARROW,STYLE_SOLID,3);
   SetIndexBuffer(2,ExtMapBuffer3);
   SetIndexEmptyValue(2,0.0);
   SetIndexArrow(2,159);
   SetIndexLabel(2,"Fractal");
//----
   
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit()
  {
//----
   
//----
   return(0);
  }
//+------------------------------------------------------------------+
int CheckBorders(int X1,int X2,int X3,double Y1,double Y2,double Y3,bool TwoTop){
int x,limit;
   if(X1>X2)limit=X1;else limit=X2;
   if(TwoTop){// TOP TWO
   for(x=RightLevel;x<limit;x++){// LINE LOOP-1   
   if(Y2+(x*1.0-X2*1.0)*(Y1-Y2)/(X1*1.0-X2*1.0)<High[x])return (1);
   }// LINE LOOP-1
   for(x=RightLevel;x<limit;x++){// LINE LOOP-2
    if(Y3+(x*1.0-X3*1.0)*(Y1-Y2)/(X1*1.0-X2*1.0)>Low[x])return (-1);
   }// LINE LOOP-2
   return (0);
   }// TOP TWO
   if(!TwoTop){// BOTTOM TWO
   for(x=RightLevel;x<limit;x++){// LINE LOOP-3   
   if(Y2+(x*1.0-X2*1.0)*(Y1-Y2)/(X1*1.0-X2*1.0)>Low[x])return (-1);
   }// LINE LOOP-3
   for(x=RightLevel;x<limit;x++){// LINE LOOP-4
    if(Y3+(x*1.0-X3*1.0)*(Y1-Y2)/(X1*1.0-X2*1.0)<High[x])return (1);
   }// LINE LOOP-4
   return (0);   
   }// BOTTOM TWO
   return (-1);}
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start()
  {
   int PosX1[2],PosX2,pos,pos1,pos2,limit;
   double value;
   bool Flag;
   int TopPeaksPos[];
   int TopPeaksIndex;
   int BottomPeaksPos[];   
   int BottomPeaksIndex;   
//----   
     limit=MaxLength;if(limit>Bars-2)limit=Bars-2;if(RightLevel<2)RightLevel=2;
      ArrayResize(TopPeaksPos,limit);ArrayResize(BottomPeaksPos,limit);     
     TopPeaksIndex=0;BottomPeaksIndex=0;
      ArrayInitialize(ExtMapBuffer1,0.0);ArrayInitialize(ExtMapBuffer2,0.0);ArrayInitialize(ExtMapBuffer3,0.0);
//----
   for(pos=RightLevel;pos<limit;pos++){// MAIN SEEK LOOP
   if(High[pos]>High[pos-1]&&High[pos]>High[pos-2])
   if(High[pos]>High[pos+1]&&High[pos]>High[pos+2]){TopPeaksPos[TopPeaksIndex]=pos;TopPeaksIndex++;}
   if(Low[pos]<Low[pos-1]&&Low[pos]<Low[pos-2])
   if(Low[pos]<Low[pos+1]&&Low[pos]<Low[pos+2]){BottomPeaksPos[BottomPeaksIndex]=pos;BottomPeaksIndex++;}
      }// MAIN SEEK LOOP
//----
     if(BottomPeaksIndex<TopPeaksIndex)limit=BottomPeaksIndex;else limit=TopPeaksIndex;
     for(pos=0;pos<limit;pos++){// SEEK LOOP
     if(TopPeaksPos[pos]<BottomPeaksPos[pos]){// TOP NEARLY     
     for(pos1=pos;pos1<TopPeaksIndex;pos1++){// SECOND POINT SEEK     
     for(pos2=0;pos2<BottomPeaksIndex;pos2++)if(BottomPeaksPos[pos2]<=TopPeaksPos[pos1])if(BottomPeaksPos[pos2]>=TopPeaksPos[pos])
     if(TopPeaksPos[pos1]-TopPeaksPos[pos]>BetweenPeaks)if(CheckBorders(TopPeaksPos[pos],TopPeaksPos[pos1],BottomPeaksPos[pos2],
     High[TopPeaksPos[pos]],High[TopPeaksPos[pos1]],Low[BottomPeaksPos[pos2]],TRUE)==0){// DRAWING     
   ExtMapBuffer1[0] = (0-TopPeaksPos[pos])*(High[TopPeaksPos[pos1]]-High[TopPeaksPos[pos]])/(TopPeaksPos[pos1]-TopPeaksPos[pos])+High[TopPeaksPos[pos]];
   ExtMapBuffer1[TopPeaksPos[pos1]] = High[TopPeaksPos[pos1]];   
   ExtMapBuffer2[0] = Low[BottomPeaksPos[pos2]]+(0-BottomPeaksPos[pos2])*
      (High[TopPeaksPos[pos1]]-High[TopPeaksPos[pos]])/(TopPeaksPos[pos1]-TopPeaksPos[pos]);
   ExtMapBuffer2[TopPeaksPos[pos1]] = Low[BottomPeaksPos[pos2]]+(TopPeaksPos[pos1]-BottomPeaksPos[pos2])*
      (High[TopPeaksPos[pos1]]-High[TopPeaksPos[pos]])/(TopPeaksPos[pos1]-TopPeaksPos[pos]);   
   ExtMapBuffer3[TopPeaksPos[pos]]=High[TopPeaksPos[pos]];ExtMapBuffer3[TopPeaksPos[pos1]]=High[TopPeaksPos[pos1]];
   ExtMapBuffer3[BottomPeaksPos[pos2]]=Low[BottomPeaksPos[pos2]];
   return (0);
      }// DRAWING     
         }// SECOND POINT SEEK     
     }else {// BOTTOM NEARLY
     for(pos1=pos;pos1<BottomPeaksIndex;pos1++){// SECOND POINT SEEK     
     for(pos2=0;pos2<TopPeaksIndex;pos2++)if(TopPeaksPos[pos2]<=BottomPeaksPos[pos1])if(TopPeaksPos[pos2]>=BottomPeaksPos[pos])
     if(BottomPeaksPos[pos1]-BottomPeaksPos[pos]>BetweenPeaks)if(CheckBorders(BottomPeaksPos[pos],BottomPeaksPos[pos1],TopPeaksPos[pos2],
     Low[BottomPeaksPos[pos]],Low[BottomPeaksPos[pos1]],High[TopPeaksPos[pos2]],FALSE)==0){// DRAWING
   ExtMapBuffer1[0] = (0-BottomPeaksPos[pos])*(Low[BottomPeaksPos[pos1]]-Low[BottomPeaksPos[pos]])/(BottomPeaksPos[pos1]-BottomPeaksPos[pos])+Low[BottomPeaksPos[pos]];
   ExtMapBuffer1[BottomPeaksPos[pos1]] = Low[BottomPeaksPos[pos1]];   
   ExtMapBuffer2[0] = High[TopPeaksPos[pos2]]+(0-TopPeaksPos[pos2])*
      (Low[BottomPeaksPos[pos1]]-Low[BottomPeaksPos[pos]])/(BottomPeaksPos[pos1]-BottomPeaksPos[pos]);
   ExtMapBuffer2[BottomPeaksPos[pos1]] = High[TopPeaksPos[pos2]]+(BottomPeaksPos[pos1]-TopPeaksPos[pos2])*
      (Low[BottomPeaksPos[pos1]]-Low[BottomPeaksPos[pos]])/(BottomPeaksPos[pos1]-BottomPeaksPos[pos]);   
   ExtMapBuffer3[BottomPeaksPos[pos]]=Low[BottomPeaksPos[pos]];ExtMapBuffer3[BottomPeaksPos[pos1]]=Low[BottomPeaksPos[pos1]];
   ExtMapBuffer3[TopPeaksPos[pos2]]=High[TopPeaksPos[pos2]];
   return (0);
      }// DRAWING     
            }// SECOND POINT SEEK     
         }// BOTTOM NEARLY     
     }// SEEK LOOP
   return(0);
  }
//+------------------------------------------------------------------+