ProRealCode - Trading & Coding with ProRealTime™
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:
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.
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.
This was what I was thinking. (y)
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
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,
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
We seem to be working on the same projects: https://www.prorealcode.com/topic/wings-trend-lines-indicator/
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.
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.
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
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
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…
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
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.
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.
Calculating Diagonal Trend Lines Using Fractals and Trigonometry
This topic contains 28 replies,
has 1 voice, and was last updated by eckaw
4 years, 10 months ago.
| Forum: | ProOrder support |
| Language: | English |
| Started: | 09/07/2017 |
| Status: | Active |
| Attachments: | 6 files |
The information collected on this form is stored in a computer file by ProRealCode to create and access your ProRealCode profile. This data is kept in a secure database for the duration of the member's membership. They will be kept as long as you use our services and will be automatically deleted after 3 years of inactivity. Your personal data is used to create your private profile on ProRealCode. This data is maintained by SAS ProRealCode, 407 rue Freycinet, 59151 Arleux, France. If you subscribe to our newsletters, your email address is provided to our service provider "MailChimp" located in the United States, with whom we have signed a confidentiality agreement. This company is also compliant with the EU/Swiss Privacy Shield, and the GDPR. For any request for correction or deletion concerning your data, you can directly contact the ProRealCode team by email at privacy@prorealcode.com If you would like to lodge a complaint regarding the use of your personal data, you can contact your data protection supervisory authority.