Backtrader: Swing Indicator

Identifying swings (also known as pivots) can be very useful for various trading styles. The obvious example is trend following where you might want to enter the trend on a dip or adjust stops to just below the most recent swing. The post will provide code for implementing a basic swing indicator.

Note: This post assumes a certain level of familiarity with Backtrader and Python. I assume you know the basics and how to initialize an indicator in a strategy. If you are new to Backtrader, you may find my getting started series which starts with Getting Setup: Python and Backtrader.

Swing Indicator

As the name suggests, our swing indicator is going to produce a signal when it determines a swing happened. Notice the past tense language? Given the nature of swings, we can only identify a swing happened “after the fact”. We need to wait a some time for more candles to appear before we can be confident is calling it a swing. With this in mind the swing indicator needs to be flexible enough so that the “sensitivity” can be altered according to personal preference.

Here is what the indicator will do:

  • Analyze a historical candle and it’s surrounding candles to determine if a swing happened.
  • The indicator will consider it a swing if:
    • The candle being checked is the highest high for the period length both before and after it.
    • The candle being checked is the lowest low for the period length both before and after it.
  • When identified, create a signal:
    • Swing High = 1
    • Swing Low = -1
    • Note: You may want to flip these around. I will discuss this further in the results section.
  • A second “Indicator” line will be used to mark when the swing happened (i.e. not when it was signaled). This is useful for peace of mind and verification that the indicator is working as expected.

The Code

Code Commentary

As you can see, this indicator is not very complex. However a couple of lines are worth explaining further:

We need to analyze the historical data both BEFORE and AFTER the candle being checked. So the whole range is double the period we select. The + 1, ensures that we have an equal amount of candles on either side of the candle that is analyzed. Next we need to get the data:

It is worth mentioning that because of how Backtrader indexes data in a line, we cannot slice the data in the same way we usually would in Python. For this reason we need to use a special get() method from the framework to return the data we want to check.

Finally we just pop() the candle being analyzed from the list and compare it against the rest of the candles that remain in the list. If it is has a higher high or lower low than the rest of the candles then we have a swing!


The first result shows a period set as 7.

Note: The red line is the swing line and the blue line is the signal line. You can only act on the signal line as the swing line is altered after the fact.

period of 7

With such a short period we can see a lot of signals are generated. Lets zoom in for a closer look:

Zoomed in period of 7

Zooming in we can see that we catch the good swings and generate a signal early enough to catch the following movement. The downside is that we also catch some questionable, insignificant swings.

Now we are looking at a chart in more detail, this would be a good time to mention why you might want to change is the signal values. I have it so -1 is a swing low and 1 is a swing high. If you want to use this indicator with a signals only script, it would make more sense to flip these around. This would mean a swing high is -1 and would indicate a short signal. Conversely, a swing low would equal 1, indicating a long signal.

Finally lets compare with a period of 14:

Signals arriving late with a period of 14

As you can see in the image, we do not have the issue of flagging low quality swings. However with such a long period set, the signals we do generate, arrive quite some time after the swing happened.

So in conclusion, there is a trade off between balancing the need to generate signals quickly against the need for only signaling significant swings. If you leave it too long, the price may not have much further to move before retracing. If you set it to too short, you can end up with too much noise. I personally think that a shorter period may suit those who are looking to capitalize on the price movement immediately following a swing. On the other side of the table, a longer period may suit those who just want to move stops after a significant swing and do not want to be caught out by the noise.