Get Highest High Prior to Lowest Low FPL

E

eddielee394

Member
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.
 
RobertPayne

RobertPayne

Member
  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
 
E

eddielee394

Member
  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.
 
RobertPayne

RobertPayne

Member
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;
 
E

eddielee394

Member
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
);
 
K

KevinSammy

New member
VIP
Hi Eddie,

Were you able to take this forward?

Thanks!
 
C

chico

New member
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.
 
C

chico

New member
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.

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);
 

Similar threads

Top