Calculating Diagonal Trend Lines Using Fractals and Trigonometry

Viewing 15 posts - 1 through 15 (of 29 total)
  • Author
    Posts
  • #45716 quote
    juanj
    Participant
    Master

    Good Day Everyone

    I am working on a trend following breakout strategy that relies on me being able to determine when a diagonal trend line has been broken based on a couple of conditions. As soon as I am finished I will share the strategy here but for now, I need some help determining a crucial ingredient;

    How can I determine the width of a candle stick in relation to height? Currently, the width of a candle stick only represent a time-unit, but I need to assign an actual point (or pip) value for the width of a candle stick to using the trigonometry formula. Here are 2 viewpoints I currently consider:

    1. It does not matter as long as they are all the same
    2. Use a percentage of an ATR[x] value calculated back from the first bar since the trade was opened.

    I would appreciate any suggestions. @Nicolas I believe having a piece of code in the library that can be used to determine when a diagonal trendline is violated will be very helpful.

    The basic idea is to calculate the diagonal trend line projecting it from the last fractal onto the next high/low that produces the widest trend line angle. The trend line is then updated using the next high/low producing a wider angle than the last, but only as long as the high/low has a close in the direction of the trend or if the close following the new high/low is higher/lower than close[1]. The trend line is considered broken when a close is outside of the calculated trend line.

    #45729 quote
    juanj
    Participant
    Master

    Okay, so I just realised it probably won’t matter as the width will be the number of bars since the last fractal. I just have to calculate the height and then use the formula Tan(bars/height) to get the angle.

    #45731 quote
    Despair
    Blocked
    Master

    This was what I was thinking. (y)

    #45732 quote
    juanj
    Participant
    Master

    Okay so here is the code, unfortunately, it is not opening trades which means I must be missing something? @Nicolas, basically here is where I will need help with some debugging.

    If hour < 9 or hour > 17 then //outside market hours
      possize = 0
      If longonmarket Then
       sell at market
      ElsIf shortonmarket Then
       exitshort at market
      EndIf
    Else
      possize = 2 //position contract size
    EndIf
    
    //Calculate Fractal
    
    once FracH = 0 //initialize fractal count
    once FracL = 0 //initialize fractal count
    For i = 0 to 4 Do
      If high[2] > high[i] Then //look for high fractal with 2 lower highs on either side
       FracH = FracH + 1
      EndIf
      If low[2] < low[i] Then //look for low fractal with 2 higher lows on either side
       FracL = FracL + 1
      EndIf
    Next
    If FracH = 4 Then //High Fractal Identified (DownTrend)
      FractalH = high[2] //High Fractal Price Level
      FractalP = barindex - tradeindex - 2 //High Fractal Bar Position
    EndIf
    If FracL = 4 Then //Low Fractal Identified (UpTrend)
      FractalL = low[2] //Low Fractal Price Level
      FractalP = barindex - tradeindex - 2 //Low Fractal Bar Position
    EndIf
    
    //Calculate trendline using widest angle from extreme of last fractal to curent extreme (Trigonometry Function)
    
    If FracH = 4 Then //Down trend due to High Fractal
      Height = FractalH - high //Calcululate height between high fractal and high of current bar
      HeightB = FractalH - close //Calcululate height between high fractal and close of current bar (used to determine trend violation)
    ElsIf FracL = 4 Then //Up trend due to High Fractal
      Height = Low - FractalL //Calcululate height between low fractal and low of current bar
      HeightB = close - FractalL //Calcululate height between high fractal and close of current bar (used to determine trend violation)
    EndIf
    
    If (barindex-tradeindex) - 2 = FractalP Then //Initialize angle using high of last bar of fractal set
      MaxAngle = Tan(1/Height) //Initial value of the angle between the fractal and the last high
    EndIf
    
    If (barindex-tradeindex) - 2 > FractalP Then //If current bar greater than end of fractal set:
      If FracH = 4 Then //For High Fractal (Down Trend)
       If (Tan(((barindex-tradeindex)-FractalP)/Height) > MaxAngle) and (((close < open) or (close < close[1]))) Then
        MaxAngle = Tan(((barindex-tradeindex)-FractalP)/Height) //calculate new max trend if down trend rules are valid
        Trendbreak = 0 //No Trend Violation Present
       EndIf
       If Trendbreak = 0 and (Tan(((barindex-tradeindex)-FractalP)/HeightB) > MaxAngle) and close > open Then
        TrendBreak = 1 //Trend violation potentially present, wait for confirmation on close of next bar
       ElsIf Trendbreak = 1 and (Tan((((barindex-tradeindex)-1)-FractalP)/HeightB) > MaxAngle) and close > close[1] Then
        Trendbreak = 2 //Trend violation confirmed, there was a close outside the trend line (close angle > trend)
       EndIf
      ElsIf FracL = 4 Then //For Low Fractal (Up Trend)
       If (Tan(((barindex-tradeindex)-FractalP)/Height) > MaxAngle) and (((close > open) or (close > close[1]))) Then
        MaxAngle = Tan(((barindex-tradeindex)-FractalP)/Height) //calculate new max trend if up trend rules are valid
        Trendbreak = 0 //No Trend Violation Present
       EndIf
       If Trendbreak = 0 and (Tan(((barindex-tradeindex)-FractalP)/HeightB) > MaxAngle) and close < open Then
        TrendBreak = 1 //Trend violation potentially present, wait for confirmation on close of next bar
       ElsIf Trendbreak = 1 and (Tan((((barindex-tradeindex)-1)-FractalP)/HeightB) > MaxAngle) and close < close[1] Then
        Trendbreak = 2 //Trend violation confirmed, there was a close outside the trend line (close angle < trend)
       EndIf
     EndIf
    EndIf
    
    If Trendbreak = 2 Then //Trend violation is confirmed:
     If FracH = 4 Then //For Up Trend:
      BreakoutL = Highest[3](high) //Determine Highest point of violation (including last candle before violation)
      Buy possize contract at BreakoutL + (AverageTrueRange[14](close)*0.7) stop //Enter into long position at specified price level
      //N.B. We need to ensure the current position is obviously closed?
     ElsIf FracL = 4 Then //For Down Trend:
      BreakoutL = Lowest[3](low) //Determine Lowest point of violation (including last candle before violation)
      Sellshort possize contract at BreakoutL - (AverageTrueRange[14](close)*0.7) stop //Enter into short position at specified price level
      //N.B. We need to ensure the current position is obviously closed?
     EndIf
    EndIf
    
    If FracH = 4 Then
     If longonmarket Then //If position is opened counter last trend, reset variables
      FracH = 0
      FracL = 0
      Trendbreak = 0
     EndIf
    ElsIf FracL = 4 Then
     If shortonmarket Then //If position is opened counter last trend, reset variables
      FracH = 0
      FracL = 0
      Trendbreak = 0
     EndIf
    EndIf
    #45794 quote
    juanj
    Participant
    Master

    Okay, so I finally figured out the problem.

    Had to rewrite big parts of the code, but the main issue was basically the fact that I did not properly identify the active trend.

    The strategy performs surprisingly well. I tested it on the EUR/USD 1Hr (see attached screenshot) but it should work on other markets and time frames as well.

    The strategy has been submitted to the PRT library. Will post the link here as soon as it is posted.

    Regards,

    Nicolas thanked this post
    #45805 quote
    Nicolas
    Keymaster
    Master

    Sorry, I’m a bit late here. Very fine and clever @juanj, well done!  I reviewed your post and your strategy is now available in the library for everyone to test and improve: trend lines breakout strategy

    #45806 quote
    Wing
    Participant
    Veteran

    We seem to be working on the same projects: https://www.prorealcode.com/topic/wings-trend-lines-indicator/

    #45906 quote
    Huw
    Participant
    Average

    Hi Juan,

    Would it be possible to code this to trade channels instead but reverse if the price goes beyond a trend line to also chase the breakout?

    I note the CAC 40 has been in a nice down channel but may break to the up side at some point for example.

    #45920 quote
    juanj
    Participant
    Master

    Hi Huw, a channel is but an area of support (for long positions) or resistance (for short positions) that is respected by the price. The strategy in effect actually aims to do exactly as you are requesting. The problem, however, is that the way in which the diagonal line is positioned in the strategy is possibly not as optimal as we I initially thought. I will attempt to improve on it to better trade with the trend. Maybe @Nicolas or @Wing or @Francesco78 can assist in graphing each revision of the lines as to make it clear how they are actually plotted.

    #45951 quote
    juanj
    Participant
    Master

    Okay, so I have been going over the code carefully and made some changes that I believe is more consistent with what I have been trying to achieve. However, in doing so I think I broke it as it stops opening trades a few trades in.

    //Stategy: Trend Breakout
    //Author: Juan Jacobs 
    //Market: Neutral
    //Timezone: UTC +2
    //Timeframe: 1Hr but not 'completely' timeframe dependant
    
    Defparam cumulateorders = False
    
    If hour < 9 or hour > 22 then //outside market hours
    possize = 0
    If longonmarket Then
    sell at market
    Bear = 0
    Bull = 0
    Trendbreak = 0
    ElsIf shortonmarket Then
    exitshort at market
    Bear = 0
    Bull = 0
    Trendbreak = 0
    EndIf
    Else
    possize = 1 //position contract size
    EndIf
    
    //Calculate Fractal
    
    once Trendbreak = 0
    
    If Trendbreak = 0 Then
    
    once FracH = 0 //initialize fractal count
    once FracL = 0 //initialize fractal count
    
    For i = 0 to 4 Do
    If high[2] > high[i] Then //look for high fractal with 2 lower highs on either side
    FracH = FracH + 1
    EndIf
    If low[2] < low[i] Then //look for low fractal with 2 higher lows on either side
    FracL = FracL + 1
    EndIf
    Next
    
    If FracH = 4 Then //High Fractal Identified
    If Bear = 0 and Bull = 0 Then
    Bear = 1 //Initialize first trend direction
    EndIf
    If Bear = 1 Then
    FractalH = high[2] //High Fractal Price Level
    FractalP = barindex - 2 //High Fractal Bar Position
    EndIf
    EndIf
    If FracL = 4 Then //Low Fractal Identified
    If Bear = 0 and Bull = 0 Then
    Bull = 1 //Initialize first trend direction
    EndIf
    If Bull = 1 Then
    FractalL = low[2] //Low Fractal Price Level
    FractalP = barindex - 3 //Low Fractal Bar Position
    EndIf
    EndIf
    
    FracH = 0 //reset fractal count
    FracL = 0 //reset fractal count
    
    //Calculate trendline using widest angle from extreme of last fractal to curent extreme (Trigonometry Function)
    
    If barindex = FractalP + 2 Then //Initialize angle using 1st candle after fractal candle
    If Bear = 1 Then
    MaxAngle = Tan(1/(FractalH - high[1])) //Initial value of the angle between the fractal and the last high
    ElsIf Bull = 1 Then
    MaxAngle = Tan(1/(low[1]-FractalL)) //Initial value of the angle between the fractal and the last high
    EndIf
    EndIf
    
    If Bear = 1 Then //Down trend
    Height = FractalH - high //Calcululate height between high fractal and high of current bar
    HeightB = FractalH - close //Calcululate height between high fractal and close of current bar (used to determine trend violation)
    ElsIf Bull = 1 Then //Up trend
    Height = Low - FractalL //Calcululate height between low fractal and low of current bar
    HeightB = close - FractalL //Calcululate height between high fractal and close of current bar (used to determine trend violation)
    EndIf
    
    EndIf
    
    If barindex > FractalP + 2 Then //If current bar greater than end of fractal set:
    If Bear = 1 Then //For Down Trend
    If Trendbreak = 0 and (Tan((barindex-FractalP)/Height) > MaxAngle) and (((close < open) or (close < close[1]))) Then
    MaxAngle = Tan((barindex-FractalP)/Height) //calculate new max trend if down trend rules are valid
    ElsIf Trendbreak = 0 and (Tan((barindex-FractalP)/HeightB) > MaxAngle) and close > open Then
    TrendBreak = 1 //Trend violation potentially present, wait for confirmation on close of next bar
    EndIF
    If Trendbreak = 1 and (Tan(((barindex-1)-FractalP)/HeightB) > MaxAngle) and close > close[1] Then
    Trendbreak = 2 //Trend violation confirmed, there was a close outside the trend line (close angle > trend)
    BreakoutL = Highest[2](high) //Determine Highest point of violation (including last candle before violation)
    EndIf
    ElsIf Bull = 1 Then //For Up Trend
    If Trendbreak = 0 and (Tan((barindex-FractalP)/Height) > MaxAngle) and (((close > open) or (close > close[1]))) Then
    MaxAngle = Tan((barindex-FractalP)/Height) //calculate new max trend if up trend rules are valid
    ElsIf Trendbreak = 0 and (Tan((barindex-FractalP)/HeightB) > MaxAngle) and close < open Then
    TrendBreak = 1 //Trend violation potentially present, wait for confirmation on close of next bar
    EndIf
    If Trendbreak = 1 and (Tan(((barindex-1)-FractalP)/HeightB) > MaxAngle) and close < close[1] Then
    Trendbreak = 2 //Trend violation confirmed, there was a close outside the trend line (close angle < trend)
    BreakoutL = Lowest[2](low) //Determine Lowest point of violation (including last candle before violation)
    EndIf
    EndIf
    EndIf
    
    If Trendbreak = 2 Then //Trend violation is confirmed:
    If Bear = 1 Then //Down Trend Present (but now broken):
    Buy possize contract at BreakoutL + (AverageTrueRange[7](close)*1) stop //Enter into long position at specified price level
    //N.B. We need to ensure the current position is obviously closed?
    ElsIf Bull = 1 Then //Up Trend Present (but now broken):
    Sellshort possize contract at BreakoutL - (AverageTrueRange[7](close)*1) stop //Enter into short position at specified price level
    //N.B. We need to ensure the current position is obviously closed?
    EndIf
    
    If Bear = 1 and longonmarket Then //If position is opened counter last trend, reset variables
    Trendbreak = 0
    Bear = 0
    Bull = 1
    ElsIf Bull = 1 and shortonmarket Then //If position is opened counter last trend, reset variables
    Trendbreak = 0
    Bear = 1
    Bull = 0
    EndIf
    EndIf
    
    //Trade Management (Note that Trend Direction need to be reset with exits's)
    
    Deviations = 1.618
    periods = 42
    
    PRICE  = LOG(customclose)
    alpha  = 2/(PERIODS+1)
    
    if barindex < PERIODS then
    EWMA = AVERAGE[3](PRICE)
    else
    EWMA = alpha * PRICE + (1-alpha)*EWMA
    endif
    
    error = PRICE - EWMA
    dev   = SQUARE(error)
    if barindex < PERIODS+1 then
    var  = dev
    else
    var   = alpha * dev + (1-alpha) * var
    endif
    ESD   = SQRT(var)
    
    BollU = EXP(EWMA + (DEVIATIONS*ESD))
    BollL = EXP(EWMA - (DEVIATIONS*ESD))
    
    RS2 = ROUND(RSI[2](close))
    
    PSH = Highest[100](high)[1]
    PSL = Lowest[100](low)[1]
    
    If longonmarket and ((close[1] > BollU and close < BollU) or (high[1] > BollU and high < BollU) or (close > PSH or close < PSL)) Then
    LE = 1
    ElsIf shortonmarket and ((close[1] < BollL and close > BollL) or (low[1] < BollL and low > BollL) or (close < PSL or close > PSH)) Then
    SE = 1
    EndIf
    
    If longonmarket and LE = 1 and RS2 >= 85 and close < BollU Then
    Sell at market
    Bear = 0
    Bull = 0
    ElsIf shortonmarket and SE = 1 and RS2 <= 15 and close > BollL Then
    Exitshort at market
    Bear = 0
    Bull = 0
    EndIf
    #45956 quote
    juanj
    Participant
    Master

    Okay, I have been crawling deeper and deeper into the rabbit hole and found more oversights in my code.

    Amongst other things I didn’t reset the Trendbreak indicator to zero if the breakout was invalid and also I didn’t cater for close = open scenarios.

    However, even after fixing the above the strategy is still only opening a few trades and then stopping. Results based on the few opened trades looks very promising though (attached)!


    @Nicolas
    I really need some expert help fixing this as I believe there are major potential waiting to be unlocked here.

    //Stategy: Trend Breakout
    //Author: Juan Jacobs
    //Market: Neutral
    //Timezone: UTC +2
    //Timeframe: 1Hr but not 'completely' timeframe dependant
    
    Defparam cumulateorders = False
    
    If hour < 9 or hour > 22 then //outside market hours
    possize = 0
    If longonmarket Then
    sell at market
    Bear = 0
    Bull = 0
    Trendbreak = 0
    ElsIf shortonmarket Then
    exitshort at market
    Bear = 0
    Bull = 0
    Trendbreak = 0
    EndIf
    Else
    possize = 1 //position contract size
    EndIf
    
    //Calculate Fractal
    
    once Trendbreak = 0
    
    If Trendbreak = 0 Then //No potential trendbreaks have been identified
    
    once FracH = 0 //initialize fractal count
    once FracL = 0 //initialize fractal count
    
    For i = 0 to 4 Do
    If high[2] > high[i] Then //look for high fractal with 2 lower highs on either side
    FracH = FracH + 1
    EndIf
    If low[2] < low[i] Then //look for low fractal with 2 higher lows on either side
    FracL = FracL + 1
    EndIf
    Next
    
    If FracH = 4 Then //High Fractal Identified
    If Bear = 0 and Bull = 0 Then
    Bear = 1 //Initialize first trend direction
    EndIf
    If Bear = 1 Then
    FractalH = high[2] //High Fractal Price Level
    FractalP = barindex - 2 //High Fractal Bar Position
    EndIf
    ElsIf FracL = 4 Then //Low Fractal Identified
    If Bear = 0 and Bull = 0 Then
    Bull = 1 //Initialize first trend direction
    EndIf
    If Bull = 1 Then
    FractalL = low[2] //Low Fractal Price Level
    FractalP = barindex - 2 //Low Fractal Bar Position
    EndIf
    EndIf
    
    FracH = 0 //reset fractal count
    FracL = 0 //reset fractal count
    
    //Calculate trendline using widest angle from extreme of last fractal to curent extreme (Trigonometry Function)
    
    If barindex = FractalP + 2 Then //Initialize angle using 1st candle after fractal candle
    If Bear = 1 Then
    MaxAngle = Tan(1/(FractalH - high[1])) //Initial value of the angle between the fractal and the last high
    ElsIf Bull = 1 Then
    MaxAngle = Tan(1/(low[1]-FractalL)) //Initial value of the angle between the fractal and the last high
    EndIf
    EndIf
    
    EndIf
    
    If Bear = 1 Then //Down trend
    Height = FractalH - high //Calcululate height between high fractal and high of current bar
    HeightB = FractalH - close[1] //Calcululate height between high fractal and close of current bar (used to determine trend violation)
    ElsIf Bull = 1 Then //Up trend
    Height = Low - FractalL //Calcululate height between low fractal and low of current bar
    HeightB = close[1] - FractalL //Calcululate height between high fractal and close of current bar (used to determine trend violation)
    EndIf
    
    If barindex > FractalP + 2 Then //If current bar greater than end of fractal set:
    If Bear = 1 Then //For Down Trend
    If Trendbreak = 1 and close >= close[1] Then
    Trendbreak = 2 //Trend violation confirmed, there was a close outside the trend line (close angle > trend)
    BreakoutL = Highest[2](high) //Determine Highest point of violation (including last candle before violation)
    ElsIf Trendbreak = 1 and close <= open[1] Then
    Trendbreak = 0//Trend violation invalidated, latest close did not confirm
    MaxAngle = TAngle //New max trend as trend break was invalidated
    EndIf
    If Trendbreak = 0 and (Tan((barindex-FractalP)/Height) > MaxAngle) and close <= open Then
    MaxAngle = Tan((barindex-FractalP)/Height) //calculate new max trend if down trend rules are valid
    ElsIf Trendbreak = 0 and (Tan((barindex-FractalP)/HeightB) > MaxAngle) and close > open Then
    TrendBreak = 1 //Trend violation potentially present, wait for confirmation on close of next bar
    TAngle = Tan((barindex-FractalP)/Height) //Save temporary angle to use if trend violation invalidated
    EndIF
    ElsIf Bull = 1 Then //For Up Trend
    If Trendbreak = 1 and close <= close[1] Then
    Trendbreak = 2 //Trend violation confirmed, there was a close outside the trend line (close angle < trend)
    BreakoutL = Lowest[2](low) //Determine Lowest point of violation (including last candle before violation)
    ElsIf Trendbreak = 1 and close >= open[1] Then
    MaxAngle = TAngle //New max trend as trend break was invalidated
    Trendbreak = 0
    EndIf
    If Trendbreak = 0 and (Tan((barindex-FractalP)/Height) > MaxAngle) and close >= open Then
    MaxAngle = Tan((barindex-FractalP)/Height) //calculate new max trend if up trend rules are valid
    ElsIf Trendbreak = 0 and (Tan((barindex-FractalP)/HeightB) > MaxAngle) and close < open Then
    TrendBreak = 1 //Trend violation potentially present, wait for confirmation on close of next bar
    TAngle = Tan((barindex-FractalP)/Height) //Save temporary angle to use if trend violation invalidated
    EndIf
    EndIf
    EndIf
    
    If Trendbreak = 2 Then //Trend violation is confirmed:
    If Bear = 1 Then //Down Trend Present (but now broken):
    Buy possize contract at BreakoutL + (AverageTrueRange[7](close)*1.6) stop //Enter into long position at specified price level
    //N.B. We need to ensure the current position is obviously closed?
    ElsIf Bull = 1 Then //Up Trend Present (but now broken):
    Sellshort possize contract at BreakoutL - (AverageTrueRange[7](close)*1.6) stop //Enter into short position at specified price level
    //N.B. We need to ensure the current position is obviously closed?
    EndIf
    
    If Bear = 1 and longonmarket Then //If position is opened counter last trend, reset variables and initialize new trend
    Trendbreak = 0
    Bear = 0
    Bull = 1
    ElsIf Bull = 1 and shortonmarket Then //If position is opened counter last trend, reset variables and initialize new trend
    Trendbreak = 0
    Bear = 1
    Bull = 0
    EndIf
    EndIf
    
    //Trade Management (Note that Trend Direction need to be reset with exits's)
    
    Deviations = 1.618
    periods = 42
    
    PRICE  = LOG(customclose)
    alpha  = 2/(PERIODS+1)
    
    if barindex < PERIODS then
    EWMA = AVERAGE[3](PRICE)
    else
    EWMA = alpha * PRICE + (1-alpha)*EWMA
    endif
    
    error = PRICE - EWMA
    dev   = SQUARE(error)
    if barindex < PERIODS+1 then
    var  = dev
    else
    var   = alpha * dev + (1-alpha) * var
    endif
    ESD   = SQRT(var)
    
    BollU = EXP(EWMA + (DEVIATIONS*ESD))
    BollL = EXP(EWMA - (DEVIATIONS*ESD))
    
    RS2 = ROUND(RSI[2](close))
    
    PSH = Highest[100](high)[1]
    PSL = Lowest[100](low)[1]
    
    If longonmarket and ((close[1] > BollU and close < BollU) or (high[1] > BollU and high < BollU) or (close > PSH or close < PSL)) Then
    LE = 1
    ElsIf shortonmarket and ((close[1] < BollL and close > BollL) or (low[1] < BollL and low > BollL) or (close < PSL or close > PSH)) Then
    SE = 1
    EndIf
    
    If longonmarket and LE = 1 and RS2 >= 85 and close < BollU Then
    Sell at market
    Bear = 0
    Bull = 0
    ElsIf shortonmarket and SE = 1 and RS2 <= 15 and close > BollL Then
    Exitshort at market
    Bear = 0
    Bull = 0
    EndIf
    
    #45959 quote
    juanj
    Participant
    Master

    Haha okay, I think I found the problem. The stop order level is constantly being updated. Talk about moving the goalposts!

    Will be back with the fix soon…

    #45969 quote
    juanj
    Participant
    Master

    Finally done, realised I also didn’t re-instate the previous trend if the buy/sell order were never met and the trend continued on in the initial direction. But I believe all logical issues have now been addressed. I also added some heuristics to optimize the ATR period used to calculate the buy/sell order level. So here is my final version, which for some frustrating reason doesn’t perform as well as the original version (I spent way too much time on this):

    //Stategy: Trend Breakout
    //Author: Juan Jacobs
    //Market: Neutral
    //Timezone: UTC +2
    //Timeframe: 1Hr but not 'completely' timeframe dependant
    
    Defparam cumulateorders = False
    
    If hour < 8 or hour > 22 then //outside market hours
    possize = 0
    If longonmarket Then
    sell at market
    Bear = 0
    Bull = 0
    Trendbreak = 0
    optimize = optimize + 1
    ElsIf shortonmarket Then
    exitshort at market
    Bear = 0
    Bull = 0
    Trendbreak = 0
    optimize = optimize + 1
    EndIf
    Else
    possize = 1 //position contract size
    EndIf
    
    // Heuristics Algorithm Start
    
    once period = 6
    Increment = 1
    MaxIncrement = 5
    Reps = 4 //Number of bars to use for analysis
    once PIncPos = 1 //Positive Increment Position
    once NIncPos = 1 //Neative Increment Position
    once Optimize = 0 ////Initialize Heuristicks Engine Counter (Must be Incremented at Position Start or Exit)
    once Mode = 1 //Switches between negative and positive increments
    once WinCountB = 0 //Initialize Best Win Count
    once StratAvgB = 0 //Initialize Best Avg Strategy Profit
    
    If Optimize = Reps Then
    WinCountA = 0 //Initialize current Win Count
    StratAvgA = 0 //Initialize current Avg Strategy Profit
    
    For z = 1 to Reps Do
    If positionperf(z) > 0 Then
    WinCountA = WinCountA + 1 //Increment Current WinCount
    EndIf
    StratAvgA = StratAvgA + StrategyProfit[z]
    Next
    StratAvgA = StratAvgA/Reps //Calculate Current Avg Strategy Profit
    
    If StratAvgA >= StratAvgB Then
    StratAvgB = StratAvgA //Update Best Strategy Profit
    BestA = Period
    EndIf
    
    If WinCountA >= WinCountB Then
    WinCountB = WinCountB  //Update Best Win Count
    BestB = Period
    EndIf
    
    If WinCountA > WinCountB and StratAvgA > StratAvgB Then
    Mode = 0
    ElsIf WinCountA < WinCountB and StratAvgA < StratAvgB and Mode = 1 Then
    Period = Period - (Increment*NIncPos)
    NIncPos = NIncPos + Increment
    Mode = 2
    ElsIf WinCountA >= WinCountB or StratAvgA >= StratAvgB and Mode = 1 Then
    Period = Period + (Increment*PIncPos)
    PIncPos = PIncPos + Increment
    Mode = 1
    ElsIf WinCountA < WinCountB and StratAvgA < StratAvgB and Mode = 2 Then
    Period = Period + (Increment*PIncPos)
    PIncPos = PIncPos + Increment
    Mode = 1
    ElsIf WinCountA > WinCountB or StratAvgA > StratAvgB and Mode = 2 Then
    Period = Period - (Increment*NIncPos)
    NIncPos = NIncPos + Increment
    Mode = 2
    EndIf
    
    If NIncPos > MaxIncrement or PIncPos > MaxIncrement Then
    If BestA = BestB Then
    Period = BestA
    Else
    Period = (BestA+BestB)/2
    EndIf
    NIncPos = 1
    PIncPos = 1
    EndIF
    
    Optimize = 0
    EndIf
    
    // Heuristics Algorithm End
    
    //Calculate Fractal
    
    once Trendbreak = 0
    
    If Trendbreak = 0 Then //No potential trendbreaks have been identified
    
    once FracH = 0 //initialize fractal count
    once FracL = 0 //initialize fractal count
    
    For i = 0 to 4 Do
    If high[2] > high[i] Then //look for high fractal with 2 lower highs on either side
    FracH = FracH + 1
    EndIf
    If low[2] < low[i] Then //look for low fractal with 2 higher lows on either side
    FracL = FracL + 1
    EndIf
    Next
    
    If FracH = 4 Then //High Fractal Identified
    If Bear = 0 and Bull = 0 Then
    Bear = 1 //Initialize first trend direction
    EndIf
    FractalH = high[2] //High Fractal Price Level
    LFractalH = low[2] //Low of High Fractal
    If Bear = 1 Then
    FractalP = barindex - 2 //High Fractal Bar Position
    EndIf
    ElsIf FracL = 4 Then //Low Fractal Identified
    If Bear = 0 and Bull = 0 Then
    Bull = 1 //Initialize first trend direction
    EndIf
    FractalL = low[2] //Low Fractal Price Level
    HFractalL = high[2] //High of Low Fractal
    If Bull = 1 Then
    FractalP = barindex - 2 //Low Fractal Bar Position
    EndIf
    EndIf
    
    FracH = 0 //reset fractal count
    FracL = 0 //reset fractal count
    
    //Calculate trendline using widest angle from extreme of last fractal to curent extreme (Trigonometry Function)
    
    If barindex = FractalP + 2 Then //Initialize angle using 1st candle after fractal candle
    If Bear = 1 Then
    MaxAngle = Tan(1/(FractalH - high[1])) //Initial value of the angle between the fractal and the last high
    ElsIf Bull = 1 Then
    MaxAngle = Tan(1/(low[1]-FractalL)) //Initial value of the angle between the fractal and the last high
    EndIf
    EndIf
    
    EndIf
    
    If Bear = 1 Then //Down trend
    Height = FractalH - high //Calcululate height between high fractal and high of current bar
    HeightB = FractalH - close[1] //Calcululate height between high fractal and close of current bar (used to determine trend violation)
    ElsIf Bull = 1 Then //Up trend
    Height = Low - FractalL //Calcululate height between low fractal and low of current bar
    HeightB = close[1] - FractalL //Calcululate height between high fractal and close of current bar (used to determine trend violation)
    EndIf
    
    If barindex > FractalP + 2 Then //If current bar greater than end of fractal set:
    If Bear = 1 Then //For Down Trend
    If Trendbreak = 1 and close >= close[1] Then
    Trendbreak = 2 //Trend violation confirmed, there was a close outside the trend line (close angle > trend)
    BreakoutP = Barindex //Breakout position
    OrderLevel = LFractalH + (AverageTrueRange[PERIOD](close)*1.618) //Enter into long position at specified price level
    PreviousLow = LFractalH //Level to re-initate preious trend
    ElsIf Trendbreak = 1 and close <= open[1] Then
    Trendbreak = 0//Trend violation invalidated, latest close did not confirm
    MaxAngle = TAngle //New max trend as trend break was invalidated
    EndIf
    If Trendbreak = 0 and (Tan((barindex-FractalP)/Height) > MaxAngle) and close <= open Then
    MaxAngle = Tan((barindex-FractalP)/Height) //calculate new max trend if down trend rules are valid
    ElsIf Trendbreak = 0 and (Tan((barindex-FractalP)/HeightB) > MaxAngle) and close > open Then
    TrendBreak = 1 //Trend violation potentially present, wait for confirmation on close of next bar
    TAngle = Tan((barindex-FractalP)/Height) //Save temporary angle to use if trend violation invalidated
    EndIF
    ElsIf Bull = 1 Then //For Up Trend
    If Trendbreak = 1 and close <= close[1] Then
    Trendbreak = 2 //Trend violation confirmed, there was a close outside the trend line (close angle < trend)
    BreakoutP = Barindex //Breakout position
    OrderLevel = HFractalL - (AverageTrueRange[PERIOD](close)*1.618) //Enter into short position at specified price level
    PreviousHigh = HFractalL //Level to re-initiate previous trend
    ElsIf Trendbreak = 1 and close >= open[1] Then
    MaxAngle = TAngle //New max trend as trend break was invalidated
    Trendbreak = 0
    EndIf
    If Trendbreak = 0 and (Tan((barindex-FractalP)/Height) > MaxAngle) and close >= open Then
    MaxAngle = Tan((barindex-FractalP)/Height) //calculate new max trend if up trend rules are valid
    ElsIf Trendbreak = 0 and (Tan((barindex-FractalP)/HeightB) > MaxAngle) and close < open Then
    TrendBreak = 1 //Trend violation potentially present, wait for confirmation on close of next bar
    TAngle = Tan((barindex-FractalP)/Height) //Save temporary angle to use if trend violation invalidated
    EndIf
    EndIf
    EndIf
    
    If Trendbreak = 2 Then //Trend violation is confirmed:
    
    If Bear = 1 and close > PreviousLow Then
    Buy possize contract at OrderLevel stop
    ElsIf Bull = 1 and close < PreviousHigh Then
    Sellshort possize contract at OrderLevel stop
    EndIf
    
    If barindex >= BreakoutP Then
    If Bear = 1 and longonmarket Then //If position is opened counter last trend, reset variables and initialize new trend
    Trendbreak = 0
    Bear = 0
    Bull = 1
    optimize = optimize + 1
    ElsIf Bear = 1 and close < PreviousLow Then //New trend invalidated and previous trend resumed
    Trendbreak = 0
    ElsIf Bull = 1 and shortonmarket Then //If position is opened counter last trend, reset variables and initialize new trend
    Trendbreak = 0
    Bear = 1
    Bull = 0
    optimize = optimize + 1
    ElsIf Bull = 1 and close > PreviousHigh Then //New trend invalidated and previous trend resumed
    Trendbreak = 0
    EndIf
    EndIf
    EndIf
    
    //Trade Management (Note that Trend Direction need to be reset with exits's)
    
    Deviations = 1.618
    periods = 42
    
    PRICE  = LOG(customclose)
    alpha  = 2/(PERIODS+1)
    
    if barindex < PERIODS then
    EWMA = AVERAGE[3](PRICE)
    else
    EWMA = alpha * PRICE + (1-alpha)*EWMA
    endif
    
    error = PRICE - EWMA
    dev   = SQUARE(error)
    if barindex < PERIODS+1 then
    var  = dev
    else
    var   = alpha * dev + (1-alpha) * var
    endif
    ESD   = SQRT(var)
    
    BollU = EXP(EWMA + (DEVIATIONS*ESD))
    BollL = EXP(EWMA - (DEVIATIONS*ESD))
    
    RS2 = ROUND(RSI[2](close))
    
    PSH = Highest[100](high)[1]
    PSL = Lowest[100](low)[1]
    
    If longonmarket and ((close[1] > BollU and close < BollU) or (high[1] > BollU and high < BollU) or (close > PSH or close < PSL)) Then
    LE = 1
    ElsIf shortonmarket and ((close[1] < BollL and close > BollL) or (low[1] < BollL and low > BollL) or (close < PSL or close > PSH)) Then
    SE = 1
    EndIf
    
    If longonmarket and LE = 1 and RS2 >= 85 and close < BollU Then
    Sell at market
    Bear = 0
    Bull = 0
    optimize = optimize + 1
    ElsIf shortonmarket and SE = 1 and RS2 <= 15 and close > BollL Then
    Exitshort at market
    Bear = 0
    Bull = 0
    optimize = optimize + 1
    EndIf
    golha and GraHal thanked this post
    #46150 quote
    Nicolas
    Keymaster
    Master

    Well done, been quite busy here and there and also a lot IRL.. Sometimes buggy codes lead to better results than final and neat ones .. that’s programmer’s life 🙁

    Did you think of a clean way to draw your trend lines or even an oscillator of their difference between price and them? Should help a lot visualize how the things goes with the strategy.

    #46158 quote
    juanj
    Participant
    Master

    I’m not too well versed with coding indicators as I try to not spend too much time in front of a screen trading. My focus is mainly on automation.

    I have spent allot of time lately designing and debugging this code and sharing it with the PRC community, so it would be nice if someone else can add to this by designing an indicator based on this concept.

Viewing 15 posts - 1 through 15 (of 29 total)
  • You must be logged in to reply to this topic.

Calculating Diagonal Trend Lines Using Fractals and Trigonometry


ProOrder support

New Reply
Author
author-avatar
juanj @juanj Participant
Summary

This topic contains 28 replies,
has 1 voice, and was last updated by eckaw
4 years, 10 months ago.

Topic Details
Forum: ProOrder support
Language: English
Started: 09/07/2017
Status: Active
Attachments: 6 files
Logo Logo
Loading...