Cup Finder pinescript in TradingView Pinescript – LonesomeTheBlue

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

//@version=4
study("Cup Finder", "CF", overlay = true, max_lines_count = 500)
loopback = input(defval = 150, title = "Number of Bars to search", minval = 30, maxval = 250)
widthr = input(defval = 5., title = "Channel Width of the Cup", minval = 1)
check_hc = input(defval = "Close", title = "Source for Breakout", options = ["Close", "High/Low"])
include_rate = input(75., title = "Contained Bar Rate %", minval = 10, maxval = 100) / 100
show_channel = input(false, title = "Show Channels of Cups")
no_label = input(false, title = "Don't Show Labels")
remove_old_lines = input(false, title = "Remove Old Lines")
remove_old_labels = input(false, title = "Remove Old Labels")
bullcolor = input(defval = color.lime, title = "Colors", inline = "colors")
bearcolor = input(defval = color.red, title = "", inline = "colors")

width = (highest(292) - lowest(292)) / 100
uwidth = width * widthr
highestbar = highestbars(30) == 0
lowestbar = lowestbars(30) == 0
bullsrc = check_hc == "Close" ? close : high
bearsrc = check_hc == "Close" ? close : low

hh = 0.
lasthh = 0.
ind = 0
bull = false
for x = 1 to loopback
    lasthh := max(lasthh, high[x])
    if bullsrc <= lasthh
        break
    
    if x >= 20 and bullsrc > high[x] and close[1] < high[x] and high[x] >= lasthh and highestbar[x]
        hh := high[x]
        ind := x
        bull := true

ll = 0.
lastll = highest(292)
if ind == 0
    for x = 1 to loopback
        lastll := min(lastll, low[x])
        if bearsrc >= lastll
            break
        
        if x >= 20 and bearsrc < low[x] and close[1] > low[x] and low[x] <= lastll and lowestbar[x]
            ll := low[x]
            ind := x

Round(val)=> round(val / syminfo.mintick) * syminfo.mintick

var cup_lines = array.new_line(0)
var label cup_label = na
levs = array.new_float(0)
bullish_cup = false
bearish_cup = false
int included = na
if ind != 0
    float pow_radius = pow(ind / 2, 2)
    end = round((ind - (ind % 2)) / 2)
    if ind % 2 == 0
        array.push(levs, bull ? hh - sqrt(pow_radius) * width : ll + sqrt(pow_radius) * width)

    for x = 1 to end 
        ycoord = sqrt(pow_radius - pow(x, 2)) * width
        array.push(levs, bull ? hh - ycoord : ll + ycoord)
        array.unshift(levs, bull ? hh - ycoord : ll + ycoord)
    if ind % 2 == 1
        array.push(levs, bull ? hh : ll)
        array.unshift(levs, bull ? hh : ll)
        
    in_cnt = 0
    for x = 0 to array.size(levs) - 1
        if (min(array.get(levs, x) + uwidth, high[x]) - max(array.get(levs, x) - uwidth, low[x]) > 0)
            in_cnt := in_cnt + 1
    
    if in_cnt / (ind + 1) >= include_rate
        if not no_label
            if remove_old_labels
                label.delete(cup_label)
            cup_label := label.new(bar_index, array.get(levs, 0), 
                      text = "Cup\nRadius = " + tostring(Round(width * ind / 2)) + "\nIncluded = " + tostring(100 * in_cnt / (ind + 1), '#.#') +"%",
                      color = bull ? bullcolor : bearcolor, 
                      textcolor = bull ? color.black : color.white,
                      textalign = text.align_left, 
                      style = bull ? label.style_label_lower_right : label.style_label_upper_right)
                
        if remove_old_lines and array.size(cup_lines) > 0
            for x = 0 to array.size(cup_lines) - 1
                line.delete(array.get(cup_lines, x))
        
        array.push(cup_lines, line.new(x1 = bar_index, y1 = array.get(levs, 0), x2 = bar_index - ind + 1, y2 = array.get(levs, 0), color = bull ? bullcolor : bearcolor, style = line.style_dashed))
        xloc = ind
        for x = 0 to array.size(levs) - 2
            array.push(cup_lines, line.new(x1 = bar_index - xloc, y1 = array.get(levs, x), x2 = bar_index - xloc + 1, y2 = array.get(levs, x + 1), color = bull ? bullcolor : bearcolor, width = 3))
            if show_channel and x % 2 == 0 and x > 0 and x < array.size(levs) - 2
                array.push(cup_lines, line.new(x1 = bar_index - xloc, y1 = array.get(levs, x) + uwidth, x2 = bar_index - xloc + 1, y2 = array.get(levs, x + 1) + uwidth, color = bull ? bullcolor : bearcolor))
                array.push(cup_lines, line.new(x1 = bar_index - xloc, y1 = array.get(levs, x) - uwidth, x2 = bar_index - xloc + 1, y2 = array.get(levs, x + 1) - uwidth, color = bull ? bullcolor : bearcolor))
            
            xloc := xloc - 1
        
        included := round(100 * in_cnt / (ind + 1))
        if bull 
            bullish_cup := true
        else
            bearish_cup := true

plot(included, title = "included", display = display.none)
alertcondition(bullish_cup, title = "Bullish Cup Found", message = 'Bullish Cup Found, Included:{{plot("included")}}')
alertcondition(bearish_cup, title = "Bearish Cup Found", message = 'Bearish Cup Found, Included:{{plot("included")}}')
alertcondition(bullish_cup or bearish_cup, title = "Cup Found", message = 'Cup Found, Included:{{plot("included")}}')

source link/details

Disclaimer:

All the pine script’s posted in this section are for learning purpose. Website does not necessarily own these pine script’s and we don’t have any intellectual property rights on them. We might copy useful pine script’s from public forums and post it in this section in a presentable format. The intent is not to copy anybody’s work but to share knowledge. If you find any misleading or non-reproducible content then please inform us at tradingwithpawan@gmail.com