#3-SuperTrend & HighLow Strategy by RConner7
#includes Backtesting utility results from eddielee394
#2 min time frame but could 3 ST ATRs and High/Low lookbackPeriod can be adjusted.
#----------------------------
#def atr1 = atr();
#def atr2 = atr() * 2;
#def atr3 = atr() * 3;
def SDmult = 2.3;
def ATRmult9 = 1.3;
def lengthsqu = 5;
input AlertOn = yes;
input AtrMult = 1.0;
input nATR = 4;
input AvgType = AverageType.ExpONENTIAL;
input AtrMult_2 = 1.2;
input nATR_2 = 4;
input AvgType_2 = AverageType.WeIGHTED;
input AtrMult_3 = 2.9;
input nATR_3 = 5;
input AvgType_3 = AverageType.ExPONENTIAL;
input PaintBars = yes;
input BubbleOn = yes;
input ShowLabel = yes;
#SMIExtreme
input audioalarm = yes;
input Price = hlc3;
input RsqLength = 5;
input RsqLimit = .5;
input SmiLimit = 30;
input chopband2 = 70;
input smibarbufr = 4;
input showBreakoutSignals = yes;
plot upper = 70;
plot lower = -70;
def overbought = SmiLimit;
def oversold = -SmiLimit;
def percentDLength = 4;
def percentKLength = 5;
#Stochastics
input over_bought = 80;
input over_sold = 20;
input KPeriod = 12;
input DPeriod = 7;
input priceH = high;
input priceL = low;
input priceC = close;
input averageType = AverageType.EXPONENTIAL;
input lengthmo = 12;
def price7 = (open + close)/2;
def K = (Highest(high, lengthmo) + Lowest(low, lengthmo)) /
2 + ExpAverage(close, lengthmo);
def Momo = Inertia(price7 - K / 2, lengthmo);
def SD = StDev(close, lengthsqu);
def Avg = ExpAverage(close, lengthsqu);
def ATRb = Average(TrueRange(high, close, low), lengthsqu);
def SDup = Avg + (SDmult * SD);
def ATRup = Avg + (ATRmult9 * ATRb);
def Squeeze3 = SDup < ATRup;
def SlowK = reference StochasticFull(over_bought, over_sold, KPeriod, DPeriod, priceH, priceL, priceC, 3, averageType).FullK;
def SlowD = reference StochasticFull(over_bought, over_sold, KPeriod, DPeriod, priceH, priceL, priceC, 3, averageType).FullD;
def badgood = (slowd crosses above slowk);
#ATRBreakout
input BuyEntry = 3;
input SellEntry = 3;
def QB = Highest(high, BuyEntry);
def QS = Lowest(low, SellEntry);
plot trueqb = QB[1];
plot trueqs = QS[1];
plot midline = (QB[1] + QS[1]) / 2;
plot sellline = ((QB[1] * 3) + (QS[1] * 2)) / 5;
plot buyline = ((QS[1] * 3) + (QB[1]) * 2) / 5;
input lengthn = 49;
def lProjection = reference TimeSeriesForecast(price = Price, length = lengthn, "bar plus" = 1);
def convolutionLength = Floor(Sqrt(lengthn));
def LeavittConvolutionSlope = reference LinearRegressionSlope(price = lProjection, length = convolutionLength);
def squeeze = (LeavittConvolutionSlope > .01) or (LeavittConvolutionSlope < -.01);
#def beginDay = if barNumber() < nATR then barNumber() else nATR;
def h = high;
def l = low;
def c = close;
def v = volume;
def bar = BarNumber();
def CloseAllCondition = CLOSE > 600000;
def EOD = close > 600000;
def NotActive = close > 6000000;
def Active1 = close < 60000;
def notrades = close > 60000000;
def ATR = MovingAverage(AvgType, TrueRange(h, c, l), nATR);
def UP_Band_Basic = HL2 + (AtrMult * ATR);
def LW_Band_Basic = HL2 + (-AtrMult * ATR);
def UP_Band = if Active1 and ((UP_Band_Basic < UP_Band[1]) or (close[1] > UP_Band[1])) then UP_Band_Basic else UP_Band[1];
def LW_Band = if Active1 and ((LW_Band_Basic > LW_Band[1]) or (close[1] < LW_Band[1])) then LW_Band_Basic else LW_Band[1];
def ST = if Active1 and ((ST[1] == UP_Band[1]) and (close < UP_Band)) then UP_Band else if ((ST[1] == UP_Band[1]) and (close > UP_Band)) then LW_Band else if ((ST[1] == LW_Band[1]) and (close > LW_Band)) then LW_Band else if ((ST[1] == LW_Band) and (close < LW_Band)) then UP_Band else LW_Band;
plot SuperTrend = ST;
SuperTrend.AssignValueColor(if c < ST then Color.RED else Color.GREEN);
SuperTrend.SetPaintingStrategy(PaintingStrategy.LINE);
AssignPriceColor(if PaintBars and c < ST
then Color.RED
else if PaintBars and c > ST
then Color.GREEN
else Color.CURRENT);
#ST2
input PaintBars_2 = no;
input BubbleOn_2 = no;
input ShowLabel_2 = no;
def beginDay_2 = if BarNumber() < nATR_2 then BarNumber() else nATR_2;
def Active_2 = close < 600000;
def ATR_2 = MovingAverage(AvgType_2, TrueRange(h, c, l), nATR_2);
def UP_Band_Basic_2 = HL2 + (AtrMult_2 * ATR_2);
def LW_Band_Basic_2 = HL2 + (-AtrMult_2 * ATR_2);
def UP_Band_2 = if Active_2 and ((UP_Band_Basic_2 < UP_Band_2[1]) or (close[1] > UP_Band_2[1])) then UP_Band_Basic_2 else UP_Band_2[1];
def LW_Band_2 = if Active_2 and ((LW_Band_Basic_2 > LW_Band_2[1]) or (close[1] < LW_Band_2[1])) then LW_Band_Basic_2 else LW_Band_2[1];
def ST_2 = if Active_2 and ((ST_2[1] == UP_Band_2[1]) and (close < UP_Band_2)) then UP_Band_2 else if ((ST_2[1] == UP_Band_2[1]) and (close > UP_Band_2)) then LW_Band_2 else if ((ST_2[1] == LW_Band_2[1]) and (close > LW_Band_2)) then LW_Band_2 else if ((ST_2[1] == LW_Band_2) and (close < LW_Band_2)) then UP_Band_2 else LW_Band_2;
plot SuperTrend_2 = ST_2;
SuperTrend_2.AssignValueColor(if c < ST_2 then Color.RED else Color.GREEN);
SuperTrend_2.SetPaintingStrategy(PaintingStrategy.LINE);
AssignPriceColor(if PaintBars_2 and c < ST_2
then Color.RED
else if PaintBars_2 and c > ST_2
then Color.GREEN
else Color.CURRENT);
#ST3
input PaintBars_3 = no;
input BubbleOn_3 = no;
input ShowLabel_3 = no;
#def beginDay_3 = if barNumber() < nATR_3 then barNumber() else nATR_3;
def Active_3 = close < 60000000;
def ATR_3 = MovingAverage(AvgType_3, TrueRange(h, c, l), nATR_3);
def UP_Band_Basic_3 = HL2 + (AtrMult_3 * ATR_3);
def LW_Band_Basic_3 = HL2 + (-AtrMult_3 * ATR_3);
def UP_Band_3 = if Active_3 and ((UP_Band_Basic_3 < UP_Band_3[1]) or (close[1] > UP_Band_3[1])) then UP_Band_Basic_3 else UP_Band_3[1];
def LW_Band_3 = if Active_3 and ((LW_Band_Basic_3 > LW_Band_3[1]) or (close[1] < LW_Band_3[1])) then LW_Band_Basic_3 else LW_Band_3[1];
def ST_3 = if Active_3 and ((ST_3[1] == UP_Band_3[1]) and (close < UP_Band_3)) then UP_Band_3 else if ((ST_3[1] == UP_Band_3[1]) and (close > UP_Band_3)) then LW_Band_3 else if ((ST_3[1] == LW_Band_3[1]) and (close > LW_Band_3)) then LW_Band_3 else if ((ST_3[1] == LW_Band_3) and (close < LW_Band_3)) then UP_Band_3 else LW_Band_3;
plot SuperTrend_3 = ST_3;
SuperTrend_3.AssignValueColor(if c < ST_3 then Color.RED else Color.GREEN);
SuperTrend_3.SetPaintingStrategy(PaintingStrategy.LINE);
AssignPriceColor(if PaintBars_3 and c < ST_3
then Color.RED
else if PaintBars_3 and c > ST_3
then Color.GREEN
else Color.CURRENT);
#VWAP
def VWAP = if open > reference VWAP()."VWAP" then 1 else 0;
#Money Flow Index
#input MFI_length = 10;
#input MFI_movingAvgLength = 2;
#def MFI = Average(moneyflow(high, close, low, volume, MFI_length), #MFI_movingAvgLength);
#ADX
#input ADXlength = 14;
#input ADXaverageType = AverageType.WILDERS;
#def ADX = DMI(ADXlength, ADXaverageType).ADX;
#def ADX_Trend = if ADX >= 25 then 1 else 0;
#swing high low
input LookbackPeriod = 2;
input HideCurrentTF = no;
def FirstBar = BarNumber();
def Highest = fold i = 1
to LookbackPeriod + 1
with p = 1
while p
do high > GetValue(high, -i);
def A = if (FirstBar > LookbackPeriod
and high == Highest(high, LookbackPeriod)
and Highest)
then high
else Double.NaN;
def Lowest = fold j = 1
to LookbackPeriod + 1
with q = 1
while q
do low < GetValue(low, -j);
def B = if (FirstBar > LookbackPeriod
and low == Lowest(low, LookbackPeriod)
and Lowest)
then low
else Double.NaN;
#--------------------------------------------------------------
def _highInPeriod1 = Highest(high, LookbackPeriod);
def _lowInPeriod1 = Lowest(low, LookbackPeriod);
#--------------------------------------------------------------
def marketLow1 = if _lowInPeriod1 < _lowInPeriod1[-LookbackPeriod] then _lowInPeriod1 else _lowInPeriod1[-LookbackPeriod];
def _markedLow1 = low == marketLow1;
rec _lastMarkedLow1 = CompoundValue(1, if IsNaN(_markedLow1) then _lastMarkedLow1[1] else if _markedLow1 then low else _lastMarkedLow1[1], low);
#--------------------------------------------------------------
def marketHigh1 = if _highInPeriod1 > _highInPeriod1[-LookbackPeriod] then _highInPeriod1 else _highInPeriod1[-LookbackPeriod];
def _markedHigh1 = high == marketHigh1;
rec _lastMarkedHigh1 = CompoundValue(1, if IsNaN(_markedHigh1) then _lastMarkedHigh1[1] else if _markedHigh1 then high else _lastMarkedHigh1[1], high);
#--------------------------------------------------------------
plot Resistance1 = _lastMarkedHigh1;
plot Support1 = _lastMarkedLow1;
#---------------------------------------
plot ph = Round(A, 2);
ph.SetPaintingStrategy(PaintingStrategy.VALUES_ABOVE);
plot pl = Round(B, 2);
pl.SetPaintingStrategy(PaintingStrategy.VALUES_BELOW);
#--------------------------------------------------------------
Resistance1.SetPaintingStrategy(PaintingStrategy.DASHES);
Resistance1.SetDefaultColor(Color.GREEN);
Resistance1.SetHiding(HideCurrentTF);
#--------------------------------------------------------------
Support1.SetPaintingStrategy(PaintingStrategy.DASHES);
Support1.SetDefaultColor(Color.RED);
Support1.SetHiding(HideCurrentTF);
#Bull
def ni = (open + close)/2;
def fast_ST_UP = if ni > ST then 1 else 0;
def slow_ST_UP = if ni > ST_2 then 1 else 0;
def slower_ST_UP = if ni > ST_3 then 1 else 0;
def any_UP = fast_ST_UP or slower_ST_UP;
def Trend_UP = if ni > ST then 1 else 0;
def Trend_UP_2 = if ni > ST_2 then 1 else 0;
def Trend_UP_3 = if ni > ST_3 then 1 else 0;
def Trend_UP_ALL = Trend_UP and Trend_UP_3;
def higher_close = if close crosses above Resistance1[1] then 1 else 0;
def candle = ((open + close) / 2);
#Bear
def fast_ST_DN = if HL2 < ST then 1 else 0;
def slow_ST_DN = if HL2 < ST_2 then 1 else 0;
def slower_ST_DN = if HL2 < ST_3 then 1 else 0;
def any_DN = fast_ST_DN or slower_ST_DN;
def Trend_DN = if HL2 < ST then 1 else 0;
def Trend_DN_2 = if HL2 < ST_2 then 1 else 0;
def Trend_DN_3 = if HL2 < ST_3 then 1 else 0;
def Trend_DN_ALL = Trend_DN and Trend_DN_3;
def lower_close = if close crosses below Support1[1] then 1 else 0;
plot middleST = (hl2[1] + ST_3[1])/2;
def fg = (high - close) < ((close - open) * 2);
def fgbear = (close-low) < ((open - close) * 2);
def goodcandle = ((high - close) < (hl2 - low)) or (open > high[1]);
def goodsellcandle = (close - low) < (high - hl2);
AddOrder(OrderType.BUY_AUTO, (any_UP) and Trend_UP_ALL and (higher_close or higher_close[1] or higher_close[2]), price = close, tickcolor = Color.ORANGE, arrowcolor = Color.ORANGE, name = "BUY");
AddOrder(OrderType.SELL_TO_CLOSE, (candle crosses below ST_2), price = open[-1], tickcolor = Color.ORANGE, arrowcolor = Color.ORANGE, name = "Sell To Close");
AddOrder(OrderType.SELL_AUTO, (any_DN) and Trend_DN_ALL and (lower_close or lower_close[1] or lower_close[2]) , price = close, tickcolor = Color.YELLOW, arrowcolor = Color.YELLOW, name = "SELL");
AddOrder(OrderType.BUY_TO_CLOSE, (candle crosses above ST_2 ), price = open[-1], tickcolor = Color.ORANGE, arrowcolor = Color.ORANGE, name = "Buy To Close");
Alert((fast_ST_UP or slow_ST_UP or slower_ST_UP) and Trend_UP and Trend_UP_2 and Trend_UP_3 and Active1 and higher_close and notrades, "BUY BUY BUY", Alert.BAR, Sound.Bell);
Alert((fast_ST_DN or slow_ST_DN or slower_ST_DN) and Trend_DN and Trend_DN_2 and Trend_DN_3 and Active1 and lower_close and notrades, "SELL SELL SELL", Alert.BAR, Sound.Ring);
############################
# FPL Extended
# Extended Floating P&L study.
# Author: Eddielee394
# Version: 1.2
# inspired by FPL Dashboard script developed by Mobius
#
############################
#Hint: An extended floating P&L study to be used alongside TOS strategies for measuring hypothetical strategy performance.\nThis is a work in progress. And may contain some bugs or other programming issues.
############################
# Instructions
# - Due to limitations with the thinkscript public api, this specific script must be added to a "strategy" study.
# Generally best practice is to append this script to the end of your custom strategy (ensuring it runs AFTER the
# `AddOrder()` function is called from the strategy). A better method would be to use as a lower study but unless
# a workaround is implemented to handle the `Entry()` function in a lower study, it can only be applied to upper strategies.
#
# - the script uses the `HidePrice()` function which will hide the actual price candles within the upper study,
# only displaying the FPL histogram.
#
############################
############################
# Metrics
# - Active Trade return %
# - Entry Count
# - Winning Entry Count
# - Win rate
# - Avg return
# - avg win
# - avg loss
# - peak to valley dd
# - largest equity dd
# - P&L low
# - P&L high
# - Highest return
# - Lowest return
############################
############################
# Todo:
# - Sharpe Ratio
# - Sortino Ratio
# - Calmar Ratio
# - Avg trade
# duration
# -Buy/hold comparison
############################
#Globals
def nan = Double.NaN;
def bn = if !IsNaN(close) and !IsNaN(close[1]) and !IsNaN(close[-1]) then BarNumber() else bn[1];
#Inputs
input fplBegin = 0000;
#hint fplBegin: start time: the time in which then dailyHighLow profit should consider the day start. Recommended value is 0000.
input fplTargetWinLoss = .50;
#hint fplTargetWinLoss: sets the target winlossRatio (in percent) which determines display colors of the W/L label.
input fplTargetWinRate = 1;
#hint fplTargetWinRate: sets the target winRate (float) which determines display colors of the WinRate label;
input fplHidePrice = no;
#hint fplHidePrice: hide's the underlying price graph. \nDefault is no.
input fplHideFPL = yes;
#hint fplHideFPL: hide's the underlying P&L graph.\nDefault is yes.
input fplShowEntryBubbles = no;
#hint fplShowEntryBubbles: display bubbles on the FPL showing the entry and exit P&L values
input fplEnableDebugging = no;
#hint fplEnableDebugging: displays various debugging labels and chart bubbles. \nIt's recommended to hide the price chart & set the fpl hide fpl setting to yes, when enabling.
#temp input var references
def begin = fplBegin;
def targetWinLoss = fplTargetWinLoss;
def targetWinRate = fplTargetWinRate;
def hidePrice = fplHidePrice;
def hideFPL = fplHideFPL;
def showEntryBubbles = fplShowEntryBubbles;
def enableDebugging = fplEnableDebugging;
#hide chart candles
HidePricePlot(hidePrice);
#Plot default Floating P&L
plot FPL = FPL();
FPL.SetPaintingStrategy(PaintingStrategy.SQUARED_HISTOGRAM);
FPL.DefineColor("Positive and Up", Color.GREEN);
FPL.DefineColor("Positive and Down", Color.DARK_GREEN);
FPL.DefineColor("Negative and Down", Color.RED);
FPL.DefineColor("Negative and Up", Color.DARK_RED);
FPL.AssignValueColor(if FPL >= 0
then if FPL > FPL[1]
then FPL.Color("Positive and Up")
else FPL.Color("Positive and Down")
else if FPL < FPL[1]
then FPL.Color("Negative and Down")
else FPL.Color("Negative and Up"));
FPL.SetHiding(hideFPL);
plot ZeroLine = if IsNaN(close)
then nan
else 0;
ZeroLine.SetDefaultColor(Color.GRAY);
ZeroLine.SetHiding(hideFPL);
#Global Scripts
script calculateDrawdown {
input plLow = 1;
input plHigh = 1;
def _drawdown = if plHigh == 0
then 0 #handles the divide by zero error
else (plLow - plHigh) / plHigh;
plot calculateDrawdown = _drawdown;
}
script incrementValue {
input condition = yes;
input increment = 1;
input startingValue = 0;
def _value = CompoundValue(1,
if condition
then _value[1] + increment
else _value[1], startingValue);
plot incrementValue = _value;
}
;
script getDurationInMins {
input gdimBarCount = 1;
#get the aggregation period (MS per bar)
def aggPeriod = GetAggregationPeriod();
#multiply length of bars by aggPeriod to determine total milliseconds then convert to minutes
def _getDurationInMins = Floor((gdimBarCount * aggPeriod) / 60000);
plot getDurationInMins = _getDurationInMins;
}
script formatDuration {
input fdBarCount = 1;
def _fdDuration = getDurationInMins(fdBarCount);
def _formatDuration = if _fdDuration >= 60 and _fdDuration < 1440 #hours but not days
then 1
else if _fdDuration >= 1440 #days
then 2
else 0;
plot formatDuration = _formatDuration;
}
script calculateDuration {
input cdBarCount = 1;
def _cdDurationFormat = formatDuration(cdBarCount);
def _cdDuration = getDurationInMins(cdBarCount);
#if minutes > hour convert to hour, else if minutes > day, then convert to days
def _calculateDuration = if _cdDurationFormat == 1
then _cdDuration / 60 #convert to hours if greater than 60min but less than a day (1440)
else if _cdDurationFormat == 2
then Ceil(_cdDuration / 1440) #convert to days if greater than 1440mins
else _cdDuration; #fallback to minutes
plot calculateDuration = _calculateDuration;
}
# Entry Calculations. Note: Only parses on a Strategy Chart
def entry = EntryPrice();
def entryPrice = if !IsNaN(entry)
then entry
else entryPrice[1];
def hasEntry = !IsNaN(entry);
def isNewEntry = entryPrice != entryPrice[1];
#is active trade
def Active = if SecondsTillTime(begin) == 0 and
SecondsFromTime(begin) == 0
then 1
else 0;
def highFPL = HighestAll(FPL);
def lowFPL = LowestAll(FPL);
def fplreturn = (FPL - FPL[1]) / FPL[1];
def cumsum = Sum(fplreturn);
def highBarNumber = CompoundValue(1, if FPL == highFPL
then bn
else highBarNumber[1], 0);
def lowBarNumber = CompoundValue(1, if FPL == lowFPL
then bn
else lowBarNumber[1], 0);
#Win/Loss ratios
def entryBarsTemp = if hasEntry
then bn
else nan;
def entryBarNum = if hasEntry and isNewEntry
then bn
else entryBarNum[1];
def isEntryBar = entryBarNum != entryBarNum[1];
def entryBarPL = if isEntryBar
then FPL
else entryBarPL[1];
def exitBarsTemp = if !hasEntry
and bn > entryBarsTemp[1]
then bn
else nan;
def exitBarNum = if !hasEntry and !IsNaN(exitBarsTemp[1])
then bn
else exitBarNum[1];
def isExitBar = exitBarNum != exitBarNum[1];
def exitBarPL = if isExitBar
then FPL
else exitBarPL[1];
def entryReturn = if isExitBar then exitBarPL - exitBarPL[1] else entryReturn[1];
def isWin = if isExitBar and entryReturn >= 0 then 1 else 0;
def isLoss = if isExitBar and entryReturn < 0 then 1 else 0;
def entryReturnWin = if isWin then entryReturn else entryReturnWin[1];
def entryReturnLoss = if isLoss then entryReturn else entryReturnLoss[1];
def entryFPLWins = if isWin then entryReturn else 0;
def entryFPLLosses = if isLoss then entryReturn else 0;
def entryFPLAll = if isLoss or isWin then entryReturn else 0;
#Counts
def entryCount = incrementValue(entryFPLAll);
def winCount = incrementValue(isWin);
def lossCount = incrementValue(isLoss);
def highestReturn = if entryReturnWin[1] > highestReturn[1]
then entryReturnWin[1]
else highestReturn[1];
def lowestReturn = if entryReturnLoss[1] < lowestReturn[1]
then entryReturnLoss[1]
else lowestReturn[1];
def winRate = winCount / lossCount;
def winLossRatio = winCount / entryCount;
def avgReturn = TotalSum(entryFPLAll) / entryCount;
def avgWin = TotalSum(entryFPLWins) / winCount;
def avgLoss = TotalSum(entryFPLLosses) / lossCount;
#Drawdown
def lowestLowBarNumber = HighestAll(if FPL == lowFPL then bn else 0);
def highestHighBarNumber = HighestAll(if FPL == highFPL and FPL != FPL[1] then bn else 0);
def hasPrevLow = lowestLowBarNumber < highestHighBarNumber;
def isPeak = FPL > Highest(FPL[1], 12) and FPL > Highest(FPL[-12], 12);
def isTrough = FPL < Lowest(FPL[1], 12) and FPL < Lowest(FPL[-12], 12);
def _peak = if isPeak then FPL else nan;
def _trough = if isTrough then FPL else nan;
def peak = if !IsNaN(_peak) then FPL else peak[1];
def trough = if !IsNaN(_trough) then FPL else trough[1];
def peakBN = if isPeak then bn else peakBN[1];
def troughBN = if isTrough then bn else troughBN[1];
def ptvDrawdown = if !hasPrevLow then calculateDrawdown(lowFPL, highFPL) else ptvDrawdown[1];
def equityDrawdown = if isTrough and trough < peak then trough - peak else equityDrawdown[1];
def equityDrawdownPercent = if isTrough and trough < peak then calculateDrawdown(trough, peak) else equityDrawdownPercent[1];
def largestEquityDrawdown = LowestAll(equityDrawdown);
def largestEquityDrawdownPercent = LowestAll(equityDrawdownPercent);
def drawdown = if hasPrevLow
then largestEquityDrawdownPercent
else ptvDrawdown;
# Drawdown Durations
def equityDrawdownLength = if bn >= peakBN and bn <= troughBN
then troughBN - peakBN
else equityDrawdownLength[1];
def ptvDrawdownLength = if bn >= highestHighBarNumber and bn <= lowestLowBarNumber
then lowestLowBarNumber - highestHighBarNumber
else ptvDrawdownLength[1];
def equityDrawdownDuration = calculateDuration(HighestAll(equityDrawdownLength));
def equityDrawdownDurationFormat = formatDuration(HighestAll(equityDrawdownLength));
def ptvDrawdownDuration = calculateDuration(ptvDrawdownLength);
def ptvDrawdownDurationFormat = formatDuration(ptvDrawdownLength);
#Daily profit
def Midnight = if Active then FPL else Midnight[1];
def DaysProfit = FPL - Midnight;
#Plots
AddChartBubble(!hideFPL and showEntryBubbles and isEntryBar, FPL, "Entry: " + entryBarPL + " | " + bn, Color.WHITE);
AddChartBubble(!hideFPL and showEntryBubbles and isExitBar, FPL, "Exit: " + exitBarPL,
color = if isWin
then Color.LIGHT_GREEN
else if isLoss
then Color.DARK_RED
else Color.GRAY,
up = no
);
#Labels
AddLabel(yes,
text = "LastEntry: " + AsPrice(entryPrice)
);
AddLabel(hasEntry,
text = "Current Trade % Return: " + AsPercent(cumsum),
color = if cumsum > 0
then Color.GREEN
else Color.RED
);
AddLabel(yes,
text = "Total Trades: " + entryCount,
color = Color.WHITE
);
AddLabel(yes,
text = "WinCount: " + winCount +
" | LossCount: " + lossCount +
" | WinRate: " + winRate,
color = if winRate >= targetWinRate
then Color.GREEN
else Color.RED
);
AddLabel(yes,
text = "W/L: " + AsPercent(winLossRatio),
color = if winLossRatio > targetWinLoss
then Color.GREEN
else Color.RED
);
AddLabel(yes,
text = "HighestReturn: " + AsDollars(highestReturn),
color = if highestReturn > 0
then Color.GREEN
else Color.RED
);
AddLabel(yes,
text = "LowestReturn: " + AsDollars(lowestReturn),
color = if lowestReturn > 0
then Color.GREEN
else Color.RED
);
AddLabel(yes,
text = "AvgReturn: " + AsDollars(avgReturn) +
" | AvgWin: " + AsDollars(avgWin) +
" | AvgLoss: " + AsDollars(avgLoss),
color = if avgReturn >= 0
then Color.LIGHT_GREEN
else Color.RED
);
AddLabel(yes,
text = "PeakToValley DD: " + AsPercent(drawdown) +
" | Duration: " + ptvDrawdownDuration +
if ptvDrawdownDurationFormat == 1
then " hours"
else if ptvDrawdownDurationFormat == 2
then " days"
else " mins" ,
color = if drawdown > 0
then Color.GREEN
else Color.RED
);
AddLabel(largestEquityDrawdown < 0,
text = "Largest Equity DD: " + AsDollars(largestEquityDrawdown) +
" | Duration: " + equityDrawdownDuration +
if equityDrawdownDurationFormat == 1
then " hours"
else if equityDrawdownDurationFormat == 2
then " days"
else " mins",
color = if largestEquityDrawdown > 0
then Color.GREEN
else Color.RED
);
AddLabel(yes,
text = "P&L High" +
(if enableDebugging
then " at bar " + highBarNumber
else "") +
": " + AsDollars(highFPL),
color = Color.GREEN
);
AddLabel(yes,
text = "P&L Low" +
(if enableDebugging
then " at bar " + lowBarNumber
else "") +
": " + AsDollars(lowFPL),
color = Color.RED
);
AddLabel(yes,
text = "Days Profit: $" + DaysProfit,
color = if DaysProfit > 0
then Color.GREEN
else Color.RED
);
AddLabel(yes,
text = "Total Profit: " + AsDollars(FPL),
color = if FPL > 0
then Color.GREEN
else Color.RED
);
#debugging
#peaks & troughs
AddChartBubble(enableDebugging and isPeak, FPL,
text = "FPL: " + FPL
+ " | Peak: " + peak
+ " | Trough: " + trough[-1]
+ " | Drawdown: " + AsPercent(calculateDrawdown(trough, peak))
+ " | PeakBN: " + peakBN
+ " | BarNumber: " + bn,
color = Color.LIME
);
AddChartBubble(enableDebugging and isTrough, FPL,
text = "FPL: " + FPL
+ " | Peak: " + peak
+ " | Trough: " + trough
+ " | Drawdown: " + AsPercent(calculateDrawdown(trough, peak))
+ " | TroughBN: " + troughBN
+ " | BarNumber: " + bn,
color = Color.LIGHT_RED,
up = no
);
AddVerticalLine(enableDebugging and isEntryBar,
text = "EntryBarNum: " + entryBarNum
+ " | ExitBarNum: " + exitBarNum[-1]
+ " | BarNumber: " + bn,
color = Color.WHITE
);
AddVerticalLine(enableDebugging and isExitBar,
text = "EntryBarNum: " + entryBarNum[1]
+ " | ExitbarNum: " + exitBarNum
+ " | BarNumber: " + bn
+ " | EntryReturn: " + entryReturn,
color = if isWin
then Color.LIGHT_GREEN
else if isLoss
then Color.LIGHT_RED
else Color.LIGHT_GREEN
);