QuantConnect Lean Algorithmic Trading Engine
Tutorials > How Do I Create an Indicator?
How Do I Create an Indicator?
Summary Creating and installing your custom indicator into Lean.
Difficulty Medium
Time Required 20 minutes

Indicators are composed of three key components:

  1. Class which implements your indicator
  2. Helper method in the base of QCAlgorithm which simplifies calls to your indicator implementation.
  3. Test methods to ensure the indicator performs to an external source.

To properly implement an indicator all components should be completed. The following tutorial will guide you through each of these components. We will attempt to use the AroonOscillator indicator as an example where possible. We will not cover indicator fundamental concepts here - to learn the fundamentals (what is a consolidator, what is a sequential indicator?) please see the Introduction to Indicators.

1. Implementing Your Indicator

You indicator class should be implemented in the QuantConnect.Indicators project in the project root. It should be a single class with no acronyms named such as "AroonOscillator.cs".

First Steps

The indicator should extend one of the base indicator types:

Indicator - If your indicator only requires singular values (e.g. ExponentialMovingAverage) you can use the Indicator base class.

TradeBarIndicator - If you need TradeBars then your indicator must extend from the TradeBarIndicator base class (E.g. AroonOscillator).

WindowIndicator<T> - If you need a rolling window of data you must extend from the WindowIndicator base class (E.g. Minimum).

All indicators require implementing four key components to perform properly in Lean.

Constructor - Implement your constructor to accept and save the necessary values for your indicator configuration. With the Aroon we need the Aroon Up and Aroon Down values.

IsReady - A Boolean flag indicating the algorithm has sufficient price history to produce real values. The Aroon is ready after it has processed at least n-period data samples.

ComputeNextValue() - Using the supplied information, compute and return the next value of the indicator. This is where you would insert any indicator implementation details.

Maintaining Extensibility

The example of Aroon is interesting because, like many indicators, it has multiple properties: the Aroon-Up and Aroon-Down. Both of these are required to calculate the Aroon value but only the delta (up - down) is returned. The delta for this example is called the Aroon Percentage. Many indicators will have one primary value, with multiple other properties which are used for making the trade decisions.

To handle these cases - each of the properties should be implemented as a "sub-indicator". To see an example please review the AroonOscillator.cs source code on Github. Aroon creates new indicators AroonUp and AroonDown as properties. This allows you to use the sub-indicator properties independently.

For example; by implementing properties as indicators the indicator extensions allow us to calculate the SMA of the Aroon Up property and return the new value as an indicator.

Example Title
Copy Code
var smaAroonUp = sma.Of( aroon.AroonUp )

2. Install Helper Method in QCAlgorithm

After implementing your indicator class you should install a helper method into the base class to help use your indicator. Indicators can be manually created and updated but we recommend a helper method to ensure they are as easy to use as possible.

For the Aroon example your primary implementation is in the AroonOscillator class; but the helper method is in the QCAlgorithm class. This helper method - AROON - is always capitalized and always returns a new instance of the algorithm you're implementing.

Aroon Helper Method
Copy Code
public AroonOscillator AROON(string symbol, int upPeriod, int downPeriod, Resolution? resolution = null)  {
      var name = CreateIndicatorName(symbol, string.Format("AROON({0},{1})", upPeriod, downPeriod), resolution);
      var aroon = new AroonOscillator(name, upPeriod, downPeriod);
      RegisterIndicator(symbol, aroon, resolution);
      return aroon;
}

In the helper method you should create your indicator unique name which will be used for charting, create your indicator instance using the constructor you built earlier, and the register the indicator for data updates.  (Registering the indicator means it will be automatically updated with price data for the symbol you specify).

3. Create Test Methods

Now we have successfully created our indicator class, and installed the helper method into QCAlgorithm. The final step is running our indicator and comparing it with a reference value. This enable us be confident in the values it is producing.

3.1 Find Reference Indicator Data

For ease of use we recommend using FreeStockCharts.com to produce reference indicator data. It easily allows download daily data and the associated indicator values. First load up the "SPY" daily chart, then apply the required indicator. On the web interface there is an "Export chat data" button which allows you to download the data required.

Once you have this data, place it in the test project: QuantConnect.Tests\TestData folder. You will see assorted data from other indicators here.

3.2 Create Indicator Test Class

In the QuantConnect.Tests\Indicators folder you will see examples of many indicator types. For simplicity we recommend copying an existing indicator and renaming it to suit your indicator class. Change the test-data file name (e.g. "spy_aroon_oscillator.txt") to match your test-data.

From here you need to loop over your data and update the indicator. The TestHelper class will do most of the leg work for you and you should just pass your indicator object into the TestIndicator method, and a evaluator function which will asset on failure.

Ideally there should be no failures but in the event there is a discrepancy between the expected value and your indicator you should use Asset to halt the test. 

See Also