Triple-Angle Trend Signal
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/

//@version=4
study("Triple-Angle Trend Signal", overlay=true)

calcDegree(src, period) =>
    rad2degree = 180 / 3.14159265359  
    ang = rad2degree * atan((src[0] - src[period]) / atr(period))
    ang

show  = input(true, title="Show Line", group="angles setting")
i_anglePriceSrc             = input(close, title="Price source", type=input.source, group="angles setting")
i_anglePeriod               = input(28, minval=1, title="Angle period", group="angles setting")
i_showLabel                 = input(true, title="Show label", group="angles setting")
spessore= input(1, title='Line thickness', group="angles setting")
colore= input(color.blue, title='Line color', group="angles setting")
verde= input(20, title="higher degrees", group="angles setting")
colore1= input(#00ff0a, title='color by higher degrees', group="angles setting")
rosso=  input(-20, title="lower degrees", group="angles setting")
colore2= input(#ff0000 , title='color by lower degrees', group="angles setting")
colore3=  input(color.orange , title='intermediate color between upper and lower grades', group="angles setting")

angle = round(calcDegree(i_anglePriceSrc, i_anglePeriod))
cCandle =  angle > verde ? colore1 : angle <= verde and angle >= rosso ? colore3 : angle < rosso ? colore2 : colore2
barcolor(cCandle, title = "bar color")

line l = na
line.delete(l[1])
l := line.new( show ? bar_index[i_anglePeriod] : na, i_anglePriceSrc[i_anglePeriod], bar_index, i_anglePriceSrc, color=colore, width= spessore) 

if (i_showLabel)
    label lab = na
    label.delete(lab[1])
    lab := label.new(bar_index[i_anglePeriod], angle < angle[i_anglePeriod] ?  high[i_anglePeriod]  : low[i_anglePeriod] , text= tostring(angle) + '°', color=cCandle, style=  angle < angle[i_anglePeriod] ?  label.style_label_down  : label.style_label_up )

// angle indicator 2

show2   = input(false, title="Show Line 2", group="angles setting 2")
i_anglePriceSrc2   = input(close, title="Price source", type=input.source, group="angles setting 2")
i_anglePeriod2    = input(35, minval=1, title="Angle period", group="angles setting 2")
i_showLabel2    = input(false, title="Show label", group="angles setting 2")
spessore2= input(1, title='Line thickness', group="angles setting 2")
colore222= input(color.purple, title='Line color', group="angles setting 2")
verde2 = input(20, title="higher degrees", group="angles setting 2")
colore12= input(#00ff0a, title='color by higher degrees', group="angles setting 2")
rosso2=  input(-20, title="lower degrees", group="angles setting 2")
colore22= input(#ff0000 , title='color by lower degrees', group="angles setting 2")
colore32=  input(color.orange , title='intermediate color between upper and lower grades', group="angles setting 2")

angle2 = round(calcDegree(i_anglePriceSrc2, i_anglePeriod2))
cCandle2 =  angle2 > verde2 ? colore12 : angle2 <= verde2 and angle2 >= rosso2 ? colore32 : angle2 < rosso2 ? colore22 : colore22

line l2 = na
line.delete(l2[1])
l2 := line.new( show2 ? bar_index[i_anglePeriod2] : na, i_anglePriceSrc2[i_anglePeriod2], bar_index, i_anglePriceSrc2, color=colore222, width= spessore2) 

if (i_showLabel2 and show2)
    label lab2 = na
    label.delete(lab2[1])
    lab2 := label.new(bar_index[i_anglePeriod2], angle2 < angle2[i_anglePeriod2] ?  high[i_anglePeriod2] : low[i_anglePeriod2] , text= tostring(angle2) + '°', color=cCandle2, style=  angle2 < angle2[i_anglePeriod2] ?  label.style_label_down  : label.style_label_up )


// angle indicator 3

show3   = input(false, title="Show Line 3", group="angles setting 3")
i_anglePriceSrc3   = input(close, title="Price source", type=input.source, group="angles setting 3")
i_anglePeriod3    = input(50, minval=1, title="Angle period", group="angles setting 3")
i_showLabel3    = input(false, title="Show label", group="angles setting 3")
spessore3= input(1, title='Line thickness', group="angles setting 3")
colore333= input(color.fuchsia, title='Line color', group="angles setting 3")
verde3 = input(20, title="higher degrees", group="angles setting 3")
colore13= input(#00ff0a, title='color by higher degrees', group="angles setting 3")
rosso3=  input(-20, title="lower degrees", group="angles setting 3")
colore23= input(#ff0000 , title='color by lower degrees', group="angles setting 3")
colore33=  input(color.orange , title='intermediate color between upper and lower grades', group="angles setting 3")

angle3 = round(calcDegree(i_anglePriceSrc3, i_anglePeriod3))
cCandle3 = angle3 > verde3 ? colore13 : angle3 <= verde3 and angle3 >= rosso3 ? colore33 : angle3 < rosso3 ? colore23 : colore23

line l3 = na
line.delete(l3[1])
l3 := line.new( show3 ? bar_index[i_anglePeriod3] : na, i_anglePriceSrc3[i_anglePeriod3], bar_index, i_anglePriceSrc3, color=colore333, width= spessore3) 

if (i_showLabel3 and show3)
    label lab3 = na
    label.delete(lab3[1])
    lab3 := label.new(bar_index[i_anglePeriod3], angle3 < angle3[i_anglePeriod3] ?  high[i_anglePeriod3]  : low[i_anglePeriod3], text= tostring(angle3) + '°', color=cCandle3, style=  angle3 < angle3[i_anglePeriod3] ?  label.style_label_down  : label.style_label_up )

// background
sfondo= angle > verde and angle2 > verde2 and angle3 > verde3 ? #00ff0a : angle < rosso and angle2 < rosso2 and angle3 < rosso3 ? #ff0000 : na
bgcolor(sfondo)

// alerts
i_showBottomExtremeAlerts   = input(true,   title="Alerts bottom extreme", group="alerts")
i_bottomExtremeThreshold    = input(-70,    title="Bottom extreme threshold", group="alerts", minval=-1)

i_showTopExtremeAlerts      = input(true,   title="Alerts top extreme", group="alerts")
i_topExtremeThreshold       = input(70,     title="Top extreme threshold", group="alerts", minval=1)

if (i_showBottomExtremeAlerts and crossunder(angle, i_bottomExtremeThreshold))
    alert('Bottom extreme cross under: ' + tostring(i_bottomExtremeThreshold), alert.freq_once_per_bar_close )
    
if (i_showBottomExtremeAlerts and crossover(angle, i_bottomExtremeThreshold))
    alert('Bottom extreme cross over: ' + tostring(i_bottomExtremeThreshold), alert.freq_once_per_bar_close )
    
if (i_showTopExtremeAlerts and crossunder(angle, i_bottomExtremeThreshold))
    alert('Top extreme cross under: ' + tostring(i_bottomExtremeThreshold), alert.freq_once_per_bar_close )
    
if (i_showTopExtremeAlerts and crossover(angle, i_topExtremeThreshold))
    alert('Top extreme cross over: ' + tostring(i_topExtremeThreshold), alert.freq_once_per_bar_close )
