Code: Select all
//@version=5
strategy("Screener 1 BreakoutFinder that works", overlay=true, max_bars_back=4000)
// General Function
f_barssince(_cond, _count) =>
_barssince = int(math.max(1, nz(bar_index - ta.valuewhen(_cond, bar_index, _count))))
_barssince
barssince(_cond, _count) => int(math.max(1, nz(f_barssince(_cond, _count))))
f_vw(cond, expr, count) => ta.valuewhen(cond, expr, count)
tostring(x, y)=> x + str.tostring(y)
var int dec = str.length(str.tostring(syminfo.mintick))-2
truncate(number, decimals) =>
factor = math.pow(10, decimals)
int(number * factor) / factor
// --------
gr1 = 'Table Style'
tabPosI = 'Middle' //input.string('Middle', 'Table Position', ['Top', 'Middle', 'Bot'], group=gr1)
titleCol = color.white //input.color(color.white, 'Background -- Title', '', '1', gr1)
pairCol = color.white //input.color(color.white, 'Pair', '', '1', gr1)
textCol = color.black //input.color(color.black, 'Text Color', group=gr1)
textSizeI = 'Small' //input.string('Small', 'Text Size', ['Small', 'Tiny', 'Normal'], group=gr1)
textSize = textSizeI=='Small'? size.small : textSizeI=='Tiny'? size.tiny : size.normal
tabPos = tabPosI=='Top'? position.top_right : tabPosI=='Bot'? position.bottom_right : position.middle_right
screenerTable = table.new(tabPos, 50,50, color.new(color.black,100), color.black, 1, color.black, 1)
prd = input.int(defval=5, title='Period', minval=2)
bo_len = input.int(defval=200, title='Max Breakout Length', minval=30, maxval=300)
cwidthu = input.float(defval=3., title='Threshold Rate %', minval=1., maxval=10) / 100
mintest = input.int(defval=2, title='Minimum Number of Tests', minval=1)
bocolorup = input.color(defval=color.blue, title='Breakout Colors', inline='bocol')
bocolordown = input.color(defval=color.red, title='', inline='bocol')
lstyle = input.string(defval=line.style_solid, title='Line Style', options=[line.style_solid, line.style_dashed, line.style_dotted])
fData()=>
//keep Pivot Points and their locations in the arrays
var phval = array.new_float(0)
var phloc = array.new_int(0)
var plval = array.new_float(0)
var plloc = array.new_int(0)
//width
lll = math.max(math.min(bar_index, 300), 1)
float h_ = ta.highest(lll)
float l_ = ta.lowest(lll)
float chwidth = (h_ - l_) * cwidthu
// check if PH/PL
ph = ta.pivothigh(prd, prd)
pl = ta.pivotlow(prd, prd)
// keep PH/PL levels and locations
if ph
array.unshift(phval, ph)
array.unshift(phloc, bar_index - prd)
if array.size(phval) > 1 // cleanup old ones
for x = array.size(phloc) - 1 to 1 by 1
if bar_index - array.get(phloc, x) > bo_len
array.pop(phloc)
array.pop(phval)
if pl
array.unshift(plval, pl)
array.unshift(plloc, bar_index - prd)
if array.size(plval) > 1 // cleanup old ones
for x = array.size(plloc) - 1 to 1 by 1
if bar_index - array.get(plloc, x) > bo_len
array.pop(plloc)
array.pop(plval)
float bomax = na
int bostart = bar_index
num = 0
hgst = ta.highest(prd)[1]
if array.size(phval) >= mintest and close > open and close > hgst
bomax := array.get(phval, 0)
xx = 0
for x = 0 to array.size(phval) - 1 by 1
if array.get(phval, x) >= close
break
xx := x
bomax := math.max(bomax, array.get(phval, x))
bomax
if xx >= mintest and open <= bomax
for x = 0 to xx by 1
if array.get(phval, x) <= bomax and array.get(phval, x) >= bomax - chwidth
num += 1
bostart := array.get(phloc, x)
bostart
if num < mintest or hgst >= bomax
bomax := na
bomax
breakup = not na(bomax) and num >= mintest and barstate.isconfirmed
[breakup, bomax, bostart, chwidth]
[lCond, bomax, bostart, chwidth] = fData()
if lCond
line.new(bar_index , bomax , bostart , bomax , color=bocolorup, style=lstyle)
line.new(bar_index , bomax - chwidth , bostart , bomax - chwidth , color=bocolorup, style=lstyle)
line.new(bostart , bomax - chwidth , bostart , bomax , color=bocolorup, style=lstyle)
line.new(bar_index , bomax - chwidth , bar_index , bomax , color=bocolorup, style=lstyle)
plotshape(lCond, location=location.belowbar, style=shape.triangleup, color=bocolorup, size=size.small)
// -------
// Screener
showTable = false
fScreen(pair, tf, rowNumber, colNumber)=>
[lCond_, bomax_, bostart_, chwidth_] = request.security(pair, tf, fData(), ignore_invalid_symbol=true)
reqCond1 = str.tostring(ta.barssince(lCond_))
Col1 = color.blue
fixRow = rowNumber+1
if pair!='' and lCond_
alert('BreakUp on' +pair+tf, alert.freq_once_per_bar_close)
fixCol2 = colNumber==1? 0 : 2
fixCol1 = colNumber==1? 1 : 3
if pair!='' and showTable
table.cell(screenerTable, fixCol1, 0, 'Pair' , bgcolor=titleCol, text_size=textSize, text_color=textCol)
table.cell(screenerTable, fixCol1, rowNumber, pair+' '+tf , bgcolor=pairCol , text_size=textSize, text_color=textCol)
table.cell(screenerTable, fixCol2, 0, 'Condition' , bgcolor=titleCol, text_size=textSize, text_color=textCol)
table.cell(screenerTable, fixCol2, rowNumber, reqCond1 , bgcolor=pairCol , text_size=textSize, text_color=textCol)
// Input Pair and TF
// Input Pair and TF
gr12 = 'Watchlist'
pair1 = input.symbol('AAPL', '1', '', '1', gr12, true), tf1 = input.timeframe('D', '', inline='1', group= gr12, confirm=true)
pair2 = input.symbol('GOOGL', '2', '', '2', gr12, true), tf2 = input.timeframe('D', '', inline='2', group= gr12, confirm=true)
pair3 = input.symbol('AMZN', '3', '', '3', gr12, true), tf3 = input.timeframe('D', '', inline='3', group= gr12, confirm=true)
pair4 = input.symbol('CSCO', '4', '', '4', gr12, true), tf4 = input.timeframe('D', '', inline='4', group= gr12, confirm=true)
pair5 = input.symbol('COST', '5', '', '5', gr12, true), tf5 = input.timeframe('D', '', inline='5', group= gr12, confirm=true)
pair6 = input.symbol('ADBE', '6', '', '6', gr12, true), tf6 = input.timeframe('D', '', inline='6', group= gr12, confirm=true)
pair7 = input.symbol('CMCSA', '7', '', '7', gr12, true), tf7 = input.timeframe('D', '', inline='7', group= gr12, confirm=true)
pair8 = input.symbol('AMD', '8', '', '8', gr12, true), tf8 = input.timeframe('D', '', inline='8', group= gr12, confirm=true)
pair9 = input.symbol('INTC', '9', '', '9', gr12, true), tf9 = input.timeframe('D', '', inline='9', group= gr12, confirm=true)
pair10 = input.symbol('HON', '10', '', '10', gr12, true), tf10 = input.timeframe('D', '', inline='10', group= gr12, confirm=true)
pair11 = input.symbol('AMGN', '11', '', '11', gr12, true), tf11 = input.timeframe('D', '', inline='11', group= gr12, confirm=true)
pair12 = input.symbol('ASML', '12', '', '12', gr12, true), tf12 = input.timeframe('D', '', inline='12', group= gr12, confirm=true)
pair13 = input.symbol('LVMH', '13', '', '13', gr12, true), tf13 = input.timeframe('D', '', inline='13', group= gr12, confirm=true)
pair14 = input.symbol('DOCU', '14', '', '14', gr12, true), tf14 = input.timeframe('D', '', inline='14', group= gr12, confirm=true)
pair15 = input.symbol('AFX', '15', '', '15', gr12, true), tf15 = input.timeframe('D', '', inline='15', group= gr12, confirm=true)
pair16 = input.symbol('MSFT', '16', '', '16', gr12, true), tf16 = input.timeframe('D', '', inline='16', group= gr12, confirm=true)
pair17 = input.symbol('FB', '17', '', '17', gr12, true), tf17 = input.timeframe('D', '', inline='17', group= gr12, confirm=true)
pair18 = input.symbol('TSLA', '18', '', '18', gr12, true), tf18 = input.timeframe('D', '', inline='18', group= gr12, confirm=true)
pair19 = input.symbol('NVDA', '19', '', '19', gr12, true), tf19 = input.timeframe('D', '', inline='19', group= gr12, confirm=true)
pair20 = input.symbol('PEP', '20', '', '20', gr12, true), tf20 = input.timeframe('D', '', inline='20', group= gr12, confirm=true)
pair21 = input.symbol('QCOM', '21', '', '21', gr12, true), tf21 = input.timeframe('D', '', inline='21', group= gr12, confirm=true)
pair22 = input.symbol('NFLX', '22', '', '22', gr12, true), tf22 = input.timeframe('D', '', inline='22', group= gr12, confirm=true)
pair23 = input.symbol('ISRG', '23', '', '23', gr12, true), tf23 = input.timeframe('D', '', inline='23', group= gr12, confirm=true)
pair24 = input.symbol('MU', '24', '', '24', gr12, true), tf24 = input.timeframe('D', '', inline='24', group= gr12, confirm=true)
pair25 = input.symbol('MNST', '25', '', '25', gr12, true), tf25 = input.timeframe('D', '', inline='25', group= gr12, confirm=true)
pair26 = input.symbol('ORLY', '26', '', '26', gr12, true), tf26 = input.timeframe('D', '', inline='26', group= gr12, confirm=true)
pair27 = input.symbol('MCHP', '27', '', '27', gr12, true), tf27 = input.timeframe('D', '', inline='27', group= gr12, confirm=true)
pair28 = input.symbol('MMM', '28', '', '28', gr12, true), tf28 = input.timeframe('D', '', inline='28', group= gr12, confirm=true)
pair29 = input.symbol('ABT', '29', '', '29', gr12, true), tf29 = input.timeframe('D', '', inline='29', group= gr12, confirm=true)
pair30 = input.symbol('ABBV', '30', '', '30', gr12, true), tf30 = input.timeframe('D', '', inline='30', group= gr12, confirm=true)
pair31 = input.symbol('ACN', '31', '', '31', gr12, true), tf31 = input.timeframe('D', '', inline='31', group= gr12, confirm=true)
pair32 = input.symbol('ALGN', '32', '', '32', gr12, true), tf32 = input.timeframe('D', '', inline='32', group= gr12, confirm=true)
pair33 = input.symbol('AWK', '33', '', '33', gr12, true), tf33 = input.timeframe('D', '', inline='33', group= gr12, confirm=true)
pair34 = input.symbol('AMAT', '34', '', '34', gr12, true), tf34 = input.timeframe('D', '', inline='34', group= gr12, confirm=true)
pair35 = input.symbol('ADP', '35', '', '35', gr12, true), tf35 = input.timeframe('D', '', inline='35', group= gr12, confirm=true)
pair36 = input.symbol('AZO', '36', '', '36', gr12, true) , tf36 = input.timeframe('D', '', inline='36', group= gr12, confirm=true)
pair37 = input.symbol('BAC', '37', '', '37', gr12, true) , tf37 = input.timeframe('D', '', inline='37', group= gr12, confirm=true)
pair38 = input.symbol('BIOGEN', '38', '', '38', gr12, true), tf38 = input.timeframe('D', '', inline='38', group= gr12, confirm=true)
pair39 = input.symbol('CDNS', '39', '', '39', gr12, true) , tf39 = input.timeframe('D', '', inline='39', group= gr12, confirm=true)
pair40 = input.symbol('CZR', '40', '', '40', gr12, true) , tf40 = input.timeframe('D', '', inline='40', group= gr12, confirm=true)
fScreen(pair1, tf1, 2, 1)
fScreen(pair2, tf2, 3, 1)
fScreen(pair3, tf3, 4, 1)
fScreen(pair4, tf4, 5, 1)
fScreen(pair5, tf5, 6, 1)
fScreen(pair6, tf6, 7, 1)
fScreen(pair7, tf7, 8, 1)
fScreen(pair8, tf8, 9, 1)
fScreen(pair9, tf9, 10, 1)
fScreen(pair10, tf10, 11, 1)
fScreen(pair11, tf11, 12, 1)
fScreen(pair12, tf12, 13, 1)
fScreen(pair13, tf13, 14, 1)
fScreen(pair14, tf14, 15, 1)
fScreen(pair15, tf15, 16, 1)
fScreen(pair16, tf16, 17, 1)
fScreen(pair17, tf17, 18, 1)
fScreen(pair18, tf18, 19, 1)
fScreen(pair19, tf19, 20, 1)
fScreen(pair20, tf20, 1, 2)
fScreen(pair21, tf21, 2, 2)
fScreen(pair22, tf22, 3, 2)
fScreen(pair23, tf23, 4, 2)
fScreen(pair24, tf24, 5, 2)
fScreen(pair25, tf25, 6, 2)
fScreen(pair26, tf26, 7, 2)
fScreen(pair27, tf27, 8, 2)
fScreen(pair28, tf28, 9, 2)
fScreen(pair29, tf29, 10, 2)
fScreen(pair30, tf30, 11, 2)
fScreen(pair31, tf31, 12, 2)
fScreen(pair32, tf32, 13, 2)
fScreen(pair33, tf33, 14, 2)
fScreen(pair34, tf34, 15, 2)
fScreen(pair35, tf35, 16, 2)
fScreen(pair36, tf36, 17, 2)
fScreen(pair37, tf37, 18, 2)
fScreen(pair38, tf38, 19, 2)
fScreen(pair39, tf39, 20, 2)
fScreen(pair40, tf40, 21, 2)
Code: Select all
sma1 = ta.sma(close, 50)
sma2 = ta.sma(close, 150)
// Entry condition
if close < sma1 and close > sma2 and close
strategy.entry('long', strategy.long)
Code: Select all
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © LonesomeTheBlue
//@version=5
indicator('Breakout Finder', 'BF', overlay=true, max_bars_back=500, max_lines_count=400)
prd = input.int(defval=5, title='Period', minval=2)
bo_len = input.int(defval=200, title='Max Breakout Length', minval=30, maxval=300)
cwidthu = input.float(defval=3., title='Threshold Rate %', minval=1., maxval=10) / 100
mintest = input.int(defval=2, title='Minimum Number of Tests', minval=1)
bocolorup = input.color(defval=color.blue, title='Breakout Colors', inline='bocol')
bocolordown = input.color(defval=color.red, title='', inline='bocol')
lstyle = input.string(defval=line.style_solid, title='Line Style', options=[line.style_solid, line.style_dashed, line.style_dotted])
//width
lll = math.max(math.min(bar_index, 300), 1)
float h_ = ta.highest(lll)
float l_ = ta.lowest(lll)
float chwidth = (h_ - l_) * cwidthu
// check if PH/PL
ph = ta.pivothigh(prd, prd)
pl = ta.pivotlow(prd, prd)
//keep Pivot Points and their locations in the arrays
var phval = array.new_float(0)
var phloc = array.new_int(0)
var plval = array.new_float(0)
var plloc = array.new_int(0)
// keep PH/PL levels and locations
if ph
array.unshift(phval, ph)
array.unshift(phloc, bar_index - prd)
if array.size(phval) > 1 // cleanup old ones
for x = array.size(phloc) - 1 to 1 by 1
if bar_index - array.get(phloc, x) > bo_len
array.pop(phloc)
array.pop(phval)
if pl
array.unshift(plval, pl)
array.unshift(plloc, bar_index - prd)
if array.size(plval) > 1 // cleanup old ones
for x = array.size(plloc) - 1 to 1 by 1
if bar_index - array.get(plloc, x) > bo_len
array.pop(plloc)
array.pop(plval)
// check bullish cup
float bomax = na
int bostart = bar_index
num = 0
hgst = ta.highest(prd)[1]
if array.size(phval) >= mintest and close > open and close > hgst
bomax := array.get(phval, 0)
xx = 0
for x = 0 to array.size(phval) - 1 by 1
if array.get(phval, x) >= close
break
xx := x
bomax := math.max(bomax, array.get(phval, x))
bomax
if xx >= mintest and open <= bomax
for x = 0 to xx by 1
if array.get(phval, x) <= bomax and array.get(phval, x) >= bomax - chwidth
num += 1
bostart := array.get(phloc, x)
bostart
if num < mintest or hgst >= bomax
bomax := na
bomax
if not na(bomax) and num >= mintest
line.new(x1=bar_index, y1=bomax, x2=bostart, y2=bomax, color=bocolorup, style=lstyle)
line.new(x1=bar_index, y1=bomax - chwidth, x2=bostart, y2=bomax - chwidth, color=bocolorup, style=lstyle)
line.new(x1=bostart, y1=bomax - chwidth, x2=bostart, y2=bomax, color=bocolorup, style=lstyle)
line.new(x1=bar_index, y1=bomax - chwidth, x2=bar_index, y2=bomax, color=bocolorup, style=lstyle)
plotshape(not na(bomax) and num >= mintest, location=location.belowbar, style=shape.triangleup, color=bocolorup, size=size.small)
alertcondition(not na(bomax) and num >= mintest, title='Breakout', message='Breakout')
// check bearish cup
float bomin = na
bostart := bar_index
num1 = 0
lwst = ta.lowest(prd)[1]
if array.size(plval) >= mintest and close < open and close < lwst
bomin := array.get(plval, 0)
xx = 0
for x = 0 to array.size(plval) - 1 by 1
if array.get(plval, x) <= close
break
xx := x
bomin := math.min(bomin, array.get(plval, x))
bomin
if xx >= mintest and open >= bomin
for x = 0 to xx by 1
if array.get(plval, x) >= bomin and array.get(plval, x) <= bomin + chwidth
num1 += 1
bostart := array.get(plloc, x)
bostart
if num1 < mintest or lwst <= bomin
bomin := na
bomin
if not na(bomin) and num1 >= mintest
line.new(x1=bar_index, y1=bomin, x2=bostart, y2=bomin, color=bocolordown, style=lstyle)
line.new(x1=bar_index, y1=bomin + chwidth, x2=bostart, y2=bomin + chwidth, color=bocolordown, style=lstyle)
line.new(x1=bostart, y1=bomin + chwidth, x2=bostart, y2=bomin, color=bocolordown, style=lstyle)
line.new(x1=bar_index, y1=bomin + chwidth, x2=bar_index, y2=bomin, color=bocolordown, style=lstyle)
plotshape(not na(bomin) and num1 >= mintest, location=location.abovebar, style=shape.triangledown, color=bocolordown, size=size.small)
alertcondition(not na(bomin) and num1 >= mintest, title='Breakdown', message='Breakdown')
alertcondition(not na(bomax) and num >= mintest or not na(bomin) and num1 >= mintest, title='Breakout or Breakdown', message='Breakout or Breakdown')