Position size FX and Crypto
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © meomeo105
//@version=5
indicator ('Position size [Limit]', "PS", overlay=true, max_bars_back=987)

//Global
textPS = ""
textPSTip = ""
textmanuPS = ""
textmanuPSTip = ""
// Input
risk = input.int(500,"Risk $")
showLabel = input.bool(true,"Show Label Price")
inputentry = input.price(0,title ='Limit Entry Price',inline="Input Entry",confirm=true)
mcolorentry = input.color(color.white,"",inline="Input Entry")
priceSL = input.price(0,title ='Price SL',inline="priceSL",confirm=true)
mcolor = input.color(color.yellow,"",inline="priceSL")
priceTP = input.price(0,title ='Price TP',inline="TPMarket",confirm=true)
mcolorTP = input.color(color.aqua,"",inline="TPMarket")
RR = input.float(1,"Auto cal TP by RR",tooltip="You are set Price TP = 0, Script will automatically calculate the price TP.")
comPerLot = input.float(3.5,"Commission",0,tooltip = "Commission size per lot(one-way). Use for fx,xau")

groupOther = "Other"
offset = input.int(3,"Offset Label",group = groupOther)
sCryptC = input.string("USD,USDT,BUSD,USDC,DAI,TUSD,UST,DGX,USDTPERP,BUSDPERP,USDCPERP","Crypto Currency",tooltip = "Crypto Currency Pair. Config Currency Split by ','",group = groupOther)

aCryptC = str.split(sCryptC,',')
containCryptC(value) =>
    bool result = false
    for i = 0 to array.size(aCryptC)-1
        if(value == array.get(aCryptC,i))
            result := true
    result
getPriceStr(_price) =>
	syminfo.mintick == 0.01 ? str.tostring(_price,'#.##') : syminfo.mintick == 0.001 ? str.tostring(_price,'#.###') : syminfo.mintick == 0.0001 ? str.tostring(_price,'#.####') : syminfo.mintick == 0.00001 ? str.tostring(_price,'#.#####') : syminfo.mintick == 0.000001 ? str.tostring(_price,'#.######') : syminfo.mintick == 0.0000001 ? str.tostring(_price,'#.#######') : syminfo.mintick == 0.00000001 ? str.tostring(_price,'#.########')  : str.tostring(_price,'#')
// 0 SL, 1 entry, 2 tp
var arrayLine = array.new_line()
var arrayLabel = array.new_label()
if(array.size(arrayLine) == 0)
    array.push(arrayLine,line.new(x1=na, y1=na,x2=na, y2=na,color = mcolor,style = line.style_solid,width = 1,xloc = xloc.bar_time))
    array.push(arrayLine,line.new(x1=na, y1=na,x2=na, y2=na,color = mcolorentry,style = line.style_dashed,width = 1,xloc = xloc.bar_time))
    array.push(arrayLine,line.new(x1=na, y1=na,x2=na, y2=na,color = mcolorTP,style = line.style_dashed,width = 1,xloc = xloc.bar_time))
    array.push(arrayLabel,label.new(x = na ,y = na,tooltip = "Stoploss",color=color.rgb(33, 47, 60), textcolor = mcolor,style=label.style_label_left, textalign = text.align_left,xloc = xloc.bar_time))
    array.push(arrayLabel,label.new(x = na ,y = na,color=color.rgb(33, 47, 60), textcolor = mcolorentry,style=label.style_label_left, textalign = text.align_left,xloc = xloc.bar_time))
    array.push(arrayLabel,label.new(x = na ,y = na,color=color.rgb(33, 47, 60), textcolor = mcolorTP,style=label.style_label_left, textalign = text.align_left,xloc = xloc.bar_time))


_pricemanuSL = math.abs(priceSL - inputentry)

if(priceTP > 0)
    RR := nz(math.abs(priceTP - inputentry) / _pricemanuSL)
if(syminfo.type == "forex" or syminfo.ticker == "XAUUSD")
    // Calculate stop loss and take profit
    unicost = syminfo.pointvalue
    if(syminfo.basecurrency == "USD" and syminfo.type == "forex")
        unicost := close / priceSL
    inputpositionSize = risk / (_pricemanuSL * unicost / syminfo.mintick + 2*comPerLot)
    pipMovement    = syminfo.ticker == "XAUUSD" ? 10 : syminfo.mintick == 0.01 ? 10 : syminfo.mintick == 0.001 ? 100 : syminfo.mintick == 0.0001 ? 1000 : syminfo.mintick == 0.00001 ? 10000 : 1
    inputstopLossPips   = _pricemanuSL * pipMovement // Stop loss in pips
    textmanuPS := str.tostring(inputpositionSize,'#.##') + " - " + str.tostring(inputstopLossPips,'#.#') + " - " + str.tostring(RR,'#.##')
    textPSTip := "Lot - Pip - R:R"
	textmanuPSTip := "Lot - Pip - R:R"
else if(syminfo.type == "crypto" and containCryptC(syminfo.currency))
	textmanuPSTip := "PS - R:R"
    inputPS = risk/_pricemanuSL
    textmanuPS := str.tostring(inputPS,'#.##') + " - " + str.tostring(RR,'#.##')

//Label SL time + (offetTrend*1000 * timeframe.in_seconds()
bartime = ta.valuewhen(high >= priceSL and low <= priceSL, time, 0)
if((str.length(textPS)>0 or str.length(textmanuPS)>0))
    line.set_xy1(array.get(arrayLine,0),bartime,priceSL)
    line.set_xy2(array.get(arrayLine,0),time + offset*1000 * timeframe.in_seconds(),priceSL)
	if(showLabel)
        label.set_xy(array.get(arrayLabel,0),time + offset*1000 * timeframe.in_seconds(),priceSL)
        label.set_text(array.get(arrayLabel,0),getPriceStr(priceSL))

bartimemanu = ta.valuewhen(high >= inputentry and low <= inputentry, time, 0)
pricemanuTP = priceSL > inputentry ? (inputentry - math.abs(priceSL - inputentry)*RR) : (inputentry + math.abs(priceSL - inputentry)*RR)
bartimemanuTP = ta.valuewhen(high >= pricemanuTP and low <= pricemanuTP, time, 0)
if (str.length(textmanuPS)>0)
	//Entry Manu
    line.set_xy1(array.get(arrayLine,1),bartimemanu ,inputentry)
    line.set_xy2(array.get(arrayLine,1),time + offset*1000 * timeframe.in_seconds(),inputentry)
    label.set_xy(array.get(arrayLabel,1),time + offset*1000 * timeframe.in_seconds(),inputentry)
    label.set_text(array.get(arrayLabel,1),textmanuPS)
    label.set_tooltip(array.get(arrayLabel,1),textmanuPSTip)
	
    line.set_xy1(array.get(arrayLine,2),bartimemanuTP,pricemanuTP)
    line.set_xy2(array.get(arrayLine,2),time + offset*1000 * timeframe.in_seconds(),pricemanuTP)
	if(showLabel)
		//Label TP Manu
	    label.set_xy(array.get(arrayLabel,2),time + offset*1000 * timeframe.in_seconds(),pricemanuTP)
        label.set_text(array.get(arrayLabel,2),getPriceStr(pricemanuTP))
        label.set_tooltip(array.get(arrayLabel,2),"TP with Entry Price : " + getPriceStr(inputentry))