Strategy PnL Library
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © serkany88

//@version=5

// @description TODO: This is a library that helps you learn current pnl of position and use it to create your own dynamic take profit or stop loss rules based on current level of your profit.
// 
library("Strategy_PnL_Library")

// @function inTrade: Checks if a position is currently open.
// @returns bool: true for yes, false for no.
export inTrade() => 
	strategy.position_size != 0 //Checks if any position is open

// @function inTrade: Checks if a position is currently open. Interchangeable with inTrade but just here for simple semantics.
// @returns bool: true for yes, false for no.
export notInTrade() => 
	strategy.position_size == 0 // Checks if any position is not open

// @function pnl: Calculates current profit or loss of position after the commission. If the strategy is not in trade it will always return na.
// @returns float: Current Profit or Loss of position, positive values for profit, negative values for loss.
export pnl() =>
	//PnL Calculation including comission
    sumOpenGrossPL = 0.0
    for tradeNo = 0 to strategy.opentrades - 1
        sumOpenGrossPL += strategy.opentrades.profit(tradeNo) - strategy.opentrades.commission(tradeNo)
    profit = inTrade() ? sumOpenGrossPL : na

// @function entryBars: Checks how many bars it's been since the entry of the position.
// @returns int: Returns a int of strategy entry bars back. Minimum value is always corrected to 1 to avoid lookback errors.
export entryBars() =>
    //Current bar state of open position used as dynamic length
    tradetime = strategy.opentrades > 0 ? bar_index - strategy.opentrades.entry_bar_index(strategy.opentrades - 1) : na
    tradetime := tradetime == 0 ? 1 : tradetime
	tradetime

// @function pnlvelocity: Calculates the velocity of pnl by following the change in open profit compared to previous bar. If the strategy is not in trade it will always return na.
// @returns float: Returns a float value of pnl velocity.
export pnlvelocity() =>
	x = inTrade() ? ta.change(pnl()) : na

// @function pnlacc: Calculates the acceleration of pnl by following the change in profit velocity compared to previous bar. If the strategy is not in trade it will always return na.
// @returns float: Returns a float value of pnl acceleration.
export pnlacc() =>
	x = inTrade() ? ta.change(pnlvelocity()) : na

// @function pnljerk: Calculates the jerk of pnl by following the change in profit acceleration compared to previous bar. If the strategy is not in trade it will always return na.
// @returns float: Returns a float value of pnl jerk.
export pnljerk() =>
	x = inTrade() ? ta.change(pnlacc()) : na

// @function pnlhigh: Calculates the highest value the pnl has reached since the start of the current position. If the strategy is not in trade it will always return na.
// @returns float: Returns a float highest value the pnl has reached.
export pnlhigh() =>
	x = inTrade() ? ta.highest(pnl(), entryBars()) : na

// @function pnllow: Calculates the lowest value the pnl has reached since the start of the current position. If the strategy is not in trade it will always return na.
// @returns float: Returns a float lowest value the pnl has reached.
export pnllow() =>
	x = inTrade() ? ta.lowest(pnl(), entryBars()) : na

// @function pnldev: Calculates the deviance of the pnl since the start of the current position. If the strategy is not in trade it will always return na.
// @returns float: Returns a float deviance value of the pnl.
export pnldev() =>
	x = inTrade() ? ta.dev(pnl(), entryBars()) : na

// @function pnlvar: Calculates the variance value of the pnl since the start of the current position. If the strategy is not in trade it will always return na.
// @returns float: Returns a float variance value of the pnl.
export pnlvar() =>
	x = inTrade() ? ta.variance(pnl(), entryBars()) : na

// @function pnlstdev: Calculates the stdev value of the pnl since the start of the current position. If the strategy is not in trade it will always return na.
// @returns float: Returns a float stdev value of the pnl.
export pnlstdev() =>
	x = inTrade() ? ta.stdev(pnl(), entryBars()) : na

// @function pnlmedian: Calculates the median value of the pnl since the start of the current position. If the strategy is not in trade it will always return na.
// @returns float: Returns a float median value of the pnl.
export pnlmedian() =>
	x = inTrade() ? ta.median(pnl(), entryBars()) : na