study("Auto Fib Retracement", overlay=true)
threshold_multiplier = input(title="Deviation", type=input.float, defval=3, minval=0)
dev_threshold = atr(10) / close * 100 * threshold_multiplier
depth = input(title="Depth", type=input.integer, defval=10, minval=1)
var extendLeft = input(false, "Extend Lines Left")
var extendRight = input(true, "Extend Lines Right")
var extending = extend.none
if extendLeft and extendRight
if extendLeft and not extendRight
if not extendLeft and extendRight
extending := extend.right
reverse = input(false, "Reverse")
prices = input(true, "Prices")
levels = input(true, "Levels")
levelsFormat = input("Values", "Levels Format", options = ["Values", "Percent"])
labelsPosition = input("Left", "Labels Position", options = ["Left", "Right"])
var isHighLast = false // otherwise the last pivot is a low pivot
pivots(src, length, isHigh) =>
if not isHigh and src[i] < c
[iH, pH] = pivots(high, depth / 2, true)
[iL, pL] = pivots(low, depth / 2, false)
calc_dev(base_price, price) =>
100 * (price - base_price) / price
pivotFound(dev, isHigh, index, price) =>
if isHighLast == isHigh and not na(lineLast)
if isHighLast ? price > pLast : price < pLast
line.set_xy2(lineLast, index, price)
else // reverse the direction (or create the very first line)
if abs(dev) > dev_threshold
// price move is significant
id = line.new(iLast, pLast, index, price, color=color.gray, width=1, style=line.style_dashed)
dev = calc_dev(pLast, pH)
[id, isHigh] = pivotFound(dev, true, iH, pH)
dev = calc_dev(pLast, pL)
[id, isHigh] = pivotFound(dev, false, iL, pL)
_draw_line(price, col) =>
var id = line.new(iLast, price, bar_index, price, color=col, width=1, extend=extending)
line.set_xy1(id, line.get_x1(lineLast), price)
line.set_xy2(id, line.get_x2(lineLast), price)
_draw_label(price, txt, txtColor) =>
x = labelsPosition == "Left" ? line.get_x1(lineLast) : line.get_x2(lineLast)
var id = label.new(x=x, y=price, text=txt, textcolor=txtColor, style=label.style_none)
label.set_xy(id, x, price)
label.set_textcolor(id, txtColor)
"(" + tostring(txt, "#.##") + ")"
_label_txt(level, price) =>
l = levelsFormat == "Values" ? tostring(level) : tostring(level * 100) + "%"
(levels ? l : "") + (prices ? _wrap(price) : "")
sl2 = input(true, "0.236")
sl3 = input(true, "0.382")
sl5 = input(true, "0.618")
sl6 = input(true, "0.786")
sl8 = input(true, "1.272")
sl9 = input(true, "1.414")
sl10 = input(true, "1.618")
sl11 = input(false, "2.618")
sl12 = input(false, "3.618")
sl13 = input(false, "4.236")
sl14 = input(false, "-0.236")
sl15 = input(false, "-0.382")
sl16 = input(false, "-0.618")
_draw_retracement(startPrice, endPrice) =>
iHL = startPrice > endPrice
diff = (iHL ? -1 : 1) * abs(startPrice - endPrice)
l1 = startPrice + diff * vall1
_draw_label(l1, _label_txt(vall1, l1), #808080)
l2 = startPrice + diff * vall2
_draw_label(l2, _label_txt(vall2, l2), #a61c00)
l3 = startPrice + diff * vall3
_draw_label(l3, _label_txt(vall3, l3), #95cc28)
l4 = startPrice + diff * vall4
_draw_label(l4, _label_txt(vall4, l4), #28cc28)
l5 = startPrice + diff * vall5
_draw_label(l5, _label_txt(vall5, l5), #28cc95)
l6 = startPrice + diff * vall6
_draw_label(l6, _label_txt(vall6, l6), #2895cc)
l7 = startPrice + diff * vall7
_draw_label(l7, _label_txt(vall7, l7), #808080)
l8 = startPrice + diff * vall8
_draw_label(l8, _label_txt(vall8, l8), #82CA89)
l9 = startPrice + diff * vall9
_draw_label(l9, _label_txt(vall9, l9), #F32C42)
l10 = startPrice + diff * vall10
_draw_label(l10, _label_txt(vall10, l10), #2796ED)
l11 = startPrice + diff * vall11
_draw_label(l11, _label_txt(vall11, l11), #a61c00)
l12 = startPrice + diff * vall12
_draw_label(l12, _label_txt(vall12, l12), #9B03AE)
l13 = startPrice + diff * vall13
_draw_label(l13, _label_txt(vall13, l13), #E80065)
l14 = startPrice + diff * vall14
_draw_label(l14, _label_txt(vall14, l14), #a61c00)
l15 = startPrice + diff * vall15
_draw_label(l15, _label_txt(vall15, l15), #95cc28)
l16 = startPrice + diff * vall16
_draw_label(l16, _label_txt(vall16, l16), #28cc95)
p1 = reverse ? line.get_y1(lineLast) : pLast
p2 = reverse ? pLast : line.get_y1(lineLast)
_draw_retracement(p1, p2)