Position Size Calculator (EzAlgo)
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// @ EzAlgo

//@version=5
indicator("Position Size Calculator (EzAlgo)", overlay=true)

table_location_input = input.string("Top Right", title="Location", options=["Bottom Right", "Bottom Left", "Bottom Center", "Top Left", "Top Center", "Top Right", "Middle left", "Middle Center", "Middle Right" ], group='Table Settings')

size = input.string(size.small, title='Text Size', options=[size.normal, size.small, size.tiny])

grp1 = 'Price Points'

entry_price = input.price(27000, title='Entry Price', group=grp1, inline='line1')
sl_price    = input.price(26000, title='Stop Loss', group=grp1, inline='line2')

showtp1 = input(true, title='', inline='line3', group=grp1)
showtp2 = input(true, title='', inline='line4', group=grp1)
showtp3 = input(true, title='', inline='line5', group=grp1)
showtp4 = input(true, title='', inline='line6', group=grp1)
tp1_price   = input.price(27400, title='Take Profit 1', group=grp1, inline='line3')
tp2_price   = input.price(28000, title='Take Profit 2', group=grp1, inline='line4')
tp3_price   = input.price(28800, title='Take Profit 3', group=grp1, inline='line5')
tp4_price   = input.price(29800, title='Take Profit 4', group=grp1, inline='line6')

dca_sw = input.bool(true, title='', group=grp1, inline='line1') 


auto_leverage_info="Auto Leverage automatically determines the optimal leverage level for a trade based on the user's Stop Loss price distance from the Entry point and the user-defined risk percentage per Entry. It also considers a user-defined Liquidation Buffer, which is a preset percentage determining how close to the Stop Loss a position can get before it's liquidated. This tool allows traders to optimize their leverage amount according to their risk tolerance."
dca_price_info='This is the value at which you initiate your second, equally-sized and leveraged position when employing Dollar-Cost Averaging (DCA) strategy. Upon reaching the DCA Price, your Entry Price adjusts to the Avg Price (Gray Line), calculated as the midpoint between your initial and DCA entries.'
liq_buff_infp='This is a pre-set percentage that determines how close to your Stop Loss your position can get before its liquidated. By manually setting this buffer, you control your comfort level of risk, and it assists the Auto Leverage feature in optimizing the leverage amount according to your risk tolerance.'
risk_info="This refers to the proportion of your account, expressed as a % or a fixed dollar amount, that you're willing to risk for each trading position. If DCA is checked, this will assume you are entering with half of the total position size per entry."
max_lev_info="This is the highest leverage level you are willing to use, even if the exchange permits higher. This limit applies when the Auto Leverage feature is enabled, ensuring your leverage does not exceed your comfort zone."
mmr_info="Maintenance Margin Rate"

dca_price  = input.price(26500, title='DCA Price', group=grp1, inline='line1',tooltip = dca_price_info)
liq_buff   = input.float(1.0, title='Liquidation Buffer%', group=grp1, inline='line2',tooltip = liq_buff_infp)
tp1_perc   = input.float(40, title='Position %', maxval=100, minval=0, group=grp1, inline='line3')
tp2_perc   = input.float(30, title='Position %', maxval=100, minval=0, group=grp1, inline='line4')
tp3_perc   = input.float(20, title='Position %', maxval=100, minval=0, group=grp1, inline='line5')
tp4_perc   = input.float(10, title='Position %', maxval=100, minval=0, group=grp1, inline='line6')

extend = input(true, title='Extend Lines')

final_tp = (showtp1?tp1_perc:0) + (showtp2?tp2_perc:0) + (showtp3?tp3_perc:0) + (showtp4?tp4_perc:0) 

grp2 = 'Risk Management'


acc_size = input.float(1000, title='Account Size', group=grp2)
risk = input.float(5.00, title='Risk per Entry', step=0.01, group=grp2, inline='risk',tooltip = risk_info)
risk_sw = input.string('%', title='', inline='risk', options=['$', '%'], group=grp2)

lev = input.float(25, title='Manual Leverage', inline='lev', group=grp2)
lev_sw = input.bool(true, title='Use Auto Leverage', inline='lev', group=grp2, tooltip = auto_leverage_info)
max_lev = input.float(50, title='Max Leverage', inline='lev2', group=grp2,tooltip = max_lev_info)
// mmr = input.float(0.5, title='MMR%', inline='lev2', group=grp2,tooltip = mmr_info)


lvg_txt = lev_sw? ' (A)' : ' (M)'


draw_level(x, txt, col) =>
    var L = line.new(bar_index, x, bar_index+1, x, extend=extend.both, color=col)
    var LBL = label.new(bar_index, x, color=color.white, textcolor=col, textalign=text.align_left, style=label.style_none, text=txt + ' (' + str.tostring(x, format.mintick) + ')')
    label.set_x(LBL, bar_index+70)

    if extend==false
        line.set_x1(L, bar_index)
        line.set_x2(L, bar_index+1)
        line.set_extend(L, extend.right)


draw_level2(x, txt, col) =>
    var L = line.new(bar_index, x, bar_index+1, x, extend=extend.both, color=col, style=line.style_dashed)
    var LBL = label.new(bar_index, x, color=color.white, textcolor=col, textalign=text.align_left, style=label.style_none, text=txt + ' (' + str.tostring(x, format.mintick) + ')')
    label.set_x(LBL, bar_index+70)

    if extend==false
        line.set_x1(L, bar_index)
        line.set_x2(L, bar_index+1)
        line.set_extend(L, extend.right)



draw_level(entry_price, 'Entry', #ffffff)
draw_level(sl_price   , 'Stop Loss', #e91e63)

if showtp1 
    draw_level(tp1_price  , str.tostring(tp1_perc) + '% @ TP1', #00e676)
if showtp2 
    draw_level(tp2_price  , str.tostring(tp2_perc) + '% @ TP2', #00e676)
if showtp3 
    draw_level(tp3_price  , str.tostring(tp3_perc) + '% @ TP3', #00e676)
if showtp4 
    draw_level(tp4_price  , str.tostring(tp4_perc) + '% @ TP4', #00e676)


if dca_sw
    draw_level(dca_price, 'DCA Entry', #ffee58)
    draw_level2(math.avg(dca_price,entry_price), 'Avg Entry', #787b86)





liq_price1 = lev_sw?  sl_price * (1-liq_buff/100)  : entry_price * (1-(100/lev)/100)

draw_level(liq_price1  , 'Liquidation', #8f20ff)



// RISK
entry_price := dca_sw==false? entry_price : math.avg(entry_price, dca_price)


SL_value = math.abs(entry_price-liq_price1)

dollar_risk = risk_sw =='%'? acc_size * risk/100 : risk




lev_val = lev_sw? dollar_risk / SL_value*entry_price/dollar_risk : lev
lev_val := math.min(lev_val, max_lev)

QTY = lev_sw?   dollar_risk / SL_value  :  (dollar_risk * lev_val)/entry_price


value = lev_sw?  QTY*entry_price : dollar_risk * lev

margin = risk_sw =='%'? risk/100 * acc_size : risk

sl_loss = (sl_price/entry_price-1) * lev_val * margin


tp1_val = showtp1? tp1_perc/100 * (tp1_price/entry_price - 1) * (QTY * entry_price) : 0
tp2_val = showtp2? tp2_perc/100 * (tp2_price/entry_price - 1) * (QTY * entry_price) : 0
tp3_val = showtp3? tp3_perc/100 * (tp3_price/entry_price - 1) * (QTY * entry_price) : 0
tp4_val = showtp4? tp4_perc/100 * (tp4_price/entry_price - 1) * (QTY * entry_price) : 0

tp_val = tp1_val + tp2_val + tp3_val + tp4_val

tp_total1 = tp1_val + tp2_val
tp_total2 = tp1_val + tp2_val + tp3_val
tp_total3 = tp1_val + tp2_val + tp3_val + tp4_val





// TABLE
string table_location = switch table_location_input
    "Bottom Right"  => position.bottom_right  
    "Top Left"      => position.top_left  
    "Top Center"    => position.top_center  
    "Top Right"     => position.top_right 
    "Middle left"   => position.middle_left 
    "Middle Center" => position.middle_center 
    "Middle Right"  => position.middle_right 
    "Bottom Left"   => position.bottom_left 
    "Bottom Center" => position.bottom_center 
    => position.bottom_right

table_color       = color.new(#07071f, 5 )//input(color.new(#07071f, 5 ), title='Table Color', group='Table Settings')
table_borderColor = color.new(#d1d1d1, 34)//input(color.new(#d1d1d1, 34), title="Table BorderColor", group='Table Settings')

var table dashboard = table.new(table_location, rows=15, columns=15, bgcolor=table_color , frame_color=color.gray, frame_width=2, border_color=table_borderColor, border_width = 0)

table.cell(dashboard, text_size=size, column=1, row=1, text_color=#ffffff, text_halign=text.align_left, text="Wallet: " + str.tostring(acc_size) + ' 💵')
table.cell(dashboard, text_size=size, column=1, row=2, text_color=#ffffff, text_halign=text.align_left, text="Margin: " + str.tostring(margin) + ' 💵')
table.cell(dashboard, text_size=size, column=1, row=3, text_color=#ffffff, text_halign=text.align_left, text="Value: " + str.tostring(value, format.mintick) + ' 💵')

table.cell(dashboard, text_size=size, column=2, row=1, text_color=#ffffff, text_halign=text.align_left, text="Risk per Entry: " + str.tostring(risk) + risk_sw)
table.cell(dashboard, text_size=size, column=2, row=2, text_color=#ffffff, text_halign=text.align_left, text="Leverage: " + str.tostring(lev_val, "#.##") + lvg_txt)
table.cell(dashboard, text_size=size, column=2, row=3, text_color=#ffffff, text_halign=text.align_left, text="Qty: " + str.tostring(QTY, "#.#####"))

table.cell(dashboard, text_size=size, column=1, row=5, text_color=#ffffff, text_halign=text.align_left, text='Entry: ')
table.cell(dashboard, text_size=size, column=1, row=4, text_color=#ffffff, text_halign=text.align_center, text='──────────────')
table.cell(dashboard, text_size=size, column=1, row=6, text_color=#e91e63, text_halign=text.align_left, text='Stop Loss: ')
table.cell(dashboard, text_size=size, column=1, row=7, text_color=#8f20ff, text_halign=text.align_left, text='Liquidation: ')

table.cell(dashboard, text_size=size, column=2, row=5, text_color=#ffffff, text_halign=text.align_left, text=str.tostring(entry_price, format.mintick))
table.cell(dashboard, text_size=size, column=2, row=4, text_color=#ffffff, text_halign=text.align_center, text='──────────────')
table.cell(dashboard, text_size=size, column=2, row=6, text_color=#ffffff, text_halign=text.align_left, text=str.tostring(sl_price, format.mintick) + ' (' + str.tostring(sl_loss, format.mintick)  + ' 💵' + ')')
table.cell(dashboard, text_size=size, column=2, row=7, text_color=#ffffff, text_halign=text.align_left, text=str.tostring(liq_price1, format.mintick) + ' (-' + str.tostring(margin, format.mintick)  + ' 💵' + ')')
table.cell(dashboard, text_size=size, column=1, row=8, text_color=#ffffff, text_halign=text.align_center, text='──────────────')
table.cell(dashboard, text_size=size, column=2, row=8, text_color=#ffffff, text_halign=text.align_center, text='──────────────')
table.cell(dashboard, text_size=size, column=1, row=9 , text_color=#ffffff, text_halign=text.align_left, text='TP Orders: ')
if showtp1
    table.cell(dashboard, text_size=size, column=1, row=10 , text_color=#ffffff, text_halign=text.align_left, text=str.tostring(tp1_perc) + '% @ ' + str.tostring(tp1_price, format.mintick))
if showtp2
    table.cell(dashboard, text_size=size, column=1, row=11 , text_color=#ffffff, text_halign=text.align_left, text=str.tostring(tp2_perc) + '% @ ' + str.tostring(tp2_price, format.mintick))
if showtp3
    table.cell(dashboard, text_size=size, column=1, row=12, text_color=#ffffff, text_halign=text.align_left, text=str.tostring(tp3_perc) + '% @ ' + str.tostring(tp3_price, format.mintick))
if showtp4
    table.cell(dashboard, text_size=size, column=1, row=13, text_color=#ffffff, text_halign=text.align_left, text=str.tostring(tp4_perc) + '% @ ' + str.tostring(tp4_price, format.mintick))


table.cell(dashboard, text_size=size, column=1, row=14, text_color=#ffffff, text_halign=text.align_left, text=str.tostring(final_tp) + '%')

table.cell(dashboard, text_size=size, column=2, row=9 , text_color=#ffffff, text_halign=text.align_left, text='Profit (Total)')
if showtp1
    table.cell(dashboard, text_size=size, column=2, row=10 , text_color=#ffffff, text_halign=text.align_left, text='+' + str.tostring(tp1_val, "#.##"))
if showtp2
    table.cell(dashboard, text_size=size, column=2, row=11 , text_color=#ffffff, text_halign=text.align_left, text='+' + str.tostring(tp2_val, "#.##") + '(' + str.tostring(tp_total1, "#.##") + ')')
if showtp3
    table.cell(dashboard, text_size=size, column=2, row=12, text_color=#ffffff, text_halign=text.align_left, text='+' + str.tostring(tp3_val, "#.##") + '(' + str.tostring(tp_total2, "#.##") + ')')
if showtp4
    table.cell(dashboard, text_size=size, column=2, row=13, text_color=#ffffff, text_halign=text.align_left, text='+' + str.tostring(tp4_val, "#.##") + '(' + str.tostring(tp_total3, "#.##") + ')')
    
table.cell(dashboard, text_size=size, column=2, row=14, text_color=#ffffff, text_halign=text.align_left, text='Total: ' + str.tostring(tp_val, '#.##') + ' 💵')

