Skip to content

Custom Indicator Lifecycle

Sample Code Structure

This article will guide you into the code structure and explain the logic behind the events and lifecycle for a cTrader indicator. To access custom indicators, open the ‘Local’ tab in the 'Automate' application.

Image title

As an example, you can create a new indicator named ‘LifeCycle Test’ with the following sample code available in the code editor window.

Image title

To reset the code back to the boilerplate code, copy the code below.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
{
    [Indicator(AccessRights = AccessRights.None)]
    public class LifeCycleTest : Indicator
    {
        [Parameter(DefaultValue = "Hello world!")]
        public string Message { get; set; }

        [Output("Main")]
        public IndicatorDataSeries Result { get; set; }

        protected override void Initialize()
        {
            // To learn more about cTrader Automate visit our Help Center:
            // https://help.ctrader.com/ctrader-automate


            Print(Message);
        }

        public override void Calculate(int index)
        {
            // Calculate value at specified index
            // Result[index] = 
        }
    }
}

At a quick glance, the code structure includes just two methods, such as the Initialize() method and the Calculate() method. Click on ‘Build’ to proceed with testing this indicator. We will also add an additional method called OnDestroy() and explain its purpose later.

The Initialization Event

When a cTrader indicator is first attached to a chart or when the user changes any of the parameter settings, an indicator instance is recreated and the Initialize() method is called. It is used to initialise any variables you plan to employ in your indicator. You can also define and reference additional indicators to create a single indicator using formulas from other indicators.

As default, the new code template includes a parameter setting called Message with the value of "Hello world!".

1
2
[Parameter(DefaultValue = "Hello world!")]
public string Message { get; set; }

In the Initialize() method, there is a line of code to print this message to the log.

1
Print(Message);

To demonstrate the Initialize() method, add an indicator instance by clicking on ‘+’ next to the ‘Build’ icon and choosing a symbol. If you click on ‘More’ in the indicator row and choose ‘Add an Instance’, the EURUSD symbol with the h1 timeframe will be added automatically.

Image title

Note

Adding an instance in cTrader Automate is the same as attaching an indicator to a chart in the 'Trade' application.

Now, open the ‘Log’ tab in the 'TradeWatch' panel under the chart. As you can see, the message ‘Hello world’ has been printed.

Image title

Every time the indicator is first added to a chart, the chart is refreshed. Or when a parameter setting is changed, an indicator instance is recreated and the Initialize() method is called again. You can try to type in a different message in the ‘Parameters’ section, and the log entry will change correspondingly.

Image title

Calculating Indicator Output

The Calculate() method is called for each index of historical data and on each incoming tick. For example, if the current chart has 1000 bars, then the Calculate() method will be called for index 0, 1, 2 … and until it reaches its maximum value of 999.

1
public override void Calculate(int index)

The Calculate() method can be called many times per second during periods of high volatility or fewer times when the market is flat. To test how it works, you can add a line of code to the body of the Calculate() method to print the index value that is being passed into the method for each new data tick. Do not forget to click on ‘Build’ each time after changes in the code editor window are added.

1
Print("Index: " + index);

To switch from the code editor window to the chart, click on the added indicator instance. If you now open the ‘Log’ tab in the 'TradeWatch' panel, you will see the values being printed in the log for the index value being passed into the method.

Image title

The OnDestroy() Method

Our final event is the OnDestroy() method, which is called when the indicator is removed from a chart and is no longer needed. You will need to write the code as it is not included when you create a new indicator.

1
2
3
4
protected override void OnDestroy()
        {
            base.OnDestroy();            
        }

This method is helpful for programmers, as it allows them to freely allocate unmanaged resources and run other finalisation tasks. This prevents memory creep and the indicator from holding onto resources after it has been removed. Some examples are closing any connections to external data feeds, freeing objects that hold a lot of data, and anything else that consumes memory.

Summary

In summary, the Initialize(), Calculate(), and OnDestroy() methods illustrate different stages of the custom indicator lifecycle. By adjusting the sample code in the 'Automate' app, you are free to decide how to initialise indicator variables, calculate the indicator output, and run finalisation tasks.

Subscribe to our YouTube channel