CDC Fibonacci Retracement and Extension
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © piriya33
// Iteration of Kitti-Playbook Fibonacci Re-Extension 2Clicks R0.0

//@version=5
indicator("CDC Fibonacci Retracement and Extension","CDC Fib retrace/extend",
 overlay = true)

// This indicator is meant to be used as a tool to quickly identify 
// fibonacci retracements and projections in multiple charts during 
// the same date range.
// Users can set the calculation date range and quickly flip through
// different charts for comparisons
// 
// Steps for using this indicator is as follows:
// 1. Specify Start Date and End Date for calculations
// 2. Choose Open-ended mode for just retracements, this will disregard
//    end date in calculations.
// 3. Select price source, if Use Highs/Lows is selected, the indicator will
//    use high and low prices for calculation, if not, closing price eill 
//    be used instead
// 4. Select and/or modify retracement / projection lines as you see fit.
// 5. Enjoy the result!

dateSet     = "Date and Data Setup"
levels      = "Retracement Levels"
plevels     = "Projection Levels"
labels      = "Retracement Level Labels Setup"

startDate   =   input.time(timestamp("1 Jan 2014"),"Start Date",group=dateSet,
                 confirm = true)
endDate     =   input.time(timestamp("14 Nov 2021"), "End Date",inline = "end",
                 group=dateSet, confirm = true)
openEnd     =   input.bool(false,"Open ended?",inline = "end", group=dateSet)
sourceType  =   input.bool(true,"Use High/Low?",
                 inline = "toggle", group=dateSet)
labelSw     =   input.bool(true,"Show Labels",
                 inline = "toggle", group=dateSet)


// Inputs for Retracement Levels Calculations

lvl01   = input(0.236,"Retracement LV1",inline="lvl01",group=levels)
lvl02   = input(0.382,"Retracement LV2",inline="lvl02",group=levels)
lvl03   = input(0.618,"Retracement LV3",inline="lvl03",group=levels)
lvl04   = input(0.786,"Retracement LV4",inline="lvl04",group=levels)
lvl05   = input(0.887,"Retracement LV5",inline="lvl05",group=levels)
lvl06   = input(0.942,"Retracement LV6",inline="lvl06",group=levels)

lvl01sw = input.bool(false,"show",inline="lvl01",group=levels)
lvl02sw = input.bool(false,"show",inline="lvl02",group=levels)
lvl03sw = input.bool(true,"show",inline="lvl03",group=levels)
lvl04sw = input.bool(true,"show",inline="lvl04",group=levels)
lvl05sw = input.bool(true,"show",inline="lvl05",group=levels)
lvl06sw = input.bool(false,"show",inline="lvl06",group=levels)

lvl01cl = input.color(color.rgb(194, 141, 17, 50),inline="lvl01",group=levels)
lvl02cl = input.color(color.rgb(17, 194, 106, 50),inline="lvl02",group=levels)
lvl03cl = input.color(color.rgb(17, 147, 194, 50),inline="lvl03",group=levels)
lvl04cl = input.color(color.rgb(12, 86, 166, 50),inline="lvl04",group=levels)
lvl05cl = input.color(color.rgb(11, 36, 115, 50),inline="lvl05",group=levels)
lvl06cl = input.color(color.rgb(97, 13, 24, 50),inline="lvl06",group=levels)

// Inputs for projection levels calculations

plv01 = input(0.618,"Projection LV1",inline="plv01",group=plevels)
plv02 = input(0.786,"Projection LV2",inline="plv02",group=plevels)
plv03 = input(1.130,"Projection LV3",inline="plv03",group=plevels)
plv04 = input(1.618,"Projection LV4",inline="plv04",group=plevels)
plv05 = input(2.618,"Projection LV4",inline="plv05",group=plevels)
plv06 = input(4.236,"Projection LV4",inline="plv06",group=plevels)

plv01sw = input.bool(false,"show",inline="plv01",group=plevels)
plv02sw = input.bool(true,"show",inline="plv02",group=plevels)
plv03sw = input.bool(false,"show",inline="plv03",group=plevels)
plv04sw = input.bool(true,"show",inline="plv04",group=plevels)
plv05sw = input.bool(true,"show",inline="plv05",group=plevels)
plv06sw = input.bool(true,"show",inline="plv06",group=plevels)

plv01cl = input.color(color.rgb(189, 150, 0, 50),"",inline="plv01",group=plevels)
plv02cl = input.color(color.rgb(189, 120, 0, 50),"",inline="plv02",group=plevels)
plv03cl = input.color(color.rgb(189, 100, 0, 50),"",inline="plv03",group=plevels)
plv04cl = input.color(color.rgb(189, 70, 0, 50),"",inline="plv04",group=plevels)
plv05cl = input.color(color.rgb(189, 30, 0, 50),"",inline="plv05",group=plevels)
plv06cl = input.color(color.rgb(189, 0, 0, 50),"",inline="plv06",group=plevels)

strFormatSw = input.int(2,"Labels Precision",2,8, group=labels)


// Check if in calculation session
inSession   = not openEnd ? 
 time >= startDate and time <= endDate : 
 time >= startDate

// Check if session has ended, if yes, start Projection calculations
outSession = not inSession and inSession[1]

// Declare Analysis Variables

float   highSource  = sourceType ? high : close
float   lowSource   = sourceType ? low : close
float   pBase       = ta.valuewhen(outSession,lowSource,0)
float   maxINT      = 2147483647.0
var     lowestVal   = maxINT
var     highestVal  = 0.0
var     Range       = 0.0
var     pRange      = 0.0

// Check for Lowest Price from Start Date then
// Check for Highest Price from Start Sate then
// Check for Highest Price again when new low is established within Range

if inSession
    if lowSource < lowestVal
        lowestVal := lowSource
    if highSource > highestVal
        highestVal := highSource
    if lowestVal < lowestVal[1]
        highestVal := highSource
    Range := highestVal - lowestVal
    
// Calculate Retracement Levels

lvl01Line   = highestVal - Range * lvl01
lvl02Line   = highestVal - Range * lvl02
lvl03Line   = highestVal - Range * lvl03
lvl04Line   = highestVal - Range * lvl04
lvl05Line   = highestVal - Range * lvl05
lvl06Line   = highestVal - Range * lvl06

// Calculate Projection Levels

plv01Line  = pBase + Range * plv01
plv02Line  = pBase + Range * plv02
plv03Line  = pBase + Range * plv03
plv04Line  = pBase + Range * plv04
plv05Line  = pBase + Range * plv05
plv06Line  = pBase + Range * plv06

// Plot Levels

boundColor   = color.gray
lowestBound  = plot(inSession ? lowestVal : na,"Highest Value",boundColor)
highestBound = plot(inSession ? highestVal : na,"Lowest Value",boundColor)

lowSourceP = plot(lowSource,"Current low price source",display=display.none)
highSourceP = plot(highSource,"Current high price source",display=display.none)
lvlp01 = plot(inSession ? lvl01sw ? lvl01Line : na : na,"lvl01",lvl01cl)
lvlp02 = plot(inSession ? lvl02sw ? lvl02Line : na : na,"lvl02",lvl02cl)
lvlp03 = plot(inSession ? lvl03sw ? lvl03Line : na : na,"lvl03",lvl03cl)
lvlp04 = plot(inSession ? lvl04sw ? lvl04Line : na : na,"lvl04",lvl04cl)
lvlp05 = plot(inSession ? lvl05sw ? lvl05Line : na : na,"lvl05",lvl05cl)
lvlp06 = plot(inSession ? lvl06sw ? lvl06Line : na : na,"lvl06",lvl06cl)

plvpbase=   plot(plv01sw or plv02sw or plv03sw or plv04sw ? pBase : na,
             "Projection Base", color.gray)
plvp00  =   plot(plv01sw or plv02sw or plv03sw or plv04sw ? pBase + Range : na,
             "Projection 100%", color.gray)

plvp01 = plot(plv01sw ? plv01Line : na,"Projection 01",plv01cl)
plvp02 = plot(plv02sw ? plv02Line : na,"Projection 02",plv02cl)
plvp03 = plot(plv03sw ? plv03Line : na,"Projection 03",plv03cl)
plvp04 = plot(plv04sw ? plv04Line : na,"Projection 04",plv04cl)
plvp05 = plot(plv05sw ? plv05Line : na,"Projection 05",plv05cl)
plvp06 = plot(plv06sw ? plv06Line : na,"Projection 06",plv06cl)

fillColor01 = lvl01sw ? lowSource < lvl01Line ? color.new(lvl01cl,80) : na : na
fillColor02 = lvl02sw ? lowSource < lvl02Line ? color.new(lvl02cl,80) : na : na
fillColor03 = lvl03sw ? lowSource < lvl03Line ? color.new(lvl03cl,50) : na : na
fillColor04 = lvl04sw ? lowSource < lvl04Line ? color.new(lvl04cl,50) : na : na
fillColor05 = lvl05sw ? lowSource < lvl05Line ? color.new(lvl05cl,50) : na : na
fillColor06 = lvl06sw ? lowSource < lvl06Line ? color.new(lvl06cl,80) : na : na

fillColorP1 = plv01sw ? highSource > plv01Line ? color.new(plv01cl,85): na : na
fillColorP2 = plv02sw ? highSource > plv02Line ? color.new(plv02cl,85): na : na
fillColorP3 = plv03sw ? highSource > plv03Line ? color.new(plv03cl,70): na : na
fillColorP4 = plv04sw ? highSource > plv04Line ? color.new(plv04cl,60): na : na
fillColorP5 = plv05sw ? highSource > plv05Line ? color.new(plv05cl,50): na : na
fillColorP6 = plv06sw ? highSource > plv06Line ? color.new(plv06cl,40): na : na

fill(lowSourceP,lvlp01,fillColor01)
fill(lowSourceP,lvlp02,fillColor02)
fill(lowSourceP,lvlp03,fillColor03)
fill(lowSourceP,lvlp04,fillColor04)
fill(lowSourceP,lvlp05,fillColor05)
fill(lowSourceP,lvlp06,fillColor06)

fill(highSourceP,plvp01,fillColorP1)
fill(highSourceP,plvp02,fillColorP2)
fill(highSourceP,plvp03,fillColorP3)
fill(highSourceP,plvp04,fillColorP4)
fill(highSourceP,plvp05,fillColorP5)
fill(highSourceP,plvp06,fillColorP6)

// Labels
// Labels displays levels and price on each retracement / projection lines

strFormat = strFormatSw == 2 ? "{0,number,#.##}" :
 strFormatSw == 3 ? "{0,number,#.###}" :
 strFormatSw == 4 ? "{0,number,#.####}" :
 strFormatSw == 5 ? "{0,number,#.#####}" :
 strFormatSw == 6 ? "{0,number,#.######}" :
 strFormatSw == 7 ? "{0,number,#.#######}" :
 strFormatSw == 8 ? "{0,number,#.########}" : na

labelTopText = "High : " +str.format(strFormat,highestVal)
labelBotText = "Low : " +str.format(strFormat,lowestVal)

// Define Text for retracement levels

labelLVL01Text = str.tostring(lvl01*100)+"% : "+str.format(strFormat,lvl01Line)
labelLVL02Text = str.tostring(lvl02*100)+"% : "+str.format(strFormat,lvl02Line)
labelLVL03Text = str.tostring(lvl03*100)+"% : "+str.format(strFormat,lvl03Line)
labelLVL04Text = str.tostring(lvl04*100)+"% : "+str.format(strFormat,lvl04Line)
labelLVL05Text = str.tostring(lvl05*100)+"% : "+str.format(strFormat,lvl05Line)
labelLVL06Text = str.tostring(lvl06*100)+"% : "+str.format(strFormat,lvl06Line)

// Define text for projection levels

labelPLV01Text =    "projection "+str.tostring(plv01*100)+"% : "+
                     str.format(strFormat,plv01Line)
labelPLV02Text =    "projection "+str.tostring(plv02*100)+"% : "+
                     str.format(strFormat,plv02Line)
labelPLV03Text =    "projection "+str.tostring(plv03*100)+"% : "+
                     str.format(strFormat,plv03Line)
labelPLV04Text =    "projection "+str.tostring(plv04*100)+"% : "+
                     str.format(strFormat,plv04Line)
labelPLV05Text =    "projection "+str.tostring(plv05*100)+"% : "+
                     str.format(strFormat,plv05Line)
labelPLV06Text =    "projection "+str.tostring(plv06*100)+"% : "+
                     str.format(strFormat,plv06Line)

// Create Labels

x_time = openEnd ? time : endDate

labelTop =  label.new(x = x_time, y = highestVal, text=labelTopText, 
             xloc=xloc.bar_time, style = label.style_none)
label.delete(labelSw ? labelTop[1] : labelTop)

labelLV1 =  label.new(x = x_time, y = lvl01Line, text=labelLVL01Text, 
             xloc=xloc.bar_time, style = label.style_none)
label.delete(labelSw and lvl01sw ? labelLV1[1] : labelLV1)

labelLV2 =  label.new(x = x_time, y = lvl02Line, text=labelLVL02Text, 
             xloc=xloc.bar_time, style = label.style_none)
label.delete(labelSw and lvl02sw ? labelLV2[1] : labelLV2)

labelLV3 =  label.new(x = x_time, y = lvl03Line, text=labelLVL03Text, 
             xloc=xloc.bar_time, style = label.style_none)
label.delete(labelSw and lvl03sw ? labelLV3[1] : labelLV3)

labelLV4 =  label.new(x = x_time, y = lvl04Line, text=labelLVL04Text, 
             xloc=xloc.bar_time, style = label.style_none)
label.delete(labelSw and lvl04sw ? labelLV4[1] : labelLV4)

labelLV5 =  label.new(x = x_time, y = lvl05Line, text=labelLVL05Text, 
             xloc=xloc.bar_time, style = label.style_none)
label.delete(labelSw and lvl05sw ? labelLV5[1] : labelLV5)

labelLV6 =  label.new(x = x_time, y = lvl06Line, text=labelLVL06Text, 
             xloc=xloc.bar_time, style = label.style_none)
label.delete(labelSw and lvl06sw ? labelLV6[1] : labelLV6)

labelBot =  label.new(x = x_time, y = lowestVal, text=labelBotText, 
             xloc=xloc.bar_time, style = label.style_none)
label.delete(labelSw ? labelBot[1] : labelBot)

labelPL1 =  label.new(x = time, y = plv01Line, text=labelPLV01Text, 
             xloc=xloc.bar_time, style = label.style_none)
label.delete(labelSw and not openEnd and plv01sw ? labelPL1[1] : labelPL1)

labelPL2 =  label.new(x = time, y = plv02Line, text=labelPLV02Text, 
             xloc=xloc.bar_time, style = label.style_none)
label.delete(labelSw and not openEnd and plv02sw ? labelPL2[1] : labelPL2)

labelPL3 =  label.new(x = time, y = plv03Line, text=labelPLV03Text, 
             xloc=xloc.bar_time, style = label.style_none)
label.delete(labelSw and not openEnd and plv03sw ? labelPL3[1] : labelPL3)

labelPL4 =  label.new(x = time, y = plv04Line, text=labelPLV04Text, 
             xloc=xloc.bar_time, style = label.style_none)
label.delete(labelSw and not openEnd and plv04sw ? labelPL4[1] : labelPL4)

labelPL5 =  label.new(x = time, y = plv05Line, text=labelPLV05Text, 
             xloc=xloc.bar_time, style = label.style_none)
label.delete(labelSw and not openEnd and plv05sw ? labelPL5[1] : labelPL5)

labelPL6 =  label.new(x = time, y = plv06Line, text=labelPLV06Text, 
             xloc=xloc.bar_time, style = label.style_none)
label.delete(labelSw and not openEnd and plv06sw ? labelPL6[1] : labelPL6)

// END //
