Skip to content

How to Use Indicators in cBots

In this article (and the video above), we explain how you can use built-in indicators in your cBots. Using indicators in a cBot is typically done for a variety of purposes, most notably making cBots take trading decisions depending on indicator outputs. To demonstrate this, we will develop a simple automated trading strategy based on the Relative Strength Indicator (RSI).

Creating a New cBot

To create a new cBot, switch to the 'Automate' application and click on 'New cBot'.

We will rename our cBot to "RSI cBot". Here is how our automated trading strategy will function.

  • The bot will enter buy positions when the RSI indicator moves below a predefined threshold.
  • The bot will enter sell positions when the RSI indicator moves above a predefined threshold.

Defining and Initialising the Indicator

The first thing we need to do is define the RSI indicator in our cBot class. To do so, we declare a new field.

1
private RelativeStrengthIndicator rsi;

Using Private Class Members

We can safely make the rsi field private as it will only be used in our cBot.

All cTrader indicators need to be initialised before we can use them. This is best done in the body of the OnStart() method so that the cBot has access to the indicator output after it begins running. cTrader offers a handy class that allows you to easily initialise built-in indicators using ready-made constructors. Before we can see how this is done, we will add two parameters necessary for initialising the RSI indicator.

1
2
3
4
5
[Parameter("Source", Group = "RSI")]
public DataSeries Source { get; set; }

[Parameter("Periods", Group = "RSI", DefaultValue = 14)]
public int Periods { get; set; }

Now that we have added our parameters, we are ready to initialise the indicator.

1
2
3
4
protected override void OnStart()
{
    rsi = Indicators.RelativeStrengthIndex(Source, Periods);
}

Implementing Trading Logic

As we have already initialised the indicator, we can call it and use it in our trading logic. In case of the RSI indicator, we can read the outputs using the Results collection.

To do so, we will use the OnBar() method and implement the following conditions.

  • If the current RSI value is below the RSI buy threshold, enter a new buy position.
  • If the current RSI value is above the RSI sell threshold, enter a new sell position.

Because we rely on predefined thresholds to execute our trading logic, we will add two more parameters to our cBot.

1
2
3
4
5
[Parameter("Buy Level", Group = "RSI", DefaultValue = 30)]
public int BuyLevel { get; set; }

[Parameter("Sell Level", Group = "RSI", DefaultValue = 70)]
public int SellLevel { get; set; }

Next, we will implement our conditions in the cBot code.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
protected override void OnBarClosed()
{
    if (rsi.Result.LastValue < BuyLevel)
    {
    // Enter buy position
    }
    else if (rsi.Result.LastValue > SellLevel)
    {
    // Enter sell position
    }
}

It is time to implement auxiliary methods for executing trading orders. This is done to create an additional level of abstraction in the code, improving readability and reusability.

We start by adding one more cBot parameter that would allow users to determine the traded volume.

1
2
[Parameter("Quantity (Lots)", Group = "Volume", DefaultValue = 1, MinValue = 0.01, Step = 0.01)]
public double Quantity { get; set; }

Afterward, we will add the Open() and Close() methods for entering a new position and closing all positions opened by the cBot in a given direction.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
private void Open(TradeType tradeType)
{
    var position = Positions.Find("SampleRSI", SymbolName, tradeType);
    var volumeInUnits = Symbol.QuantityToVolumeInUnits(Quantity);

    if (position == null)
        ExecuteMarketOrder(tradeType, SymbolName, volumeInUnits, "RSI cBot");
}

private void Close(TradeType tradeType)
{
    foreach (var position in Positions.FindAll("SampleRSI", SymbolName, tradeType))
        ClosePosition(position);
}

We can use our auxiliary methods to complete the automated trading strategy.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
protected override void OnTick()
{
    if (rsi.Result.LastValue < BuyLevel)
    {
        Close(TradeType.Sell);
        Open(TradeType.Buy);
    }
    else if (rsi.Result.LastValue > SellLevel)
    {
        Close(TradeType.Buy);
        Open(TradeType.Sell);
    }
}

Backtesting the cBot

After we finish coding the cBot, we can build it and switch to the 'Backtesting' tab to see how it performs on historical data. To learn more about backtesting, click here.

We can also attach the Relative Strength Indicator to the current chart to see whether the trades executed by the bot match the intended entry points.

To learn more about using and developing cBots, feel free to browse other sections of the documentation and subscribe to our YouTube channel to be notified when we publish a new video.

Subscribe to our YouTube channel