Indicator Code Samples
Simple Indicators¶
The High Minus Low Indicator calculates the difference between the current bar’s High and Low prices and displays it in an output series, which is drawn on the chart as a line connecting the values at each bar.
1 2 3 4 5 6 7 8 9 10 11 12 |
|
The IndicatorAttribute is applied to the class to indicate certain characteristics such as:
- IsOverlay: if it will be overlayed on the chart or on a separate panel (IsOverlay = true/false);
- TimeZone: The time zone of indicator data and server time
- AccessRights: The indicator code access rights
- ScalePrecision: the scale precision on the chart (ScalePrecision = 5 in the present example).
Note
Check the Indicator Attribute section for the complete list.
The IndicatorAttribute is required even if the properties in parenthesis are omitted (for example [Indicator()]
).
As mentioned in the previous section the indicator must be an Indicator derived class:
1 |
|
The Output Attribute is applied to mark an IndicatorDataSeries
as output to the chart.
The property that is marked with the output attribute should be public so that it can be referenced from other classes.
As with the Indicator attribute, the Output attribute allows specifying characteristics such as:
- the name given to the output (
Main
in the present example); - the color (
LineColor = "Orange"
in the present example), you can also use hexadecimal color codes.
Note
Check the OutputAttribute section for the complete list.
The name will be displayed in the small panel that is displayed when you add an instance.
From this panel, you can change the other characteristics of the output, such as the color, thickness, and line type.
IndicatorDataSeries
is a list of doubles that can be indexed like an array.
Hence, the value at each [index]
in the list Result
is assigned in the Calculate
method as follows:
1 2 3 4 |
|
To find the total number of elements in a series use the Count
property as follows: Bars.HighPrices.Count
.
If you type Bars.HighPrices
in the editor followed by a period (dot), Intellisense will populate the list.
As you might have noticed, Bars.HighPrices[index]
and Bars.LowPrices[index]
are also indexed in the same fashion.
They are of type DataSeries
which is also a list of doubles but this type is read-only (values can be retrieved but not assigned).
The Bars interface contains the following series:
- OpenPrices
- HighPrices
- LowPrices
- ClosePrices
- MedianPrices
- TypicalPrices
- WeightedPrices
- TickVolumes
- OpenTimes
It also has SymbolName and TimeFrame properties of the relevant instance.
In other words, it will retrieve the above values of whichever symbol and Timeframe you choose when you create a new instance.
If you type Bars in the editor followed by a period (dot), Intellisense will populate the list.
Bars itself is also a collection, and you can access each bar by passing it's index, and it will return a bar object:
1 2 3 4 5 |
|
Indicators with Parameters¶
In most cases, the indicators can vary according to the user input.
The Simple Moving Average is designed to accept the price source and the period for the calculation as the input parameters.
Input must be preceded by the Parameter attribute as it is shown in the code below - the Source and the Periods properties are preceded by the [Parameter()]
attribute.
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 27 28 29 30 |
|
The Indicator instance panel with the parameters as set above will look as follows (click cog to open the parameters dropdown):
Like the Indicator and Output attributes discussed earlier, the [Parameter()]
attribute can define certain characteristics to the input:
1 |
|
- The name that is displayed in the input panel of an instance (MA Periods).
- The default value of an input which is the initial value before it can be changed by the user (
DefaultValue = 14
). - The minimum and maximum values in case of numbers (MinValue = 1, MaxValue = 20).
Note
Check the ParameterAttribute section for the complete list.
Currently, the supported types of input are:
- DataSeries
- int
- double
- string
- bool
- MovingAverageType
- Enums
- TimeFrame
If the input is a price source such as Open, High, Low or Close, then make the property a DataSeries type:
1 2 |
|
The default value for the DataSeries type is Closed and it cannot be set.
If you need multi option parameter use .NET enums:
1 2 3 4 5 6 7 8 9 |
|
If the input needs to be a number, then int (integer) or double (decimal) can be used:
1 2 |
|
Declare a bool for a yes/no type input. The values “Yes” and “No” correspond to “true” or “false” respectively:
1 2 |
|
Nested Indicators¶
In certain occasions, it is necessary to use Nested indicators.
The Nested indicator is an indicator which value depends on the value of other indicators.
Such is the case with the Sample DeMarker indicator which is located in the Indicators tab by default.
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 27 28 29 30 31 32 33 |
|
In the example above deMinMA and deMaxMA are indicators which are used for the calculation of the DeMark indicator.
Nested indicators need to be defined in the Initialize()
method.
For example, deMinMA is defined as the simple moving average of the series deMin.
1 |
|
deMin in its turn is defined in the Calculate method as the max of the last two Low price values.
1 |
|
The IntelliSense will populate the list of all built-in indicators once you type Indicators. (followed by a period (dot) in the editor.
The IntelliSense also shows the list of the input parameters to the referenced indicator once the indicator has been selected from the list.
Custom Indicators¶
A custom indicator is any indicator you create in cTrader Automate. The Sample Indicators provided in the Indicators tab by default are custom indicators.
Follow these steps to reference a custom indicator:
1. Click Manage References to the upper left of the code editor.
2. In Indicators section of the Reference Manager pop-up check the required indicators and click Apply. Alternatively, use the advanced search to find the required indicator.
Referenced Custom Indicators are defined in the Initialize()
method just like the nested built-in indicators, but the syntax is slightly different.
The name of the custom indicator should be enclosed in angle brackets following the GetIndicator
directive.
The parameters of the referenced indicator follow enclosed in parenthesis just like with built-in indicators, as follows:
1 |
|
Example:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
|
Oscillators and the Levels Attribute¶
The Indicators that oscillate around a constant value belong to the category of the Oscillators.
When creating Oscillators it is useful to draw a horizontal or “level” line at that constant value around which the indicator oscillates. In many cases, this value is zero.
The momentum oscillator typically oscillates around 100, so we will add a level line at that value using the Levels attribute.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
|
Note that the levels can only be used when the indicator is not overlayed on the chart.
That is, the property IsOverlay
is not set to true in the Indicator attribute as follows: [Indicator("Momentum Oscillator", IsOverlay = false)]
.
This will not work. IsOverlay
is false by default so if it is omitted like in the following example, the indicator will be displayed below the chart and the Levels will be displayed properly.
If multiple lines are necessary, then add a comma-separated list of the values within the parenthesis. For example:
1 |
|
1 |
|
1 |
|
IsLastBar Property¶
In certain cases, we may need an indicator that requires to be calculated at the last bar.
Then, the IsLastBar
property can be checked, to determine if as the name suggests, the index parameter of the Calculate method, is that of the last bar.
The following indicator displays the last open time in New York and Tokyo while the indicator is based on UTC time.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
|
Combining Indicators¶
In case you want to have many indicators displayed on the same panel that are not overlayed on the chart you may combine them in one custom indicator.
The following indicator combines the Aroon, RSI and Directional Movement System Indicators in one.
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 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
|
Multiple Timeframes¶
Example 1: Using multiple timeframes.
The following example displays a moving average on different timeframes.
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 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
|
Example 2: Using Multiple timeframes and Symbols.
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 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
|