//+------------------------------------------------------------------+
//|                                        TD_Points&Lines_mgtd1.mq4 |
//|                                           Vladislav Goshkov (VG) |
//|                                                      4vg@mail.ru |
//+------------------------------------------------------------------+
#property copyright "Vladislav Goshkov (VG)"
#property link      "4vg@mail.ru"

#property indicator_chart_window

extern int SetPoint=0;
extern int StepBack=0;
extern int Qw1=1;
extern int Qw2=1;
extern int Qw3=1;

int i=1,NP=0,D=0,
    iB_Up=0,iB_Dn=0,
    S1=0,
    S2=0,
    UpLev=0,
    DownLev=0,
    iP_Up=0,
    iP_Dn=0,
    value=0,
    CurPeriod=0,
    shift=0;

datetime  nTime=0;

double UpV=0,
       DownV=0,
       iP=0,
       target = 0,
       UpP[2]={0,0},
       DownP[2]={0,0},
       PP1=0,PP2=0,PP3=0;

int    DownBT[2]={0,0}, // Bar Time
       UpBT[2]={0,0},
       UpB[2]={0,0},    // Bar Num
       DownB[2]={0,0};
string buff_str = "";
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
//---- indicators
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Custor indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit()
  {
//---- TODO: add your code here
Comment(" ");   
ObjectDelete("TD_Up");
ObjectDelete("TD_Dn");
ObjectDelete("Target");
ObjectDelete("Break_Sig_Up");
ObjectDelete("Break_Sig_Dn");
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start()
  {
   //int    counted_bars=IndicatorCounted();
//---- TODO: add your code here
if ( (nTime!=Time[0]) || (CurPeriod!=Period()) ) {
   UpP[0] = 0;
   UpP[1] = 0;

//=================================================
//******** Поиск опорных точек предложения ********
//=================================================
   for(i=2+StepBack,D=2,NP=0; (NP<D)&&(i<Bars); i++) {//Begin
       if (High[i]!= High[i+1]) { 
          if( (High[i]>High[i+1] && High[i]>High[i-1] && High[i]>Close[i+2] ) 
              && High[i]> UpP[0] ) {
	     	 UpB[NP]  = i;
		    UpBT[NP] = Time[i];
		    UpP[NP]  = High[i];
		    NP++;
		    }
		  }

    if (High[i]== High[i+1])  { 
       if ( (High[i]>High[i+2] && High[i]>High[i-1] && High[i]>Close[i+3] ) && High[i]> UpP[0] ) {
	     	 UpB[NP]  = i;
		    UpBT[NP] = Time[i];
		    UpP[NP]  = High[i];
		    NP++;
		    }
		  }
     if(i == (Bars-2) ) {
	     	 UpB[NP]  = i;
		    UpBT[NP] = Time[i];
		    UpP[NP]  = High[i];
		    break;
		    }
     }//for(i=2+StepBack,D=2,NP=0; NP<D; ) {//End;

//=================================================
//********** Поиск опорных точек спроса ***********
//=================================================
   DownP[0] = 1000000000;
   DownP[1] = 1000000000;
   for(i=2+StepBack,D=2,NP=0; (NP<D)&&(i<Bars); i++) {//Begin
    if (Low[i]!= Low[i+1])  { 
       if ( (Low[i]<Low[i+1] && Low[i]<Low[i-1] && Low[i]<Close[i+2] ) && Low[i]< DownP[0] ){
	  	    DownB[NP] = i;
		    DownBT[NP]= Time[i];
		    DownP[NP] = Low[i];
		    NP++;
		    }
		  //i++;
		  };
    if (Low[i]== Low[i+1])  { 
       if ( (Low[i]<Low[i+2] && Low[i]<Low[i-1] && Low[i]<Close[i+3] ) && Low[i]< DownP[0] ){
	  	    DownB[NP] = i;
		    DownBT[NP]= Time[i];
		    DownP[NP] = Low[i];
		    NP++;
		    }
		  //i++;
		  };
     if (i == (Bars-2) ) { 
	  	    DownB[NP] = i;
		    DownBT[NP]= Time[i];
		    DownP[NP] = Low[i];
		    break;
		    };
     }//End;
     

UpV = (UpP[1]-UpP[0])/(UpB[0]-UpB[1]);
DownV = (DownP[1]-DownP[0])/(DownB[0]-DownB[1]);

//=================================================
//****       Рисуем  TD-линии                  ****
//=================================================
   buff_str = "TD_Up";
   if(ObjectFind(buff_str) == -1) {
      ObjectCreate(buff_str, OBJ_TREND, 0, UpBT[1], UpP[1],UpBT[0], UpP[0]);
      ObjectSet(buff_str, OBJPROP_STYLE, STYLE_SOLID);
      ObjectSet(buff_str, OBJPROP_COLOR, DodgerBlue);
      //ObjectMove(buff_str, 0, UpBT[1], UpP[1],UpBT[0], UpP[0]);
      }
   else {
      ObjectMove(buff_str, 1, UpBT[0], UpP[0]);
      ObjectMove(buff_str, 2, UpBT[1], UpP[1]);
      }

   buff_str = "TD_Dn";
   if(ObjectFind(buff_str) == -1) {
      ObjectCreate(buff_str, OBJ_TREND, 0, DownBT[1], DownP[1],DownBT[0], DownP[0]);
      ObjectSet(buff_str, OBJPROP_STYLE, STYLE_SOLID);
      ObjectSet(buff_str, OBJPROP_COLOR, OrangeRed);
      //ObjectMove(buff_str, 0, UpBT[1], UpP[1],UpBT[0], UpP[0]);
      }
   else {
      ObjectMove(buff_str, 1, DownBT[0], DownP[0]);
      ObjectMove(buff_str, 2, DownBT[1], DownP[1]);
      }

   CurPeriod = Period();
   nTime = Time[0];
   }//if (nTime <> Time[0]) {
//----
   target = 0;

	for( i=UpB[0]; i>=StepBack; i--){
	   if( (Close[i]>UpP[0]+UpV*(UpB[0]-i)) && (Close[i+1]<UpP[0]+UpV*(UpB[0]-(i+1))) ) {
		    iB_Up=i; 
		    iP=UpP[0]+UpV*(UpB[0]-i);
		    iP_Up = iP; 
		    S1=Lowest(NULL,0,MODE_LOW,UpB[1],0);
		    S2=Lowest(NULL,0,MODE_CLOSE,UpB[1],0);

	       PP1=iP+((UpP[1]+UpV*(UpB[1]-S1))-Low[S1]);
	       PP2=iP+((UpP[1]+UpV*(UpB[1]-S2))-Low[S2]);
          PP3=iP+((UpP[1]+UpV*(UpB[1]-S1))-Close[S1]);
		    if((Qw1!=0 && Close[2]>Close[1])
          || (Qw2!=0 && Open[0]> iP)
          || (Qw3!=0 && (Close[0]+(Close[0]-MathMin(Low[0],Close[1])))<iP) ) {
             target = (PP1+PP2+PP3)/3;
             buff_str = "Break_Sig_Up";
             if(ObjectFind(buff_str) == -1) {
                ObjectCreate(buff_str, OBJ_ARROW,0, Time[iB_Up], iP+2*Point );
                ObjectSet(buff_str, OBJPROP_ARROWCODE, 164);
                ObjectSet(buff_str, OBJPROP_COLOR, Red);
                }
             else {
                ObjectMove(buff_str, 0, Time[iB_Up], iP+2*Point );
                }
             }
		    }
	   }

   for( i=DownB[0]; i>=StepBack;i--) {
	   if( (Close[i]<DownP[0]+DownV*(DownB[0]-i)) && (Close[i+1]>DownP[0]+DownV*(DownB[0]-(i+1))) ) {
	       iB_Dn=i; 
		    iP=DownP[0]+DownV*(DownB[0]-i);
		    iP_Dn = iP;
		    S1=Highest(NULL,0,MODE_HIGH,DownB[1],0);
		    S2=Highest(NULL,0,MODE_CLOSE,DownB[1],0);

          PP1=iP-(High[S1]-(DownP[1]+DownV*(DownB[1]-S1)));
	       PP2=iP-(High[S2]-(DownP[1]+DownV*(DownB[1]-S2)));
	       PP3=iP-(Close[S1]-(DownP[1]+DownV*(DownB[1]-S1)));
    		 if((Qw1!=0 && Close[1]<Close[0] )
          || (Qw2!=0 && Open[0] < iP )
		    || (Qw3!=0 && (Close[0]+(Close[0]-MathMax(High[0],Close[1])))>iP) ) {
             target = (PP1+PP2+PP3)/3;
             buff_str = "Break_Sig_Dn";
             if(ObjectFind(buff_str) == -1) {
                ObjectCreate(buff_str, OBJ_ARROW,0, Time[iB_Dn], iP+2*Point );
                ObjectSet(buff_str, OBJPROP_ARROWCODE, 164);
                ObjectSet(buff_str, OBJPROP_COLOR, Blue);
                }
             else {
                ObjectMove(buff_str, 0, Time[iB_Dn], iP+2*Point );
                }
             }
 		    }
		}//for( i=DownB[1]; i>=StepBack;i--) {

   buff_str = "Target";
   if(ObjectFind(buff_str) == -1) {
      ObjectCreate(buff_str, OBJ_HLINE,0, Time[0], target );
      ObjectSet(buff_str, OBJPROP_STYLE, STYLE_DOT);
      ObjectSet(buff_str, OBJPROP_COLOR, YellowGreen);
      //ObjectMove(buff_str, 0, UpBT[1], UpP[1],UpBT[0], UpP[0]);
      }
   else {
      ObjectMove(buff_str, 0, Time[0], target );
      }



//----
   return(0);
  }
//+------------------------------------------------------------------+