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

//@version=5
indicator('Donchian Screener', overlay=true)

_remove_exchange(ticker) =>
    res = ticker == '' ? '' : array.get(str.split(ticker, ':'), 1)
    res
    
_donchian(len, hilo, offset) =>
    highest = ta.highest(high, len)
    lowest = ta.lowest(low, len)
    hi = hilo ? high : close
    lo = hilo ? low : close
    signal = hi > highest[offset] and hi[1] < highest[offset + 1] ? 1 : lo < lowest[offset] and lo[1] > lowest[offset + 1] ? -1 : 0
    signal

use_hilo = input.bool(true, "Use High/Low Price Breakouts")
offset = input.int(1, "Upper/Lower Band Breakout Offset", minval=0, step=1)
pos = input.string("Top Right", "Panel Position", ["Top Right", "Middle Right", "Bottom Right"])
timeframe = input.timeframe("D", "Default Timeframe")

t1 = input.symbol('BMFBOVESPA:VALE3', 'Ticker 1')
t1len = input.int(20, 'Length 1', step=1, minval=1)
t2 = input.symbol('', 'Ticker 2')
t2len = input.int(20, 'Length 2', step=1, minval=1)
t3 = input.symbol('', 'Ticker 3')
t3len = input.int(20, 'Length 3', step=1, minval=1)
t4 = input.symbol('', 'Ticker 4')
t4len = input.int(20, 'Length 4', step=1, minval=1)
t5 = input.symbol('', 'Ticker 5')
t5len = input.int(20, 'Length 5', step=1, minval=1)
t6 = input.symbol('', 'Ticker 6')
t6len = input.int(20, 'Length 6', step=1, minval=1)
t7 = input.symbol('', 'Ticker 7')
t7len = input.int(20, 'Length 7', step=1, minval=1)
t8 = input.symbol('', 'Ticker 8')
t8len = input.int(20, 'Length 8', step=1, minval=1)
t9 = input.symbol('', 'Ticker 9')
t9len = input.int(20, 'Length 9', step=1, minval=1)
t10 = input.symbol('', 'Ticker 10')
t10len = input.int(20, 'Length 10', step=1, minval=1)

t1name = _remove_exchange(t1)
t2name = _remove_exchange(t2)
t3name = _remove_exchange(t3)
t4name = _remove_exchange(t4)
t5name = _remove_exchange(t5)
t6name = _remove_exchange(t6)
t7name = _remove_exchange(t7)
t8name = _remove_exchange(t8)
t9name = _remove_exchange(t9)
t10name = _remove_exchange(t10)

h1 = t1 == '' ? 0 : request.security(t1, timeframe, _donchian(t1len, use_hilo, offset))
h2 = t2 == '' ? 0 : request.security(t2, timeframe, _donchian(t2len, use_hilo, offset))
h3 = t3 == '' ? 0 : request.security(t3, timeframe, _donchian(t3len, use_hilo, offset))
h4 = t4 == '' ? 0 : request.security(t4, timeframe, _donchian(t4len, use_hilo, offset))
h5 = t5 == '' ? 0 : request.security(t5, timeframe, _donchian(t5len, use_hilo, offset))
h6 = t6 == '' ? 0 : request.security(t6, timeframe, _donchian(t6len, use_hilo, offset))
h7 = t7 == '' ? 0 : request.security(t7, timeframe, _donchian(t7len, use_hilo, offset))
h8 = t8 == '' ? 0 : request.security(t8, timeframe, _donchian(t8len, use_hilo, offset))
h9 = t9 == '' ? 0 : request.security(t9, timeframe, _donchian(t9len, use_hilo, offset))
h10 = t10 == '' ? 0 : request.security(t10, timeframe, _donchian(t10len, use_hilo, offset))

ut1 = h1 == 1
ut2 = h2 == 1
ut3 = h3 == 1
ut4 = h4 == 1
ut5 = h5 == 1
ut6 = h6 == 1
ut7 = h7 == 1
ut8 = h8 == 1
ut9 = h9 == 1
ut10 = h10 == 1

dt1 = h1 == -1
dt2 = h2 == -1
dt3 = h3 == -1
dt4 = h4 == -1
dt5 = h5 == -1
dt6 = h6 == -1
dt7 = h7 == -1
dt8 = h8 == -1
dt9 = h9 == -1
dt10 = h10 == -1

up_label = 'UP TREND \n\n'

up_label := ut1 ? up_label + t1name + '\n' : up_label
up_label := ut2 ? up_label + t2name + '\n' : up_label
up_label := ut3 ? up_label + t3name + '\n' : up_label
up_label := ut4 ? up_label + t4name + '\n' : up_label
up_label := ut5 ? up_label + t5name + '\n' : up_label
up_label := ut6 ? up_label + t6name + '\n' : up_label
up_label := ut7 ? up_label + t7name + '\n' : up_label
up_label := ut8 ? up_label + t8name + '\n' : up_label
up_label := ut9 ? up_label + t9name + '\n' : up_label
up_label := ut10 ? up_label + t10name + '\n' : up_label

down_label = 'DOWN TREND \n\n'
down_label := dt1 ? down_label + t1name + '\n' : down_label
down_label := dt2 ? down_label + t2name + '\n' : down_label
down_label := dt3 ? down_label + t3name + '\n' : down_label
down_label := dt4 ? down_label + t4name + '\n' : down_label
down_label := dt5 ? down_label + t5name + '\n' : down_label
down_label := dt6 ? down_label + t6name + '\n' : down_label
down_label := dt7 ? down_label + t7name + '\n' : down_label
down_label := dt8 ? down_label + t8name + '\n' : down_label
down_label := dt9 ? down_label + t9name + '\n' : down_label
down_label := dt10 ? down_label + t10name + '\n' : down_label

position = pos == "Bottom Right" ? position.bottom_right : pos == "Middle Right" ? position.middle_right : position.top_right
var table perfTable = table.new(position, 1, 2, border_width = 3)

f_fillCell(_table, _column, _row, _value, _color) =>
    _c_color = _color
    _transp = 80
    _cellText = str.tostring(_value)
    table.cell(_table, _column, _row, _cellText, bgcolor = color.new(_c_color, _transp), text_color = _c_color, width = 10)    

f_fillCell(perfTable, 0, 0, up_label, #239B56)
f_fillCell(perfTable, 0, 1, down_label, #E74C3C)