Flare
fi(ki)=>'ra' // © fikira This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
//@version=5
indicator(title= "Flare", max_lines_count= 500, max_labels_count= 500, overlay= true)


_='         
             - - - ––––––––––––– - - - [                   INPUT                     ] - - - ––––––––––––– - - -          ='


lnSize   = input.int  (defval= 80    , title= 'Width of flare'                   , minval=   5, maxval=83)
clBack   = math.min   (lnSize, input.int(defval= 40, title= 'x bars back (close)', minval=   1, maxval=83, 
 tooltip =             "will take the lowest value of \n ╭╴ 'Width of flare'\n ╰╴  'x close back' "     ))
pow      = input.float(defval= 1.2   , title= 'pow'                              , step  = 0.05          )
step     = input.float(defval= 0.15  , title= 'step'                             , step  = 0.01          )
iBgc     = input.bool (defval= false , title= 'bgcolor'                                                  )
sLab     = input.bool (defval= true  , title= 'Label'                                                    , 
 tooltip =             "Shows start of flare -> point 'x bars back (close)'"                             ) 
st_Draw  = input.int  (defval= 1000  , title= 'start calculating last x bars'                            )


_='         
             - - - ––––––––––––– - - - [             create type "flare"             ] - - - ––––––––––––– - - -          ='


// @type               An object of 5 linefill array's (a_Lf1-5), 1 int iDir (direction) & 1 color (cCol)
type flare
    linefill[] a_Lf1 = na
    linefill[] a_Lf2 = na
    linefill[] a_Lf3 = na
    linefill[] a_Lf4 = na
    linefill[] a_Lf5 = na
    int        iDir  = na
    color      cCol  = na


_='
             –––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––                   
             - - - ––––––––––––– - - - [                  FUNCTIONS                  ] - - - ––––––––––––– - - -                    
             - - - ––––––––––––– - - - [                                             ] - - - ––––––––––––– - - -          ='
_='=         ––––––––––––––––––––––––––[      add lines to array at bar_index 0      ]––––––––––––––––––––––––––          ='


// @function                          Sets the new created flare object at the first bar
set_flare_0(flare obj) => 
    if barstate.isfirst
        //
        for i = 0 to lnSize 
            //
            l1 = line.new(x1= na, y1= na, x2= na, y2= na)
            l2 = line.new(x1= na, y1= na, x2= na, y2= na)
            l3 = line.new(x1= na, y1= na, x2= na, y2= na)
            l4 = line.new(x1= na, y1= na, x2= na, y2= na)
            l5 = line.new(x1= na, y1= na, x2= na, y2= na)
            l6 = line.new(x1= na, y1= na, x2= na, y2= na)
//  note   *1
            obj.a_Lf1.unshift(linefill.new(line1= l1, line2= l2, color= na))
            obj.a_Lf2.unshift(linefill.new(line1= l2, line2= l3, color= na))
            obj.a_Lf3.unshift(linefill.new(line1= l3, line2= l4, color= na))
            obj.a_Lf4.unshift(linefill.new(line1= l4, line2= l5, color= na))
            obj.a_Lf5.unshift(linefill.new(line1= l5, line2= l6, color= na))


_='=         ––––––––––––––––––––––––––[ set lines x1, y1, x2, y2, this at every bar ]––––––––––––––––––––––––––          ='


// @function                             Updates every linefill from the flare object
set_flare_A(flare obj, series int closeBack) =>
    //
    if last_bar_index - bar_index < st_Draw
        for i = 0 to lnSize 
//  note   *2
            obj.a_Lf1.get(i).get_line1().set_xy1(bar_index - closeBack + i    , close[closeBack] - math.pow(i -1, pow + (2 * step)))
            obj.a_Lf1.get(i).get_line1().set_xy2(bar_index - closeBack + i + 1, close[closeBack] - math.pow(i   , pow + (2 * step)))
            // 
            obj.a_Lf1.get(i).get_line2().set_xy1(bar_index - closeBack + i    , close[closeBack] - math.pow(i -1, pow + (1 * step)))
            obj.a_Lf1.get(i).get_line2().set_xy2(bar_index - closeBack + i + 1, close[closeBack] - math.pow(i   , pow + (1 * step)))       
            obj.a_Lf2.get(i).get_line1().set_xy1(bar_index - closeBack + i    , close[closeBack] - math.pow(i -1, pow + (1 * step)))
            obj.a_Lf2.get(i).get_line1().set_xy2(bar_index - closeBack + i + 1, close[closeBack] - math.pow(i   , pow + (1 * step)))
            //
            obj.a_Lf2.get(i).get_line2().set_xy1(bar_index - closeBack + i    , close[closeBack] - math.pow(i -1, pow + (0 * step)))
            obj.a_Lf2.get(i).get_line2().set_xy2(bar_index - closeBack + i + 1, close[closeBack] - math.pow(i   , pow + (0 * step)))
            obj.a_Lf3.get(i).get_line1().set_xy1(bar_index - closeBack + i    , close[closeBack] - math.pow(i -1, pow + (0 * step)))
            obj.a_Lf3.get(i).get_line1().set_xy2(bar_index - closeBack + i + 1, close[closeBack] - math.pow(i   , pow + (0 * step)))
            //
            obj.a_Lf3.get(i).get_line2().set_xy1(bar_index - closeBack + i    , close[closeBack] + math.pow(i -1, pow + (0 * step)))
            obj.a_Lf3.get(i).get_line2().set_xy2(bar_index - closeBack + i + 1, close[closeBack] + math.pow(i   , pow + (0 * step)))
            obj.a_Lf4.get(i).get_line1().set_xy1(bar_index - closeBack + i    , close[closeBack] + math.pow(i -1, pow + (0 * step)))
            obj.a_Lf4.get(i).get_line1().set_xy2(bar_index - closeBack + i + 1, close[closeBack] + math.pow(i   , pow + (0 * step)))
            //
            obj.a_Lf4.get(i).get_line2().set_xy1(bar_index - closeBack + i    , close[closeBack] + math.pow(i -1, pow + (1 * step)))
            obj.a_Lf4.get(i).get_line2().set_xy2(bar_index - closeBack + i + 1, close[closeBack] + math.pow(i   , pow + (1 * step)))
            obj.a_Lf5.get(i).get_line1().set_xy1(bar_index - closeBack + i    , close[closeBack] + math.pow(i -1, pow + (1 * step)))
            obj.a_Lf5.get(i).get_line1().set_xy2(bar_index - closeBack + i + 1, close[closeBack] + math.pow(i   , pow + (1 * step)))
            //
            obj.a_Lf5.get(i).get_line2().set_xy1(bar_index - closeBack + i    , close[closeBack] + math.pow(i -1, pow + (2 * step)))
            obj.a_Lf5.get(i).get_line2().set_xy2(bar_index - closeBack + i + 1, close[closeBack] + math.pow(i   , pow + (2 * step)))


_='=         ––––––––––––––––––––––––––[  set color ~ condition, this at every bar   ]––––––––––––––––––––––––––          ='


// @function                              sets color ~ condition at every bar
set_flare_B(flare obj) =>
    //
    if last_bar_index - bar_index < st_Draw
        dist = bar_index - obj.a_Lf1.get(0).get_line1().get_x1() 
//  note   *3
        clAbove6 = close > obj.a_Lf5.get(dist).get_line2().get_price(bar_index)  
        clAbove5 = close > obj.a_Lf4.get(dist).get_line2().get_price(bar_index)  
        clAbove4 = close > obj.a_Lf3.get(dist).get_line2().get_price(bar_index)  
        clBelow3 = close < obj.a_Lf3.get(dist).get_line1().get_price(bar_index)  
        clBelow2 = close < obj.a_Lf2.get(dist).get_line1().get_price(bar_index)  
        clBelow1 = close < obj.a_Lf1.get(dist).get_line1().get_price(bar_index)  
//  note   *4
        obj.iDir := 
         switch
            clAbove6 =>                 3 
            clAbove5 =>                 2
            clAbove4 =>                 1
            clBelow1 =>                -3 
            clBelow2 =>                -2
            clBelow3 =>                -1
            => 0
        //
        obj.cCol := 
         switch
            clAbove6 =>                input.color(defval= color.lime  , title= '', group= 'color UP', inline= 'up') 
            clAbove5 =>                input.color(defval= color.green , title= '', group= 'color UP', inline= 'up') 
            clAbove4 =>                input.color(defval= color.yellow, title= '', group= 'color UP', inline= 'up') 
            clBelow1 =>                input.color(defval= #FF0000     , title= '', group= 'color DN', inline= 'dn')
            clBelow2 =>                input.color(defval= color.red   , title= '', group= 'color DN', inline= 'dn')
            clBelow3 =>                input.color(defval= color.orange, title= '', group= 'color DN', inline= 'dn')
            =>                                             color.blue
        // 
        for i = 0 to lnSize 
//  note   *5
            obj.a_Lf1.get(i).get_line1().set_color(color.new(obj.cCol, math.max(0,          100 - (100 / lnSize * i))))
            obj.a_Lf2.get(i).get_line1().set_color(color.new(obj.cCol,                      100                      ))
            obj.a_Lf3.get(i).get_line1().set_color(color.new(obj.cCol, math.max(0,          100 - (100 / lnSize * i))))
            obj.a_Lf4.get(i).get_line2().set_color(color.new(obj.cCol,                      100                      ))
            obj.a_Lf4.get(i).get_line1().set_color(color.new(obj.cCol, math.max(0,          100 - (100 / lnSize * i))))
            obj.a_Lf5.get(i).get_line2().set_color(color.new(obj.cCol, math.max(0,          100 - (100 / lnSize * i))))
//  note   *6
            obj.a_Lf1.get(i).set_color            (color.new(obj.cCol, math.max(0, math.min(100 ,  100 / lnSize * i))))
            obj.a_Lf2.get(i).set_color            (color.new(obj.cCol, math.max(0, math.min(100 ,  125 / lnSize * i))))
            //
            obj.a_Lf4.get(i).set_color            (color.new(obj.cCol, math.max(0, math.min(100 ,  125 / lnSize * i))))
            obj.a_Lf5.get(i).set_color            (color.new(obj.cCol, math.max(0, math.min(100 ,  100 / lnSize * i))))


_='
             - - - ––––––––––––– - - - [                                             ] - - - ––––––––––––– - - -          
             –––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––          ='



_='
             - - - ––––––––––––– - - - [                    ACTION                   ] - - - ––––––––––––– - - -          ='


_='=         ––––––––––––––––––––––––––[                  Draw "Flare"               ]––––––––––––––––––––––––––          ='


var flare ConcaveCone = 
  flare.new(
      a_Lf1= array.new<linefill>(), 
      a_Lf2= array.new<linefill>(), 
      a_Lf3= array.new<linefill>(), 
      a_Lf4= array.new<linefill>(), 
      a_Lf5= array.new<linefill>(), 
      iDir= na, 
      cCol= na) 


set_flare_0(ConcaveCone          )    
set_flare_A(ConcaveCone, clBack  )
set_flare_B(ConcaveCone          )


_='=         ––––––––––––––––––––––––––[          Draw plotshape() & bgcolor         ]––––––––––––––––––––––––––          ='


plotshape  (ConcaveCone.iDir <= 0 ? high : na, "", shape.labeldown, location.abovebar, color.new(ConcaveCone.cCol, 25), 0, size=size.tiny)
plotshape  (ConcaveCone.iDir >= 0 ? low  : na, "", shape.labelup  , location.belowbar, color.new(ConcaveCone.cCol, 25), 0, size=size.tiny)
bgcolor    (iBgc                  ?                                                    color.new(ConcaveCone.cCol, 95)   :      na       )


_='=         ––––––––––––––––––––––––––[              Draw start label()            ]––––––––––––––––––––––––––          ='


up = close[clBack] > open[clBack]
var label lab = na
if sLab
    lab  := 
     label.new(bar_index - clBack, close[clBack], 
     text = 'start', textcolor= color.yellow  ,
     style= up ? label.style_label_lower_right  : 
                 label.style_label_upper_right  )
    (lab[1]).delete()



_='
             - - - ––––––––––––– - - - [                     NOTES                   ] - - - ––––––––––––– - - -          ='


//  note   *1
_='         obj.a_Lf1.unshift(linefill.new(l1, l2, na))                     in  "set_flare_0()" function                  ='
_='         obj         -> object (ConcaveCone)                                                                           ='
_='         a_Lf1       -> first linefill[] array of flare object                                                         ='

_='         In the ACTION part, we create a "ConcaveCone" OBJECT of "flare" TYPE                                          ='
_='         "ConcaveCone" has a "linefill[]" field, here we add a "linefill.new()"                                        ='

_='   ->     ConcaveCone.a_Lf1.unshift(linefill.new(...))                                                                 ='


//  note   *2
_='         obj.a_Lf1.get(i).get_line1().set_xy1(bar_index ..., close ...)  in  "set_flare_A()" function                  ='

_='         obj         -> object (ConcaveCone)                                                                           ='
_='         a_Lf1       -> first linefill[] array of flare object                                                         ='
_='         get(i)      -> get   linefill in linefill[] array                                                             ='
_='         get_line1() -> get_line1()  of retrieved linefill                                                             ='
_='         set_xy1     -> sets x1 & y1 of retrieved line1()                                                              ='


//  note   *3
_='         obj.a_Lf1.get(dist).get_line2().get_price(bar_index)            in "set_flare_B()" function                   ='
_='         obj         -> object (ConcaveCone)                                                                           ='
_='         a_Lf1       -> first linefill[] array of flare object                                                         ='
_='         get(dist)   -> dist is 1 specific linefill from the linefill[] array                                          ='
_='                          -> in this case the line at currect bar                                                      ='
_='         get_line2() -> get_line2()  of retrieved linefill                                                             ='
_='         get_price() -> retrieves price from this line at current bar_index                                            ='
_='                          -> then check where close is against prices (below/above)                                    ='


//  note   *4
_='                          -> update  iDir of flare object (obj.iDir)                                                   ='
_='                          -> update color of flare object (obj.cCol)                                                   ='


//  note   *5
_='         obj.a_Lf1.get(i).get_line1().set_color(color.new(obj.cCol,...)) in "set_flare_B()" function                   ='
_='         obj         -> object (ConcaveCone)                                                                           ='
_='         a_Lf1       -> first linefill[] array of flare object                                                         ='
_='         get(i)      -> get   linefill in linefill[] array                                                             ='
_='         get_line1() -> get_line1()  of retrieved linefill                                                             ='
_='         set_color() -> sets colour  of retrieved line1()                                                              ='

_='         another option is to change colour according to "i" and "lnSize" values                                       ='
_='         Examples:                                                                                                     ='
_='           obj.a_Lf1.get(i).get_line1().set_color(color.rgb(0, ((255 / lnSize) * i), ((255 / lnSize) * i), 0))         ='
_='           obj.a_Lf1.get(i).get_line1().set_color(color.rgb(200, 255 -               ((255 / lnSize) * i), 0, 0)       ='


//  note   *6
_='         obj.a_Lf1.get(i).set_color(color.new(cCol,...))                 in "set_flare_B()" function                   ='
_='         obj         -> object (ConcaveCone)                                                                           ='
_='         a_Lf1       -> first linefill[] array of flare object                                                         ='
_='         get(i)      -> get   linefill in linefill[] array                                                             ='
_='         set_color() -> sets colour  of retrieved linefill                                                             ='


_='
             - - - ––––––––––––– - - - [                     END                     ] - - - ––––––––––––– - - -          ='
