In this article, we will implement a trading strategy that will combine a Relative Strength Indicator and a Simple Moving Average. Let’s call it an **RSI and moving average trading strategy**. We explain the strategy and code it in Python.

What is the idea behind the strategy? That is to have both indicators that confirm a good entry point with acceptable risk and reward. The strategy is coded in Python and shown in detail.

**Python Trading Strategy Backtesting – How To Do It (Plenty of examples with code and images)**

## The logic behind RSI – the Relative Strength Indicator in Python

First, let us explain the logic of the Relative Strength Index (RSI). Why it is useful and under which circumstances it should be implemented?

Welles Wilder, the author of the indicator used the following general rules:

When the RSI is over 70, it is said that the security is overbought, and when the indicator is less than 30% is said that the security is oversold. You can read more about the RSI indicator on this link.

The formula is:

And:

When we look at the formula there is only one variable – the other components are constant values. In the next table, we will see where the and come from:

It is necessary to separate the data by the number of days when the security goes up (gain) or down (loss), see picture above. The process to estimate the Average Gain (Up) is represented in table below:

Days | Price | Difference | Formula Moving Avg | Moving Avg |

Day 2 | 11 | 1 | ||

Day 4 | 10 | 2 | ||

Day 5 | 15 | 5 | (1+2+5)/3 | 2.67 |

Day 8 | 16 | 4 | (2+4+4)/3 | 3.67 |

Day 9 | 17 | 1 | (5+4+1)/3 | 3.33 |

The Average Loss (Down) estimation follows a similar process but with the values presented in the red graphics above.

## Simple Moving Average coded in Python

This is perhaps the most widely known technical indicator, and it is calculated as the average from the last n-days. The main use of this indicator is for identifying trends. Its formula is:

To illustrate the calculation, let’s say the number of periods is *k=3* (we use a 3-day moving average). Let’s show an example in the following table:

On Day 5 there are two important values, the price = 15, and the SMA(3) = 11.00; when the price is higher than the SMA it is assumed there is an upward trend. In case the SMA is lower than the price it is assumed there is a downward trend.

## The strategy’s trading rules

The strategy has the following rules:

- Buy when the 14-day RSI is
**lower than**30, but the closing price is higher than the 5-day SMA. - Sell when the 14-day RSI is greater than 70 and the closing price is lower than the 5-day SMA.

The logic behind this strategy is simple:

We need to wait until the security is oversold or overbought, and at the same time, the closing price is lower or higher than the SMA.

In other words, we need to confirm that there is a strong bearish or bullish sentiment in the market to place a trade in the opposite direction.

## Python Code for Relative Strength Index (RSI) and Moving average trading strategy

Let’s show you how the Python code looks like for this strategy:

### Python data

To implement our strategy, we need to import the following libraries:

The next step is to download the data.

We use the **yfinance** package to download historical prices of Walmart security (WMT). The data starts on 2020-01-03, and ends on 2022-01-10. The frequency is daily:

We use the closing price.

### Calculate the RSI indicator using Python

The first step in calculating the RSI involves the estimation of the Average Gain and the Average Loss.

- To do this we set the interval to 14 days,
- We differentiate the close series to generate the variable
*close_diff*, - Next the variable
*up*(representing gain) will be the values from*close_diff*greater than zero, - And the variable
*down*(representing loss) the values lower than zero:

Then we need to calculate the simple moving average from the variables *up* and *down*:

Finally, it is the time to put it all together to estimate the RSI:

### Calculating a moving average in Python

This process is estimated like this:

We apply the function “**.rolling(days).mean()***” *to the pandas series variable *close*, and we will obtain a series with the moving average of the last 5 days.

### Parameter settings of our strategy

Why do we use a 14-days RSI and a 5-day SMA?

The 14-day RSI is the most typical time frame for this indicator, but you are free to use fewer or more days. Today, we use it to show you how it can be done in Python.

The 5-day SMA was set by trial and error, in case you change the time length from 5 to 10 or 3 you will see that there is not much difference.

### Estimate Signals

The signal generates the entry point – where we buy. To make this we need to follow the strategy rules we made further up in the article, which is “buy when the 14-day RSI is **lower than** 30 and the closing price is **greater than** the 5-day SMA:

We “sell when the 14-day RSI is **greater than** 70 and the closing price **is lower than** the 5-day SMA:

The result of *signal_for_buy* and *signal_for_sell* are pandas series with true or false values.

### Equity curve of the trading strategy

The equity curve measures the performance of a trading strategy over time the x-axis showing the time and the profit and loss are on the y-axis.

In the image below, you will see the code associated with the equity curve tailored for our strategy:

Now is the moment to break down the previous image. The loop will iterate over the variables *signal_for_buy* and *signal_for_sell*, the *enumerate* built-in function will generate the variable *ind*:

The output is:

These are the conditions necessary for recording our buy and sell:

We will add data to our list *operations* when the variable *buy* is True and at the same time, *open_position* is False, while we will close our position when *sell* is True and *open_postion* is True.

Note that the variable operations append a list with: *Date*, *daily total return*, *type of operation*, *RSI*, *SMA* and *Closing Price*. The second component in the list is the total daily return ().

In the image below we see the condition: *len(operations) > 0 and operations[-1][-2] == “long” *that will add data into the list operations until there is not a new *sell* signal.

Finally, it is time to review the code for creating the equity curve of our strategy. This is the cumulative return for Wal-Mart and the RSI. But first, we show the list *operations *to a pandas data frame and add the name of each column. Then we add the code to plot our variables of interest:

## Strategy Performance SPY and QQQ

It’s time to end the article, and we do that but backtesting two heavily traded assets:

Let’s see how the same strategy performs for S&P 500 and Nasdaq 100. We use SPY and QQQ. To make this change please change WMT for SPY or QQQ in **yf.Ticker(WMT’)**