Composite Cosmetic Candles
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © EsIstTurnt

//@version=5
indicator("Composite Cosmetic Candles",overlay=true)
//Inputs 
src           = input.source(close,'Source',group="Oscillator")
osctype       = input.string("RSI",options=["RSI","CCI","COG","MFI","CMO","TSI","COPPOCK","VOLUME","OC Range","HL Range","BOP","BBP"],group="Oscillator")
len           = input.int(16,'Length',group="Oscillator") 
levels        = input.int(5,'Sections',options=[2,3,4,5,6,7,8,9,10],group='Measurement Meter')
transp        = input.int(50,'Transparency',group='Appearance')
topbot        = input.bool(false,'Plot Candle Open+Close along with Dividing Levels',group="Measurement Meter")
label         = input.bool(true,'Show Value Label',group="Measurement Meter")
osc_col       = input.bool(false,'Bar Color uses Oscillator Instead',group='Appearance')
solidfill     = input.bool(false,'Single Color Bar Fill',group='Appearance')
showosc       = input.bool(true,'Fill Bar Partially based on Oscillator Values',group='Appearance')

float osc = switch osctype       // Switch selecting oscillator type to use 
    "RSI"     => ta.rsi(src, len)
    "CCI"     => ta.cci(src, len)
    "COG"     => ta.cog(src, len)
    "MFI"     => ta.mfi(src, len)
    "CMO"     => ta.cmo(src, len)
    "TSI"     => ta.tsi(src, len,len*2)
    "COPPOCK" => ta.wma(ta.roc(src,math.round(1.1*len))+ta.roc(src,math.round(1.4*len)),len)
    "VOLUME"  => volume-volume[1]
    "OC Range"=> (math.max(open,close)-math.min(open,close))/ta.highest(math.max(open,close)-math.min(open,close),len )
    "HL Range"=> (high-low)/(ta.highest(high-low,len))
    "BOP"     => (close - open) / (high - low)
    "BBP"     => (high - ta.ema(close, len))+(low - ta.ema(close, len))




candles(float src,int lb = 0)=>               //Oscillator Candle Function - Open,High,Low will remain the same, but close is going to be a percentage of the actual bars close based upon the oscillator divided by the max value 
    max=lb == 0?ta.max(src):ta.highest(src,lb)// \
    min=lb == 0?ta.min(src):ta.lowest (src,lb)//  - Converting Oscillator Value to a float value
    dif=max-min//                               /
    pct=min>=0?src/max:((src-min)/dif)//      /
    bar=math.max(open,close)-math.min(open,close) //Absolute Value of close-open
    dir=open>close // Do we subtract or add?
    lev=dir?math.max(open,close)-(pct*bar):math.min(open,close)+(pct*bar) // Checks candle direction, then multiplies the float value by the actual candle body's difference to get the oscillator fill level
    _open=open //\
    _high=high//  - Values Are left the Same
    _low=low//   /
    _close=lev// Oscillator Close Value
    [_open,_high,_low,_close]

[_open,_high,_low,_close]=candles(osc)//Now assign Variables using above function (name kept same for simplicity)

s= showosc?math.abs(_close-_open)/3:math.abs(close-open)/3// Using the absolute value of close-open or _close-open, divide it by three (Could be more but I Ran out of plots ahem* TradingView...) for candle fill levels
l1=close>open?_open+(1*s):_open-(1*s)// \ 
l2=close>open?_open+(2*s):_open-(2*s)// - Level # * value from above added or subtracted to the candle's open, depending on which direction the bar moved.
l3=close>open?_open+(3*s):_open-(3*s)// /


//      
sections(num)=>                                                              //Candle Dividing Level Function - up to 9 levels but theoretically you can have as many as TV will allow if you want by adding more 
    span=math.max(open,close)-math.min(open,close)                           //Absolute difference between Open and Close values
    divi=1/num                                                               //1 divided by user input # of levels to give us a float value of what each individual level should be a multiple of
    bool=open>close                                                          //Down Candle?
    lev1=bool?num>=2 ?open-span*(1 *divi):na:num>=2 ?open+(span*(divi*1 )):na///
    lev2=bool?num>=3 ?open-span*(2 *divi):na:num>=3 ?open+(span*(divi*2 )):na///\
    lev3=bool?num>=4 ?open-span*(3 *divi):na:num>=4 ?open+(span*(divi*3 )):na//   \
    lev4=bool?num>=5 ?open-span*(4 *divi):na:num>=5 ?open+(span*(divi*4 )):na//     \
    lev5=bool?num>=6 ?open-span*(5 *divi):na:num>=6 ?open+(span*(divi*5 )):na//       Checks If candle is green or red, then if the selected # of levels is greater than or equal to the level # 
    lev6=bool?num>=7 ?open-span*(6 *divi):na:num>=7 ?open+(span*(divi*6 )):na//     /   of each line, if so then adds or subtracts the product of the float value multiplied by the  corresponding 
    lev7=bool?num>=8 ?open-span*(7 *divi):na:num>=8 ?open+(span*(divi*7 )):na//   /     level to give us another float value which is then multiplied by the actual candle body's difference, na
    lev8=bool?num>=9 ?open-span*(8 *divi):na:num>=9 ?open+(span*(divi*8 )):na////       if selected # of levels is lower
    lev9=bool?num>=10?open-span*(9 *divi):na:num>=10?open+(span*(divi*9 )):na///
    top=math.max(open,close)                                                 // \ 
                                                                             //  Actual Candle Body's Open and Close, for plotting them as steplines aswell if selected  
    bot=math.min(open,close)                                                 // /  
    [lev1,lev2,lev3,lev4,lev5,lev6,lev7,lev8,lev9,top,bot,num]
//
[lev1,lev2,lev3,lev4,lev5,lev6,lev7,lev8,lev9,top,bot,num]= sections(levels)//Now assign Variables using above function (name kept same for simplicity)

//Colors
up_col=color.new(#acfb00,transp)
dn_col=color.new(#ff0000,transp)
osccolor =osc_col   ?color.new(osc>osc[1]?up_col:dn_col,transp) :color.new(_open<_close?up_col:dn_col,transp*1)

color1   =osc_col   ?color.new(osc>osc[1]?#0CFA36:#E90606,transp*1   ) :color.new(_open<_close?#0CFA36:#E90606,transp*1   )//\
color2   =osc_col   ?color.new(osc>osc[1]?#35FA0C:#E90606,transp*1.11) :color.new(_open<_close?#35FA0C:#E90606,transp*1.11)//  \
color3   =osc_col   ?color.new(osc>osc[1]?#5DFA0C:#D90616,transp*1.22) :color.new(_open<_close?#5DFA0C:#D90616,transp*1.22)//   Colors for Candle Fills
color4   =osc_col   ?color.new(osc>osc[1]?#AFFA0C:#C90626,transp*1.33) :color.new(_open<_close?#AFFA0C:#C90626,transp*1.33)//   /

//Plots
divider1=plot(lev1,'Level 1',style=plot.style_stepline,color=color.new(color.from_gradient(lev1,_low,_high,dn_col,up_col),transp))//\
divider2=plot(lev2,'Level 2',style=plot.style_stepline,color=color.new(color.from_gradient(lev2,_low,_high,dn_col,up_col),transp))// \
divider3=plot(lev3,'Level 3',style=plot.style_stepline,color=color.new(color.from_gradient(lev3,_low,_high,dn_col,up_col),transp))//  \
divider4=plot(lev4,'Level 4',style=plot.style_stepline,color=color.new(color.from_gradient(lev4,_low,_high,dn_col,up_col),transp))//   \
divider5=plot(lev5,'Level 5',style=plot.style_stepline,color=color.new(color.from_gradient(lev5,_low,_high,dn_col,up_col),transp))//    -Plot Candle Dividers
divider6=plot(lev6,'Level 6',style=plot.style_stepline,color=color.new(color.from_gradient(lev6,_low,_high,dn_col,up_col),transp))//   /
divider7=plot(lev7,'Level 7',style=plot.style_stepline,color=color.new(color.from_gradient(lev7,_low,_high,dn_col,up_col),transp))//  /
divider8=plot(lev8,'Level 8',style=plot.style_stepline,color=color.new(color.from_gradient(lev8,_low,_high,dn_col,up_col),transp))// /
divider9=plot(lev9,'Level 9',style=plot.style_stepline,color=color.new(color.from_gradient(lev9,_low,_high,dn_col,up_col),transp))///
topplot =plot(topbot?top:na,'Top',linewidth=2,style=plot.style_stepline,color=open>close?dn_col:up_col) 
botplot =plot(topbot?bot:na,'Bottom',linewidth=2,style=plot.style_stepline,color=open>close?dn_col:up_col)
plotcandle( solidfill==false?na:_open,_high,_low,_close,color=osccolor,wickcolor=osccolor,bordercolor = osccolor)//Plot Solid Candle
plotcandle( solidfill? na :_open,_high,_low ,l1    ,'open-l1 Candle' ,color=color4   ,wickcolor=color4   ,bordercolor = color4)// \
plotcandle( solidfill? na :l1   ,_high,_low ,l2    ,'l1-l2 Candle'   ,color=color3   ,wickcolor=color3   ,bordercolor = color3)//  \
                                                                                                                               //   Plot Gradient Candles which together, produce a nicer looking 
plotcandle( solidfill? na :l2   ,_high,_low ,l3    ,'l2-l3 Candle'   ,color=color2   ,wickcolor=color2   ,bordercolor = color2)//  /  candle with the same extremeties as above
plotcandle( solidfill? na :l3   ,_high,_low ,_close,'l3-close Candle',color=color1   ,wickcolor=color1   ,bordercolor = color1)// /


//Labeling, self explanitory 

//Text for lables
string rf = osc>osc[1]?"(Rising)":"(Falling)"
var label1 = label?label.new (bar_index, _close, "", style=label.style_none):na
var label2 = label?label.new (bar_index, _close- (0.05*close), "", style=label.style_none):na


label.set_xloc(label1, time, xloc.bar_time)
label.set_xloc(label2, time, xloc.bar_time)

label.set_text(label1, text= osctype +"="+  str.tostring(math.round_to_mintick(osc))+rf)

label.set_text(label2, text= "(max = " + str.tostring(math.round(ta.max(osc))) + " min = " + str.tostring(math.round(ta.min(osc)) ) + ")")
label.set_y(label1, ta.highest(high,8))

label.set_y(label2, ta.lowest(low,8))
label.set_textcolor(label1,color1)

