How do I calculate values on a trendline?

 

Suppose I draw a trendline, and I want an indicator that can draw lines above and below it by x pips. So I first find the trendline, take its price and time values, and calculate slope, then plot the lines. However, certain instruments close early on fridays and open later on mondays, so even though there is no gap between the last bar of friday and the first bar of monday, it's reflected in the chart. The result is these ridges that show up every weekend. How do I fix this?

(the picture is a H4 chart of a crude oil CFD with two lines offset by 50 cents from the trendline.) 

WTIcrude H4 

 
1mathboy1:

 So I first find the trendline, take its price and time values, and calculate slope, then plot the lines. However, certain instruments close early on fridays and open later on mondays, so even though there is no gap between the last bar of friday and the first bar of monday, it's reflected in the chart. The result is these ridges that show up every weekend. How do I fix this?

(the picture is a H4 chart of a crude oil CFD with two lines offset by 50 cents from the trendline.) 

 

I don't see why you would need to calculate the slope. You can just take the values from the trendline

You could code something like this

#property copyright "GumRai"
#property link      "none"
#property version   "1.00"
#property strict
#property indicator_chart_window
#property indicator_buffers 2
#property indicator_plots   2
//--- plot UpperLine
#property indicator_label1  "UpperLine"
#property indicator_type1   DRAW_LINE
#property indicator_color1  clrDodgerBlue
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1
//--- plot LowerLine
#property indicator_label2  "LowerLine"
#property indicator_type2   DRAW_LINE
#property indicator_color2  clrRed
#property indicator_style2  STYLE_SOLID
#property indicator_width2  1

//--- input parameters
input string      TLName="Trendline";//Trendline Name
input double      U_Offset=0.50;//Upper Line Offset
input double      L_Offset=0.50;//Lower Line Offset

//--- indicator buffers
double         UpperLineBuffer[];
double         LowerLineBuffer[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   SetIndexBuffer(0,UpperLineBuffer);
   SetIndexBuffer(1,LowerLineBuffer);
   
   
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| 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(ObjectFind(0,TLName)>=0)
    {
    if(prev_calculated==0)
      DrawLines();
    else
      for(int x=1;x>=0;x--)
        {
        double val=ObjectGetValueByShift(TLName,x);
        if(val>0)
           {
           UpperLineBuffer[x]=val+U_Offset;
           LowerLineBuffer[x]=val-L_Offset;
           }
        }
    }
//--- return value of prev_calculated for next call
   return(rates_total);
  }
  
//+------------------------------------------------------------------+
//| DrawLines function                                              |
//+------------------------------------------------------------------+
void DrawLines()
 {
 int x;
 for(x=Bars-1;x>=0;x--)
    {
    UpperLineBuffer[x]=EMPTY_VALUE;
    LowerLineBuffer[x]=EMPTY_VALUE;
    }
    
 datetime T1=(datetime)ObjectGet(TLName,OBJPROP_TIME1);
 datetime T2=(datetime)ObjectGet(TLName,OBJPROP_TIME2);
 if(T2<T1)
    T1=T2;
 x = iBarShift(Symbol(),0,T1);
 for(;x>=0;x--)
    {
    double val=ObjectGetValueByShift(TLName,x);
    if(val>0)
       {
       UpperLineBuffer[x]=val+U_Offset;
       LowerLineBuffer[x]=val-L_Offset;
       }
    }
 }

//+------------------------------------------------------------------+
//| ChartEvent function                                              |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam)
  {
  if(id==CHARTEVENT_OBJECT_DRAG && sparam==TLName)
     DrawLines();
  if(id==CHARTEVENT_OBJECT_CHANGE && sparam==TLName)
     DrawLines();
  
  
//---
   
  }
//+------------------------------------------------------------------+

 

 Unless there's a specific reason for having the lines as buffers, you could simply create 2 new trendlines with the offset

 
GumRai:

I don't see why you would need to calculate the slope. You can just take the values from the trendline

You could code something like this

 

 Unless there's a specific reason for having the lines as buffers, you could simply create 2 new trendlines with the offset

 Ok I was planning to use this to create an EA, so for example, "If the last bar closes above the line, buy." I can use the arrays upperlinebuffer and lowerlinebuffer right?
 
1mathboy1:
 Ok I was planning to use this to create an EA, so for example, "If the last bar closes above the line, buy." I can use the arrays upperlinebuffer and lowerlinebuffer right?
Yes
Reason: