This article complements our extensive list of indicator code samples. We expand on some concepts mentioned in these code samples and discuss several advanced features you can implement when creating new indicators.
The cloud attribute
You have probably seen transparent clouds on trading charts.
You can add clouds to your indicator outputs by using the CloudAttribute class attribute as shown in the example below:
usingcAlgo.API;usingcAlgo.API.Indicators;usingSystem;namespacecAlgo{/// <summary>/// This indicator shows how to make a built-in cTrader indicator multi time frame and how to use cloud attribute/// </summary>[Indicator(IsOverlay = true, TimeZone = TimeZones.UTC, AccessRights = AccessRights.None), Cloud("Top", "Bottom", Opacity = 0.2)]publicclassBollingerBandsMTFCloudSample:Indicator{privateBollingerBands_bollingerBands;privateBars_baseBars;[Parameter("Base TimeFrame", DefaultValue = "Daily")]publicTimeFrameBaseTimeFrame{get;set;}[Parameter("Source", DefaultValue = DataSeriesType.Close)]publicDataSeriesTypeDataSeriesType{get;set;}[Parameter("Periods", DefaultValue = 14, MinValue = 0)]publicintPeriods{get;set;}[Parameter("Standard Deviation", DefaultValue = 2, MinValue = 0)]publicdoubleStandardDeviation{get;set;}[Parameter("MA Type", DefaultValue = MovingAverageType.Simple)]publicMovingAverageTypeMaType{get;set;}[Output("Main", LineColor = "Yellow", PlotType = PlotType.Line, Thickness = 1)]publicIndicatorDataSeriesMain{get;set;}[Output("Top", LineColor = "Red", PlotType = PlotType.Line, Thickness = 1)]publicIndicatorDataSeriesTop{get;set;}[Output("Bottom", LineColor = "Red", PlotType = PlotType.Line, Thickness = 1)]publicIndicatorDataSeriesBottom{get;set;}protectedoverridevoidInitialize(){_baseBars=MarketData.GetBars(BaseTimeFrame);varbaseSeries=GetBaseSeries();_bollingerBands=Indicators.BollingerBands(baseSeries,Periods,StandardDeviation,MaType);}publicoverridevoidCalculate(intindex){varbaseIndex=_baseBars.OpenTimes.GetIndexByTime(Bars.OpenTimes[index]);Main[index]=_bollingerBands.Main[baseIndex];Top[index]=_bollingerBands.Top[baseIndex];Bottom[index]=_bollingerBands.Bottom[baseIndex];}privateDataSeriesGetBaseSeries(){switch(DataSeriesType){caseDataSeriesType.Open:return_baseBars.OpenPrices;caseDataSeriesType.High:return_baseBars.HighPrices;caseDataSeriesType.Low:return_baseBars.LowPrices;caseDataSeriesType.Close:return_baseBars.ClosePrices;default:thrownewArgumentOutOfRangeException("DataSeriesType");}}}publicenumDataSeriesType{Open,High,Low,Close}}
The CloudAttribute constructor takes two output line names. Afterwards, it automatically plots the cloud to match the space between these two outputs.
You can also set the opacity of the cloud by using the Opacity property. To set up the cloud colour, use the FirstColor property. By default, the colour of the cloud will match the colour of the first line in the indicator output.
Work with colours
The Algo API includes the Colorenum that can be used to configure the colours for Chart objects, chart controls and outputs.
The values of the Colorenum represent commonly used colours. You can use them without having to deal with hexadecimal or ARGB colour codes.
When customising outputs, you can set their colours by using the LineColor string property. As shown below, it accepts both named colours and hexadecimal colour codes.
1234
_=Chart.DrawStaticText("NamedColor","This is text using Color class color name properties",VerticalAlignment.Center,HorizontalAlignment.Center,Color.Red);_=Chart.DrawStaticText("HexadecimalColor","This is text using Hexadecimal color",VerticalAlignment.Bottom,HorizontalAlignment.Center,Color.FromHex("#FF5733"));_=Chart.DrawStaticText("ARGBColor","This is text using ARGB color",VerticalAlignment.Top,HorizontalAlignment.Center,Color.FromArgb(255,200,100,60));_=Chart.DrawStaticText("ParsedNameColor","This is text using color name by parsing it from string",VerticalAlignment.Center,HorizontalAlignment.Left,Color.FromName("Yellow"));
1 2 3 4 5 6 7 8 910111213
varstackPanel=newStackPanel{Orientation=Orientation.Vertical,HorizontalAlignment=HorizontalAlignment.Center,VerticalAlignment=VerticalAlignment.Center};stackPanel.AddChild(newTextBlock{Text="Red Color property",BackgroundColor=Color.Red});stackPanel.AddChild(newTextBlock{Text="Hexadecimal Color code",BackgroundColor=Color.FromHex("#FF5733")});stackPanel.AddChild(newTextBlock{Text="ARGB Color",BackgroundColor=Color.FromArgb(200,100,40,80)});stackPanel.AddChild(newTextBlock{Text="Color Name",BackgroundColor=Color.FromName("Green")});Chart.AddControl(stackPanel);
Colours can also be treated as customisable parameters. To allow users to select custom colours (for example, the colours of the lines drawn by an indicator), declare a parameter of the Color type.
In the example below, we create a simple (high minus low) indicator that, upon being initialised, displays text on the trading chart to which it is attached.
1 2 3 4 5 6 7 8 910111213141516171819
usingcAlgo.API;usingcAlgo.API.Indicators;usingcAlgo.API.Collections;usingcAlgo.API.Internals;namespacecAlgo{[Indicator(IsOverlay = false, TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]publicclassHighMinusLowColor:Indicator{[Parameter("Text Color", DefaultValue="#f54242")]publicColorTextColor{get;set;}publicoverridevoidInitialize(){varstaticText=Chart.DrawStaticText("static","This text shows how color parameters work",VerticalAlignment.Center,HorizontalAlignment.Center,TextColor);}}}
Output types
There are several different types of output available for custom indicators:
Line - a continuous line.
DiscontinuousLine - a non-continuous line that is useful for cases in which your indicator does not always have a calculation value.
Points - a point or a dot for each bar.
Histogram - a series of vertical bars. When using this type, set the IsOverlay property of your indicator to false.
To set an output type, use the PlotType property as demonstrated below.
The enum type is needed to create parameters that have several predefined options from which users could choose. We use the enum type in the following example:
If you add this parameter to an indicator or cBot, you will see a multi-option interactable menu allowing you to choose one of the specified enum values.
Work with time
Platform and server time
You can get the current server time by accessing either the Server.Time or Server.TimeInUtc properties.
The Server.Time property represents the current time in your indicator or cBot time zone established via the TimeZone property.
Bar open time
Use the Bars.OpenTime collection to get the bar open times. The time zone will be based on the time zone you have specified in the TimeZone class attribute.
Use the Application.UserTimeOffset property to get the time zone of the user's platform. This is primarily used for converting your indicator time to the user's time zone.
The Application.UserTimeOffset property returns a TimeSpan object representing the time offset set by the user in their cTrader platform compared to UTC time.
You can also choose to get notified when a user changes their platform time offset. To do so, use the Application.UserTimeOffsetChanged event.
cTrader supports dedicated date and time parameter types that allow you to get strongly typed date and time values as input for your algos instead of using the string parameter type.
By using the new date and time parameter types, you can obtain values in your algo time zone with built-in minimum and maximum validation and full optimisation support, just like other parameter types.
To get a certain time value via a customisable parameter, you can use these C# types: