PhinkTrade Risk Manager Essentials
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © PhinkTrade 2022

//@version=5
indicator('PhinkTrade Risk Manager Essentials v.2.2', shorttitle = 'Risk Manager Essentials v.2.2 [PhinkTrade]', overlay=true)  


////////////////////////////////////
//Start settings
entry1_defVal = 0.0
entry2_defVal = 0.0
entry3_defVal = 0.0
stopLoss_defVal = 0.0
target1_defVal = 0.0
target2_defVal = 0.0
target3_defVal = 0.0
currentEquity_defVal = 1000
percentRisk_defVal = 1
showMinimumIdealTarget_defVal = true
displayAverageTarget_defVal = false
displayAverageEntry_defVal = false
chartCurrencyPrecision_defVal = "2"
baseCurrencyPrecision_defVal = "4"
pricePrecision_defVal = "2" 
labelSizeSetting_defVal = 'Normal'
labelPositionReference_defVal = 'Auto' //'Latest Bar Date / Time', 'Journal Date / Time' 


////////////////////////////////////
// Inputs

// Prices Settings

entry1 = input.price(title='Entry 1', group='Entries', defval=entry1_defVal, inline='entries 1', confirm=true, tooltip='Define your entry price. You can also define 2 more entries in \'Settings\' window.')
entry2 = input.price(title='Entry 2', group='Entries', defval=entry2_defVal, inline='entries 1')
entry3 = input.price(title='Entry 3', group='Entries', defval=entry3_defVal, inline='entries 1')
stopLoss = input.price(title='Stop Loss', defval=stopLoss_defVal, group='Risk', confirm=true, tooltip='Define your stop loss price.')
target1 = input.price(title='Target 1', group='Targets', defval=target1_defVal, inline='targets 1', confirm=true, tooltip='Define your target price. You can also define 2 more targets (or no target at all - set all to 0) in \'Settings\' window.')
target2 = input.price(title='Target 2', group='Targets', defval=target2_defVal, inline='targets 1')
target3 = input.price(title='Target 3', group='Targets', defval=target3_defVal, inline='targets 1')

// Base Settings
currentEquity = input.float(title='Starting Capital (in chart currency)', defval=currentEquity_defVal, group='Base Settings', confirm=true, minval=0.00000001, tooltip="Your starting capital for this trade. Must be set in order for position size to be calculated.\n\n\'Chart currency\' is the one usually displayed at the top right corner, over the scale bar (e.g. USD in a BTCUSD chart).\n\nRecommended: update it before every trade, so your risk amount remains under control. This is the main point of this indicator, after all! 😉")
percentRisk = input.float(title='Risk (as % of Starting Capital)', defval=percentRisk_defVal, minval=0, maxval=100, group='Risk', confirm=true, tooltip='Define how much of your starting capital you are willing to lose if this trade gets stopped out (in % terms).') / 100

// Journal Settings
tradeDateTime = input.time(title='Trade Date / Time', defval=0, group='Journal', inline='Journal', tooltip='Date and time of the trade. Labels Position Reference setting can use this information to display labels near the date/time defined here.') //timestamp('01 Jan 2021 00:00 +0000')

// Display Settings

showMinimumIdealTarget = input.bool(title='Display Minimum Recommended Target (3:1 Return/Risk Best Practice)', defval=showMinimumIdealTarget_defVal, group='Display Settings')
displayAverageTarget = input.bool(title='Display Average Target', defval=displayAverageTarget_defVal, group='Display Settings')
displayAverageEntry = input.bool(title='Display Average Entry', defval=displayAverageEntry_defVal, group='Display Settings')

chartCurrencyPrecision = input.string(title='Chart Currency Precision', defval=chartCurrencyPrecision_defVal, options=['0','1','2','3','4','5','6','7','8'], group='Display Settings')
baseCurrencyPrecision = input.string(title='Base Currency / Asset Precision', defval=baseCurrencyPrecision_defVal, options=['0','1','2','3','4','5','6','7','8'], group='Display Settings')
pricePrecision = input.string(title='Price Precision', defval=pricePrecision_defVal, options=['0','1','2','3','4','5','6','7','8'], group='Display Settings')

labelSizeSetting = input.string(title='Labels Size', defval=labelSizeSetting_defVal, options=['Tiny', 'Small', 'Normal', 'Large'], group='Display Settings')
labelPositionReference = input.string(title='Labels Position Reference', options=['Auto','Latest Bar Date / Time', 'Journal Date / Time'], defval=labelPositionReference_defVal, group='Display Settings', tooltip='Choose to display labels near the latest bar (real-time), near the date / time defined in Journal settings, above, or automatically (default; if no custom trade date is set, labels will be displayed near the latest bar; otherwise, near the chosen date).')
labelOffsetToTheRight = input.int(title='Labels offset (to the right)', defval=10, group='Display Settings', tooltip='Use to reposition labels farther or closer to reference date / time chosen above.')
secondaryLabelsOffsetToTheRight = input.int(title='Secondary labels offset (to the right)', defval=10, group='Display Settings', tooltip='Use to reposition secondary labels (Minimum Recommended Target, Average Entry and Average Target) farther or closer to reference date / time chosen above.')
longEntriesLabelsBgColor = input.color(title='Long Entries Labels Backg. Color', defval=color.green, group='Display Settings', inline='Colors 1')
longEntriesLabelsTxtColor = input.color(title='Long Entries Labels Text Color', defval=color.white, group='Display Settings', inline='Colors 1')
shortEntriesLabelsBgColor = input.color(title='Short Entries Labels Backg. Color', defval=color.red, group='Display Settings', inline='Colors 2')
shortEntriesLabelsTxtColor = input.color(title='Short Entries Labels Text Color', defval=color.white, group='Display Settings', inline='Colors 2')
longStopLabelBgColor = input.color(title='Long Stop Label Backg. Color', defval=color.red, group='Display Settings', inline='Colors 3')
longStopLabelTxtColor = input.color(title='Long Stop Label Text Color', defval=color.white, group='Display Settings', inline='Colors 3')
shortStopsLabelsBgColor = input.color(title='Short Stop Label Backg. Color', defval=color.green, group='Display Settings', inline='Colors 4')
shortStopsLabelsTxtColor = input.color(title='Short Stop Label Text Color', defval=color.white, group='Display Settings', inline='Colors 4')
longTargetsLabelsBgColor = input.color(title='Long Targets Labels Backg. Color', defval=color.red, group='Display Settings', inline='Colors 5')
longTargetsLabelsTxtColor = input.color(title='Long Targets Labels Text Color', defval=color.white, group='Display Settings', inline='Colors 5')
shortTargetsLabelsBgColor = input.color(title='Short Targets Labels Backg. Color', defval=color.green, group='Display Settings', inline='Colors 6')
shortTargetsLabelsTxtColor = input.color(title='Short Targets Labels Text Color', defval=color.white, group='Display Settings', inline='Colors 6')
minimumLongTargetsLabelsBgColor = input.color(title='Minimum Long Target Label Backg. Color', defval=#F5F5F5, group='Display Settings', inline='Colors 7')
minimumLongTargetsLabelsTxtColor = input.color(title='Minimum Long Target Label Text Color', defval=color.red, group='Display Settings', inline='Colors 7')
minimumShortTargetsLabelsBgColor = input.color(title='Minimum Short Target Label Backg. Color', defval=#F5F5F5, group='Display Settings', inline='Colors 8')
minimumShortTargetsLabelsTxtColor = input.color(title='Minimum Short Target Label Text Color', defval=color.green, group='Display Settings', inline='Colors 8')


////////////////////////////////////
//Functions

getFormattingString(precision) =>

    formattingString = ""

    if precision == 0
        formattingString := "#"
    else if precision > 0
        formattingString := "#."
        for i = 1 to precision
            formattingString := formattingString + "#"
    
    formattingString

targetForReturnRiskRatio(maxRisk, avgEntry, orderSize, rrRatio, tradeSide) =>

    target = 0.0
    
    entryValue = orderSize * avgEntry / syminfo.mintick * syminfo.pointvalue * syminfo.mintick

    if true
        if tradeSide == 'Long'
            target := (syminfo.mintick * ((rrRatio * maxRisk) / (syminfo.pointvalue * syminfo.mintick)) + avgEntry * orderSize) / orderSize
            target
        else
            target := (syminfo.mintick * ((rrRatio * maxRisk) / (syminfo.pointvalue * syminfo.mintick)) + avgEntry * orderSize) / orderSize
            target
            
    target
    
expectedResultIfFullyExecuted(target, avgEntry, orderSize, tradeSide) =>

    netResult = 0.0
    entryValue = orderSize * avgEntry / syminfo.mintick * syminfo.pointvalue * syminfo.mintick
    takeProfitValue = orderSize * target / syminfo.mintick * syminfo.pointvalue * syminfo.mintick
            
    grossResult = takeProfitValue - entryValue
    netResult := grossResult
    netResult
    
returnOverRisk(expectedReturn, allowedRisk) =>

    returnRatio = expectedReturn / allowedRisk
    returnRatio

    
////////////////////////////////////
// Init Vars

maxRisk = currentEquity * percentRisk

entries = array.new_float(0, na)
if entry1 != 0.0
    array.push(entries, entry1)
if entry2 != 0.0
    array.push(entries, entry2)
if entry3 != 0.0
    array.push(entries, entry3)

avgEntry = array.avg(entries)

tradeSide = avgEntry >= stopLoss ? 'Long' : 'Short'

targets = array.new_float(0, na)
if target1 != 0.0
    array.push(targets, target1)
if target2 != 0.0
    array.push(targets, target2)
if target3 != 0.0
    array.push(targets, target3)

avgTarget = array.avg(targets)

// Minimum Ideal Target (based on 3:1 best practice)
minimalIdealReturnRiskRatio = 3

targetsOrderSizesInBaseCurrency = array.new_float(0, na)

maxAllowedPositionSizeInBaseCurrency = 0.0
effectiveMaxAllowedPositionSizeInBaseCurrency = 0.0
averageEntrySizeInBaseCurrency = 0.0
effectiveAverageEntrySizeInBaseCurrency = 0.0

entrySize1InBaseCurrency = 0.0
entrySize2InBaseCurrency = 0.0
entrySize3InBaseCurrency = 0.0

positionSize = 0.0

entrySize1 = 0.0
entrySize2 = 0.0
entrySize3 = 0.0

averageEntrySize = 0.0

averageTakeProfitSizeInBaseCurrency = 0.0

targetSize1InBaseCurrency = 0.0
targetSize2InBaseCurrency = 0.0
targetSize3InBaseCurrency = 0.0

targetSize1 = 0.0
targetSize2 = 0.0
targetSize3 = 0.0

rawAverageTargetSizeInBaseCurrency = 0.0

chartCurrencyFormattingString = getFormattingString(str.tonumber(chartCurrencyPrecision))
baseCurrencyFormattingString = getFormattingString(str.tonumber(baseCurrencyPrecision))
priceFormattingString = getFormattingString(str.tonumber(pricePrecision))


////////////////////////////////////
// Main Calcs

//Calculate Max Allowed Position Size
    
maxAllowedPositionSizeInBaseCurrency := maxRisk / ((avgEntry - stopLoss) / syminfo.mintick * syminfo.pointvalue * syminfo.mintick)

// Calculate Individual Entry Sizes, considering initial / raw Max Position Size, in Base Currency, being equally divided between number of entries
averageEntrySizeInBaseCurrency := float(maxAllowedPositionSizeInBaseCurrency / array.size(entries))  // even distribution between entries (shall be changed in future releases to support uneven distributions)

// Set entry orders sizes for further calculations    
entrySize1InBaseCurrency := entry1 != 0.0 ? averageEntrySizeInBaseCurrency : 0.0
entrySize2InBaseCurrency := entry2 != 0.0 ? averageEntrySizeInBaseCurrency : 0.0
entrySize3InBaseCurrency := entry3 != 0.0 ? averageEntrySizeInBaseCurrency : 0.0

effectiveMaxAllowedPositionSizeInBaseCurrency := entrySize1InBaseCurrency + entrySize2InBaseCurrency + entrySize3InBaseCurrency
effectiveAverageEntrySizeInBaseCurrency := effectiveMaxAllowedPositionSizeInBaseCurrency / array.size(entries)

averageTakeProfitSizeInBaseCurrency := float(averageEntrySizeInBaseCurrency * array.size(entries) / array.size(targets))

targetSize1InBaseCurrency := target1 != 0.0 ? averageTakeProfitSizeInBaseCurrency : 0.0
targetSize2InBaseCurrency := target2 != 0.0 ? averageTakeProfitSizeInBaseCurrency : 0.0
targetSize3InBaseCurrency := target3 != 0.0 ? averageTakeProfitSizeInBaseCurrency : 0.0


// Set Display Variables
positionSize := effectiveMaxAllowedPositionSizeInBaseCurrency
averageEntrySize := effectiveAverageEntrySizeInBaseCurrency

entrySize1 := entry1 != 0.0 ? entrySize1InBaseCurrency : 0.0
entrySize2 := entry2 != 0.0 ? entrySize2InBaseCurrency : 0.0
entrySize3 := entry3 != 0.0 ? entrySize3InBaseCurrency : 0.0

targetSize1 := target1 != 0.0 ? targetSize1InBaseCurrency : 0.0
targetSize2 := target2 != 0.0 ? targetSize2InBaseCurrency : 0.0
targetSize3 := target3 != 0.0 ? targetSize3InBaseCurrency : 0.0

currencyToDisplay = syminfo.basecurrency

//Adjust position size given chosen precision (to avoid a wrong total position size given rounding on average size)
precisionAdjustedPositionSize = array.size(entries) * str.tonumber(str.tostring(math.abs(averageEntrySize), baseCurrencyFormattingString))

// Results and Return : Risk Ratios Calcs

minimumIdealTarget = targetForReturnRiskRatio(maxRisk, avgEntry, effectiveMaxAllowedPositionSizeInBaseCurrency, minimalIdealReturnRiskRatio, tradeSide)
minimumIdealTargetExpectedGainIfFullyExecuted = expectedResultIfFullyExecuted(minimumIdealTarget, avgEntry, effectiveMaxAllowedPositionSizeInBaseCurrency, tradeSide)

// Targets Calculations

// Target 1
target1ExpectedGain = expectedResultIfFullyExecuted(target1, avgEntry, targetSize1InBaseCurrency, tradeSide)
target1ReturnOverRisk = returnOverRisk(target1ExpectedGain, maxRisk)

// Target 2
target2ExpectedGain = expectedResultIfFullyExecuted(target2, avgEntry, targetSize2InBaseCurrency, tradeSide)
target2ReturnOverRisk = returnOverRisk(target2ExpectedGain, maxRisk)

// Target 3
target3ExpectedGain = expectedResultIfFullyExecuted(target3, avgEntry, targetSize3InBaseCurrency, tradeSide)
target3ReturnOverRisk = returnOverRisk(target3ExpectedGain, maxRisk)

// Average Target
avgTargetExpectedGain = expectedResultIfFullyExecuted(avgTarget, avgEntry, effectiveMaxAllowedPositionSizeInBaseCurrency, tradeSide)
avgTargetReturnOverRisk = returnOverRisk(avgTargetExpectedGain, maxRisk)

// All data produced at this point
// Moving to Presentation / Plotting


////////////////////////////////////
// PLOTTINGS

//Labels Positioning and Style
labelXPosition = ((labelPositionReference == 'Auto') and tradeDateTime == 0) or labelPositionReference == 'Latest Bar Date / Time' ? time + labelOffsetToTheRight * (time - time[1]) : tradeDateTime + labelOffsetToTheRight * (time - time[1])
secondaryLabelXPosition = ((labelPositionReference == 'Auto') and tradeDateTime == 0) or labelPositionReference == 'Latest Bar Date / Time' ? time + secondaryLabelsOffsetToTheRight * (time - time[1]) : tradeDateTime + secondaryLabelsOffsetToTheRight * (time - time[1])
labelStyle = label.style_label_left
labelSize = labelSizeSetting == 'Small' ? size.small : labelSizeSetting == 'Tiny' ? size.tiny : labelSizeSetting == 'Normal' ? size.normal : labelSizeSetting == 'Large' ? size.large : size.small


// Primary Labels

// Entries 

entry1LabelString = 'Entry 1: ' + (tradeSide == 'Long' ? 'Buy ' : 'Sell ') + str.tostring(math.abs(entrySize1), baseCurrencyFormattingString) + ' ' + currencyToDisplay + ' at ' + str.tostring(entry1, priceFormattingString)
entry1TooltipString = entry1LabelString
entry1Label = entry1 > 0.0 ? label.new(x=labelXPosition, y=entry1, text=entry1LabelString, color=tradeSide == 'Long' ? longEntriesLabelsBgColor : shortEntriesLabelsBgColor, textcolor=tradeSide == 'Long' ? longEntriesLabelsTxtColor : shortEntriesLabelsTxtColor, style=labelStyle, xloc=xloc.bar_time, size=labelSize, tooltip=entry1TooltipString) : na
label.delete(entry1Label[1])

entry2LabelString = 'Entry 2: ' + (tradeSide == 'Long' ? 'Buy ' : 'Sell ') + str.tostring(math.abs(entrySize2), baseCurrencyFormattingString) + ' ' + currencyToDisplay + ' at ' + str.tostring(entry2, priceFormattingString)
entry2TooltipString = entry2LabelString
entry2Label = entry2 > 0.0 ? label.new(x=labelXPosition, y=entry2, text=entry2LabelString, color=tradeSide == 'Long' ? longEntriesLabelsBgColor : shortEntriesLabelsBgColor, textcolor=tradeSide == 'Long' ? longEntriesLabelsTxtColor : shortEntriesLabelsTxtColor, style=labelStyle, xloc=xloc.bar_time, size=labelSize, tooltip=entry2TooltipString) : na
label.delete(entry2Label[1])

entry3LabelString = 'Entry 3: ' + (tradeSide == 'Long' ? 'Buy ' : 'Sell ') + str.tostring(math.abs(entrySize3), baseCurrencyFormattingString) + ' ' + currencyToDisplay + ' at ' + str.tostring(entry3, priceFormattingString)
entry3TooltipString = entry3LabelString
entry3Label = entry3 > 0.0 ? label.new(x=labelXPosition, y=entry3, text=entry3LabelString, color=tradeSide == 'Long' ? longEntriesLabelsBgColor : shortEntriesLabelsBgColor, textcolor=tradeSide == 'Long' ? longEntriesLabelsTxtColor : shortEntriesLabelsTxtColor, style=labelStyle, xloc=xloc.bar_time, size=labelSize, tooltip=entry3TooltipString) : na
label.delete(entry3Label[1])

// Stop Loss

stopLossLabelString = 'Stop Loss: ' + (tradeSide == 'Long' ? 'Sell ' : 'Buy ') + str.tostring(math.abs(precisionAdjustedPositionSize)) + ' ' + currencyToDisplay + ' at ' + str.tostring(stopLoss, priceFormattingString) + ' (Gross Risk: ' + str.tostring(maxRisk, chartCurrencyFormattingString) + ' ' + syminfo.currency + ')'
stopLossTooltipString = stopLossLabelString
stopLossLabel = stopLoss > 0.0 ? label.new(x=labelXPosition, y=stopLoss, text=stopLossLabelString, color=tradeSide == 'Long' ? longStopLabelBgColor : shortStopsLabelsBgColor, textcolor=tradeSide == 'Long' ? longStopLabelTxtColor : shortStopsLabelsTxtColor, style=labelStyle, xloc=xloc.bar_time, size=labelSize, tooltip=stopLossTooltipString) : na
label.delete(stopLossLabel[1])

// Targets

target1BuySellLabelString = (tradeSide == 'Long' ? 'Sell ' : 'Buy ') + str.tostring(math.abs(targetSize1), baseCurrencyFormattingString) + ' ' + currencyToDisplay
target1LabelString = 'Target 1: ' + target1BuySellLabelString + ' at ' + str.tostring(target1, priceFormattingString) + ' (Gross Return: ' + str.tostring(target1ExpectedGain, chartCurrencyFormattingString) + ' ' + syminfo.currency + '; ' + str.tostring(target1ReturnOverRisk, '#.##') + ':1 R/R)'
target1TooltipString = target1LabelString + '. Return if fully executed at entry and target.'
intendedTargetLabel = target1 > 0.0 ? label.new(x=labelXPosition, y=target1, text=target1LabelString, color=tradeSide == 'Long' ? longTargetsLabelsBgColor : shortTargetsLabelsBgColor, textcolor=tradeSide == 'Long' ? longTargetsLabelsTxtColor : shortTargetsLabelsTxtColor, style=labelStyle, xloc=xloc.bar_time, size=labelSize, tooltip=target1TooltipString) : na
label.delete(intendedTargetLabel[1])

target2BuySellLabelString = (tradeSide == 'Long' ? 'Sell ' : 'Buy ') + str.tostring(math.abs(targetSize2), baseCurrencyFormattingString) + ' ' + currencyToDisplay
target2LabelString = 'Target 2: ' + target2BuySellLabelString + ' at ' + str.tostring(target2, priceFormattingString) + ' (Gross return: ' + str.tostring(target2ExpectedGain, chartCurrencyFormattingString) + ' ' + syminfo.currency + '; ' + str.tostring(target2ReturnOverRisk, '#.##') + ':1 R/R)'
target2TooltipString = target2LabelString + '. Return if fully executed at entry and target.'
target2Label = target2 > 0.0 ? label.new(x=labelXPosition, y=target2, text=target2LabelString, color=tradeSide == 'Long' ? longTargetsLabelsBgColor : shortTargetsLabelsBgColor, textcolor=tradeSide == 'Long' ? longTargetsLabelsTxtColor : shortTargetsLabelsTxtColor, style=labelStyle, xloc=xloc.bar_time, size=labelSize, tooltip=target2TooltipString) : na
label.delete(target2Label[1])

target3BuySellLabelString = (tradeSide == 'Long' ? 'Sell ' : 'Buy ') + str.tostring(math.abs(targetSize3), baseCurrencyFormattingString) + ' ' + currencyToDisplay
target3LabelString = 'Target 3: ' + target3BuySellLabelString + ' at ' + str.tostring(target3, priceFormattingString) + ' (Gross return: ' + str.tostring(target3ExpectedGain, chartCurrencyFormattingString) + ' ' + syminfo.currency + '; ' + str.tostring(target3ReturnOverRisk, '#.##') + ':1 R/R)'
target3TooltipString = target3LabelString + '. Return if fully executed at entry and target.'
target3Label = target3 > 0.0 ? label.new(x=labelXPosition, y=target3, text=target3LabelString, color=tradeSide == 'Long' ? longTargetsLabelsBgColor : shortTargetsLabelsBgColor, textcolor=tradeSide == 'Long' ? longTargetsLabelsTxtColor : shortTargetsLabelsTxtColor, style=labelStyle, xloc=xloc.bar_time, size=labelSize, tooltip=target3TooltipString) : na
label.delete(target3Label[1])


// Secondary Labels

// Minimum Ideal Target

minimumIdealTargetBuySellLabelString = (tradeSide == 'Long' ? 'Sell ' : 'Buy ') + str.tostring(math.abs(positionSize), baseCurrencyFormattingString) + ' ' + currencyToDisplay
minimumIdealTargetLabelString = 'Minimum Recommended Target: ' + minimumIdealTargetBuySellLabelString + ' at ' + str.tostring(minimumIdealTarget, priceFormattingString) + ' (Gross return: ' + str.tostring(minimumIdealTargetExpectedGainIfFullyExecuted, chartCurrencyFormattingString) + ' ' + syminfo.currency + '; ' + str.tostring(minimalIdealReturnRiskRatio, '#.##') + ':1 R/R)'
minimumIdealTargetTooltipString = minimumIdealTargetLabelString + '. Return if fully executed at entry and target.'

minimumIdealTargetLabel = showMinimumIdealTarget and minimumIdealTarget > 0.0 ? label.new(x=secondaryLabelXPosition, y=minimumIdealTarget, text=minimumIdealTargetLabelString, color=tradeSide == 'Long' ? minimumLongTargetsLabelsBgColor : minimumShortTargetsLabelsBgColor, textcolor=tradeSide == 'Long' ? minimumLongTargetsLabelsTxtColor : minimumShortTargetsLabelsTxtColor, style=labelStyle, xloc=xloc.bar_time, size=labelSize, tooltip=minimumIdealTargetTooltipString) : na
label.delete(minimumIdealTargetLabel[1])

// Average Entry

avgEntryBuySellLabelString = (tradeSide == 'Long' ? 'Long ' : 'Short ') + str.tostring(math.abs(positionSize), baseCurrencyFormattingString) + ' ' + currencyToDisplay
avgEntryLabelString = 'Average Entry: ' + avgEntryBuySellLabelString + ' at ' + str.tostring(avgEntry, priceFormattingString)
avgEntryTooltipString = avgEntryLabelString
avgEntryLabel = avgEntry > 0.0 and displayAverageEntry and array.size(entries) > 1 ? label.new(x=secondaryLabelXPosition, y=avgEntry, text=avgEntryLabelString, color=tradeSide == 'Long' ? longEntriesLabelsBgColor : shortEntriesLabelsBgColor, textcolor=tradeSide == 'Long' ? longEntriesLabelsTxtColor : shortEntriesLabelsTxtColor, style=labelStyle, xloc=xloc.bar_time, size=labelSize, tooltip=avgEntryTooltipString) : na
label.delete(avgEntryLabel[1])

// Average Target

avgTargetBuySellLabelString = (tradeSide == 'Long' ? 'Sell ' : 'Buy ') + str.tostring(math.abs(positionSize), baseCurrencyFormattingString) + ' ' + currencyToDisplay
avgTargetLabelString = 'Average Target: ' + avgTargetBuySellLabelString + ' at ' + str.tostring(avgTarget, priceFormattingString) + ' (Gross return: ' + str.tostring(avgTargetExpectedGain, chartCurrencyFormattingString) + ' ' + syminfo.currency + '; ' + str.tostring(avgTargetReturnOverRisk, '#.##') + ':1 R/R)'
avgTargetTooltipString = avgTargetLabelString + '. Return if fully executed at entry and target.'
avgTargetLabel = avgTarget > 0.0 and displayAverageTarget and array.size(targets) > 1 ? label.new(x=secondaryLabelXPosition, y=avgTarget, text=avgTargetLabelString, color=tradeSide == 'Long' ? longTargetsLabelsBgColor : shortTargetsLabelsBgColor, textcolor=tradeSide == 'Long' ? longTargetsLabelsTxtColor : shortTargetsLabelsTxtColor, style=labelStyle, xloc=xloc.bar_time, size=labelSize, tooltip=avgTargetTooltipString) : na
label.delete(avgTargetLabel[1])
