TD_Points_Line_mgtd1.1

Download script
Author: Vladislav Goshkov (VG)
TD_Points_Line_mgtd1.1

Overview of Logic

This script is designed to analyze price movements on a trading chart to identify significant trend "breakouts" and project potential price targets. It operates by scanning historical price data to find key structural points in the market—specifically areas where price reached new highs or lows—and then calculates mathematical paths based on those points.

Core Functionalities

1. Identification of Structural Peaks and Troughs The script scans the chart history to find two primary types of data points:

  • Supply Points (Highs): It looks for specific bars where the price reached a peak that is higher than the surrounding candles.
  • Demand Points (Lows): It seeks out bars where the price hit a bottom that is lower than its neighbors.

The script specifically looks for "significant" peaks or troughs by ensuring they aren't just minor fluctuations, but rather stand out relative to the preceding and following price action.

2. Trend Line Construction Once these significant high and low points are identified, the script connects the most recent two points of each type:

  • It draws a Trend Line for Highs (Supply) connecting the two most recent peaks.
  • It draws a Trend Line for Lows (Demand) connecting the two most recent bottoms.

This provides a visual representation of the current "path" the market is traveling.

3. Breakout Detection The script continuously monitors whether the current price is crossing these trend lines. It looks for specific moments where the price "breaks out" of the established path.

  • Bullish Breakouts: Triggered when the price moves above a descending supply trend line.
  • Bearish Breakouts: Triggered when the price moves below an ascending demand trend line.

The script includes specific logic filters (toggles) to verify these breakouts, checking for confirmation in the candle shapes and opening/closing prices to ensure the move has momentum.

4. Automated Target Projection When a valid breakout is detected, the script automatically calculates three different potential price targets:

  • Target 1: Based on the distance between recent highs and lows.
  • Target 2: Based on the relationship between current prices and previous historical lows/highs.
  • Target 3: Based on the difference between the closing prices of those key points.
  • Average Target: A final target is calculated by averaging these three values to provide a "consensus" price level.

Visual Output on Chart

To help the user read these calculations, the script places several visual elements directly on the chart:

  • Trend Lines: Solid lines connecting the major peaks and troughs.
  • Breakout Signals: Arrows appear at the exact moment a trend line is broken to notify the user of the shift.
  • Price Targets: Horizontal lines appear automatically at the calculated target levels (represented by different colors and styles like dashed or solid lines).
  • Reference Marker: A specific marker is placed on the chart to indicate where the current calculation cycle began.
13 Views
0 Downloads
0 Favorites
TD_Points_Line_mgtd1.1
//+------------------------------------------------------------------+
//|                                        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 StepBack=0;
extern bool Qw1=True;
extern bool Qw2=True;
extern bool Qw3=True;
extern color UpLineColor = Blue;
extern int   UpLnWidth = 1;
extern color DnLineColor = Red;
extern int   DnLnWidth = 1;
extern color MarkColor   = Blue;
extern int   MarkNumber  = 217;

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(" ");   
ObjectsDeleteAll();
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start()
  {
int Target_Style[4] = {STYLE_DASH,STYLE_DASH,STYLE_DASH,STYLE_SOLID},
    Target_Color[4] = {DimGray,MediumSpringGreen,SeaGreen,Blue},
    Target_LW[4]    = { 1, 1, 1, 2 };
double target[4];
//---- 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, UpLineColor);
      ObjectSet(buff_str, OBJPROP_WIDTH, UpLnWidth);
      }
   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, DnLineColor);
      ObjectSet(buff_str, OBJPROP_WIDTH, DnLnWidth);
      }
   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]) {
//----
   for(i=0;i<4;i++) target[i] = 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]-i,i);
		    S2=Lowest(NULL,0,MODE_CLOSE,UpB[1]-i,i);

	       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 && Close[i+2]>Close[i+1])
          || (Qw2 && Open[i]> iP)
          || (Qw3 && (Close[i+1]+(Close[i+1]-MathMin(Low[i+1],Close[i+2])))<iP) ) {
             target[0] = PP1;
             target[1] = PP2;
             target[2] = PP3;
             target[3] = (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]-i,i);
		    S2=Highest(NULL,0,MODE_CLOSE,DownB[1]-i,i);

          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 && Close[i+2]<Close[i+1] )
          || (Qw2 && Open[i] < iP )
		    || (Qw3 && (Close[i+1]+(Close[i+1]-MathMax(High[i+1],Close[i+2])))>iP) ) {
             target[0] = PP1;
             target[1] = PP2;
             target[2] = PP3;
             target[3] = (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--) {

   for(i=3;i>=0;i--) {
      buff_str = "Target"+i;
      if(ObjectFind(buff_str) == -1) {
         ObjectCreate(buff_str, OBJ_HLINE,0, Time[0], target[i] );
         ObjectSet(buff_str, OBJPROP_STYLE, Target_Style[i]);
         ObjectSet(buff_str, OBJPROP_COLOR, Target_Color[i]);
         ObjectSet(buff_str, OBJPROP_WIDTH, Target_LW[i]);
         }
      else {
         ObjectMove(buff_str, 0, Time[0], target[i] );
         }
      }


//----
string buff_str = "TD_LatestCulcBar";
   if(ObjectFind(buff_str) == -1) {
      ObjectCreate(buff_str, OBJ_ARROW,0, Time[StepBack], Low[StepBack]-2*Point );
      ObjectSet(buff_str, OBJPROP_ARROWCODE, MarkNumber);
      ObjectSet(buff_str, OBJPROP_COLOR, MarkColor);
      }
   else {
      ObjectMove(buff_str, 0, Time[StepBack], Low[StepBack]-2*Point );
      }
   return(0);
  }
//+------------------------------------------------------------------+

Comments