Sonarlab - Psych/Whole Number Levels 
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © ClayeWeight
// Enjoy the Free Script!

//@version=5
indicator("Psych/Whole Number Levels", overlay = true)

_grp = "Sonarlab.io"
_v = input.string("v1.1", title="Version", options=["v1.1"], group=_grp)

// -----------
_fx = "Forex & Indices & BTC/ETH"
show_250pip = input.bool(true, title="Show 250 pip levels", group=_fx)
pip250_line_count = input.int(5, title="Line Count", group=_fx)
pip250_line_style = input.string("Solid", title="Line Style", options=["Solid", "Dashed", "Dotted"], inline="style250", group=_fx)
line_style250 = pip250_line_style == "Solid" ? line.style_solid : pip250_line_style == "Dashed" ? line.style_dashed : line.style_dotted
pip250_color = input.color(#b22833, title="", inline="style250", group=_fx)

// -----------
show_100pip = input.bool(true, title="Show 100 pip levels", group=_fx)
pip100_line_count = input.int(5, title="Line Count", group=_fx)
pip100_line_style = input.string("Dashed", title="Line Style", options=["Solid", "Dashed", "Dotted"], inline="style", group=_fx)
line_style100 = pip100_line_style == "Solid" ? line.style_solid : pip100_line_style == "Dashed" ? line.style_dashed : line.style_dotted
pip100_color = input.color(#1848cc, title="", inline="style", group=_fx)

// -----------
show_intraday_pip = input.bool(true, title="Show Intra Day Pip Levels", group=_fx)
intraday_line_count = input.int(5, title="Line Count", group=_fx)
intraday_line_style = input.string("Dotted", title="Line Style", options=["Solid", "Dashed", "Dotted"], inline="stylefx", group=_fx)
line_styleintraday = intraday_line_style == "Solid" ? line.style_solid : intraday_line_style == "Dashed" ? line.style_dashed : line.style_dotted
intraday_color = input.color(#fbc02d, title="", inline="stylefx", group=_fx)

// -----------
_alert = "Alerts"
alert_intraday = input.bool(true, title="Alert Intra Day Levels", group=_alert)
alert_100 = input.bool(true, title="Alert 100 Pip Levels", group=_alert)
alert_250 = input.bool(true, title="Alert 250 Pip Levels", group=_alert)

// --------------------
step = syminfo.mintick * 1000
step100 = step 
step250  = step * 2.5

var intradayLevelLines = array.new_line()
var levelLines100 = array.new_line()
var levelLines250 = array.new_line()

remove_lines(_lines) =>
    for l in _lines
        line.delete(l)

print_line(showBool, lineArray, total, step, stepAdd, multi, col, style) =>
    if showBool
        for n = 0 to total - 1
            stepUp = syminfo.type == 'forex' or syminfo.type == 'crypto' ? math.ceil(close / step) * step + (n * multi) : int(close / step) * step + stepAdd + (n * multi)
            stepUp := syminfo.type == 'forex' and show_intraday_pip ? stepUp + stepAdd * step : stepUp
            stepDn = syminfo.type == 'forex' or syminfo.type == 'crypto' ? math.floor(close / step) * step - (n * multi) : int(close / step) * step + stepAdd - (n * multi)
            stepDn := syminfo.type == 'forex' and show_intraday_pip ? stepDn + stepAdd * step : stepDn
            array.push(lineArray, line.new(bar_index, stepUp, bar_index - 1, stepUp, xloc=xloc.bar_index, extend=extend.both, color=col, width=1, style=style))
            array.push(lineArray, line.new(bar_index, stepDn, bar_index - 1, stepDn, xloc=xloc.bar_index, extend=extend.both, color=col, width=1, style=style))
    

alert_me(lineLevels) =>
    for l in lineLevels
        if open < line.get_y1(l) and close > line.get_y1(l)
            alert("Price is above " + str.tostring(line.get_y1(l)) )
            break
        if open > line.get_y1(l) and close < line.get_y1(l)
            alert("Price is below " + str.tostring(line.get_y1(l)) )
            break

if alert_250
    alert_me(levelLines250)
if alert_100
    alert_me(levelLines100)
if alert_intraday
    alert_me(intradayLevelLines)

if barstate.islast
    remove_lines(intradayLevelLines)
    remove_lines(levelLines100)
    remove_lines(levelLines250)
    if syminfo.type == 'forex'
        print_line(show_250pip, levelLines250, pip250_line_count, step250, 0, step250, pip250_color, line_style250)
        print_line(show_100pip, levelLines100, pip100_line_count, step100, 0, step100, pip100_color, line_style100)

        if timeframe.isintraday
            print_line(show_intraday_pip, intradayLevelLines, intraday_line_count, step, 0.2, step, intraday_color, line_styleintraday)
            print_line(show_intraday_pip, intradayLevelLines, intraday_line_count, step, 0.5, step, intraday_color, line_styleintraday)
            print_line(show_intraday_pip, intradayLevelLines, intraday_line_count, step, 0.8, step, intraday_color, line_styleintraday)

    if syminfo.type == 'index' or syminfo.type == 'cfd'
        print_line(show_250pip, levelLines250, pip250_line_count, 1000, 500, 250, pip250_color, line_style250)
        print_line(show_100pip, levelLines100, pip100_line_count, 100, 0, 100, pip100_color, line_style100)
    
    if syminfo.type == 'crypto'
        if str.startswith(syminfo.ticker, "BTC")
            print_line(show_100pip, levelLines100, pip100_line_count, 1000, 0, 1000, pip100_color, line_style100)
            print_line(show_250pip, levelLines250, pip250_line_count, 1500, 0, 1500, pip250_color, line_style250)
            if timeframe.isintraday
                print_line(show_intraday_pip, intradayLevelLines, intraday_line_count, 250, 0, 250, intraday_color, line_styleintraday)

        if str.startswith(syminfo.ticker, "ETH")    
            print_line(show_100pip, levelLines100, pip100_line_count, 100, 0, 100, pip100_color, line_style100)
            print_line(show_250pip, levelLines250, pip250_line_count, 250, 0, 250, pip250_color, line_style250)
            if timeframe.isintraday
                print_line(show_intraday_pip, intradayLevelLines, intraday_line_count, 50, 0, 50, intraday_color, line_styleintraday)