Using QuantConnect for RSI-Based Algorithmic Trading: A Deeper Dive (2024)

Algorithmic trading is a method of executing orders using automated pre-programmed trading instructions accounting for variables such as time, price, and volume. One of the popular tools for algorithmic trading is QuantConnect, a platform that provides its users with a robust framework to design, build and backtest their strategies.

In this post, we will discuss the implementation of a simple Relative Strength Index (RSI)-based strategy using QuantConnect. We will cover some important concepts such as RollingWindows, WarmUp and TradeBar which are crucial in implementing such strategies.

The strategy we are implementing is based on the Relative Strength Index (RSI), a popular momentum oscillator that measures the speed and change of price movements. The RSI oscillates between zero and 100 and is typically used to identify overbought or oversold conditions in a market. Specifically, our strategy consists of the following rules:

  1. If the RSI(2) is less than 15, we enter a position at the close.
  2. We exit the position at the close if today’s close is higher than yesterday’s high.

In our algorithm, we have defined an RSI period of 2 (self.rsi_period = 2), meaning the RSI is calculated based on the last two data points. This makes the RSI more sensitive to recent price changes.

Additionally, we have set the RSI lower threshold to 15 (self.rsi_lower = 15). When the RSI falls below this level, it indicates that the asset is heavily oversold, and it could be a good time to buy. While the common threshold used for the RSI to indicate oversold conditions is 30, our aggressive threshold of 15 means this strategy is looking for quite extreme oversold conditions before deciding to buy.

A RollingWindow is a data structure in QuantConnect used for storing the most recent data points. This is crucial when developing strategies that need to reference past data. A RollingWindow operates in a first-in, first-out manner, meaning that the most recent data point is at the front of the window and the oldest at the back.

The RollingWindow is used to store the trailing data, keeping the strategy's memory footprint low and providing efficient access to historical data points. It is used in this strategy to maintain the high prices of the last two days.

When using certain indicators or features like RollingWindow, we need historical data to be available before the algorithm starts executing trades. The WarmUp period in QuantConnect is a way to ‘fast-forward’ through a certain amount of data at the start of the algorithm to ensure all indicators and other data structures are ready to go. In our case, we set a WarmUp period equal to the size of our RollingWindow.

In QuantConnect, financial data is represented in different forms like TradeBar, QuoteBar, Tick, etc. A TradeBar represents a bar of trading data and contains information like the opening price, closing price, highest price, lowest price, and volume of trades during the bar’s timespan.

In this strategy, we use daily TradeBar data of SPY for calculating the RSI and determining entry and exit points.

The backtest results of the strategy from 2010 to 2022 show promising returns with a net profit of 158.251% and a compounding annual return of 7.568%. The strategy executed a total of 852 trades during this period, with a win rate of 62%.

However, the strategy experienced a significant drawdown of 23.5%. In particular, the years between 2018 and 2021 saw a downturn in the portfolio value. This could be due to a combination of factors, including adverse market conditions during that period (including the COVID-19 market crash), limitations in the strategy’s model, high transaction costs, or the strategy being overfitted to past market conditions.

We’ve also created a data visualization of the strategy’s equity over time. As we can see from the chart, the strategy experienced steady growth over the backtesting period, with a few significant drawdowns. This visualization can provide a quick overview of the strategy’s performance over time and help identify periods of underperformance that may warrant further investigation.

Using QuantConnect for RSI-Based Algorithmic Trading: A Deeper Dive (2)

Here are some insights we can derive:

1. **Sharpe Ratio (0.57):** This measures the risk-adjusted return of the strategy. A Sharpe Ratio of 0.57 indicates a moderate level of risk for the returns provided by the strategy. Generally, a Sharpe Ratio above 1 is considered good.

2. **Total Trades (852):** This strategy executed 852 trades during the backtest period.

3. **Average Win (1.05%) and Average Loss (-1.08%):** On average, winning trades resulted in a 1.05% profit while losing trades resulted in a 1.08% loss. This indicates that the losses on individual trades are slightly higher than the gains.

4. **Compounding Annual Return (7.568%):** This is the annual rate of return, considering the compounding effect. The strategy achieved an annual return of about 7.57%.

5. **Drawdown (23.500%):** This is the largest drop from a peak to a trough during a specific record period of an investment, a trading account, or a fund. It’s used to measure the historical risk of different investments. A 23.5% drawdown indicates a significant downturn in the portfolio value at some point. The years 2018–2021 might have presented market dynamics that the strategy was not fitted to handle.

6. **Net Profit (158.251%):** The strategy resulted in a net profit of 158.251% over the backtest period.

7. **Win Rate (62%):** The strategy won 62% of its trades.

8. **Profit-Loss Ratio (0.97):** This is the ratio of the profit of winning trades to the loss of losing trades. A ratio of 0.97 suggests that the losses are slightly higher than the profits.

9. **Beta (0.476):** This is a measure of the strategy’s systematic risk, or the sensitivity of the strategy to the overall market movement. A beta of less than 1 means the strategy is theoretically less volatile than the market.

10. **Total Fees ($3344.64):** The total transaction costs incurred by the strategy.

11. **Estimated Strategy Capacity ($760000000.00):** This is an estimate of the amount of capital that can be deployed in this strategy without impacting the market.

12. **Portfolio Turnover (15.23%):** This is a measure of how frequently assets within a fund are bought and sold by the managers. A portfolio turnover of 15.23% indicates a relatively low level of trading activity in the portfolio.

These metrics provide a comprehensive overview of the strategy’s performance, its risk and return profile, and its trading characteristics. They can be used to compare the strategy with other strategies or benchmark indices.

This simple RSI-based trading strategy shows potential for profitable trades, but like all strategies, it has periods of drawdowns and may not perform well in all market conditions. Regular performance monitoring, tweaking the parameters, and considering other factors such as transaction costs and market impact can help improve the strategy’s performance.

QuantConnect provides a powerful and flexible platform for developing, backtesting, and deploying algorithmic trading strategies. With features like RollingWindow for efficient data handling and TradeBar for capturing market data, QuantConnect makes it easier to implement and test a wide range of trading strategies.

import numpy as np
from QuantConnect.Algorithm import QCAlgorithm
from QuantConnect.Indicators import *
from QuantConnect import Resolution
from QuantConnect.Data.Market import TradeBar

class RsiCloseAlgorithm(QCAlgorithm):
def Initialize(self):
self.SetStartDate(2010, 1, 1) # Set the start date for backtesting
self.SetEndDate(2023, 1, 1) # Set the end date for backtesting
self.SetCash(100000) # Set the initial cash balance for backtesting

# Define the symbol we want to trade
self.symbol = self.AddEquity("SPY", Resolution.Daily).Symbol

# RSI parameters
self.rsi_period = 2
self.rsi_lower = 15

# Set up the RSI indicator
self.rsi = self.RSI(self.symbol, self.rsi_period, MovingAverageType.Simple, Resolution.Daily)

# Initialize a RollingWindow to keep track of past TradeBars
self.barWindow = RollingWindow[TradeBar](2)

def OnData(self, data):
# Add the current TradeBar to the RollingWindow
self.barWindow.Add(data[self.symbol])

# Skip if the RollingWindow is not ready
if not self.barWindow.IsReady:
return

# Get the past high price from the RollingWindow
pastHigh = self.barWindow[1].High

# Check if RSI is lower than the defined threshold
if self.rsi.Current.Value < self.rsi_lower:
self.SetHoldings(self.symbol, 1.0)

# Check if today's close is higher than yesterday's high
if self.Portfolio[self.symbol].Invested and self.Securities[self.symbol].Close > pastHigh:
self.Liquidate(self.symbol)

# Plot RSI on chart
self.Plot("Indicators", "RSI", self.rsi.Current.Value)
self.Plot("Indicators", "Oversold Level", self.rsi_lower)

Using QuantConnect for RSI-Based Algorithmic Trading: A Deeper Dive (2024)

References

Top Articles
Latest Posts
Article information

Author: Sen. Ignacio Ratke

Last Updated:

Views: 5948

Rating: 4.6 / 5 (56 voted)

Reviews: 95% of readers found this page helpful

Author information

Name: Sen. Ignacio Ratke

Birthday: 1999-05-27

Address: Apt. 171 8116 Bailey Via, Roberthaven, GA 58289

Phone: +2585395768220

Job: Lead Liaison

Hobby: Lockpicking, LARPing, Lego building, Lapidary, Macrame, Book restoration, Bodybuilding

Introduction: My name is Sen. Ignacio Ratke, I am a adventurous, zealous, outstanding, agreeable, precious, excited, gifted person who loves writing and wants to share my knowledge and understanding with you.