Get Highest High Prior to Lowest Low FPL

I'm working on a more comprehensive Floating PL study (used in conjunction with strategies) and need to calculate the Peak to Valley drawdown percentage. I'm able to calculate the drawdown fine when the HighestAll value occurs before the LowestAll value. But when the LowestAll value occurs BEFORE HighestAll value I can't seem to figure out how to get the Highest value prior to the bar number of the LowestAll value.
Any insight would be much appreciated.
 
  1. Find the bar number of the lowest low
  2. Set the temp high value to high for all bars below that bar number and to 0 for all bars above that bar number
  3. Find the highest high of all the temp high values
  4. Profit
 

Join useThinkScript to post your question to a community of 21,000+ developers and traders.

  1. Find the bar number of the lowest low
  2. Set the temp high value to high for all bars below that bar number and to 0 for all bars above that bar number
  3. Find the highest high of all the temp high values
  4. Profit
The issue I'm running into isn't so much the logic, I have that hammered out. It's the syntax. Specifically, how to iterate over the bars preceding the LowestLow bar number. My initial thought was to add a condition to get the current bar number if LowestLow then use that value as the length for GetMaxValueOffset() . But that function doesn't accept dynamic variables for length. I tried using a recursive variable to check if the prev bar, is higher than the current bar - but once again, the issue was how to start at the correct index (i.e. LowestLow barNumber()). Lastly, I attempted to fold() everything, but same issue with dynamic indexing. So not sure what specific syntax to use in order to get that highest value preceeding the lowest low.
 
Ruby:
# +------------------------------------------------------------+
# |   Example: Find the highest value before the lowest low    |
# |                        Robert Payne                        |
# |               https://funwiththinkscript.com               |
# +------------------------------------------------------------+
# 1. Find the bar number of the lowest low
def bn = BarNumber();
def lowestLowBarNumber = HighestAll(if low == LowestAll(low) then bn else 0);
# 2. Set the temp high value to high for all bars below that bar number
#    and to 0 for all bars above that bar number
def tempHigh = if bn < lowestLowBarNumber then high else 0;
# 3. Find the highest high of all the temp high values
def highestHighBefore = HighestAll(tempHigh);
# 4. Profit
plot highLine = highestHighBefore;

ToZmyoa.png
 
Awesome, thanks @RobertPayne. Had to make a few minor tweaks to suit my use-case, but this worked perfect. Once I finish with the full custom P&L study i'll post it to the forum, but in the interim here's an excerpt of the code that handles calculating the Max Peak to Valley drawdown for a strategy just in case anyone else is looking to do something similar. Also, if anyone has any feedback on optimization feel free to share.

Code:
def 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"));
def highFPL = HighestAll(FPL);
def LowFPL = LowestAll(FPL);
def bn = BarNumber();


#Drawdown
def lowestLowBarNumber = HighestAll(if FPL == lowFPL then bn else 0);
def highestHighBarNumber = HighestAll(if FPL == highFPL then bn else 0);

def hasPrevLow = lowestLowBarNumber < highestHighBarNumber;

def lowFPLTemp = if bn > highestHighBarNumber then FPL else 0;
def highFPLTemp = if bn < lowestLowBarNumber then FPL else 0;

def lowFPLAfter = LowestAll(lowFPLTemp);
def highFPLBefore = HighestAll(highFPLTemp);

def dd = (lowFPL - highFPL) / highFPL;

def ddBefore = if hasPrevLow
               then (lowFPL - highFPLBefore) / highFPLBefore
               else nan;

def ddAfter = if hasPrevLow 
              then (lowFPLAfter - highFPL) / highFPL
              else nan;

def drawdown; 
if hasPrevLow {
    drawdown = if ddBefore > ddAfter 
               then ddBefore 
               else ddAfter;

} else {
    drawdown = dd;

}


AddLabel(yes, "Max DD: " +  AsPercent(drawdown),
        if drawdown > 0 
        then Color.GREEN
        else Color.RED
);
 
Hello Robert, thanks for the post. It helped me figure out one issue of the lowest bar. Could I send you what I have and maybe you can spot where I am missing the high bar. What I am trying to do is: when chart opens it displays the LowestAll Price and barNumber and HighestAll and barNumber in a Label at the top of the screen. The LowestAll price, lowest bar and HighestAll price work but the HighestAll barNumber is off by several bars(never the same amount). I'm close I just can't see the issue.
 
I figured it out.

This will find the low and high of a chart plus the barnumber for each displayed across the top left of chart.

Code:
def HighLevel = HighestALL(high);
def bnh = barNumber();
def LowLevel = LowestAll(low);
def bnl = BarNumber();

def lowestLowBarNumber = HighestAll(if low == LowestAll(low) then bnl else 0);
def highestHighBarNumber= HighestAll(if high == HighestAll(high) then bnl else 1);

AddLabel(yes, "Low: " + LowLevel + " SB: " + lowestLowBarNumber, Color.WHITE);
AddLabel(yes, "High: " + HighLevel + " SB: " + highestHighBarNumber, Color.WHITE);
 
Good evening, I have been making a scanner that searches for a specific pattern in thinkscript, it is supposed to scan between the last 20 to 10 bars, get the highest high between that point and then search for the lowest low after; that is between the highest high and the 10 bars, I have come up with this but I'm missing the part where it searches for the lowest low after the HH because the Lowest() function needs constants in the length parameter, so I'm stuck trying to figure out how can I get the number of days between the HH and the 10-day bar, without it being a variable, since otherwise, the function will not allow it. Thank you in advance, have a good day.
Code:
input BetweenOldestBar = 20;
input BetweenNewestBar = 10;
input PercentageDifference = 5;

def DifferenceBars = BetweenOldestBar - BetweenNewestBar;
def HHigh = Highest(HIGH[BetweenNewestBar], DifferenceBars);
def lowAfterHighest = if HHigh then Lowest(low[-BetweenNewestBar],BetweenNewestBar-1) else lowAfterHighest[1];
#
def DollarDifference = HHigh - lowAfterHighest;
def ConverterDollarTOPercentage = DollarDifference/HHigh;
def PercentageConverter = PercentageDifference/100;
def Condition = ConverterDollarTOPercentage > PercentageConverter and LowAfterHighest > High[BetweenOldestBar];

plot Scan = Condition;
 
Good evening, I have been making a scanner that searches for a specific pattern in thinkscript, it is supposed to scan between the last 20 to 10 bars, get the highest high between that point and then search for the lowest low after; that is between the highest high and the 10 bars, I have come up with this but I'm missing the part where it searches for the lowest low after the HH because the Lowest() function needs constants in the length parameter, so I'm stuck trying to figure out how can I get the number of days between the HH and the 10-day bar, without it being a variable, since otherwise, the function will not allow it. Thank you in advance, have a good day.
Code:
input BetweenOldestBar = 20;
input BetweenNewestBar = 10;
input PercentageDifference = 5;

def DifferenceBars = BetweenOldestBar - BetweenNewestBar;
def HHigh = Highest(HIGH[BetweenNewestBar], DifferenceBars);
def lowAfterHighest = if HHigh then Lowest(low[-BetweenNewestBar],BetweenNewestBar-1) else lowAfterHighest[1];
#
def DollarDifference = HHigh - lowAfterHighest;
def ConverterDollarTOPercentage = DollarDifference/HHigh;
def PercentageConverter = PercentageDifference/100;
def Condition = ConverterDollarTOPercentage > PercentageConverter and LowAfterHighest > High[BetweenOldestBar];

plot Scan = Condition;

There might be an easier way, but this seems to find the low after the high within the 20-10 bar range. This is a regular study and I've left the bubbles to visualize the approach, which is based on the bar numbers at each point.

Code:
input BetweenOldestBar = 20;
input BetweenNewestBar = 10;

def DifferenceBars  = BetweenOldestBar - BetweenNewestBar;


def barNum = if IsNaN(close) then Double.NaN else barNumber();
def lastBar = HighestAll(barNum);
def barOldest = if lastBar <= BetweenOldestBar then 1 else lastBar - BetweenOldestBar + 1;
def barNewest = if lastBar <= BetweenNewestBar then 1 else lastBar - BetweenNewestBar + 1;
def inRange = if BarNumber() >= barOldest and BarNumber() < barNewest then 1 else 0;

AddChartBubble(lastBar == BarNumber(), "price location" = HIGH, "Last: " + lastBar, Color.CYAN);
AddChartBubble(barOldest == BarNumber(), "price location" = HIGH, "P1: " + barOldest, Color.CYAN);
AddChartBubble(barNewest == BarNumber(), "price location" = HIGH, "P2: " + barNewest, Color.CYAN);

AddVerticalLine(barOldest == BarNumber(), "Oldest: " + BarNumber(), Color.CYAN);
AddVerticalLine(barNewest == BarNumber(), "Newest: " + BarNumber(), Color.CYAN);

def periodH = if barNewest - 1 == BarNumber() then Highest(high, DifferenceBars) else 0;
plot periodHigh = HighestAll(periodH);

def highBarNumber = if inRange and periodHigh == high then BarNumber() else highBarNumber[1];
def afterHigh = if highBarNumber > 0 and BarNumber() > highBarNumber and inRange then 1 else 0;

AddChartBubble(periodHigh == high and afterHigh, "price location" = HIGH, "period high: " + highBarNumber, Color.CYAN);

def lowsAH = if afterHigh then low else Double.NaN;
plot lowAfterHigh = LowestAll(lowsAH);
 

Similar threads

Not the exact question you're looking for?

Start a new thread and receive assistance from our community.

87k+ Posts
264 Online
Create Post

Similar threads

Similar threads

The Market Trading Game Changer

Join 2,500+ subscribers inside the useThinkScript VIP Membership Club
  • Exclusive indicators
  • Proven strategies & setups
  • Private Discord community
  • ‘Buy The Dip’ signal alerts
  • Exclusive members-only content
  • Add-ons and resources
  • 1 full year of unlimited support

Frequently Asked Questions

What is useThinkScript?

useThinkScript is the #1 community of stock market investors using indicators and other tools to power their trading strategies. Traders of all skill levels use our forums to learn about scripting and indicators, help each other, and discover new ways to gain an edge in the markets.

How do I get started?

We get it. Our forum can be intimidating, if not overwhelming. With thousands of topics, tens of thousands of posts, our community has created an incredibly deep knowledge base for stock traders. No one can ever exhaust every resource provided on our site.

If you are new, or just looking for guidance, here are some helpful links to get you started.

What are the benefits of VIP Membership?
VIP members get exclusive access to these proven and tested premium indicators: Buy the Dip, Advanced Market Moves 2.0, Take Profit, and Volatility Trading Range. In addition, VIP members get access to over 50 VIP-only custom indicators, add-ons, and strategies, private VIP-only forums, private Discord channel to discuss trades and strategies in real-time, customer support, trade alerts, and much more. Learn all about VIP membership here.
How can I access the premium indicators?
To access the premium indicators, which are plug and play ready, sign up for VIP membership here.
Back
Top