Author: Amba
Indicators Used
Fractals
0 Views
0 Downloads
0 Favorites
Tangent2-S
//+------------------------------------------------------------------+
//|                                                     Tangent2.mq4 |
//|                                                             Amba |
//|                                                                a |
//+------------------------------------------------------------------+
#property copyright "Amba"
#property link      "a"
#property version   "1.00"
#property strict
#property indicator_chart_window
#property indicator_buffers 3
//#property indicator_plots   2
//--- plot LineH
#property indicator_label1  "LineH"
#property indicator_type1   DRAW_LINE
#property indicator_color1  clrNavy
#property indicator_style1  STYLE_DASH
#property indicator_width1  1
//--- plot LineL
#property indicator_label2  "LineL"
#property indicator_type2   DRAW_LINE
#property indicator_color2  clrNavy
#property indicator_style2  STYLE_DASH
#property indicator_width2  1

#property indicator_label3  "Q"
#property indicator_type3   DRAW_NONE
#property indicator_color3  clrNONE
#property indicator_style3  STYLE_DASH
#property indicator_width3  1
//--- input parameters
extern bool bFollow=true;     //Follow by Time[0]
extern int bars=100;          //N bars for window of calc.
extern datetime d1=0;         //Window start
extern datetime d2=0;         //Window end
extern bool bShowObj=false;   //Show graph obj.
//--- indicator buffers
double         LineHBuffer[];
double         LineLBuffer[];
double         Params[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
datetime TimeStartOfTF(datetime dt, ENUM_TIMEFRAMES per)
  {
//Print(dt, " ", per);
   if(per<PERIOD_W1)
      return((datetime)floor(dt/per/60)*per*60);
   else
      if(per==PERIOD_MN1)
         dt=dt-(TimeDay(dt)-1)*86400;
      else
         if(per==PERIOD_W1)
            dt=dt-TimeDayOfWeek(dt)*86400;

   dt=TimeStartOfTF(dt,PERIOD_D1);
   return(dt);
  }


//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   IndicatorDigits(Digits+1);
   SetIndexBuffer(0,LineHBuffer);
   SetIndexBuffer(1,LineLBuffer);
   SetIndexBuffer(2,Params);
   string name2="TGT2";

   if(bFollow)
     {
      d2=Time[0];
      d1=Time[bars];
      ObjectDelete(name2);
      //bShowObj=false;
     }



   if(bShowObj && ObjectFind(name2)>=0)
      if(d1!=ObjectGet(name2,OBJPROP_TIME1) || d2!=ObjectGet(name2,OBJPROP_TIME2))
        {
         d1=(datetime)ObjectGet(name2,OBJPROP_TIME1);
         d2=(datetime)ObjectGet(name2,OBJPROP_TIME2);
        }
   if(d1==0 || d2==0)
     {
      if(bars==0)
        {
         d2=TimeStartOfTF(TimeCurrent(),PERIOD_D1);
         d1=TimeStartOfTF(d2-86400,PERIOD_D1);
         d1=Time[iBarShift(NULL,0,d1)+1];
        }
      else
        {
         d2=Time[0];
         d1=Time[bars];
        }
     }

   datetime l1,l2;
   l1=fmin(d1,d2);
   l2=fmax(d1,d2);
   d1=l1;
   d2=l2;
//Print(d1," ",d2);

//CalcTangents();
   EventSetTimer(1);

//---
   return(INIT_SUCCEEDED);
  }

double KH,BH,KL,BL;
datetime DL1,DL2,DH1,DH2;
double PH1,PH2,PL1,PL2;
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void CalcTangents(datetime _d1, datetime _d2, bool flag=false)
  {
   ArrayInitialize(LineHBuffer,EMPTY_VALUE);
   ArrayInitialize(LineLBuffer,EMPTY_VALUE);
   ArrayInitialize(Params,EMPTY_VALUE);
   int i1=iBarShift(NULL,0,_d1),i2=iBarShift(NULL,0,_d2), length=i1-i2+1;
   int imh=iHighest(NULL,0,MODE_HIGH,length,i2),xmh=i2;
   int iml=iLowest(NULL,0,MODE_LOW,length,i2),xml=i2;
   int x1,x2;
   double y1,y2,K,B;
   bool isUpTrend=(iml>imh);
   for(int ti=0; ti<2; ti++)
     {
      //PrintFormat("%d %d %s %s",isUpTrend,ti,TimeToStr(d1),TimeToStr(d2));
      double am[];
      int amax;
      if(isUpTrend)
        {
         if(ti==0)
           {
            x1=iml;
            y1=Low[x1];
            x2=imh;
            y2=Low[x2];
           }
         else
           {
            x1=iml;
            y1=Low[x1];
            x2=iHighest(NULL,0,MODE_HIGH,(x1-i2+1),i2);
            y2=Low[x2];
           }
         CalcKB(x1,y1,x2,y2,K,B);
         //PrintFormat("WL0 x1=%d, x2=%d",x1,x2);

         bool fnd=false;
         for(int x=x2+2; x<x1; x++)
            if(iFractals(NULL,0,MODE_LOWER,x)>0)
              {
               x2=x;
               y2=Low[x];
               fnd=true;
               CalcKB(x1,y1,x2,y2,K,B);
               break;
              }
         if(!fnd)
           {
            ArrayResize(am,x1-x2);
            ArrayInitialize(am,0);
            for(int ic=x1; ic>x2; ic--)
               am[x1-ic]=(y2-Low[ic])/(ic-x2);
            amax=0;
            if(ArraySize(am)>1)
               amax=ArrayMaximum(am);
            if(amax>0)
               x2=x1-amax;
            else
               x2=x1;
           }
         //PrintFormat("WL1 x1=%d, x2=%d",x1,x2);
         y2=Low[x2];
         CalcKB(x1,y1,x2,y2,K,B);

         ArrayResize(am,x1-x2);
         ArrayInitialize(am,0);
         for(int ic=x1; ic>x2; ic--)
            am[x1-ic]=(y2-Low[ic])/(ic-x2);
         //am[x1-ic]=K*ic+B-Low[ic];

         amax=0;
         if(ArraySize(am)>0)
            amax=ArrayMaximum(am);
         x1=x1-amax;
         //PrintFormat("WL2 x1=%d, x2=%d",x1,x2);
         y1=fmin(Low[x1],y2);
         CalcKB(x1,y1,x2,y2,K,B);


         for(int i=x1; i>=0; i--)
            LineLBuffer[i]=K*i+B;

         KL=K;
         BL=B;
         DL1=Time[x1];
         PL1=y1;
         DL2=Time[x2];
         PL2=y2;
        }
      else
        {
         if(ti==0)
           {
            x1=imh;
            y1=High[x1];
            x2=iml;
            y2=High[x2];
           }
         else
           {
            x1=imh;
            y1=High[x1];
            x2=iLowest(NULL,0,MODE_LOW,(x1-i2+1),i2);
            y2=High[x2];
           }
         CalcKB(x1,y1,x2,y2,K,B);
         //PrintFormat("WH0 x1=%d, x2=%d",x1,x2);


         bool fnd=false;
         for(int x=x2+2; x<x1; x++)
            if(iFractals(NULL,0,MODE_UPPER,x)>0 && ((y1-High[x])/(x1-x)<=(High[x]-y2)/(x-x2)))
              {
               //PrintFormat("%s %s %s ",TimeToStr(Time[x1]),TimeToStr(Time[x]),TimeToStr(Time[x2]));
               x2=x;
               y2=High[x];
               fnd=true;
               CalcKB(x1,y1,x2,y2,K,B);
               //Print(Time[x2], " F ", High[x2]," ",K*x2+B);
               break;
              }

         if(!fnd)
           {
            ArrayResize(am,x1-x2);
            ArrayInitialize(am,0);
            for(int ic=x1; ic>x2; ic--)
               am[x1-ic]=(High[ic]-y2)/(ic-x2);
            amax=0;
            if(ArraySize(am)>1)
               amax=ArrayMaximum(am);
            if(amax>0)
               x2=x1-amax;
            else
               x2=x1;
            //Print(Time[x2], " T ", High[x2]," ",K*x2+B);
           }
         //PrintFormat("WH1 x1=%d, x2=%d",x1,x2);
         y2=High[x2];
         CalcKB(x1,y1,x2,y2,K,B);

         ArrayResize(am,x1-x2);
         ArrayInitialize(am,0);
         for(int ic=x1; ic>x2; ic--)
            am[x1-ic]=(High[ic]-y2)/(ic-x2);
         //am[x1-ic]=K*ic+B-Low[ic];

         amax=0;
         if(ArraySize(am)>0)
            amax=ArrayMaximum(am);
         x1=x1-amax;
         //PrintFormat("WH2 x1=%d, x2=%d",x1,x2);
         y1=fmax(High[x1],y2);
         CalcKB(x1,y1,x2,y2,K,B);


         for(int i=x1; i>=0; i--)
            LineHBuffer[i]=K*i+B;

         KH=K;
         BH=B;
         DH1=Time[(int)x1];
         PH1=y1;
         DH2=Time[(int)x2];
         PH2=y2;
        }
      isUpTrend=!isUpTrend;
     }

   if(!flag && KH!=KL)
     {
      double xxx=-(BH-BL)/(KH-KL);
      //Print(xxx);
      //if(xxx>i2+14)//fmin(iBarShift(NULL,0,DH1),iBarShift(NULL,0,DL1)))
      //  {
      //   _d1=fmax(DH1,DL1);
      //   CalcTangents(_d1,_d2,true);
      //   return;
      //  }
     }

   Params[0]=KH;
   Params[1]=BH;
   Params[2]=KL;
   Params[3]=BL;
   Params[4]=(double)DL1;
   Params[5]=(double)DL2;
   Params[6]=(double)DH1;
   Params[7]=(double)DH2;

   if(bShowObj)
     {
      TrendCreate(0,"W2",0,DL1,PL1,DL2,PL2,clrBlack,STYLE_DASH,1,true,true,true,true);
      TrendCreate(0,"W1",0,DH1,PH1,DH2,PH2,clrBlack,STYLE_DASH,1,true,true,true,true);
      string name2="TGT2";
      if(!ObjectCreate(name2,OBJ_RECTANGLE,0,d1,Low[iml],d2,High[imh]))
        {
         ObjectSet(name2,OBJPROP_TIME1,d1);
         ObjectSet(name2,OBJPROP_TIME2,d2);
         ObjectSet(name2,OBJPROP_PRICE1,Low[iml]);
         ObjectSet(name2,OBJPROP_PRICE2,High[imh]);
        }
      ObjectSet(name2,OBJPROP_BACK,false);
      ObjectSetInteger(0,name2,OBJPROP_SELECTABLE,true);
      ObjectSetInteger(0,name2,OBJPROP_SELECTED,true);
      ObjectSetInteger(0,name2,OBJPROP_HIDDEN,true);
      ObjectSet(name2,OBJPROP_COLOR,clrGray);
      ObjectSet(name2,OBJPROP_STYLE,STYLE_DOT);

     }
  }

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void CalcKB(double x1, double y1, double x2, double y2, double& K, double& B)
  {
   double Dx=x2-x1;
   double Dy=y2-y1;
   if(Dx==0)
      K=0;
   else
      K=Dy/Dx;
   B=y1-K*x1;
  }


//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void CalcSignals()
  {

  }


//+------------------------------------------------------------------+
//| 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[])
  {
//---
   if(rates_total!=prev_calculated || prev_calculated==0)
     {
      if(bFollow)
        {
         d2=Time[0];
         d1=Time[bars];
        }
      CalcTangents(d1,d2);
      CalcSignals();
     }

//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+
//| Timer function                                                   |
//+------------------------------------------------------------------+
void OnTimer()
  {
//---
   string name2="TGT2";
   if(ObjectFind(name2)>=0)
     {
      if(d1!=ObjectGet(name2,OBJPROP_TIME1) || d2!=ObjectGet(name2,OBJPROP_TIME2))
        {
         d1=(datetime)ObjectGet(name2,OBJPROP_TIME1);
         if(!bFollow)
            d2=(datetime)ObjectGet(name2,OBJPROP_TIME2);
         datetime l1,l2;
         l1=fmin(d1,d2);
         l2=fmax(d1,d2);
         d1=l1;
         d2=l2;
         if(bars>0)
           {
            int i1=iBarShift(NULL,0,d1), i2=iBarShift(NULL,0,d2), nb=i1-i2+1;
            bars=nb;
           }
         CalcTangents(d1,d2);
        }
     }

  }
//+------------------------------------------------------------------+
//| ChartEvent function                                              |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam)
  {
//---


  }
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
bool TrendCreate(const long            chart_ID=0,
                 const string          name="TrendLine",
                 const int             sub_window=0,
                 datetime              time1=0,
                 double                price1=0,
                 datetime              time2=0,
                 double                price2=0,
                 const color           clr=clrRed,
                 const ENUM_LINE_STYLE style=STYLE_SOLID,
                 const int             width=1,
                 const bool            back=false,
                 const bool            selection=true,
                 const bool            ray_right=false,
                 const bool            hidden=false,
                 const long            z_order=0)
  {
   ResetLastError();
   if(!ObjectCreate(chart_ID,name,OBJ_TREND,sub_window,time1,price1,time2,price2))
     {
      ObjectSet(name,OBJPROP_TIME1,time1);
      ObjectSet(name,OBJPROP_TIME2,time2);
      ObjectSet(name,OBJPROP_PRICE1,price1);
      ObjectSet(name,OBJPROP_PRICE2,price2);
     }
   ObjectSetInteger(chart_ID,name,OBJPROP_COLOR,clr);
   ObjectSetInteger(chart_ID,name,OBJPROP_STYLE,style);
   ObjectSetInteger(chart_ID,name,OBJPROP_WIDTH,width);
   ObjectSetInteger(chart_ID,name,OBJPROP_BACK,back);
   ObjectSetInteger(chart_ID,name,OBJPROP_SELECTABLE,selection);
   ObjectSetInteger(chart_ID,name,OBJPROP_SELECTED,selection);
   ObjectSetInteger(chart_ID,name,OBJPROP_RAY_RIGHT,ray_right);
   ObjectSetInteger(chart_ID,name,OBJPROP_HIDDEN,hidden);
   ObjectSetInteger(chart_ID,name,OBJPROP_ZORDER,z_order);
   return(true);
  }
//+------------------------------------------------------------------+

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

Comments

Markdown supported. Formatting help

Markdown Formatting Guide

Element Markdown Syntax
Heading # H1
## H2
### H3
Bold **bold text**
Italic *italicized text*
Link [title](https://www.example.com)
Image ![alt text](image.jpg)
Code `code`
Code Block ```
code block
```
Quote > blockquote
Unordered List - Item 1
- Item 2
Ordered List 1. First item
2. Second item
Horizontal Rule ---