Calculating Diagonal Trend Lines Using Fractals and Trigonometry
Forums › ProRealTime English forum › ProOrder support › Calculating Diagonal Trend Lines Using Fractals and Trigonometry
- This topic has 28 replies, 1 voice, and was last updated 3 years ago by eckaw.
-
-
09/07/2017 at 10:45 AM #45716
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:
- It does not matter as long as they are all the same
- 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.
09/07/2017 at 1:17 PM #4572909/07/2017 at 2:53 PM #4573109/07/2017 at 3:16 PM #45732Okay 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.
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495If hour < 9 or hour > 17 then //outside market hourspossize = 0If longonmarket Thensell at marketElsIf shortonmarket Thenexitshort at marketEndIfElsepossize = 2 //position contract sizeEndIf//Calculate Fractalonce FracH = 0 //initialize fractal countonce FracL = 0 //initialize fractal countFor i = 0 to 4 DoIf high[2] > high[i] Then //look for high fractal with 2 lower highs on either sideFracH = FracH + 1EndIfIf low[2] < low[i] Then //look for low fractal with 2 higher lows on either sideFracL = FracL + 1EndIfNextIf FracH = 4 Then //High Fractal Identified (DownTrend)FractalH = high[2] //High Fractal Price LevelFractalP = barindex - tradeindex - 2 //High Fractal Bar PositionEndIfIf FracL = 4 Then //Low Fractal Identified (UpTrend)FractalL = low[2] //Low Fractal Price LevelFractalP = barindex - tradeindex - 2 //Low Fractal Bar PositionEndIf//Calculate trendline using widest angle from extreme of last fractal to curent extreme (Trigonometry Function)If FracH = 4 Then //Down trend due to High FractalHeight = FractalH - high //Calcululate height between high fractal and high of current barHeightB = 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 FractalHeight = Low - FractalL //Calcululate height between low fractal and low of current barHeightB = close - FractalL //Calcululate height between high fractal and close of current bar (used to determine trend violation)EndIfIf (barindex-tradeindex) - 2 = FractalP Then //Initialize angle using high of last bar of fractal setMaxAngle = Tan(1/Height) //Initial value of the angle between the fractal and the last highEndIfIf (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]))) ThenMaxAngle = Tan(((barindex-tradeindex)-FractalP)/Height) //calculate new max trend if down trend rules are validTrendbreak = 0 //No Trend Violation PresentEndIfIf Trendbreak = 0 and (Tan(((barindex-tradeindex)-FractalP)/HeightB) > MaxAngle) and close > open ThenTrendBreak = 1 //Trend violation potentially present, wait for confirmation on close of next barElsIf Trendbreak = 1 and (Tan((((barindex-tradeindex)-1)-FractalP)/HeightB) > MaxAngle) and close > close[1] ThenTrendbreak = 2 //Trend violation confirmed, there was a close outside the trend line (close angle > trend)EndIfElsIf FracL = 4 Then //For Low Fractal (Up Trend)If (Tan(((barindex-tradeindex)-FractalP)/Height) > MaxAngle) and (((close > open) or (close > close[1]))) ThenMaxAngle = Tan(((barindex-tradeindex)-FractalP)/Height) //calculate new max trend if up trend rules are validTrendbreak = 0 //No Trend Violation PresentEndIfIf Trendbreak = 0 and (Tan(((barindex-tradeindex)-FractalP)/HeightB) > MaxAngle) and close < open ThenTrendBreak = 1 //Trend violation potentially present, wait for confirmation on close of next barElsIf Trendbreak = 1 and (Tan((((barindex-tradeindex)-1)-FractalP)/HeightB) > MaxAngle) and close < close[1] ThenTrendbreak = 2 //Trend violation confirmed, there was a close outside the trend line (close angle < trend)EndIfEndIfEndIfIf 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?EndIfEndIfIf FracH = 4 ThenIf longonmarket Then //If position is opened counter last trend, reset variablesFracH = 0FracL = 0Trendbreak = 0EndIfElsIf FracL = 4 ThenIf shortonmarket Then //If position is opened counter last trend, reset variablesFracH = 0FracL = 0Trendbreak = 0EndIfEndIf09/08/2017 at 10:49 AM #45794Okay, 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,
1 user thanked author for this post.
09/08/2017 at 11:31 AM #45805Sorry, 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
09/08/2017 at 11:34 AM #45806We seem to be working on the same projects: https://www.prorealcode.com/topic/wings-trend-lines-indicator/
09/10/2017 at 10:55 PM #45906Hi 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.
09/11/2017 at 9:39 AM #45920Hi 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.
09/11/2017 at 3:35 PM #45951Okay, 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.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175//Stategy: Trend Breakout//Author: Juan Jacobs//Market: Neutral//Timezone: UTC +2//Timeframe: 1Hr but not 'completely' timeframe dependantDefparam cumulateorders = FalseIf hour < 9 or hour > 22 then //outside market hourspossize = 0If longonmarket Thensell at marketBear = 0Bull = 0Trendbreak = 0ElsIf shortonmarket Thenexitshort at marketBear = 0Bull = 0Trendbreak = 0EndIfElsepossize = 1 //position contract sizeEndIf//Calculate Fractalonce Trendbreak = 0If Trendbreak = 0 Thenonce FracH = 0 //initialize fractal countonce FracL = 0 //initialize fractal countFor i = 0 to 4 DoIf high[2] > high[i] Then //look for high fractal with 2 lower highs on either sideFracH = FracH + 1EndIfIf low[2] < low[i] Then //look for low fractal with 2 higher lows on either sideFracL = FracL + 1EndIfNextIf FracH = 4 Then //High Fractal IdentifiedIf Bear = 0 and Bull = 0 ThenBear = 1 //Initialize first trend directionEndIfIf Bear = 1 ThenFractalH = high[2] //High Fractal Price LevelFractalP = barindex - 2 //High Fractal Bar PositionEndIfEndIfIf FracL = 4 Then //Low Fractal IdentifiedIf Bear = 0 and Bull = 0 ThenBull = 1 //Initialize first trend directionEndIfIf Bull = 1 ThenFractalL = low[2] //Low Fractal Price LevelFractalP = barindex - 3 //Low Fractal Bar PositionEndIfEndIfFracH = 0 //reset fractal countFracL = 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 candleIf Bear = 1 ThenMaxAngle = Tan(1/(FractalH - high[1])) //Initial value of the angle between the fractal and the last highElsIf Bull = 1 ThenMaxAngle = Tan(1/(low[1]-FractalL)) //Initial value of the angle between the fractal and the last highEndIfEndIfIf Bear = 1 Then //Down trendHeight = FractalH - high //Calcululate height between high fractal and high of current barHeightB = FractalH - close //Calcululate height between high fractal and close of current bar (used to determine trend violation)ElsIf Bull = 1 Then //Up trendHeight = Low - FractalL //Calcululate height between low fractal and low of current barHeightB = close - FractalL //Calcululate height between high fractal and close of current bar (used to determine trend violation)EndIfEndIfIf barindex > FractalP + 2 Then //If current bar greater than end of fractal set:If Bear = 1 Then //For Down TrendIf Trendbreak = 0 and (Tan((barindex-FractalP)/Height) > MaxAngle) and (((close < open) or (close < close[1]))) ThenMaxAngle = Tan((barindex-FractalP)/Height) //calculate new max trend if down trend rules are validElsIf Trendbreak = 0 and (Tan((barindex-FractalP)/HeightB) > MaxAngle) and close > open ThenTrendBreak = 1 //Trend violation potentially present, wait for confirmation on close of next barEndIFIf Trendbreak = 1 and (Tan(((barindex-1)-FractalP)/HeightB) > MaxAngle) and close > close[1] ThenTrendbreak = 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)EndIfElsIf Bull = 1 Then //For Up TrendIf Trendbreak = 0 and (Tan((barindex-FractalP)/Height) > MaxAngle) and (((close > open) or (close > close[1]))) ThenMaxAngle = Tan((barindex-FractalP)/Height) //calculate new max trend if up trend rules are validElsIf Trendbreak = 0 and (Tan((barindex-FractalP)/HeightB) > MaxAngle) and close < open ThenTrendBreak = 1 //Trend violation potentially present, wait for confirmation on close of next barEndIfIf Trendbreak = 1 and (Tan(((barindex-1)-FractalP)/HeightB) > MaxAngle) and close < close[1] ThenTrendbreak = 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)EndIfEndIfEndIfIf 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?EndIfIf Bear = 1 and longonmarket Then //If position is opened counter last trend, reset variablesTrendbreak = 0Bear = 0Bull = 1ElsIf Bull = 1 and shortonmarket Then //If position is opened counter last trend, reset variablesTrendbreak = 0Bear = 1Bull = 0EndIfEndIf//Trade Management (Note that Trend Direction need to be reset with exits's)Deviations = 1.618periods = 42PRICE = LOG(customclose)alpha = 2/(PERIODS+1)if barindex < PERIODS thenEWMA = AVERAGE[3](PRICE)elseEWMA = alpha * PRICE + (1-alpha)*EWMAendiferror = PRICE - EWMAdev = SQUARE(error)if barindex < PERIODS+1 thenvar = develsevar = alpha * dev + (1-alpha) * varendifESD = 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)) ThenLE = 1ElsIf shortonmarket and ((close[1] < BollL and close > BollL) or (low[1] < BollL and low > BollL) or (close < PSL or close > PSH)) ThenSE = 1EndIfIf longonmarket and LE = 1 and RS2 >= 85 and close < BollU ThenSell at marketBear = 0Bull = 0ElsIf shortonmarket and SE = 1 and RS2 <= 15 and close > BollL ThenExitshort at marketBear = 0Bull = 0EndIf09/11/2017 at 6:06 PM #45956Okay, 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.123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182//Stategy: Trend Breakout//Author: Juan Jacobs//Market: Neutral//Timezone: UTC +2//Timeframe: 1Hr but not 'completely' timeframe dependantDefparam cumulateorders = FalseIf hour < 9 or hour > 22 then //outside market hourspossize = 0If longonmarket Thensell at marketBear = 0Bull = 0Trendbreak = 0ElsIf shortonmarket Thenexitshort at marketBear = 0Bull = 0Trendbreak = 0EndIfElsepossize = 1 //position contract sizeEndIf//Calculate Fractalonce Trendbreak = 0If Trendbreak = 0 Then //No potential trendbreaks have been identifiedonce FracH = 0 //initialize fractal countonce FracL = 0 //initialize fractal countFor i = 0 to 4 DoIf high[2] > high[i] Then //look for high fractal with 2 lower highs on either sideFracH = FracH + 1EndIfIf low[2] < low[i] Then //look for low fractal with 2 higher lows on either sideFracL = FracL + 1EndIfNextIf FracH = 4 Then //High Fractal IdentifiedIf Bear = 0 and Bull = 0 ThenBear = 1 //Initialize first trend directionEndIfIf Bear = 1 ThenFractalH = high[2] //High Fractal Price LevelFractalP = barindex - 2 //High Fractal Bar PositionEndIfElsIf FracL = 4 Then //Low Fractal IdentifiedIf Bear = 0 and Bull = 0 ThenBull = 1 //Initialize first trend directionEndIfIf Bull = 1 ThenFractalL = low[2] //Low Fractal Price LevelFractalP = barindex - 2 //Low Fractal Bar PositionEndIfEndIfFracH = 0 //reset fractal countFracL = 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 candleIf Bear = 1 ThenMaxAngle = Tan(1/(FractalH - high[1])) //Initial value of the angle between the fractal and the last highElsIf Bull = 1 ThenMaxAngle = Tan(1/(low[1]-FractalL)) //Initial value of the angle between the fractal and the last highEndIfEndIfEndIfIf Bear = 1 Then //Down trendHeight = FractalH - high //Calcululate height between high fractal and high of current barHeightB = FractalH - close[1] //Calcululate height between high fractal and close of current bar (used to determine trend violation)ElsIf Bull = 1 Then //Up trendHeight = Low - FractalL //Calcululate height between low fractal and low of current barHeightB = close[1] - FractalL //Calcululate height between high fractal and close of current bar (used to determine trend violation)EndIfIf barindex > FractalP + 2 Then //If current bar greater than end of fractal set:If Bear = 1 Then //For Down TrendIf Trendbreak = 1 and close >= close[1] ThenTrendbreak = 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] ThenTrendbreak = 0//Trend violation invalidated, latest close did not confirmMaxAngle = TAngle //New max trend as trend break was invalidatedEndIfIf Trendbreak = 0 and (Tan((barindex-FractalP)/Height) > MaxAngle) and close <= open ThenMaxAngle = Tan((barindex-FractalP)/Height) //calculate new max trend if down trend rules are validElsIf Trendbreak = 0 and (Tan((barindex-FractalP)/HeightB) > MaxAngle) and close > open ThenTrendBreak = 1 //Trend violation potentially present, wait for confirmation on close of next barTAngle = Tan((barindex-FractalP)/Height) //Save temporary angle to use if trend violation invalidatedEndIFElsIf Bull = 1 Then //For Up TrendIf Trendbreak = 1 and close <= close[1] ThenTrendbreak = 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] ThenMaxAngle = TAngle //New max trend as trend break was invalidatedTrendbreak = 0EndIfIf Trendbreak = 0 and (Tan((barindex-FractalP)/Height) > MaxAngle) and close >= open ThenMaxAngle = Tan((barindex-FractalP)/Height) //calculate new max trend if up trend rules are validElsIf Trendbreak = 0 and (Tan((barindex-FractalP)/HeightB) > MaxAngle) and close < open ThenTrendBreak = 1 //Trend violation potentially present, wait for confirmation on close of next barTAngle = Tan((barindex-FractalP)/Height) //Save temporary angle to use if trend violation invalidatedEndIfEndIfEndIfIf 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?EndIfIf Bear = 1 and longonmarket Then //If position is opened counter last trend, reset variables and initialize new trendTrendbreak = 0Bear = 0Bull = 1ElsIf Bull = 1 and shortonmarket Then //If position is opened counter last trend, reset variables and initialize new trendTrendbreak = 0Bear = 1Bull = 0EndIfEndIf//Trade Management (Note that Trend Direction need to be reset with exits's)Deviations = 1.618periods = 42PRICE = LOG(customclose)alpha = 2/(PERIODS+1)if barindex < PERIODS thenEWMA = AVERAGE[3](PRICE)elseEWMA = alpha * PRICE + (1-alpha)*EWMAendiferror = PRICE - EWMAdev = SQUARE(error)if barindex < PERIODS+1 thenvar = develsevar = alpha * dev + (1-alpha) * varendifESD = 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)) ThenLE = 1ElsIf shortonmarket and ((close[1] < BollL and close > BollL) or (low[1] < BollL and low > BollL) or (close < PSL or close > PSH)) ThenSE = 1EndIfIf longonmarket and LE = 1 and RS2 >= 85 and close < BollU ThenSell at marketBear = 0Bull = 0ElsIf shortonmarket and SE = 1 and RS2 <= 15 and close > BollL ThenExitshort at marketBear = 0Bull = 0EndIf09/11/2017 at 6:21 PM #4595909/11/2017 at 8:36 PM #45969Finally 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):
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269//Stategy: Trend Breakout//Author: Juan Jacobs//Market: Neutral//Timezone: UTC +2//Timeframe: 1Hr but not 'completely' timeframe dependantDefparam cumulateorders = FalseIf hour < 8 or hour > 22 then //outside market hourspossize = 0If longonmarket Thensell at marketBear = 0Bull = 0Trendbreak = 0optimize = optimize + 1ElsIf shortonmarket Thenexitshort at marketBear = 0Bull = 0Trendbreak = 0optimize = optimize + 1EndIfElsepossize = 1 //position contract sizeEndIf// Heuristics Algorithm Startonce period = 6Increment = 1MaxIncrement = 5Reps = 4 //Number of bars to use for analysisonce PIncPos = 1 //Positive Increment Positiononce NIncPos = 1 //Neative Increment Positiononce Optimize = 0 ////Initialize Heuristicks Engine Counter (Must be Incremented at Position Start or Exit)once Mode = 1 //Switches between negative and positive incrementsonce WinCountB = 0 //Initialize Best Win Countonce StratAvgB = 0 //Initialize Best Avg Strategy ProfitIf Optimize = Reps ThenWinCountA = 0 //Initialize current Win CountStratAvgA = 0 //Initialize current Avg Strategy ProfitFor z = 1 to Reps DoIf positionperf(z) > 0 ThenWinCountA = WinCountA + 1 //Increment Current WinCountEndIfStratAvgA = StratAvgA + StrategyProfit[z]NextStratAvgA = StratAvgA/Reps //Calculate Current Avg Strategy ProfitIf StratAvgA >= StratAvgB ThenStratAvgB = StratAvgA //Update Best Strategy ProfitBestA = PeriodEndIfIf WinCountA >= WinCountB ThenWinCountB = WinCountB //Update Best Win CountBestB = PeriodEndIfIf WinCountA > WinCountB and StratAvgA > StratAvgB ThenMode = 0ElsIf WinCountA < WinCountB and StratAvgA < StratAvgB and Mode = 1 ThenPeriod = Period - (Increment*NIncPos)NIncPos = NIncPos + IncrementMode = 2ElsIf WinCountA >= WinCountB or StratAvgA >= StratAvgB and Mode = 1 ThenPeriod = Period + (Increment*PIncPos)PIncPos = PIncPos + IncrementMode = 1ElsIf WinCountA < WinCountB and StratAvgA < StratAvgB and Mode = 2 ThenPeriod = Period + (Increment*PIncPos)PIncPos = PIncPos + IncrementMode = 1ElsIf WinCountA > WinCountB or StratAvgA > StratAvgB and Mode = 2 ThenPeriod = Period - (Increment*NIncPos)NIncPos = NIncPos + IncrementMode = 2EndIfIf NIncPos > MaxIncrement or PIncPos > MaxIncrement ThenIf BestA = BestB ThenPeriod = BestAElsePeriod = (BestA+BestB)/2EndIfNIncPos = 1PIncPos = 1EndIFOptimize = 0EndIf// Heuristics Algorithm End//Calculate Fractalonce Trendbreak = 0If Trendbreak = 0 Then //No potential trendbreaks have been identifiedonce FracH = 0 //initialize fractal countonce FracL = 0 //initialize fractal countFor i = 0 to 4 DoIf high[2] > high[i] Then //look for high fractal with 2 lower highs on either sideFracH = FracH + 1EndIfIf low[2] < low[i] Then //look for low fractal with 2 higher lows on either sideFracL = FracL + 1EndIfNextIf FracH = 4 Then //High Fractal IdentifiedIf Bear = 0 and Bull = 0 ThenBear = 1 //Initialize first trend directionEndIfFractalH = high[2] //High Fractal Price LevelLFractalH = low[2] //Low of High FractalIf Bear = 1 ThenFractalP = barindex - 2 //High Fractal Bar PositionEndIfElsIf FracL = 4 Then //Low Fractal IdentifiedIf Bear = 0 and Bull = 0 ThenBull = 1 //Initialize first trend directionEndIfFractalL = low[2] //Low Fractal Price LevelHFractalL = high[2] //High of Low FractalIf Bull = 1 ThenFractalP = barindex - 2 //Low Fractal Bar PositionEndIfEndIfFracH = 0 //reset fractal countFracL = 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 candleIf Bear = 1 ThenMaxAngle = Tan(1/(FractalH - high[1])) //Initial value of the angle between the fractal and the last highElsIf Bull = 1 ThenMaxAngle = Tan(1/(low[1]-FractalL)) //Initial value of the angle between the fractal and the last highEndIfEndIfEndIfIf Bear = 1 Then //Down trendHeight = FractalH - high //Calcululate height between high fractal and high of current barHeightB = FractalH - close[1] //Calcululate height between high fractal and close of current bar (used to determine trend violation)ElsIf Bull = 1 Then //Up trendHeight = Low - FractalL //Calcululate height between low fractal and low of current barHeightB = close[1] - FractalL //Calcululate height between high fractal and close of current bar (used to determine trend violation)EndIfIf barindex > FractalP + 2 Then //If current bar greater than end of fractal set:If Bear = 1 Then //For Down TrendIf Trendbreak = 1 and close >= close[1] ThenTrendbreak = 2 //Trend violation confirmed, there was a close outside the trend line (close angle > trend)BreakoutP = Barindex //Breakout positionOrderLevel = LFractalH + (AverageTrueRange[PERIOD](close)*1.618) //Enter into long position at specified price levelPreviousLow = LFractalH //Level to re-initate preious trendElsIf Trendbreak = 1 and close <= open[1] ThenTrendbreak = 0//Trend violation invalidated, latest close did not confirmMaxAngle = TAngle //New max trend as trend break was invalidatedEndIfIf Trendbreak = 0 and (Tan((barindex-FractalP)/Height) > MaxAngle) and close <= open ThenMaxAngle = Tan((barindex-FractalP)/Height) //calculate new max trend if down trend rules are validElsIf Trendbreak = 0 and (Tan((barindex-FractalP)/HeightB) > MaxAngle) and close > open ThenTrendBreak = 1 //Trend violation potentially present, wait for confirmation on close of next barTAngle = Tan((barindex-FractalP)/Height) //Save temporary angle to use if trend violation invalidatedEndIFElsIf Bull = 1 Then //For Up TrendIf Trendbreak = 1 and close <= close[1] ThenTrendbreak = 2 //Trend violation confirmed, there was a close outside the trend line (close angle < trend)BreakoutP = Barindex //Breakout positionOrderLevel = HFractalL - (AverageTrueRange[PERIOD](close)*1.618) //Enter into short position at specified price levelPreviousHigh = HFractalL //Level to re-initiate previous trendElsIf Trendbreak = 1 and close >= open[1] ThenMaxAngle = TAngle //New max trend as trend break was invalidatedTrendbreak = 0EndIfIf Trendbreak = 0 and (Tan((barindex-FractalP)/Height) > MaxAngle) and close >= open ThenMaxAngle = Tan((barindex-FractalP)/Height) //calculate new max trend if up trend rules are validElsIf Trendbreak = 0 and (Tan((barindex-FractalP)/HeightB) > MaxAngle) and close < open ThenTrendBreak = 1 //Trend violation potentially present, wait for confirmation on close of next barTAngle = Tan((barindex-FractalP)/Height) //Save temporary angle to use if trend violation invalidatedEndIfEndIfEndIfIf Trendbreak = 2 Then //Trend violation is confirmed:If Bear = 1 and close > PreviousLow ThenBuy possize contract at OrderLevel stopElsIf Bull = 1 and close < PreviousHigh ThenSellshort possize contract at OrderLevel stopEndIfIf barindex >= BreakoutP ThenIf Bear = 1 and longonmarket Then //If position is opened counter last trend, reset variables and initialize new trendTrendbreak = 0Bear = 0Bull = 1optimize = optimize + 1ElsIf Bear = 1 and close < PreviousLow Then //New trend invalidated and previous trend resumedTrendbreak = 0ElsIf Bull = 1 and shortonmarket Then //If position is opened counter last trend, reset variables and initialize new trendTrendbreak = 0Bear = 1Bull = 0optimize = optimize + 1ElsIf Bull = 1 and close > PreviousHigh Then //New trend invalidated and previous trend resumedTrendbreak = 0EndIfEndIfEndIf//Trade Management (Note that Trend Direction need to be reset with exits's)Deviations = 1.618periods = 42PRICE = LOG(customclose)alpha = 2/(PERIODS+1)if barindex < PERIODS thenEWMA = AVERAGE[3](PRICE)elseEWMA = alpha * PRICE + (1-alpha)*EWMAendiferror = PRICE - EWMAdev = SQUARE(error)if barindex < PERIODS+1 thenvar = develsevar = alpha * dev + (1-alpha) * varendifESD = 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)) ThenLE = 1ElsIf shortonmarket and ((close[1] < BollL and close > BollL) or (low[1] < BollL and low > BollL) or (close < PSL or close > PSH)) ThenSE = 1EndIfIf longonmarket and LE = 1 and RS2 >= 85 and close < BollU ThenSell at marketBear = 0Bull = 0optimize = optimize + 1ElsIf shortonmarket and SE = 1 and RS2 <= 15 and close > BollL ThenExitshort at marketBear = 0Bull = 0optimize = optimize + 1EndIf09/13/2017 at 4:00 PM #46150Well 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.
09/13/2017 at 5:29 PM #46158I’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.
-
AuthorPosts
Find exclusive trading pro-tools on