Indicator · Pine Script v5 · On the chart

Visible Fibonacci

by ivansoft· code credited to TradingView

An indicator that draws Fibonacci retracement levels on the price chart for the part of the chart currently in view.

View on GitHub

Repaints

GitHub stars1on the repository
Pine versionv5runs as is
Lines of code574
Settings40inputs
LicenceNone statedfile: MPL-2.0
Last update1 year ago1 Mar 2025

Add It to Your TradingView Chart

  1. 1Copy the scriptPress Copy script above, or the copy button on the code below.
  2. 2Open the Pine EditorOpen a TradingView chart and choose Pine Editor at the bottom of the screen.
  3. 3Paste over the templateCreate a new indicator, select all of the template text and paste. Press Save and give it a name.
  4. 4Add it to the chartPress Add to chart, then adjust the settings with the gear icon next to its name.

Source Code

574 lines of Pine Script v5 from edu_std/visible_fibo.pine, published under MPL-2.0 (file header). Keep the author's credit and licence lines when you reuse it.

visible_fibo.pine
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © TradingView

//@version=5
indicator("Visible Fibonacci", "Visible Fib", true, max_lines_count = 500)

// Visible Fibonacci
// v1, 2023.01.01 

// This code was written using the recommendations from the Pine Script™ User Manual's Style Guide:
//   https://www.tradingview.com/pine-script-docs/en/v5/writing/Style_guide.html



import PineCoders/VisibleChart/4 as chart



//#region ———————————————————— Constants and Inputs


// ————— Constants

// Colors 
color GRAY    = color.gray
color RED     = color.red
color ORANGE  = color.orange
color TEAL    = color.teal
color RUBY    = #e91e63
color AQUA    = color.aqua
color BLUE    = color.blue
color GREEN   = color.green
color PURPLE  = color.purple
color LIME    = color.lime
color FUCHSIA = color.fuchsia

// Line Type 
string TY01 = " ─ Line"
string TY02 = " ┄ Dashed line"
string TY03 = " ┉ Dotted line"

// Fib level type
string LV01  = "Values" 
string LV02  = "Percent" 

// Fib calculation type
string FT01  = "Visible Chart Range" 
string FT02  = "Visible Zig Zag"

// Label placement 
string LB01  = "Left"
string LB02  = "Center"
string LB03  = "Right"
string LB04  = "Top"
string LB05  = "Middle"
string LB06  = "Bottom"

// Label Size
string SZ01  = "tiny"
string SZ02  = "small"
string SZ03  = "normal"
string SZ04  = "large"
string SZ05  = "huge"

// Tool Tips 
string TT_FT = "Choose from 2 calculation types:
 \n\n• 'Visible Chart Range' \nCalculates the Fibonacci retracement based on the high and low of the visible chart range.
 \n\n• 'Visible Zig Zag' \nCalculates the Fibonacci retracement based on zig zag pivots within the visible chart range."
string TT_ZZ = "Show Zig Zag lines when the 'Visible Zig Zag' display type is enabled."
string TT_MP = "When enabled, adds a pivot in the opposite direction if a new pivot is not found in the number of bars in the 'Pivot Length'."
string TT_PL = "Number of bars back to track pivots (ex. Highest point in 50 bars)."
string TT_ZA = "Your choices here dictate the Zig Zag line color, line width, and line style."
string TT_LP = "Places the fib retracement on the nth pivot point back from the last visible pivot."

// Inputs
string fibTypeInput      = input.string(FT01,  "Fib Calculation Type",      options = [FT01, FT02],      tooltip = TT_FT)

string GRP1              = "Visible ZigZag"
bool   showZZInput       = input.bool(true,    "Show Zig Zag",              group = GRP1, inline = "00", tooltip = TT_ZZ)
bool   addPivotInput     = input.bool(true,    "Detect additional pivots",  group = GRP1, inline = "01", tooltip = TT_MP)
int    lengthInput       = input.int(50,       "   Pivot Length",           group = GRP1, minval = 1,    tooltip = TT_PL)
color  zzBullColorInput  = input.color(GRAY,   "   ",                       group = GRP1, inline = "02")
color  zzBearColorInput  = input.color(GRAY,   "",                          group = GRP1, inline = "02")
int    zzwidthInput      = input.int(2,        "",                          group = GRP1, inline = "02", minval  = 1)
string zzStyleInput      = input.string(TY01,  "",                          group = GRP1, inline = "02", tooltip = TT_ZA, options = [TY01, TY02, TY03])
int    pivotInput        = input.int(1,        "   nth Last Pivot",         group = GRP1, minval = 0,    tooltip = TT_LP)

string GRP2              = "Fib Levels"
bool   extendRtInput     = input.bool(true,    "Extend to real time",       group = GRP2)
bool   extendRightInput  = input.bool(false,   "Extend lines right",        group = GRP2)
bool   extendLeftInput   = input.bool(false,   "Extend lines left",         group = GRP2)
bool   trendLineInput    = input.bool(true,    "Trend Line",                group = GRP2, inline = "10")
color  trendColorInput   = input.color(GRAY,   "",                          group = GRP2, inline = "10")
int    trendWidthInput   = input.int(1,        "",                          group = GRP2, inline = "10", minval  = 1)
string trendStyleInput   = input.string(TY02,  "",                          group = GRP2, inline = "10", options = [TY01, TY02, TY03])
int    levelsWidthInput  = input.int(1,        "Levels Line",               group = GRP2, inline = "11", minval  = 1)
string fibStyleInput     = input.string(TY01,  "",                          group = GRP2, inline = "11", options = [TY01, TY02, TY03])
string extStyleInput     = input.string(TY03,  "",                          group = GRP2, inline = "11", options = [TY01, TY02, TY03])
bool   show000Input      = input.bool(true,    "",                          group = GRP2, inline = "20")
float  level000Input     = input.float(0,      "",                          group = GRP2, inline = "20") 
color  color000Input     = input.color(GRAY,   "",                          group = GRP2, inline = "20")
bool   show236Input      = input.bool(true,    "",                          group = GRP2, inline = "20")
float  level236Input     = input.float(0.236,  "",                          group = GRP2, inline = "20") 
color  color236Input     = input.color(RED,    "",                          group = GRP2, inline = "20")
bool   show382Input      = input.bool(true,    "",                          group = GRP2, inline = "21")
float  level382Input     = input.float(0.382,  "",                          group = GRP2, inline = "21") 
color  color382Input     = input.color(ORANGE, "",                          group = GRP2, inline = "21")
bool   show500Input      = input.bool(true,    "",                          group = GRP2, inline = "21")
float  level500Input     = input.float(0.5,    "",                          group = GRP2, inline = "21") 
color  color500Input     = input.color(GREEN,  "",                          group = GRP2, inline = "21")
bool   show618Input      = input.bool(true,    "",                          group = GRP2, inline = "22")
float  level618Input     = input.float(0.618,  "",                          group = GRP2, inline = "22") 
color  color618Input     = input.color(TEAL,   "",                          group = GRP2, inline = "22")
bool   show786Input      = input.bool(true,    "",                          group = GRP2, inline = "22")
float  level786Input     = input.float(0.786,  "",                          group = GRP2, inline = "22") 
color  color786Input     = input.color(AQUA,   "",                          group = GRP2, inline = "22")
bool   show100Input      = input.bool(true,    "",                          group = GRP2, inline = "23")
float  level100Input     = input.float(1,      "",                          group = GRP2, inline = "23") 
color  color100Input     = input.color(GRAY,   "",                          group = GRP2, inline = "23")
bool   show161Input      = input.bool(true,    "",                          group = GRP2, inline = "23")
float  level161Input     = input.float(1.618,  "",                          group = GRP2, inline = "23") 
color  color161Input     = input.color(BLUE,   "",                          group = GRP2, inline = "23")
bool   show261Input      = input.bool(true,    "",                          group = GRP2, inline = "24")
float  level261Input     = input.float(2.618,  "",                          group = GRP2, inline = "24") 
color  color261Input     = input.color(RED,    "",                          group = GRP2, inline = "24")
bool   show361Input      = input.bool(true,    "",                          group = GRP2, inline = "24")
float  level361Input     = input.float(3.618,  "",                          group = GRP2, inline = "24") 
color  color361Input     = input.color(PURPLE, "",                          group = GRP2, inline = "24")
bool   show423Input      = input.bool(true,    "",                          group = GRP2, inline = "25")
float  level423Input     = input.float(4.236,  "",                          group = GRP2, inline = "25") 
color  color423Input     = input.color(RUBY,   "",                          group = GRP2, inline = "25")
bool   show127Input      = input.bool(false,   "",                          group = GRP2, inline = "25")
float  level127Input     = input.float(1.272,  "",                          group = GRP2, inline = "25") 
color  color127Input     = input.color(ORANGE, "",                          group = GRP2, inline = "25")
bool   show141Input      = input.bool(false,   "",                          group = GRP2, inline = "26")
float  level141Input     = input.float(1.414,  "",                          group = GRP2, inline = "26") 
color  color141Input     = input.color(RED,    "",                          group = GRP2, inline = "26")
bool   show227Input      = input.bool(false,   "",                          group = GRP2, inline = "26")
float  level227Input     = input.float(2.272,  "",                          group = GRP2, inline = "26") 
color  color227Input     = input.color(ORANGE, "",                          group = GRP2, inline = "26")
bool   show241Input      = input.bool(false,   "",                          group = GRP2, inline = "27")
float  level241Input     = input.float(2.414,  "",                          group = GRP2, inline = "27") 
color  color241Input     = input.color(GREEN,  "",                          group = GRP2, inline = "27")
bool   show200Input      = input.bool(false,   "",                          group = GRP2, inline = "27")
float  level200Input     = input.float(2,      "",                          group = GRP2, inline = "27") 
color  color200Input     = input.color(TEAL,   "",                          group = GRP2, inline = "27")
bool   show300Input      = input.bool(false,   "",                          group = GRP2, inline = "28")
float  level300Input     = input.float(3,      "",                          group = GRP2, inline = "28") 
color  color300Input     = input.color(AQUA,   "",                          group = GRP2, inline = "28")
bool   show327Input      = input.bool(false,   "",                          group = GRP2, inline = "28")
float  level327Input     = input.float(3.272,  "",                          group = GRP2, inline = "28") 
color  color327Input     = input.color(GRAY,   "",                          group = GRP2, inline = "28")
bool   show341Input      = input.bool(false,   "",                          group = GRP2, inline = "29")
float  level341Input     = input.float(3.414,  "",                          group = GRP2, inline = "29") 
color  color341Input     = input.color(BLUE,   "",                          group = GRP2, inline = "29")
bool   show400Input      = input.bool(false,   "",                          group = GRP2, inline = "29")
float  level400Input     = input.float(4,      "",                          group = GRP2, inline = "29") 
color  color400Input     = input.color(RED,    "",                          group = GRP2, inline = "29")
bool   show427Input      = input.bool(false,   "",                          group = GRP2, inline = "30")
float  level427Input     = input.float(4.272,  "",                          group = GRP2, inline = "30") 
color  color427Input     = input.color(PURPLE, "",                          group = GRP2, inline = "30")
bool   show441Input      = input.bool(false,   "",                          group = GRP2, inline = "30")
float  level441Input     = input.float(4.414,  "",                          group = GRP2, inline = "30") 
color  color441Input     = input.color(RUBY,   "",                          group = GRP2, inline = "30")
bool   show461Input      = input.bool(false,   "",                          group = GRP2, inline = "31")
float  level461Input     = input.float(4.618,  "",                          group = GRP2, inline = "31") 
color  color461Input     = input.color(ORANGE, "",                          group = GRP2, inline = "31")
bool   show476Input      = input.bool(false,   "",                          group = GRP2, inline = "31")
float  level476Input     = input.float(4.764,  "",                          group = GRP2, inline = "31") 
color  color476Input     = input.color(TEAL,   "",                          group = GRP2, inline = "31")
bool   useFillInput      = input.bool(true,    "Background",                group = GRP2, inline = "32")
int    bgTranspInput     = input.int(90,       "",                          group = GRP2, inline = "32")
bool   invertFibInput    = input.bool(false,   "Reverse",                   group = GRP2)
bool   useLogScaleInput  = input.bool(false,   "Log scale Fibs",            group = GRP2)

string GRP3              = "Labels"
bool   showPricesInput   = input.bool(true,    "Prices",                    group = GRP3)
bool   showLevelsInput   = input.bool(true,    "Levels",                    group = GRP3, inline = "40")
string levelTypeInput    = input.string(LV01,  "",                          group = GRP3, inline = "40", options = [LV01, LV02])
string labelXInput       = input.string(LB01,  "Fib Labels",                group = GRP3, inline = "41", options = [LB01, LB02, LB03])
string labelYInput       = input.string(LB04,  "",                          group = GRP3, inline = "41", options = [LB04, LB05, LB06])
string labelSizeInput    = input.string(SZ03,  "",                          group = GRP3, inline = "41", options = [SZ01, SZ02, SZ03, SZ04, SZ05])
bool   tLabelsInput      = input.bool(true,    "Time Labels",               group = GRP3, inline = "42")
string tLabelSizeInput   = input.string(SZ03,  "",                          group = GRP3, inline = "42", options = [SZ01, SZ02, SZ03, SZ04, SZ05])
//#endregion



//#region ———————————————————— User-defined Types


// @type                A coordinate in price and time.   
// @field y             A value on the Y axis (price).     
// @field x             A value on the X axis (time). 
type point 
    float y
    int   x 


// @type                A level of significance used to determine directional movement or potential support and resistance.
// @field start         The coordinate of the previous `pivotPoint`.
// @field end           The coordinate of the current `pivotPoint`.
// @field dir           Direction of movement of the `pivotPoint`. A value of 1 is used for an upward direction, -1 for downward. 
// @field ln            A line object connecting the `start` to the `end`. 
// @field bars          Number of bars in the pivot. Default is 0 bars. 
type pivotPoint
    point start
    point end
    int   dir
    line  ln
    int   bars = 0


// @type                Horizontal levels that indicate possible support and resistance where price could potentially reverse direction.
// @field level         A Fibonacci ratio as a decimal. 
// @field fibColor      A color for the lines and labels.
// @field fibLine       A line object for the main fib level. 
// @field extLine       A line object for the fib level that is extended from the last pivot to the last bar. 
// @field fibLabel      A label to display the `level` at the `fibLine`.
type fibLevel
    float level
    color fibColor
    line  fibLine
    line  extLine 
    label fibLabel
//#endregion



//#region ———————————————————— Global Variables

// Arrays for lines, labels, and colors. 
var array<float>    levels      = array.new<float>()
var array<fibLevel> fibLevels   = array.new<fibLevel>()
var array<int>      sortedArray = array.new<int>()

// Set line extension type.
string extendExt = extendRightInput ? extend.right : extend.none
string extendFib = switch
    not extendRtInput and extendLeftInput and extendRightInput => extend.both 
    not extendRtInput and extendRightInput => extend.right
    extendLeftInput => extend.left 
    => extend.none

// Label display conditions.
bool   showLabels  = showPricesInput or showLevelsInput
bool   showPercent = levelTypeInput == LV02
string labelStyle  = switch 
    labelYInput == LB04 and labelXInput == LB01 => label.style_label_lower_right
    labelYInput == LB05 and labelXInput == LB01 => label.style_label_right
    labelYInput == LB06 and labelXInput == LB01 => label.style_label_upper_right
    labelYInput == LB04 and labelXInput == LB02 => label.style_label_down
    labelYInput == LB05 and labelXInput == LB02 => label.style_label_center
    labelYInput == LB06 and labelXInput == LB02 => label.style_label_up
    labelYInput == LB04 and labelXInput == LB03 => label.style_label_lower_left 
    labelYInput == LB05 and labelXInput == LB03 => label.style_label_left 
    labelYInput == LB06 and labelXInput == LB03 => label.style_label_upper_left 

// Determine display type. 
bool useZigZag = fibTypeInput == FT02
//#endregion



//#region ———————————————————— Functions 


// @function            Converts a value from exponential to logarithmic form.
// @param value         (series float) The value to convert to log. 
// @returns             (float) The log value. 
toLog(series float value) =>
    float exponent = math.abs(value)
    float product  = math.log10(exponent + 0.0001) + 4
    float result   = exponent < 1e-8 ? 0 : value < 0 ? - product : product
    

// @function            Converts a value from logarithmic to exponential form.
// @param value         (series float) The value to convert from log.
// @returns             (float) The exponential value. 
fromLog(series float value) =>
    float exponent = math.abs(value)
    float product  = math.pow(10, exponent - 4) - 0.0001
    float result   = exponent < 1e-8 ? 0 : value < 0 ? - product : product


// @function            Determines a fib price based on the chart's high and low price dependant on if the fib retracement is bullish or bearish. Converts to log scale when dictated by user-selection.  
// @param value         (series float) Fib level in decimal form. 
// @param hiPrice       (series float) Retracement high. 
// @param loPrice       (series float) Retracement low. 
// @param isBull        (series bool) Condition determining if the retracement is bullish. 
// @returns             (float) The fib price. 
getPrice(series float value, series float hiPrice, series float loPrice, series bool isBull) =>
    float hiPoint  = useLogScaleInput ? toLog(hiPrice) : hiPrice
    float loPoint  = useLogScaleInput ? toLog(loPrice) : loPrice
    float fibPrice = 
     isBull and invertFibInput or not isBull and not invertFibInput ? 
     loPoint + ((hiPoint - loPoint) * value) : 
     hiPoint - ((hiPoint - loPoint) * value)
    float result = useLogScaleInput ? fromLog(fibPrice) : fibPrice


// @function            Determines a line style based on a user defined input string matching one of the `TY*` constants. 
// @param styleString   (series string) Input string. 
// @returns             (string) A string in `line.style*` format. 
lineStyle(simple string styleString) =>
    string result = switch styleString
        TY01 => line.style_solid
        TY02 => line.style_dashed
        TY03 => line.style_dotted


// @function            Populates global arrays with a `fibLevel` object and fib value when the corresponding input condition is selected. 
// @param condition     (simple bool) Condition to determine if the fib level is to be displayed. 
// @param value         (simple float) Value of the user-defined fib level. 
// @param color         (series color) Color for the fib line and label. 
// @returns             (void) Function has no return.  
populate(simple bool condition, simple float value, series color color) => 
    if condition
        fibLevel fib = fibLevel.new(value, color)
        fib.fibLine      := line.new(na, na, na, na, xloc.bar_time, extendFib, color, lineStyle(fibStyleInput), levelsWidthInput)
        if extendRtInput
            fib.extLine  := line.new(na, na, na, na, xloc.bar_time, extendExt, color, lineStyle(extStyleInput), levelsWidthInput)
        if showLabels
            fib.fibLabel := label.new(na, na, "",    xloc.bar_time, yloc.price, color(na), labelStyle, color, labelSizeInput)
        array.push(levels, value)
        array.push(fibLevels, fib)


// @function            Sets a linefill object between each fibLevel object. 
// @returns             (void) Function has no return. 
setBg() =>
    line temp1 = na
    line temp2 = na
    for sortedIndex in sortedArray
        fibLevel fib = array.get(fibLevels, sortedIndex)
        color fillColor = color.new(fib.fibColor, bgTranspInput)
        if not na(temp1)
            linefill.new(temp1, fib.fibLine, fillColor)
            if extendRtInput
                linefill.new(temp2, fib.extLine, fillColor)
        temp1 := fib.fibLine
        temp2 := fib.extLine


// @function            Determines a string for use within a fib label. The text will contain the fib price/percent and/or the fib level dependant on user selections for "Prices" and "Levels".
// @param value         (series float) The fib level from one of the `level*Input` user selections. 
// @param price         (series float) The corresponding price level for the fib level. 
// @returns             (string) A string containing the fib `value` and/or the fib `price`. 
labelText(series float value, series float price) =>
    string levelString = showPercent ? str.tostring(value * 100, format.percent) : str.format("{0, number, #.###}", value)
    string result = switch 
        showPricesInput and showLevelsInput => str.format("{0}({1})", levelString, str.tostring(price, format.mintick))
        showPricesInput                     => str.format("({0})", str.tostring(price, format.mintick))
        showLevelsInput                     => levelString


// @function            Determines a X time coordinate in UNIX time for fib labels dependant on the user's location selection of "Labels", and the `LB*` constants. 
// @returns             (int) A time for fib labels. 
labelTime(series int leftTime, series int rightTime) =>
    int result = switch labelXInput
        LB01 => leftTime
        LB02 => int(math.avg(leftTime, extendRtInput ? chart.right_visible_bar_time : rightTime))
        LB03 => extendRtInput ? chart.right_visible_bar_time : rightTime


// @function            Produces a label with the formatted time and price for the point it is placed. Continues to update the location and text on each bar. 
// @param x             (series int) Bar UNIX time of the label position. 
// @param y             (series float) Price of the label position.
// @param color         (simple color) Color for the text and label.  
// @param style         (series string) Label style. Accepts one of the `label.style_*` built-in constants. 
// @returns             (void) Function has no return. 
timeLabel(series int x, series float y, simple color color, series string style) =>
    var label timeLabel = label.new(na, na, na, xloc.bar_time, yloc.price, color.new(color, 80), style, color, tLabelSizeInput)
    label.set_xy(timeLabel, x, y)
    label.set_text(timeLabel, str.format("{0}\n{1,time, dd/MM/yy @ HH:mm:ss}", str.tostring(y, format.mintick), x))


// @function            Produces a line object that sets it's bar time and price on each bar.
// @param x1            (series int) bar UNIX time of the first point of the line.
// @param y1            (series float) Price of the first point of the line.
// @param x2            (series int) bar UNIX time of the second point of the line.
// @param y2            (series float) Price of the second point of the line.
// @returns             (void) Function has no return. 
hiLoLine(series int x1, series float y1, series int x2, series float y2) =>
    var line hiLoLine = line.new(na, na, na, na, xloc.bar_time, extend.none, trendColorInput, lineStyle(trendStyleInput), trendWidthInput)
    line.set_xy1(hiLoLine, x1, y1)
    line.set_xy2(hiLoLine, x2, y2)


// @function            Updates price and time of `fibLevel`s and label text. 
// @param leftTime      (series int) bar UNIX time of the first point of the fib retracement.
// @param rightTime     (series int) bar UNIX time of the second point of the fib retracement.
// @param hiPrice       (series float) Price of the high point of the fib retracement.
// @param loPrice       (series float) Price of the low point of the fib retracement.
// @param isBull        (series bool) Condition to determine if the retracement is bullish. 
// @returns             (void) Function has no return. 
setLevels(series int leftTime, series int rightTime, series float hiPrice, series float loPrice, series bool isBull) =>
    int labelTime = labelTime(leftTime, rightTime)
    for fib in fibLevels
        float fibPrice = getPrice(fib.level, hiPrice, loPrice, isBull)
        line.set_xy1(fib.fibLine, leftTime,  fibPrice)
        line.set_xy2(fib.fibLine, rightTime, fibPrice)
        if extendRtInput
            line.set_xy1(fib.extLine, rightTime, fibPrice)
            line.set_xy2(fib.extLine, chart.right_visible_bar_time, fibPrice)
        if showLabels
            label.set_xy(fib.fibLabel, labelTime, fibPrice)
            label.set_text(fib.fibLabel, labelText(fib.level, fibPrice))


// @function            Adds a `value` to the begining of the `id` array, while removing from the end of the array if the array size exceeds the `max` size. 
// @param id            (any array type) An array object.
// @param max           (simple int) The maximum size of the array. 
// @param value         (series <type of the array's elements>) The value to add to the start of the array.
// @returns             (void) Function has no return. 
addToArray(id, simple int max, value) =>  
    array.unshift(id, value)   
    if array.size(id) > max
        array.pop(id)


// @function            Creates and adds a new "pivotPoint" object to the `pivotArray` when a change in `dir` is detected. Sets a line between the new and previous pivot points when "show zigzag" is enabled.             
// @param length        (simple int) Number of bars to search for a "pivotPoint".
// @param pivotArray    (array<pivotPoint>) An array of "pivotPoints". 
// @param addPivots     (simple bool) Condition to search for additonal pivots, Adds a pivot in the opposite direction if a pivot is not found in `length` bars. Default is true. 
// @returns             (void) Function has no return.     
addPivot(simple int length, array<pivotPoint> pivotArray, simple bool addPivots = true) =>
    pivotPoint piv  = array.get(pivotArray, 0)
    int   altLen    = math.max(piv.bars, 1)
    int   hiBar     = ta.highestbars(length)
    int   loBar     = ta.lowestbars(length)
    int   altHiBar  = ta.highestbars(altLen)
    int   altLoBar  = ta.lowestbars(altLen)
    float altHi     = ta.highest(altLen)
    float altLo     = ta.lowest(altLen)
    bool  missedPiv = piv.bars >= length and addPivots and not (hiBar == 0 and high > piv.end.y or loBar == 0 and low < piv.end.y) 
    var int dir = na
    dir := switch
        missedPiv => nz(dir, altHiBar < altLoBar ? 1 : -1) * -1
        hiBar + loBar == 0 => dir * -1 
        hiBar == 0 =>  1 
        loBar == 0 => -1 
        => dir
    if dir != dir[1] and time <= chart.right_visible_bar_time
        [hiLo, altHiLo, offset, lineColor] = switch
            dir > 0 => [high, altHi, altHiBar, zzBullColorInput] 
            =>         [low,  altLo, altLoBar, zzBearColorInput] 
        [pivY, bars] = switch
            missedPiv => [altHiLo, math.abs(offset)]
            =>           [hiLo, 0]
        point newPoint   = point.new(pivY, time[bars])
        pivotPoint pivot = pivotPoint.new(piv.end, newPoint, dir, bars = bars) 
        if showZZInput and time >= chart.left_visible_bar_time
            pivot.ln := line.new(piv.end.x, piv.end.y, time[bars], pivY, 
              xloc.bar_time, extend.none, lineColor, lineStyle(zzStyleInput), zzwidthInput)
        addToArray(pivotArray, math.max(3, pivotInput + 1), pivot)


// @function            Updates the price and time of the developing "pivotPoint" if the latest calculated "point" exceeds the last committed value.
// @param length        (simple int) Number of bars to search for a "pivotPoint".
// @param pivotArray    (array<pivotPoint>) An array of "pivotPoints". 
// @returns             (void) Function has no return. 
updatePivot(simple int length, array<pivotPoint> pivotArray) =>
    if time <= chart.right_visible_bar_time
        pivotPoint piv = array.get(pivotArray, 0)
        int   dir  = piv.dir 
        float hiLo = dir > 0 ? high : low
        piv.bars  += 1
        if hiLo * dir > piv.end.y * dir 
            piv.end.y := hiLo
            piv.end.x := time
            piv.bars  := 0
            if showZZInput and time >= chart.left_visible_bar_time
                if na(piv.ln) 
                    color lineColor = dir > 0 ? zzBullColorInput : zzBearColorInput
                    piv.ln := line.new(piv.start.x, piv.start.y, time, hiLo, 
                     xloc.bar_time, extend.none, lineColor, lineStyle(zzStyleInput), zzwidthInput)
            line.set_xy2(piv.ln, time, hiLo)


// @function            Calculates Zig Zag based on pivots formed over the lookback `length`. 
// @param length        (simple int) Number of bars to search for a "pivotPoint".
// @param addPivots     (simple bool) Condition to search for additonal pivots, Adds a pivot in the opposite direction if a pivot is not found in `length` bars. Default is true. 
// @returns             (array<pivotPoint>) An array of "pivotPoint" objects.      
zigZag(simple int length, simple bool addPivots = true) =>
    var array<pivotPoint> pivots = array.new<pivotPoint>(1, pivotPoint.new(point.new(close), point.new(close)))
    updatePivot(length, pivots)
    addPivot(length, pivots, addPivots)
    pivots


// @function            Renders a start "point" and end "point" for the `nthPivot` back in the visible range when "Use zig zag" is enabled, and returns the 2 coordinates as a tuple. 
// @param nthPivot      (simple int) The nth pivot. 
// @returns             ([int, float, int, float]) The start point time, the start point price, the end point time, the end point price. 
findHiLo(simple int nthPivot) => 
    int   leftX  = na  
    float leftY  = na  
    int   rightX = na  
    float rightY = na  
    if useZigZag
        array<pivotPoint> pivotArray = zigZag(lengthInput, addPivotInput)
        if barstate.islast 
            pivotPoint pivot = array.get(pivotArray, nthPivot)
            leftX  := pivot.start.x  
            leftY  := pivot.start.y  
            rightX := pivot.end.x
            rightY := pivot.end.y
            if showZZInput
                line.set_style(pivot.ln, lineStyle(trendStyleInput))
    [leftX, leftY, rightX, rightY]
//#endregion



//#region ———————————————————— Calculations 


// Determine pivot points when "use zig zag" is enabled. 
[leftX, leftY, rightX, rightY] = findHiLo(pivotInput)


// Fib high and low values and their time x-coordinate. 
bool  zzBull    = leftY < rightY
float chartHigh = useZigZag ? math.max(leftY,   rightY) : chart.high()
float chartLow  = useZigZag ? math.min(leftY,   rightY) : chart.low()
int   hiTime    = useZigZag ? zzBull ? rightX : leftX   : chart.highBarTime()
int   loTime    = useZigZag ? zzBull ? leftX  : rightX  : chart.lowBarTime()
bool  isBull    = useZigZag ? zzBull : loTime < hiTime
int   leftTime  = math.min(hiTime, loTime)
int   rightTime = math.max(hiTime, loTime)

// Determine label style for time labels. 
string hiTimeStyle = isBull ? label.style_label_lower_right : label.style_label_lower_left
string loTimeStyle = isBull ? label.style_label_upper_left  : label.style_label_upper_right

// Create fibLevel objects on first bar, populate levels array, create sortedArray for object sorting. 
if barstate.isfirst
    populate(show000Input, level000Input, color000Input)
    populate(show236Input, level236Input, color236Input)
    populate(show382Input, level382Input, color382Input)
    populate(show500Input, level500Input, color500Input)
    populate(show618Input, level618Input, color618Input)
    populate(show786Input, level786Input, color786Input)
    populate(show100Input, level100Input, color100Input)
    populate(show161Input, level161Input, color161Input)
    populate(show261Input, level261Input, color261Input)
    populate(show361Input, level361Input, color361Input)
    populate(show423Input, level423Input, color423Input)
    populate(show127Input, level127Input, color127Input)
    populate(show141Input, level141Input, color141Input)
    populate(show227Input, level227Input, color227Input)
    populate(show241Input, level241Input, color241Input)
    populate(show200Input, level200Input, color200Input)
    populate(show300Input, level300Input, color300Input)
    populate(show327Input, level327Input, color327Input)
    populate(show341Input, level341Input, color341Input)
    populate(show400Input, level400Input, color400Input)
    populate(show427Input, level427Input, color427Input)
    populate(show441Input, level441Input, color441Input)
    populate(show461Input, level461Input, color461Input)
    populate(show476Input, level476Input, color476Input)
    sortedArray := array.sort_indices(levels)
    if useFillInput
        setBg()

// Set fibLevel properties on last bar. Draw time labels and hi/lo line. 
if barstate.islast
    setLevels(leftTime, rightTime, chartHigh, chartLow, isBull)
    if tLabelsInput
        timeLabel(hiTime, chartHigh, LIME,    hiTimeStyle)
        timeLabel(loTime, chartLow,  FUCHSIA, loTimeStyle)
    if trendLineInput and not (showZZInput and useZigZag)
        hiLoLine(hiTime, chartHigh, loTime, chartLow)
//#endregion

Overview

Visible Fibonacci can base the levels on the high and low of the visible range or on zig zag pivots found within it, with a pivot length setting and an option to pick the nth last pivot. Each level can be shown or hidden and given its own value, colour and style. Lines can extend left, right or to the live bar.

Details

Published by

ivansoft on GitHub

Code credit

TradingView, as written in the script's header

Draws

On the price chart

Markets

Any symbol

Timeframes

Any timeframe

Risk Notes

  • Signals can change on the live bar or after it closes (repainting)

Topics

pinescripttradingvew

Settings

The inputs you can change from the gear icon on the chart. Defaults are the author's.

SettingTypeDefaultVariable
Fib Calculation TypestringFT01fibTypeInput
Show Zig ZagbooltrueshowZZInput
Detect additional pivotsbooltrueaddPivotInput
   Pivot Lengthint50lengthInput
   colorGRAYzzBullColorInput
zzBearColorInputcolorGRAYzzBearColorInput
zzwidthInputint2zzwidthInput
zzStyleInputstringTY01zzStyleInput
   nth Last Pivotint1pivotInput
Extend to real timebooltrueextendRtInput
Extend lines rightboolfalseextendRightInput
Extend lines leftboolfalseextendLeftInput
Show all 40 settings
SettingTypeDefaultVariable
Trend LinebooltruetrendLineInput
trendColorInputcolorGRAYtrendColorInput
trendWidthInputint1trendWidthInput
trendStyleInputstringTY02trendStyleInput
Levels Lineint1levelsWidthInput
fibStyleInputstringTY01fibStyleInput
extStyleInputstringTY03extStyleInput
show000Inputbooltrueshow000Input
level000Inputfloat0level000Input
color000InputcolorGRAYcolor000Input
show236Inputbooltrueshow236Input
level236Inputfloat0.236level236Input
color236InputcolorREDcolor236Input
show382Inputbooltrueshow382Input
level382Inputfloat0.382level382Input
color382InputcolorORANGEcolor382Input
show500Inputbooltrueshow500Input
level500Inputfloat0.5level500Input
color500InputcolorGREENcolor500Input
show618Inputbooltrueshow618Input
level618Inputfloat0.618level618Input
color618InputcolorTEALcolor618Input
show786Inputbooltrueshow786Input
level786Inputfloat0.786level786Input
color786InputcolorAQUAcolor786Input
show100Inputbooltrueshow100Input
level100Inputfloat1level100Input
color100InputcolorGRAYcolor100Input
Third-party code. ForexR did not write, test or endorse this script, and the summary above was generated automatically from its code and README. Indicators describe the past, and a strategy's backtest can look better than live trading, especially when a script repaints. Check it in the Strategy Tester and on a demo account before you rely on it.

Similar Pine Scripts

947 stars

Moving Average Channel plots separate simple moving averages for upper and lower bands on the price chart. It fills the space between bands with semi-transparent color and colors bars green above the upper band, red below the lower band, or gray in between. Us

Indicator v4 Moving averagesSupport & resistance
Updated 11 days ago · GPL-3.0 GitHub repository of Moving Average Channel

ICT Equal Highs and Lows

by ArunKBhaskar
575 stars

This overlay indicator finds pivot highs and lows on the price chart and compares the last two highs and the last two lows. When the percentage difference between a pair is below the Equal HL threshold, it treats them as equal levels and draws a box. Left and

Indicator v5 SMC / ICT / price actionSupport & resistance
Updated 1 year ago · MPL-2.0 GitHub repository of ICT Equal Highs and Lows
330 stars

This indicator monitors multiple cryptocurrency symbols for trading signals. It calculates and plots entry prices, take profit, and stop loss levels for each symbol including BTCUSDT, ETHUSDT, BNBUSDT and others. Price crossovers trigger buy, sell or close ale

Indicator v5 Support & resistanceScreeners & dashboards
Updated 2 months ago · None stated GitHub repository of Multi Alert Long/Short [Alorse]

This overlay indicator draws a fixed-range volume profile on the price chart, splitting traded activity into up and down volume at each price level. It also plots a sentiment profile, a developing point of control, and value-area high and low around a configur

Indicator v5 VolumeSupport & resistance
Updated 2 months ago · MIT GitHub repository of Volume Profile and Indicator by DGT

BZ-tracker

by Allen1212
303 stars

The BZ-tracker indicator marks ARK Invest buy and sell transactions on stock charts with labels. It plots green labels for purchases and red labels for sales, each annotated with a multiplier such as X1 or X2 to show the number of ARK ETFs trading the stock on

Indicator v4 Support & resistanceScreeners & dashboards
Updated 2 years ago · None stated GitHub repository of BZ-tracker

Function - Linear Regression

by ricardosantos79
261 stars

This indicator fits a linear regression through stored pivot highs and lows and draws the resulting channel on the price chart. A function returns predicted values, maximum and minimum deviations, and the average absolute deviation. Confirmed two-bar pivots up

Indicator v5 TrendSupport & resistance
Updated 4 years ago · None stated GitHub repository of Function - Linear Regression

More Support & resistance scripts

Related on ForexR

Trade Your Charts With a Regulated Broker

Compare brokers that connect to TradingView, with spreads, minimum deposits and leverage side by side.

Compare brokers