
#property indicator_separate_window
#property indicator_buffers 1
#property indicator_color1 Blue
#property indicator_width1 1
 
extern string Trendline_Name = "A_Line";    
extern int Applied_Price = PRICE_CLOSE;     
 
double A_t[]; 
double LineAngleTg;                         
double LinePrice1, LinePrice2;              
datetime LineTime1, LineTime2;              
int Shift1, Shift2;                         
int Multiplier;                             
bool NeedUpdate;
 
int init()
{
  if((Applied_Price < 0) || (Applied_Price > 6)) Applied_Price = PRICE_CLOSE;
  SetIndexBuffer(0, A_t);
  SetIndexStyle(0, DRAW_LINE);

  SetIndexLabel(0, PriceConstToStr(Applied_Price));
//----
  NeedUpdate = true;
  Multiplier = MathPow(10, Digits);

  return(0);
}
 
int start()
{
  int limit = Bars - IndicatorCounted();
  if(limit < Bars) limit++;
  CalcAngleTg();
  if(NeedUpdate)
  {
    limit = Bars - 1;
    NeedUpdate = false;
  }
  for(int i=0; i<limit; i++)
    A_t[i] = (GetPrice(Applied_Price, i) - LinePrice1) * Multiplier - (GetShift(i) - GetShift(Shift1)) * LineAngleTg;
//----
  return(0);
}
//+------------------------------------------------------------------+
 
void CalcAngleTg()
{
  if(ObjectFind(Trendline_Name) == -1) return;
//----
  double tg;
//----
  LinePrice1 = ObjectGet(Trendline_Name, OBJPROP_PRICE1);
  LinePrice2 = ObjectGet(Trendline_Name, OBJPROP_PRICE2);
  LineTime1 = ObjectGet(Trendline_Name, OBJPROP_TIME1);
  LineTime2 = ObjectGet(Trendline_Name, OBJPROP_TIME2);
//----
  Shift1 = iBarShift(NULL, 0, LineTime1, true);
  Shift2 = iBarShift(NULL, 0, LineTime2, true);
//----
  tg = (LinePrice2 - LinePrice1) * Multiplier / (GetShift(Shift2) - GetShift(Shift1));
  if(tg != LineAngleTg) NeedUpdate = true;
  LineAngleTg = tg;
//----
  //Print("tg(angle) = ", LineAngleTg);
}
 
double GetPrice(int price_const, int shift)
{
  switch(price_const)
  {
    case PRICE_CLOSE: return(Close[shift]);
    case PRICE_OPEN: return(Open[shift]);
    case PRICE_HIGH: return(High[shift]);
    case PRICE_LOW: return(Low[shift]);
    case PRICE_MEDIAN: return((High[shift] + Low[shift]) / 2);
    case PRICE_TYPICAL: return((High[shift] + Low[shift] + Close[shift]) / 3);
    case PRICE_WEIGHTED: return((High[shift] + Low[shift] + Close[shift]*2) / 4);
  }
}
 
int GetShift(int index)
{
  return(Bars-1 - index);
}
 
string PriceConstToStr(int price_const)
{
  switch(price_const)
  {
    case PRICE_CLOSE: return("Close");
    case PRICE_OPEN: return("Open");
    case PRICE_HIGH: return("High");
    case PRICE_LOW: return("Low");
    case PRICE_MEDIAN: return("Median price");
    case PRICE_TYPICAL: return("Typical price");
    case PRICE_WEIGHTED: return("Weighted price");
  }
}
//+------------------------------------------------------------------+