Tradingview – HLHB Forex Trend-Catcher System

This week we will be raiding once again for a strategy to implement on Tradingview! It is not the first time we have used this site and may not be the last time! It is one of the few sites where authors put their neck on the line and publish complete trading systems for free. As such, regardless of the results, we should appreciate that there are people out there willing to provide these resources that we can all learn from.

HLHB Forex Trend-Catcher System

The strategy was authored by Hucklekiwi Pip back in 2015 and is still being updated today. She says that the system was designed to simply catch short-term forex trends. At its heart, the system is a simple EMA crossover strategy with a couple of other indicators used for confirming entries.

Let’s take a look at the rule-set.


  • EMA (5)
  • EMA (10)
  • RSI (10)
  • ADX (14)

Entry Criteria

  • Long
    • EMA 5 crosses over EMA 10 and,
    • RSI crosses over the 50 level and,
    • ADX > 25
  • Short
    • EMA 5 crosses under EMA 10 and,
    • RSI crosses under the 50 level and,
    • ADX > 25

Exit Criteria

  • Take profit at 400 pips
  • Trailing stoploss at 150 pips
  • An opposite entry signal occurs (flip the position)
  • Close all positions at the end of the week.

Further Reading

For full details of the system, head over to Baby Pips and take a look at the following articles:

The strategy has been updated a few times. This implementation attempts to follow the latest ruleset. However, there are several updates and experiments that have been performed over the years. As such, it is possible that something is missing.

The Code

strategy("Hucklekiwi Pip - HLHB Trend-Catcher System", shorttitle="HLHB TCS", overlay=true,
  default_qty_type=strategy.percent_of_equity, default_qty_value=100)

// -----------------------------------------------------------------------------
// HLHB Trend-Catcher System as described on
// Strategy Author: Hucklekiwi Pip 
// Coded By: Backtest Rookies
// -----------------------------------------------------------------------------
// Refs:
//   - Original System:
//   - Updated System:
// Description (From Hucklekiwi Pip)
//   The HLHB System simply aims to catch short-term forex trends.
//   It is patterned after the Amazing Crossover System that Robopip once backtested.
//   In fact, it was one of his highest-scoring mechanical systems in 2014! 
//   The system can be applied to any pair, but since I’m into major pairs, 
//   I’m applying it to the 1-hour charts of EUR/USD and GBP/USD.
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
// Setup
// -----
//  - EUR/USD 1-hour chart
//  - GBP/USD 1-hour chart
//  - 5 EMA: blue line
//  - 10 EMA: red line
//  - RSI (10) applied to the median price (HL/2)
//  - ADX (14)
// Entry
// -----
//  - BUY when the 5 EMA crosses above the 10 EMA from underneath and the RSI 
//    crosses above the 50.0 mark from the bottom.
//  - SELL when the 5 EMA crosses below the 10 EMA from the top and the RSI 
//    crosses below the 50.0 mark from the top.
//  - Make sure that the RSI did cross 50.0 from the top or bottom and not just 
//    ranging tightly around the level.
//  - ADX > 25 for Buy and Sells
// Exit
// ----
//  - Use a 50-pip trailing stop and a 200-pip profit target. This increases the 
//    chances of the system riding longer trends.
//  - Close the trade when a new signal materializes.
//  - Close all trades by the end of the week.
// -----------------------------------------------------------------------------

// Strategy Varaibles
// -------------------
ema_fast_len = input(5, title='Fast EMA Length')
ema_slow_len = input(10 , title='Slow EMA Length')
rsi_len = input(10, title='Slow EMA Length')
session_end_hour = input(16, minval=0, maxval=23, title='Weekly Session End (Hour)')
session_end_minute = input(0, minval=0, maxval=59, title='Weekly Session End (Minute)')
// Targets taken from the update post which states 150 & 400 instead of 50 and 200.
profit_target = input(400, title='Profit Target (Pips/Points)')
trailing_stop_dist = input(150, title='Trailing Stop Distance (Pips/Points)')
adx_filt = input(true, title='User ADX Filter')
adx_min = input(25, minval=0, title='Minimum ADX Level')
adx_len = input(14, title="ADX Smoothing")
di_len = input(14, title="DI Length")

// Setup the Indicators
ema_fast = ema(close, ema_fast_len)
ema_slow = ema(close, ema_slow_len)
rsi_ind = rsi(close, rsi_len)

// ADX
adx_dirmov(len) =>
	up = change(high)
	down = -change(low)
	plusDM = na(up) ? na : (up > down and up > 0 ? up : 0)
    minusDM = na(down) ? na : (down > up and down > 0 ? down : 0)
	truerange = rma(tr, len)
	plus = fixnan(100 * rma(plusDM, len) / truerange)
	minus = fixnan(100 * rma(minusDM, len) / truerange)
	[plus, minus]

adx_adx(dilen, adxlen) =>
	[plus, minus] = adx_dirmov(dilen)
	sum = plus + minus
	adx = 100 * rma(abs(plus - minus) / (sum == 0 ? 1 : sum), adxlen)
	[adx, plus, minus]

[adx_sig, adx_plus, adx_minus] = adx_adx(di_len, adx_len)

// Strategy Logic
ema_long_cross = crossover(ema_fast, ema_slow)
ema_short_cross = crossunder(ema_fast, ema_slow)
rsi_long_cross = crossover(rsi_ind, 50)
rsi_short_cross = crossunder(rsi_ind, 50)
adx_check = adx_filt ? adx_sig >= adx_min : true

longCondition = ema_long_cross and rsi_long_cross and adx_check
if (longCondition)
    strategy.entry("Long", strategy.long)

shortCondition = ema_short_cross and rsi_short_cross and adx_check
if (shortCondition)
    strategy.entry("Short", strategy.short)

strategy.exit("SL/TP", "Long", profit=profit_target,  loss=trailing_stop_dist, trail_points=trailing_stop_dist)  
strategy.exit("SL/TP", "Short", profit=profit_target, loss=trailing_stop_dist, trail_points=trailing_stop_dist)  

// Friday = 6
// If we miss the hour for some reason (due to strange timeframe), then close immediately
// Else if we are on the closing hour, then check to see if we are on or passed the close minute
close_time = dayofweek == 6 ? 
  hour[0] > session_end_hour ? true :
  hour[0] == session_end_hour ?
      minute[0] >= session_end_minute :
  false : false


// Plotting
plot(ema_fast, color=blue, title="Fast EMA")
plot(ema_slow, color=red, title="Slow EMA")

plotshape(rsi_long_cross, style=shape.triangleup, size=size.tiny, location=location.belowbar, color=green, title='RSI Long Cross Marker')
plotshape(rsi_short_cross, style=shape.triangledown, size=size.tiny, location=location.abovebar, color=red, title='RSI Short Cross Marker')

// ADX Filter Highlight
bgcolor(adx_filt and adx_check ? orange : na, transp=90)

Strategy Commentary

As this post is not a pure coding tutorial, we will focus less on the syntax and mechanics of pine script. Instead, we will use this section to discuss and explain the operation and features of the strategy.

As mentioned above, the code attempts to follow the HLHB Trend-catcher strategy as closely as possible. This means that the default settings have been implemented according to the authors rule-set. However, for flexibility, inputs have been provided for as many variables as possible so that you can tweak the strategy to suit your own needs.

ADX Filter

The ADX filter was added as a strategy update/tweak to the system. As such, the feature has a toggle to make this filter optional. This will allow users to see the difference between using the filter and not. When activated and ADX is above the minimum level (default of 25), then the background will change color to orange. This indicates that the filter is ready to allow trades.

Weekly Session End

One of the exit criteria of the strategy is that all positions must be closed out at the end of the week. The author states in her article that she uses 4pm on a Friday as her end of week cut off.

This has been implemented but the logic regarding how we close the position can be a bit confusing to wrap your head around. Therefore, it makes sense to explain it in more detail here. Essentially, every time we receive a new bar of data we make a simple check to see if the current time of the candle is on or after the close time. Once we detect this is true, we send a market order to close the position. That last sentence is very important as it means that if we input 4pm as our time to close the position, we will only detect that it is time to close the position when a bar is received whose time is 4pm or after. This means that if we send a market order at 4pm, the earliest the order will be executed shall be the open of the following bar.

If that is still confusing, it could be because Tradingview reports the time of the bar as the opening time. You can see this if you move to live data. In the example below, the real time is 48 minutes past the hour. However, the time of the bar is reported as 30 minutes past the hour (which was the open). For historical data, this is the time that the script will see until the next bar is received.

So as a user, you will need to adjust this to find a suitable closing time for your timeframe! If you want to close as close to 4pm as possible, you might set Weekly Session End (Hour) to 15 and Weekly Session End (Minute) to 45 when you are on the 15-minute timeframe. This would send an order to close at 3:45pm and would be executed at the open of 4:00pm.

Plotting Overview

The following chart gives a little overview of some of the not so obvious chart elements.


Overall the results are ok. However, it should be noted that the strategy often will enter and exit on the same bar using the default stop loss and take profit settings. This can be problematic in back-testing. Especially with trailing stops on Tradingview! Therefore be a little cautious. When testing with historical data we never really know if the high was hit first or the low. This forces the backtesting engine to make an assumption and it can lead to unrealistic results. As such, if you are interested in trying out this strategy and you want to keep the default settings, you should also forward test it with live data. This will ensure trades are entered and exited correctly on each bar as with live data we do have the information about what is happening between the openand closeof the bar. For a further supporting info, see our repainting guide.

(Click on the images below to enlarge)





Find This Post Useful?

If this post saved you time and effort, please consider support the site! There are many ways to support us and some won’t even cost you a penny.