[TT$] Trade Tracker - By BlueJayBird
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © BlueJayBird

//@version=5
indicator(title='[TT$] Trade Tracker - By BlueJayBird', shorttitle='TT$', overlay=true)


// === GLOBAL SCOPE VARIABLES
nl = '\n'
// Main Colors
green_bull = color.new(#26a69a, 0) // Classi Green
red_bear = color.new(#ef5350, 0) // Classi Red

// ========================================================================= //
// ------------------------------> FUNCTIONS <------------------------------ //
// ========================================================================= //
    
// >> Round numbers
// → Credits: PineCoders felas.
f_round(_value, _decimals) =>
	if _decimals == -1
		_value
	else
		_power = math.pow(10, _decimals)
		math.round((math.abs(_value) * _power) / _power * math.sign(_value), 2)

// >> To string
f_string_helper(_prefix, _variable, _round, _suffix) =>
	_res = str.tostring(f_round(_variable, _round))
	_prefix + ': ' + _res + ' ' + _suffix + nl

// >> Get bar_index from timestamp
f_barindex_from_timestamp(_timestamp) =>
	bartime = int(ta.change(time))
	math.floor((timenow - _timestamp) / bartime)

// >> Function returning the sub-string of `_str` to the left of the `_of` separating character.
// → Credits: https://www.tradingview.com/script/l0wdrsUO-String-Manipulation-Framework-PineCoders-FAQ/
f_strLeftOf(_str, _of) =>
	// string _str: string to separate.
	// string _op : separator character.
	string[] _chars = str.split(_str, "")
	int _len = array.size(_chars)
	int _ofPos = array.indexof(_chars, _of)
	string[] _substr = array.new_string(0)
	if _ofPos > 0 and _ofPos <= _len - 1
		_substr := array.slice(_chars, 0, _ofPos)
	string _return = array.join(_substr, "")


// === Settings
// Enablers
enable_trade_tracker = input.bool(defval=true, title='Trade Tracker Indicator', tooltip='For better tracking your trades, both shorts and longs.', group='Settings')
enable_tt_emojis = input.bool(defval=false, title='Emojis 😉', group='Settings')
enable_tt_labels = input.bool(defval=true, title='Data Pane 📐', group='Settings')
// Timezone
tt_time_zone_input = input.string(defval='GMT-3 Argentina Time (ART)', title='Current Timezone', options=['GMT+1 Central European Time (CET)', 'GMT+2 Eastern European Time (EET)', 'GMT+3 Moscow Time (MSK)', 'GMT+4 Armenia Time (AMT)', 'GMT+5 Pakistan Standard Time (PKT)', 'GMT+6 Omsk Time (OMSK)', 'GMT+7 Kranoyask Time (KRAT)', 'GMT+8 China Standard Time (CST)', 'GMT+9 Japan Standard Time (JST)', 'GMT+10 Eastern Australia Standard Time (AEST)', 'GMT+11 Sakhalin Time (SAKT)', 'GMT+12 New Zealand Standard Time (NZST)', 'GMT+0 Greenwich Mean Time (GMT)', 'GMT-1 West Africa Time (WAT)', 'GMT-2 Azores Time (AT)', 'GMT-3 Argentina Time (ART)', 'GMT-4 Atlantic Standard Time (AST)', 'GMT-5 Eastern Standard Time (EST)', 'GMT-6 Central Standard Time (CST)', 'GMT-7 Mountain Standard Time (MST)', 'GMT-8 Pacific Standard Time (PST)', 'GMT-9 Alaska Standard Time (AKST)', 'GMT-10 Hawaii Standard Time (HST)', 'GMT-11 Nome Time (NT)	X', 'GMT-12 International Date Line West (IDLW)'], group='Settings')
tt_time_zone = f_strLeftOf(tt_time_zone_input, ' ')


// ========================================================================= //
// --------------------------> Trade Tracker <------------------------------ //
// ========================================================================= //

// === Inputs
// Main
tt_time			= input.time(defval=0, title='⏰ Entry Time', group='Input', confirm=true) // tt_time → 
tt_entry		= input.price(defval=0, title='🎲 Entry ($)', group='Input', confirm=true)
tt_target		= input.price(defval=0, title='🎯 Target ($)', group='Input', confirm=true)
tt_stop			= input.float(defval=0.5, title='⛔ Stop-Loss (%)', group='Input')
tt_break		= input.float(defval=0.26, title='🪓 Break-Even (%)', group='Input')
tt_fee			= input.float(defval=0.1, title='💱 Fee (%)', group='Input')
tt_else			= input.price(defval=0, title='👻 Else ($)', group='Input')
tt_quote = input.string(defval='', title='Quote',tooltip='Insert suitable quote value for the pair (for example: USD, USDT, etc)', group='Input') // For Base-Quote pairs

// Modifiers
tt_offset_right		= input.int(defval=3, title='Offset Right (🎲🎯👻)', group='Offset')
tt_offset_left		= input.int(defval=1, title='Offset Left (⛔🪓)', group='Offset')
tt_offset_current = input.int(defval=6, title='Offset Current (💲)', group='Offset')
tt_label_offset_x = input.int(defval=23, title='Offset Data Pane X📐(Bars)', group='Offset')
tt_label_offset_y = input.int(defval=0, title='Offset Data Pane Y📐 ($)', group='Offset')

// timestamp(timezone, year, month, day, hour, minute, second) → series[integer]
tt_timestamp			= timestamp(year(tt_time, tt_time_zone), month(tt_time, tt_time_zone), dayofmonth(tt_time, tt_time_zone), hour(tt_time, tt_time_zone), minute(tt_time, tt_time_zone))

// === Enablers
enable_tt_entry  = input.bool(defval=true, title='Entry 🎲', group='Emoji Enablers')
enable_tt_target = input.bool(defval=true, title='Target 🎯', group='Emoji Enablers')
enable_tt_stop   = input.bool(defval=true, title='Stop-Loss ⛔', group='Emoji Enablers')
enable_tt_break  = input.bool(defval=true, title='Break-Even 🪓', group='Emoji Enablers')
enable_tt_else   = input.bool(defval=false, title='Else 👻', group='Emoji Enablers')
enable_tt_current  = input.bool(defval=true, title='Current Closing 💲', group='Emoji Enablers')

// === Plotting
// >> Colors
tt_entry_color	= color.new(#f4ff04, 0) // Strong Yellow
tt_target_color	= color.new(color.lime, 0)
tt_stop_color	= color.new(color.red, 0)
tt_break_color	= color.new(color.blue, 0)
tt_else_color	= color.new(color.white, 0)
tt_current_color = close >= open ? green_bull : red_bear
// >> Line Locations
float tt_stop_location = 0.0
float tt_break_location = 0.0
if tt_target <= tt_entry
	tt_stop_location := tt_entry + tt_entry * (tt_stop / 100)
	tt_break_location := tt_entry - tt_entry * (tt_break / 100)
else
	tt_stop_location := tt_entry - tt_entry * (tt_stop / 100)
	tt_break_location := tt_entry + tt_entry * (tt_break / 100)
// >> Emojis Left Location
tt_offset_left_new = (f_barindex_from_timestamp(tt_time) + tt_offset_left) * -1

// >> Emojis
plotchar(series=enable_trade_tracker and enable_tt_emojis and enable_tt_entry ? tt_entry : na, title='Entry', char='🎲', location=location.absolute, color=tt_entry_color , offset=tt_offset_right, size=size.small, show_last=1)
plotchar(series=enable_trade_tracker and enable_tt_emojis and enable_tt_target ? tt_target : na, title='Target', char='🎯', location=location.absolute, color=tt_target_color , offset=tt_offset_right, size=size.small, show_last=1)
plotchar(series=enable_trade_tracker and enable_tt_emojis and enable_tt_stop ? tt_stop_location : na, title='Stop', char='⛔', location=location.absolute, color=tt_stop_color , offset=tt_offset_left_new, size=size.small, show_last=1)
plotchar(series=enable_trade_tracker and enable_tt_emojis and enable_tt_break ? tt_break_location : na, title='Break', char='🪓', location=location.absolute, color=tt_break_color , offset=tt_offset_left_new, size=size.small, show_last=1)
plotchar(series=enable_trade_tracker and enable_tt_emojis and enable_tt_current ? close : na, title='Current', char='$', location=location.absolute, color=tt_current_color , offset=tt_offset_current, size=size.small, show_last=1)
plotchar(series=enable_trade_tracker and enable_tt_emojis and enable_tt_else ? tt_else : na, title='Else', char='👻', location=location.absolute, color=tt_else_color , offset=tt_offset_right, size=size.small, show_last=1)
// >> Lines
// TODO: https://stackoverflow.com/questions/62143030/adding-new-line-in-future-price
entry_line 	= line.new(x1=tt_time, y1=tt_entry, x2=time, y2=tt_entry, xloc=xloc.bar_time, extend=extend.none, color=tt_entry_color, style=line.style_solid, width=2)
target_line = line.new(x1=tt_time, y1=tt_target, x2=time, y2=tt_target, xloc=xloc.bar_time, extend=extend.none, color=tt_target_color, style=line.style_solid,   width=1)
stop_line 	= line.new(x1=tt_time, y1=tt_stop_location, x2=time, y2=tt_stop_location, xloc=xloc.bar_time, extend=extend.none, color=tt_stop_color, style=line.style_solid, width=1)
break_line 	= line.new(x1=tt_time, y1=tt_break_location, x2=time, y2=tt_break_location, xloc=xloc.bar_time, extend=extend.none, color=tt_break_color, style=line.style_solid, width=1)
// >> Update Lines
line.set_xy2(id=entry_line, x=time, y=tt_entry)
line.set_xy2(id=target_line, x=time, y=tt_target)
line.set_xy2(id=stop_line, x=time, y=tt_stop_location)
line.set_xy2(id=break_line, x=time, y=tt_break_location)
// >> Lines Deletion
if not enable_trade_tracker
	line.delete(entry_line)
	line.delete(target_line)
	line.delete(stop_line)
	line.delete(break_line)
// // >> Fill Lines
// linefill.new(entry_line, stop_line, color.new(color.red, 95))
// linefill.new(entry_line, target_line, color.new(color.green, 95))

// === Boxes
var box_stop = box.new(left=time, top=0, right=time, bottom=0, xloc=xloc.bar_time)
var box_target = box.new(left=time, top=0, right=time, bottom=0, xloc=xloc.bar_time)
// Update boxes
box_switch = tt_target <= tt_entry ? tt_entry + tt_entry * (tt_stop / 100) : tt_entry - tt_entry * (tt_stop / 100)
// Update Stop Box
box.set_lefttop(box_stop, tt_time, tt_entry)
box.set_rightbottom(box_stop, time, box_switch)
box.set_border_color(box_stop, color.new(color.white, 100))
box.set_bgcolor(box_stop, color.new(color.red, 90))
// Update Target Box
box.set_lefttop(box_target, tt_time, tt_entry)
box.set_rightbottom(box_target, time, tt_target)
box.set_border_color(box_target, color.new(color.white, 100))
box.set_bgcolor(box_target, color.new(color.green, 90))
// Box Deletion
if not enable_trade_tracker
	box.delete(box_stop)
	box.delete(box_target)

// ========================================================================= //
// ----------------------> Trade Tracker Data Label <----------------------- //
// ========================================================================= //

// === Strings
// - Declaration
tt_text_main = ''
tt_splitter = '-------------------------\n'
// - Time Format
tt_format_1 = '{0,date,medium}'
tt_format_2 = '{0,time,medium}'

// === Label Presets
var label tt_data_id = na
label.delete(tt_data_id)
tt_data_id := label.new(x=bar_index + tt_label_offset_x, y=tt_entry + tt_label_offset_y, text=tt_text_main, xloc=xloc.bar_index, color=color.new(color.black, 10), style=label.style_label_center, textcolor=color.white, size=size.large, textalign=text.align_left)

// === Data Gathering
// Getting data from lines
// - Target
float tt_target_percent = 0.0
tt_target_percent := math.abs(((tt_target - tt_entry) / tt_entry) * 100)
// - Current
float tt_current_percent = 0.0
tt_current_percent := math.abs(((close - tt_entry) / tt_entry) * 100)
// - From Lines
tt_stop_value = line.get_y1(stop_line)
tt_break_value = line.get_y1(break_line)

// === Setting data
// Data 1
tt_data_date = str.format(tt_format_1, tt_timestamp)
tt_data_time = str.format(tt_format_2, tt_timestamp)
tt_data_1a = str.format('🌎 Time Zone: {0}\n', tt_time_zone)
tt_data_1b = str.format('📆 Date: {0}\n', tt_data_date)
tt_data_1c = str.format('⏰ Time: {0}\n', tt_data_time)
tt_dataset_1 = str.format('{0}{1}{2}{3}',tt_data_1a ,tt_data_1b ,tt_data_1c, tt_splitter)
// Data 2
tt_data_2a = f_string_helper('🎲 Entry', tt_entry, 2, tt_quote)
tt_data_2b = f_string_helper('🎯 Target', tt_target, 2, tt_quote)
tt_data_2c = f_string_helper('⛔ Stop', tt_stop_value, 2, tt_quote)
tt_data_2d = f_string_helper('🪓 Break', tt_break_value, 2, tt_quote)
tt_dataset_2 = str.format('{0}{1}{2}{3}{4}', tt_data_2a, tt_data_2b, tt_data_2c, tt_data_2d, tt_splitter)
// Data 3
tt_data_3a = f_string_helper('🎯 Target', tt_target_percent, 2, '%')
tt_data_3b = f_string_helper('⛔ Stop', tt_stop, 2, '%')
tt_data_3c = f_string_helper('🪓 Break', tt_break, 2, '%')
tt_data_3d = f_string_helper('💱 Fee', tt_fee, 2, '%')
tt_dataset_3 = str.format('{0}{1}{2}{3}{4}', tt_data_3a, tt_data_3b, tt_data_3c, tt_data_3d, tt_splitter)
// Data 4
tt_data_4a = f_string_helper('💲 Current', close, 2, tt_quote)
tt_data_4b = str.format('💲 Current: {0} %', str.tostring(f_round(tt_current_percent, 2)))
tt_dataset_4 = str.format('{0}{1}', tt_data_4a, tt_data_4b)
// Debugging Values
// debug_one = str.format('Debug One: {0}\n', bar_index) 
// debug_two = str.format('Debug Two: {0}', bar_index + tt_label_offset_x)
// debug = str.format('{0}{1}', debug_one, debufg_t_ywo)

// === Data Display
tt_text_main := str.format('{0}{1}{2}{3}', tt_dataset_1, tt_dataset_2, tt_dataset_3, tt_dataset_4) //, debug)
label.set_text(id=tt_data_id, text=tt_text_main)
// Pane Deletion
if not enable_tt_labels or not enable_trade_tracker
	label.delete(tt_data_id)


// END

// TODO: 1) Add alerts; 2) Change label for display, use table instead; 3) Add some other variables and tweaks.