Swings in price action can provide logical entry points for both trend reversal and trend following strategies. They signal that price has reversed from a significant movement or retracement and that price might continue to move in the opposite direction. If you are looking to enter at the end of a retracement or trend, a swing can give you a little confidence that you are trading in the right direction.
It is not all rosy though, detecting a swing is only possible well after the fact. Furthermore, the lag in swing detection is far greater than most lagging indicators. The more confidence you want in confirming a swing, the more the detection of it will lag price action and therefore, the later you are able to enter a trade.
In this post, we are going to build a swing indicator for Tradingview, take a look at situations where it can be utilized well and then just as importantly, look at some examples of when it might get you into trouble.
The Swing Indicator
The indicator shall allow users to “analyse” a recent historical candle to detect whether it was a swing point. This will work by inputting a number to select which historical candle you want to check. The indicator will then check all candles after it until the current candle. It shall also check the same amount of candles before it. If the candle analysed has the lowest low or highest high in the complete range, then we know it was a swing point.
Swing Indicator Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
//@version=3 study("Swing Indicator", overlay=true) //////////////////////////////////////////////////////////////////////////////// // Date:2018.03.15 // Author: Backtest-Rookies.com // Version: 1.0 // Description: Swing Dectection Indicator //////////////////////////////////////////////////////////////////////////////// // Notes: // // /////////////////////////////////////////////////////////////////////////////// barsback = input(7, title='Bars back to check for a swing') showsig = input(false, title='Show Signal Markers') swing_detection(index)=> swing_high = false swing_low = false start = (index*2) - 1 // -1 so we have an even number of swing_point_high = high[index] swing_point_low = low[index] //Swing Highs for i = 0 to start swing_high := true if i < index if high[i] > swing_point_high swing_high := false break // Have to do checks before pivot and after seperately because we can get // two highs of the same value in a row. Notice the > and >= difference if i > index if high[i] >= swing_point_high swing_high := false break //Swing lows for i = 0 to start swing_low := true if i < index if low[i] < swing_point_low swing_low := false break // Have to do checks before pivot and after seperately because we can get // two lows of the same value in a row. Notice the > and >= difference if i > index if low[i] <= swing_point_low swing_low := false break [swing_high, swing_low] // Check for a swing [swing_high, swing_low] = swing_detection(barsback) // Plotting plotshape(swing_high, style=shape.arrowdown, location=location.abovebar, color=red, text='SH', offset=-barsback) plotshape(swing_low, style=shape.arrowup, location=location.belowbar, color=green, text='SL', offset=-barsback) plotshape(showsig ? swing_high : na, style=shape.arrowdown, location=location.abovebar, color=blue, text='Sig') plotshape(showsig ? swing_low : na, style=shape.arrowup, location=location.belowbar, color=blue, text='Sig') |
Code Commentary
All the swing detection magic is performed in one large swing_dectection()
function. This function simply loops through the full range of candles both before and after the analysed candle. If at any point, another candle has a higher high or lower low, the loop is broken and false
is returned. Conversely, if the loop makes it to the end without a break
, we have a swing and true
is returned.
For more information on how to write loops and functions see these two tutorials:
Next, when plotting the swing, we need to use the offset
parameter. This is because the script evaluates true
on the current candle but we are actually analysing a historical candle. As such, we need to offset the plot by the barsback
input value so the swing is marked correctly.
Finally, we optionally plot a marker on the current bar. The reason for this is that the current bar is the first bar when the signal is confirmed and as such, we could not act on the swing before it. This marker can be used for signalling entries and alerts.
About that lag
In the opening section, we mentioned the lag. The further we look back, the greater the lag. This can be a blessing as well as a curse depending on your goals. On one hand, the more lag we allow, the more confidence we have that the swing was real. Then, on the other hand, we can have so much lag that the move as already completed by the time we are ready to act. Let’s take a look.
First up we have a chart showing the indicator using default settings.
At first glance, it looks great. It nicely identifies the each of the swing highs and lows in the range. However, if you turn the signal marker on, it looks like this:
As you can see, the move is often nearly over before we know about it. Therefore we know the default settings are not suitable for ranging markets with small swings.
If we then reduce the lag (by reducing the number of bars back), we can enter earlier but the problem here is we start generating lots of conflicting signals:
Again this is not ideal but that is the price we must pay to be early! In this scenario, it is better not to act on every swing. Instead, focus on swings that are close to known support/resistance levels or confirming another indicators’ bias.
Trending Markets
If we are running a long-only strategy and trying to “buy the dip”, we can turn off plotting of the short swings and reduce the barsback
to find some nice long entries on a trending stock.
Technical Analysis
In the final example, the indicator is used to assist with other technical analysis. Here we are easily able to spot divergence between an RSI and the price action.
Improvement and Extension Ideas
One extension that immediately springs to mind would be to add a second input that allows you to specify how many candles to check prior to the analysed candle. This would allow a lopsided detection where we check fewer candles after the swing than before it. The hypothesis is that this would allow us to still enter early whilst maintaining some confidence that a swing is forming.
To finish off, it is worth pointing out that swings can also help you identify support/resistance levels and form the basis for trend line detection. Therefore, even if you see no value in using the code in its current form, it could still form an important building block for other more complex indicators.
hi,
we can get more accurate swing high and swing lows if we filter out the candles which are inside bars we need the candles must be closed out side the body and wicks of the previous candles . as the price action is happening within the range of previous bar. we need close outside tha bar . https://www.tradingview.com/x/uKrRCObn/ please have look and edit it .
hope it will works and avoid whipshaws..
hi guys , thanks for this its great. I’ve been unsuccessfully trying to add an alert condition to it but specifically for swing lows , is it possible to do this for just swing lows please!!?? (I’m aware of the lag) any help greatly appreciated!
Hi Mark,
It should be just as simple as placing the
swing_low
variable insidealertcondition()
then setting up the alert through the alert wizard.Can you provide a link to a screenshot or example code what you are trying?
thanks for the response, i think i must have been over complicating it, sorted now thanks very much Rookie1!
Hey,
Great stuff,
I don’t have much of a coding background but i know a little. I’m trying to use the current swing high or swing lows as a stop loss. I’m trying to refer to recent lows but i’m i can’t get it to work.
What I wish to happen is to say when close price goes beneath current swing low, exit current trade.
Here’s a section of the code that i thought may work but it hasn’t:
//bull entry
SL = swing_low
longCondition = close > ema(close,21)
if (longCondition)
strategy.entry(“Long 1”, strategy.long)
stopCondition = close < SL
if (stopCondition)
strategy.close("long1")
Can you please recommend any way to get this to work?
Kind Regards,
Darius
Hi Darius
I was thinking about the same thing.
The problem with your code is that SL (swing_low) is just a series of true or false.
Your stop condition stopCondition = close < SL is comparing floats to boolean, numbers to true or false.
The only way around it would be to alter the rest of the code so that the function was returning the price of the low swing, rather than true or false.