avatarJohnJoy

Summary

The provided content is a beginner's guide to using QuantConnect for backtesting trading strategies, detailing the process from creating an account to executing a simple algorithm.

Abstract

The article serves as an introductory tutorial for new users of QuantConnect, a powerful online algorithmic trading platform. It walks readers through the initial steps of setting up an account, creating a new algorithm using the platform's default template, and understanding key concepts such as the Initialize and OnData methods. The author emphasizes the ease of accessing a wide range of US equities data and using built-in indicators like the Simple Moving Average (SMA) for strategy development. The guide also covers practical aspects of running a backtest, including the interpretation of results and the use of market orders to simulate trading decisions based on the SMA indicator. The article aims to equip beginners with the foundational knowledge necessary to start building and testing their own trading algorithms on QuantConnect.

Opinions

  • The author finds QuantConnect extremely convenient and useful for quickly backtesting trading strategies.
  • They believe that everyone can get started with QuantConnect by following the provided steps.
  • QuantConnect's extensive data library, which includes over 27,500 US equities, is highlighted as a significant advantage for users.
  • The platform's advanced functionalities, such as data normalization modes and a wide range of supported indicators, are praised for their utility in algorithm development.
  • The author suggests that the QuantConnect community and documentation are valuable resources for learning and improving algorithmic trading strategies.

Beginner’s Guide to Using QuantConnect(Part 1)

Integrating QuantConnect to boost your algo journey

I have been playing around with QuantConnect for the past few weeks and I find it extremely convenient and useful in quickly backtesting trading strategies.

In this article, I want to dive deeply into the key concepts of the platform so that any beginner can get started and build their first strategy.

CREATING AN ACCOUNT

First of all, you have to create an account with QuantConnect, which is pretty simple. Go to the login page and signup, or if you’re already signed up, log in to QuantConnect(https://www.quantconnect.com/login)

I believe everyone has created an account with the platform. you will be directed to the below page after login.

Now click on the Create New Algorithm

Next, Click on Use Default Template

You are now directed to the workspace environment, where all the coding takes place.

Now let’s do a deep dive into the key concepts of the platform, so you can start building your first strategy right away.

PLATFORM CONCEPTS

I will explain important concepts you need to understand to start working with the platform, but there are far more advanced functionalities that the platform provides which we will cover, once we get a good understanding of the basic framework and building blocks of the platform.

Let’s use a simple code, that is available in the official documentation, to better understand the working of the platform and how each component works together to provide you with the result(You can replace the template code with the below one)

# Import all the functionality you need to run algorithms
from AlgorithmImports import *

# Define a trading algorithm that is a subclass of QCAlgorithm
class MyAlgorithm(QCAlgorithm):
    # Define an Initialize method.
    # This method is the entry point of your algorithm where you define a series of settings.
    # LEAN only calls this method one time, at the start of your algorithm.
    def Initialize(self) -> None:
        # Set start and end dates
        self.SetStartDate(2018, 1, 1)
        self.SetEndDate(2022, 6, 1)
        # Set the starting cash balance to $100,000 USD
        self.SetCash(100000)
        # Add data for the S&P500 index ETF
        self.AddEquity("SPY")

    # Define an OnData method. 
    # This method receives all the data you subscribe to in discrete time slices.
    # It's where you make trading decisions.
    def OnData(self, slice: Slice) -> None:
        # Allocate 100% of the portfolio to SPY
        if not self.Portfolio['SPY'].Invested:
            self.SetHoldings("SPY", 1)

You will notice all our code is inside the MyAlgorithm class, which inherits from the QCAlgorithm class of QuantConnect.This class provides different methods where we can implement our strategy.

Let’s start with the most used and first method we implement Initialize method. This method is only used once at the beginning of the algorithm execution. Here, we can add the start and end date period, set our starting cash, add a list of data on which we want to run the backtest, and additional settings like what models we want to set, scheduling events, or running indicators which we will discuss later.

def Initialize(self) -> None:
        # Set start and end dates
        self.SetStartDate(2018, 1, 1)
        self.SetEndDate(2022, 6, 1)
        # Set the starting cash balance to $100,000 USD
        self.SetCash(100000)
        # Add data for the S&P500 index ETF
        self.AddEquity("SPY")

In the code, we are using SetStartDate and SetEndDate to set our backtesting period, SetCash for starting capital, and AddEquity to add the instrument data.QuantConnect contains over 27,500 US equities, this saves us a lot of time as we don’t have a source, clean or aggregate data from different data providers as all the data is adjusted for splits, dividends, or delisting. It also provides advanced functionalities to work with unadjusted data using data normalization modes.

After the initialize method, we go to the OnData method, which is the event handler; which means it is called when an event happens; in this case when we receive new data. There are also other event handlers provided by the platform like OnOrderEvent(called when an order is submitted), and OnEndofDay(called when a day ends), which we will discuss in more detail later.

def OnData(self, slice: Slice) -> None:
        # Allocate 100% of the portfolio to SPY
        if not self.Portfolio['SPY'].Invested:
            self.SetHoldings("SPY", 1)

Ok, let’s focus on the OnData method for now, this method gets called when we receive each new data from the start date to the end date. In this case, since we are dealing with daily data, therefore we receive new data each trading day the method gets called, at the end time of each bar

In the code above code, we are just checking if the Portfolio is invested or not. We do this by using the portfolio object which is a dictionary where the key is a symbol, in this case ‘SPY, and the value is a SecurityHolding. The SecurityHolding has a bunch of properties like invested(check if we hold any security), quantity(how much of security purchased), and much more.

self.Portfolio['SPY'].Quantity # gets the number of shares purchased
self.Portfolio['SPY'].AveragePrice  # average price of security held

After that, we purchase the security using SetHolding, which is a helper method provided by QuantConnect. The SetHolding method calculates the number of asset units to purchase based on the portfolio weight you provide and then submits market orders. In this example, we are using 100% of the portfolio.

Now let’s run the code by pressing the backtest button at the top right, this will start our backtest, and provide us with the result.(There will be a 20-second delay to start the process if you’re using the free tier)

Now let’s improve on the code above, so we can discuss more functionalities provided by the platform

# Import all the functionality you need to run algorithms
from AlgorithmImports import *

# Define a trading algorithm that is a subclass of QCAlgorithm
class MyAlgorithm(QCAlgorithm):
    # Define an Initialize method.
    # This method is the entry point of your algorithm where you define a series of settings.
    # LEAN only calls this method one time, at the start of your algorithm.
    def Initialize(self) -> None:
        # Set start and end dates
        self.SetStartDate(2018, 1, 1)
        self.SetEndDate(2022, 6, 1)
        # Set the starting cash balance to $100,000 USD
        self.SetCash(100000)
        # Add data for the S&P500 index ETF 
        self.spy = self.AddEquity("SPY",Resolution.Daily).Symbol
        #Add RSI indicator
        self.slow_sma = self.SMA(self.spy,100)
        self.SetWarmUp(100)
   

    # Define an OnData method. 
    # This method receives all the data you subscribe to in discrete time slices.
    # It's where you make trading decisions.
    def OnData(self, data: Slice) -> None:
        if not self.spy in data  not data[self.spy].HasData:
          return
        #Get the current price data
        price = data[self.spy].Close

        # Allocate 100% of the portfolio to SPY
        if not self.Portfolio['SPY'].Invested:
            if price > self.slow_sma.Current.Value:
              #use market order to enter position
              self.MarketOrder(self.spy,int(self.Portfolio.Cash/price))

First of all, you can see that, the data is being added as a symbol object, and stored inside self.spy variable.

self.spy = self.AddEquity("SPY").Symbol

There is some added benefit of using a symbol object, instead of just using the ticker itself, we can access the exchange it trades on, the security type (e.g., equity, forex, futures), and any specific properties or identifiers associated with the instrument.(https://www.quantconnect.com/alpha/docs/key-concepts/what-is-a-symbol)

Next, you can see I have added a simple moving average indicator in the code.QuantConnect has hundreds of supported indicators we can use readily in our code. Here we just need to pass the data and lookback period (100, in this case) as parameters.

self.slow_sma = self.SMA(self.spy,100)
self.SetWarmUp(100)

Also, note that I had used SetWarmUp, this is a helper method provided by the platform, that ensures that trading takes place from the get-go and we don’t have to wait for 100 days till the indicator gets its first value. It automatically downloads the historical data and does the calculations so the indicator value is available from the first day itself. (Note, for more complicated indicators this may not be suitable and we need to warm it up manually)

We now look into the data parameter of the OnData method. It is a slice object, which is a TradeBars object. TradeBars is a dictionary of TradeBar, where the key is the Symbol and the value is a TradeBar. It contains the stock data for all subscribed symbols, including Open, High, Low, Close prices, Volume, and other data fields. The Slice object provides an easy way to access and manipulate the data for multiple securities simultaneously.

Slice
├─ SymbolData ("SPY")
│   ├─ PriceData
│   │   ├─ Open
│   │   ├─ High
│   │   ├─ Low
│   │   └─ Close
│   └─ OtherData
│       ├─ Volume
│       ├─ Dividends
│       └─ ...

We check if the symbol is present in the data object and then get the current closing price of the stock at that specific point in time. (Note, it is yesterday’s closing price). Now we check whether the current price is greater than the current rsi value if the condition is satisfied

if price > self.slow_sma.Current.Value:
  self.MarketOrder(self.spy,int(self.Portfolio.Cash/price))

We can now send an order to place, we are using MarketOrder which takes two parameters symbol and quantity. The quantity is calculated using the last closing price and the amount of cash available in the portfolio. This sends an order that uses 100% of the cash available in the portfolio.

I think this provides basic introductory information regarding, how to use the QuantConnect platform to run your first strategy. we will dive into more functionalities QuantConnect provides to retail traders in further parts

John Joy

Algorithmic Trading
Trading System
Trading Bot
Trading
Backtesting
Recommended from ReadMedium