Calculating Diagonal Trend Lines Using Fractals and Trigonometry

Viewing 14 posts - 16 through 29 (of 29 total)
  • Author
    Posts
  • #50434 quote
    Madrosat
    Participant
    Master

    Hello Nicolas

    did you realize this indicators who draw oblique trend lines and oscillator??

    Gianluca thanked this post
    #50934 quote
    Nicolas
    Keymaster
    Master

    I tried at that moment but I did not manage to obtain something satisfactory in the time that I had been imparted to this task … Too many good topics and good ideas to explore and only so little time 😐

    Gianluca thanked this post
    #50987 quote
    Madrosat
    Participant
    Master

    I do not doubt that with a little time you’ll get there, we’ll wait for you.

    congratulations

    Madrosat

    #59212 quote
    juanj
    Participant
    Master

    @Nicolas, I would like us to revisit this strategy. I have noticed that it has performed well since I posted my last version on 11 September, adding 33 new trades with a win rate of 63.64% and a Gain/Loss Ratio of 2.71 and a Gain to Drawdown ratio of 3.39.

    I still need some help graphing the trend lines.

    #59218 quote
    Nicolas
    Keymaster
    Master

    If you could identify at least 2 points of the trendline in your code, we could plot it easily. If you can separate all the trading stuff from the trendline calculation in your code, I could help for sure.

    #59349 quote
    juanj
    Participant
    Master

    Hi Nicolas

    Okay so here is the part of the code that calculates the trend.

    The first point of the trend line is obviously the last swing high/low (FractalH or FractalL) and the bar position being FractalP

    The second point would be the last high/low that results in the MaxAngle to be greater than the last value it held.

    //Calculate Fractal (Swing Point)
    
    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
    FractalP = barindex - 2 //High Fractal Bar Position
    EndIf
    If 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
    FractalP = barindex - 2 //Low Fractal Bar Position
    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 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
    
    If barindex - 2 = FractalP Then //Initialize angle using high of last bar of fractal set
    MaxAngle = Tan(2/Height) //Initial value of the angle between the fractal and the last high
    EndIf
    
    once Trendbreak = 0
    
    If barindex - 2 > FractalP Then //If current bar greater than end of fractal set:
    If Bear = 1 Then //For Down Trend
    If (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
    Trendbreak = 0 //No Trend Violation Present
    EndIf
    If 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
    ElsIf 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)
    EndIf
    ElsIf Bull = 1 Then //For Up Trend
    If (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
    Trendbreak = 0 //No Trend Violation Present
    EndIf
    If 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
    ElsIf 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)
    EndIf
    EndIf
    EndIf
    golha thanked this post
    #59358 quote
    Nicolas
    Keymaster
    Master

    Something like this? (made only the support lines)

    defparam calculateonlastbars=1000
    
    //Calculate Fractal (Swing Point)
    
    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
    FractalP = barindex - 2 //High Fractal Bar Position
    EndIf
    If 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
    FractalP = barindex - 2 //Low Fractal Bar Position
    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 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
    
    If barindex - 2 = FractalP Then //Initialize angle using high of last bar of fractal set
    MaxAngle = Tan(2/Height) //Initial value of the angle between the fractal and the last high
    EndIf
    
    once Trendbreak = 0
    
    If barindex - 2 > FractalP Then //If current bar greater than end of fractal set:
    If Bear = 1 Then //For Down Trend
    If (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
    Trendbreak = 0 //No Trend Violation Present
    EndIf
    If 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
    ElsIf 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)
    EndIf
    ElsIf Bull = 1 Then //For Up Trend
    If (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
    Trendbreak = 0 //No Trend Violation Present
    EndIf
    If 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
    ElsIf 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)
    EndIf
    EndIf
    EndIf
    
    if bull and maxangle>maxangle[1] then 
    drawsegment(barindex,low,fractalP,fractalL) coloured(200,0,0)
    endif
    
    return //fractalH,fractalL, MaxAngle

    If “MaxAngle” is superior to the last one and it’s a bull trend, draw a new segment (not a complete line to have a clear chart).

    #59372 quote
    golha
    Participant
    Junior

    Dear Juan,

    will you please post your latest version. This is very interesting. I noticed the part of the code that you have reposted is slightly different form the one posted last year. I know slight difference in a code could be the difference between  losing and winning!

    Many thanks.

    #59568 quote
    juanj
    Participant
    Master

    @Nicolas, thank you for the indicator.

    It is difficult to say whether or not it looks correct as I can imagine there to be many new lines being drawn constantly.

    However the rules is basically as follows:

    Once a swing high/low is identified with 2 lower highs/higher lows on either side;

    1. Draw an initial line from the high/low of the swing point to the high/low of the 2nd shoulder which should technically be the lowest/highest of the 2 shoulders. This gives the initial value for MaxAngle.
    2. Now after every new bar the angle between the high/low of the swing point and the latest high/low will be calculated and compared to the current value being held by MaxAngle. If the new angle is greater it means a high/low outside the diagonal line is present. To determine whether this constitutes a break, we recalculate the angle using the close. If the close also falls outside the trend line a potential break is present and we will wait for the next candle stick to confirm. If the close does not fall outside the trend line, then the trend remains intact and the high/low will be used to update the new MaxAngle value.
    3. If a new swing high/low is present, this will be used as the new point from which the trend line is calculated.
    golha thanked this post
    #59570 quote
    juanj
    Participant
    Master

    Would basically look something like this:

    #59683 quote
    golha
    Participant
    Junior

    Juan, you can use the line equation. like this:

    If the line equation is  y=mx+b and the coordinates of a point is (x0,y0) then compare y0 and mxo+b, for example if y0>mxo+b then the point is above the line, etc.

    x0 is bar index and y0 is price.

    in case needed, equation of a line passing two points

    y − y1 = m(x − x1)

    m= y2-y1/x2-x1      y is price,m is bar index

     

    thus forget the angle business all together

    #59778 quote
    juanj
    Participant
    Master

    I ran this puppy on USDJPY and were quite surprised by the results (see attached), especially considering that I used the EURUSD during optimization and testing:


    @Golha
    Here is the latest version of the code:

    //Stategy: Trend Breakout
    //Author: Juan Jacobs (Jd3gjacobs@gmail.com)
    //Market: Neutral
    //Timezone: UTC +2
    //Timeframe: 1Hr but not 'completely' timeframe dependant
    
    Defparam cumulateorders = False
    
    If hour < 3 or hour >= 20 then //market hours EURUSD: 8-23 USDJPY: 3-20 AUDUSD: 5-20
    possize = 0
    If longonmarket Then
    sell at market
    ElsIf shortonmarket Then
    exitshort at market
    EndIf
    Bear = 0
    Bull = 0
    Trendbreak = 0
    Else
    possize = 1 //position contract size
    EndIf
    
    // Heuristics Algorithm Start
    
    once OPT = 1
    
    If OPT < 2 and onmarket then
    OPT = 0
    ElsIf countofposition = 0 Then
    OPT = 1
    EndIF
    
    If OPT = 0 Then
    optimize = optimize + 1
    OPT = 2
    EndIf
    
    ////////////////////////////////////////
    
    //GRAPH periods AS "Periods"
    
    once periods = 2.5
    Increment = 0.05
    MaxIncrement = 6
    Reps = 6 //Number of trades 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 i = 1 to Reps Do
    If positionperf(i) > 0 Then
    WinCountA = WinCountA + 1 //Increment Current WinCount
    EndIf
    StratAvgA = StratAvgA + positionperf(i)
    Next
    StratAvgA = StratAvgA/Reps //Calculate Current Avg Strategy Profit
    
    If StratAvgA >= StratAvgB Then
    StratAvgB = StratAvgA //Update Best Strategy Profit
    BestA = Periods
    EndIf
    
    If WinCountA >= WinCountB Then
    WinCountB = WinCountA  //Update Best Win Count
    BestB = Periods
    EndIf
    
    If WinCountA > WinCountB and StratAvgA > StratAvgB Then
    Mode = 0
    ElsIf WinCountA < WinCountB and StratAvgA < StratAvgB and Mode = 1 Then
    Periods = Periods - (Increment*NIncPos)
    NIncPos = NIncPos + 1
    Mode = 2
    ElsIf WinCountA >= WinCountB or StratAvgA >= StratAvgB and Mode = 1 Then
    Periods = Periods + (Increment*PIncPos)
    PIncPos = PIncPos + 1
    Mode = 1
    ElsIf WinCountA < WinCountB and StratAvgA < StratAvgB and Mode = 2 Then
    Periods = Periods + (Increment*PIncPos)
    PIncPos = PIncPos + 1
    Mode = 1
    ElsIf WinCountA > WinCountB or StratAvgA > StratAvgB and Mode = 2 Then
    Periods = Periods - (Increment*NIncPos)
    NIncPos = NIncPos + 1
    Mode = 2
    EndIf
    
    If NIncPos > MaxIncrement or PIncPos > MaxIncrement Then
    If BestA = BestB Then
    Periods = BestA
    Else
    Periods = (BestA+BestB)/2
    EndIf
    NIncPos = 1
    PIncPos = 1
    EndIF
    
    Optimize = 0
    EndIf
    
    // Heuristics Algorithm End
    
    If Trendbreak = 0 Then //No potential trendbreaks have been identified
    
    //Calculate Fractal
    
    FracH = 0 //initialize fractal count
    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
    
    //Calculate trendline using widest angle from extreme of last fractal to curent extreme (Trigonometry Function)
    
    If barindex = FractalP + 2 Then //Initialize angle using greatest candle after fractal candle
    If Bear = 1 Then
    MaxAngleA = Tan(1/(FractalH - high[0])) //Initial value of the angle between the fractal and the 1st high after fractal high
    MaxAngleB = Tan(1/(FractalH - high[1])) //Initial value of the angle between the fractal and the 2nd high after fractal high
    MaxAngle = MAX(MaxAngleA,MaxAngleB)
    ElsIf Bull = 1 Then
    MaxAngleA = Tan(1/(low[0]-FractalL)) //Initial value of the angle between the fractal and the 1st low after fractal low
    MaxAngleB = Tan(1/(low[1]-FractalL)) //Initial value of the angle between the fractal and the 2nd low after fractal low
    MaxAngle = MAX(MaxAngleA,MaxAngleB)
    EndIf
    EndIf
    
    EndIf
    
    If Bear = 1 Then //Down trend
    Height = abs(FractalH - high) //Calcululate height between high fractal and high of current bar
    HeightB = abs(FractalH - close) //Calcululate height between high fractal and close of current bar (used to determine trend violation)
    HeightC = abs(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 = abs(Low - FractalL) //Calcululate height between low fractal and low of current bar
    HeightB = abs(close - FractalL) //Calcululate height between high fractal and close of current bar (used to determine trend violation)
    HeightC = abs(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[22](close)*periods) //Enter into long position at specified price level
    PreviousLow = FractalL //Lowest[15](low)//Level to re-initate preious trend
    ElsIf Trendbreak = 1 and Tan((barindex-FractalP)/HeightC) > TAngle Then
    MaxAngle = TAngle //New max trend as trend break was invalidated
    Trendbreak = 0
    EndIf
    If Trendbreak = 0 and (Tan((barindex-FractalP)/Height) < MaxAngle) and (Tan((barindex-FractalP)/HeightB) > MaxAngle) Then
    MaxAngle = Tan((barindex-FractalP)/Height) //calculate new max trend if down trend rules are valid
    ElsIf Trendbreak = 0 and (Tan((barindex-FractalP)/Height) < MaxAngle) and (Tan((barindex-FractalP)/HeightB) < MaxAngle) 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[22](close)*periods) //Enter into short position at specified price level
    PreviousHigh = FractalH // Highest[15](high) //Level to re-initiate previous trend
    ElsIf Trendbreak = 1 and Tan((barindex-FractalP)/HeightC) > TAngle Then
    MaxAngle = TAngle //New max trend as trend break was invalidated
    Trendbreak = 0
    EndIf
    If Trendbreak = 0 and (Tan((barindex-FractalP)/Height) < MaxAngle) and (Tan((barindex-FractalP)/HeightB) > MaxAngle) Then
    MaxAngle = Tan((barindex-FractalP)/Height) //calculate new max trend if up trend rules are valid
    ElsIf Trendbreak = 0 and (Tan((barindex-FractalP)/Height) < MaxAngle) and (Tan((barindex-FractalP)/HeightB) < MaxAngle) 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
    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
    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
    period = 42
    
    PRICE  = LOG(customclose)
    alpha  = 2/(PERIOD+1)
    
    if barindex < PERIOD 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
    golha and BullFlag thanked this post
    #163381 quote
    eckaw
    Participant
    Veteran

    @JuanJ I find this strategy really interesting! However, I am struggling to make Money Management work with this. None of the MM code I can find here seems to work. I have made sure to change positionsize to possize but it still doesn’t work, there seem to be something in your code that overrides it but I cannot figure out what. Any help would be massively appreciated.

    #163382 quote
    eckaw
    Participant
    Veteran

    Do you run this still live?

    I seem to get interesting backtest results with this also:

    period = period2 * AverageTrueRange[periodv]

    (period2 and periodv to be optimised)

Viewing 14 posts - 16 through 29 (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, 11 months ago.

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