Entry Assistant by Ivan
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © ivanroyloewen

//@version=5
indicator("Entry Assistant", overlay = true)
//-------------------------------------------------------------------------------------------------------------------------------( General Inputs / Variables ) ---------------------------------------------

var direction = "Direction"

// are you planning to go Long ( displays data to assist entering Long positions)
var going_Long = input(title = "Long", defval = true, inline = direction, group = direction)
// are you planning to go Short ( displays data to assist entering Short positions)
var going_Short = input(title = "Short", defval = false, inline = direction, group = direction)

var show = "Show"

// display the stop loss line
var show_Stop = input(title = "Stop", defval = true, inline = show, group = show)
// display the BOC line
var show_BOC = input(title = "BOC", defval = true, inline = show, group = show)
// display the entry signal ( when current candle breaks previous candle )
var show_Entry_Signal = input(title = "Entry", defval = true, inline = show, group = show)
// only display the last three digits of the price ( on the price label )
var show_Only_Last_Three_Digits = input(title = "Three Digits Only", defval = true, inline = show, group = show)

//-------------------------------------------------------------------------------------------------------------------------------( Long Inputs ) ------------------------------------------------------------

var variables_Long = "Long Variables"

// how much price below the current candle do you want to Stop line placed
var pips_Below_Candle_Stop_Long = input.float(title = "Pips spacing below candle for stop loss", defval = 1.0, minval = 0, maxval = 1000, group = variables_Long)
// how much price above the Long BOC line until Long entry signal is displayed
var pips_Above_BOC_Entry_Long = input.float(title = "Pips spacing above BOC for entry signal", defval = 0.1, minval = 0, maxval = 1000, group = variables_Long)
// how many candles ahead on the x axis is the Long price label placed
var label_Distance_Long = input.int(title = "Label horizontal distance", defval = 20, minval = 0, maxval = 100, group = variables_Long)

// Long Colors
var colors_Long = "Long Colors"

// the color of the Long Stop line
var line_Color_Long = input.color(title = "Stop", defval = #5b9cf6, inline = colors_Long, group = "Long Colors")
// the color of the Long BOC line
var line_BOC_Color_Long = input.color(title = "BOC", defval = #ac774f, inline = colors_Long, group = "Long Colors")
// the color of the Long entry signal
var entry_Signal_Color_Long = input.color(title = "Entry", defval = color.green, inline = colors_Long, group = "Long Colors")
// the color of the Long label
var label_Color_Long = input(title = "Label", defval = #3179f5, inline = colors_Long, group = "Long Colors")
// the color of the Long label text
var labe_Text_Color_Long = input(title = "Text", defval = color.white, inline = colors_Long, group = "Long Colors")

//-------------------------------------------------------------------------------------------------------------------------------( Short Inputs ) -----------------------------------------------------------

var variables_Short = "Short Variables"

// how much price above the current candle do you want to Stop line placed
var pips_Below_Candle_Stop_Short = input.float(title = "Pips spacing above candle for stop loss", defval = 1.0, minval = 0, maxval = 1000, group = variables_Short )
// how much price below the Short BOC line until Short entry signal is displayed
var pips_Above_BOC_Entry_Short = input.float(title = "Pips spacing below BOC for entry signal", defval = 0.1, minval = 0, maxval = 1000, group = variables_Short )
// how many candles ahead on the x axis is the Short price label placed
var label_Distance_Short = input.int(title = "Label horizontal distance", defval = 20, minval = 0, maxval = 100, group = variables_Short )

var colors_Short = "Short Colors"

// the color of the Short Stop line
var line_Color_Short = input.color(title = "Stop", defval = #5b9cf6, inline = colors_Short, group = "Short Colors")
// the color of the Short BOC line
var line_BOC_Color_Short = input.color(title = "BOC", defval = #ac774f, inline = colors_Short, group = "Short Colors")
// the color of the Short entry signal
var entry_Signal_Color_Short = input.color(title = "Entry", defval = color.green, inline = colors_Short, group = "Short Colors")
// the color of the Short label
var label_Color_Short = input(title = "Label", defval = #3179f5, inline = colors_Short, group = "Short Colors")
// the color of the Short label text
var label_Text_Color_Short = input(title = "Text", defval = color.white, inline = colors_Short, group = "Short Colors")

//-------------------------------------------------------------------------------------------------------------------------------( Price Calculation ) -----------------------------------------------------------

var price_Digit_Count = str.length(str.tostring(syminfo.mintick))

// the time frame, calculated by the time between the current and previous candle
time_Frame = time - time[1]

// rounds numbers
Truncate(number, decimals) =>
    factor = math.pow(10, decimals)
    int(number * factor) / factor

// get the price value from the given inputs
pips_Price_Value_Stop_Long = syminfo.mintick * Truncate(pips_Below_Candle_Stop_Long, 1) * 10
pips_Price_Value_BOC_Long = syminfo.mintick * Truncate(pips_Above_BOC_Entry_Long, 1) * 10

// calculate the new line positions with the pips price value
price_Stop_Long = low - pips_Price_Value_Stop_Long
price_BOC_Entry_Long = high[1] + pips_Price_Value_BOC_Long

// the position where the Long label will be initially placed
long_Label_Point = chart.point.new(time = time, index = bar_index, price = price_Stop_Long)
long_Label_Text = str.tostring(price_Stop_Long)
// check if the current label text has less character than the instruments max digits price ( this means a "0" zero has been rounded off )
if str.length(long_Label_Text) < price_Digit_Count
    // get the amount of zeros that have been rounded off
    int amount_Of_Zeros_Rounded_Off = price_Digit_Count - str.length(long_Label_Text)
    // add as many zeros back on that have been rounded off
    for i = 1 to amount_Of_Zeros_Rounded_Off by 1
        // add the zero back onto the label text
        long_Label_Text += "0"


// get the price value from the given inputs
pips_Price_Value_Stop_Short = syminfo.mintick * Truncate(pips_Below_Candle_Stop_Short, 1) * 10
pips_Price_Value_BOC_Short = syminfo.mintick * Truncate(pips_Above_BOC_Entry_Short, 1) * 10

// calculate the new line positions with the pips price value
price_Stop_Short = high + pips_Price_Value_Stop_Short
price_BOC_Entry_Short = low[1] - pips_Price_Value_BOC_Short

// the position where the Short label will be initially placed
short_Label_Point = chart.point.new(time = time, index = bar_index, price = price_Stop_Short)
short_Label_Text = str.tostring(price_Stop_Short)
// check if the current label text has less character than the instruments max digits price ( this means a "0" zero has been rounded off )
if str.length(short_Label_Text) < price_Digit_Count
    // get the amount of zeros that have been rounded off
    int amount_Of_Zeros_Rounded_Off = price_Digit_Count - str.length(short_Label_Text)
    // add as many zeros back on that have been rounded off
    for i = 1 to amount_Of_Zeros_Rounded_Off by 1
        // add the zero back onto the label text
        short_Label_Text += "0"

//-------------------------------------------------------------------------------------------------------------------------------( Handle Long Data / Drawings ) --------------------------------------------

// if you are going Long
if going_Long
    // draw the Long Stop line below the current candle
    stop_Line_Long = line.new(bar_index[1], price_Stop_Long, bar_index, price_Stop_Long, xloc.bar_index, extend.right, line_Color_Long, line.style_solid, 2)
    // delete the previous Long Stop line
    line.delete(stop_Line_Long[1])
    // if you are showing the Long BOC ( Break Of Candle ) line
    if show_BOC
        // draw the Long BOC line at the previous candles high
        line_Long_BOC = line.new(bar_index[1], high[1], bar_index, high[1], xloc.bar_index, extend.right, line_BOC_Color_Long, line.style_solid, 2)
        // delete the previous Long BOC line
        line.delete(line_Long_BOC[1])
    // set the default value to ERR ( error )
    last_Three_Characters = "ERR"
    // only show the last three digits of the stop loss price
    if show_Only_Last_Three_Digits
        // remove the decimal when only showing three digshow_Only
        long_Label_Text := str.replace( long_Label_Text , target = ".", replacement = "")
    // check for this condition to prevent compialation errors
    if str.length(long_Label_Text) - 3 < 0 == false
        // get the last 3 characters from the Long Stop line price
        last_Three_Characters := str.substring(long_Label_Text, str.length(long_Label_Text) - 3)
    // draw the Long label displaying the price of the Long line ( display only last 3 characters if specified )
    label_Long = label.new(point = long_Label_Point, style = label.style_label_up, text = show_Only_Last_Three_Digits ? last_Three_Characters : long_Label_Text, color = label_Color_Long, textcolor = labe_Text_Color_Long, xloc = xloc.bar_time, size = size.huge)
    // adjust the Long label x position based off of input
    label_Long.set_x(time + label_Distance_Long * time_Frame)
    // delete the previous Long label
    label.delete(label_Long[1])
    // draw a box when the current price has broken above the Long BOC line ( plus the additional pips from input)
    BOC_Signal = box.new(bar_index[1], high , bar_index, price_BOC_Entry_Long, border_color = na, bgcolor = entry_Signal_Color_Long, extend = extend.right)
    // delete the previous Long BOC signal box
    box.delete(BOC_Signal[1])
    // if show entry signal is false or the current candles high is not above the previous candles high
    if show_Entry_Signal == false or high > price_BOC_Entry_Long == false
        // delete the current Long BOC signal box
        box.delete(BOC_Signal)

//-------------------------------------------------------------------------------------------------------------------------------( Handle Short Data / Drawings ) -------------------------------------------

// if you are going Short
if going_Short
    // draw the Short Stop line above the current candle
    stop_Line_Short = line.new(bar_index[1], price_Stop_Short, bar_index, price_Stop_Short, xloc.bar_index, extend.right, line_Color_Short, line.style_solid, 2)
    // delete the previous Short Stop line
    line.delete(stop_Line_Short[1])
    // if you are showing the BOC ( Break Of Candle ) line
    if show_BOC
        // draw the Short BOC line at the previous candles low
        line_Short_BOC = line.new(bar_index[1], low[1], bar_index, low[1], xloc.bar_index, extend.right, line_BOC_Color_Short, line.style_solid, 2)
        // delete the previous Short BOC line
        line.delete(line_Short_BOC[1])
    // set the default value to ERR ( error )
    last_Three_Characters = "ERR"
    // only show the last three digits of the stop loss price
    if show_Only_Last_Three_Digits
        // remove the decimal when only showing three digshow_Only
        short_Label_Text := str.replace( short_Label_Text , target = ".", replacement = "")
    // check for this condition to prevent compialation errors
    if str.length(short_Label_Text) - 3 < 0 == false// or str.length(short_Label_Text) - 3 < str.length(short_Label_Text) - 1
        // get the last 3 characters from the Short Stop line price
        last_Three_Characters := str.substring(short_Label_Text, str.length(short_Label_Text) - 3)
    // draw the Short label displaying the price of the Short line ( display only last 3 characters if specified )
    label_Short = label.new(point = short_Label_Point, style = label.style_label_down, text = show_Only_Last_Three_Digits ? last_Three_Characters : short_Label_Text, color = label_Color_Short, textcolor = label_Text_Color_Short, xloc = xloc.bar_time, size = size.huge)
    // adjust the Short label x position based off of input
    label_Short.set_x(time + label_Distance_Short * time_Frame)
    // delete the previous Short label  
    label.delete(label_Short[1])
    // draw a box when the current price has broken below the Short BOC line ( minus the additional pips from input)
    BOC_Signal = box.new(bar_index[1], price_BOC_Entry_Short, bar_index, low, border_color = na, bgcolor = entry_Signal_Color_Short, extend = extend.right)
    // delete the previous Short BOC signal box
    box.delete(BOC_Signal[1])
    // if show entry signal is false or the current candles low is not below the previous candles low
    if show_Entry_Signal == false or low < price_BOC_Entry_Short == false
        // delete the current Short BOC signal box
        box.delete(BOC_Signal)
    //------------------------------------------------------------------------------------------------------------------------------- ( Execute Functions) ----------------------------------------------------