Aller au contenu

Opérations avancées avec les indicateurs

Cet article complète notre liste complète d'exemples de code d'indicateurs. Nous développons certains concepts mentionnés dans ces exemples de code et discutons de plusieurs fonctionnalités avancées que vous pouvez implémenter lors de la création de nouveaux indicateurs.

L'attribut cloud

Vous avez probablement vu des nuages transparents sur les graphiques de trading.

Image title

Vous pouvez ajouter des nuages à vos sorties d'indicateur en utilisant l'attribut de classe CloudAttribute comme indiqué dans l'exemple ci-dessous :

 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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
using cAlgo.API;
using cAlgo.API.Indicators;
using System;

namespace cAlgo
{
    /// <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)]
    public class BollingerBandsMTFCloudSample : Indicator
    {
        private BollingerBands _bollingerBands;

        private Bars _baseBars;

        [Parameter("Base TimeFrame", DefaultValue = "Daily")]
        public TimeFrame BaseTimeFrame { get; set; }

        [Parameter("Source", DefaultValue = DataSeriesType.Close)]
        public DataSeriesType DataSeriesType { get; set; }

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

        [Parameter("Standard Deviation", DefaultValue = 2, MinValue = 0)]
        public double StandardDeviation { get; set; }

        [Parameter("MA Type", DefaultValue = MovingAverageType.Simple)]
        public MovingAverageType MaType { get; set; }

        [Output("Main", LineColor = "Yellow", PlotType = PlotType.Line, Thickness = 1)]
        public IndicatorDataSeries Main { get; set; }

        [Output("Top", LineColor = "Red", PlotType = PlotType.Line, Thickness = 1)]
        public IndicatorDataSeries Top { get; set; }

        [Output("Bottom", LineColor = "Red", PlotType = PlotType.Line, Thickness = 1)]
        public IndicatorDataSeries Bottom { get; set; }

        protected override void Initialize()
        {
            _baseBars = MarketData.GetBars(BaseTimeFrame);

            var baseSeries = GetBaseSeries();

            _bollingerBands = Indicators.BollingerBands(baseSeries, Periods, StandardDeviation, MaType);
        }

        public override void Calculate(int index)
        {
            var baseIndex = _baseBars.OpenTimes.GetIndexByTime(Bars.OpenTimes[index]);

            Main[index] = _bollingerBands.Main[baseIndex];
            Top[index] = _bollingerBands.Top[baseIndex];
            Bottom[index] = _bollingerBands.Bottom[baseIndex];
        }

        private DataSeries GetBaseSeries()
        {
            switch (DataSeriesType)
            {
                case DataSeriesType.Open:
                    return _baseBars.OpenPrices;

                case DataSeriesType.High:
                    return _baseBars.HighPrices;

                case DataSeriesType.Low:
                    return _baseBars.LowPrices;

                case DataSeriesType.Close:
                    return _baseBars.ClosePrices;
                default:

                    throw new ArgumentOutOfRangeException("DataSeriesType");
            }
        }
    }

    public enum DataSeriesType
    {
        Open,
        High,
        Low,
        Close
    }
}

Le constructeur CloudAttribute prend deux noms de lignes de sortie. Ensuite, il trace automatiquement le nuage pour correspondre à l'espace entre ces deux sorties.

Vous pouvez également définir l'opacité du nuage en utilisant la propriété Opacity. Pour configurer la couleur du nuage, utilisez la propriété FirstColor. Par défaut, la couleur du nuage correspondra à la couleur de la première ligne dans la sortie de l'indicateur.

Travailler avec les couleurs

L'API Algo inclut l'enum Color qui peut être utilisé pour configurer les couleurs des objets Chart, des contrôles de graphique et des sorties.

Les valeurs de l'enum Color représentent les couleurs couramment utilisées. Vous pouvez les utiliser sans avoir à gérer les codes de couleur hexadécimaux ou ARGB.

Lors de la personnalisation des sorties, vous pouvez définir leurs couleurs en utilisant la propriété de chaîne LineColor. Comme indiqué ci-dessous, elle accepte à la fois les couleurs nommées et les codes de couleur hexadécimaux.

1
2
3
4
_ = 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
 9
10
11
12
13
var stackPanel = new StackPanel
{
    Orientation = Orientation.Vertical,
    HorizontalAlignment = HorizontalAlignment.Center,
    VerticalAlignment = VerticalAlignment.Center
};

stackPanel.AddChild(new TextBlock { Text = "Red Color property", BackgroundColor = Color.Red });
stackPanel.AddChild(new TextBlock { Text = "Hexadecimal Color code", BackgroundColor = Color.FromHex("#FF5733") });
stackPanel.AddChild(new TextBlock { Text = "ARGB Color", BackgroundColor = Color.FromArgb(200, 100, 40, 80) });
stackPanel.AddChild(new TextBlock { Text = "Color Name", BackgroundColor = Color.FromName("Green") });

Chart.AddControl(stackPanel);
1
2
3
4
5
[Output("Hexadecimal", LineColor = "#FF5733", PlotType = PlotType.Line, Thickness = 1)]
public IndicatorDataSeries Hexadecimal { get; set; }

[Output("Name", LineColor = "Red", PlotType = PlotType.Line, Thickness = 1)]
public IndicatorDataSeries Name { get; set; }

Remarque

Les couleurs peuvent également être traitées comme des paramètres personnalisables. Pour permettre aux utilisateurs de sélectionner des couleurs personnalisées (par exemple, les couleurs des lignes tracées par un indicateur), déclarez un paramètre de type Color.

1
2
[Parameter("Drawing Color", DefaultValue = "#f54242")]
public Color DrawingColor { get; set; }

Dans l'exemple ci-dessous, nous créons un indicateur simple (haut moins bas) qui, lors de son initialisation, affiche du texte sur le graphique de trading auquel il est attaché.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
using cAlgo.API;
using cAlgo.API.Indicators;
using cAlgo.API.Collections;
using cAlgo.API.Internals;

namespace cAlgo
{
    [Indicator(IsOverlay = false, TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class HighMinusLowColor: Indicator
    {
        [Parameter("Text Color", DefaultValue="#f54242")]
        public Color TextColor { get; set; }

        public override void Initialize()
        {
            var staticText = Chart.DrawStaticText("static", "This text shows how color parameters work", VerticalAlignment.Center, HorizontalAlignment.Center, TextColor);
        }
    }
}

Types de sortie

Plusieurs types de sortie différents sont disponibles pour les indicateurs personnalisés :

  • Line - une ligne continue.
  • DiscontinuousLine - une ligne non continue qui est utile dans les cas où votre indicateur n'a pas toujours de valeur de calcul.
  • Points - un point ou un point pour chaque barre.
  • Histogram - une série de barres verticales. Lors de l'utilisation de ce type, définissez la propriété IsOverlay de votre indicateur sur false.

Pour définir un type de sortie, utilisez la propriété PlotType comme démontré ci-dessous.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
[Output("Line", PlotType = PlotType.Line)]
public IndicatorDataSeries Line { get; set; }

[Output("Discontinuous Line", PlotType = PlotType.DiscontinuousLine)]
public IndicatorDataSeries DiscontinuousLine { get; set; }

[Output("Points", PlotType = PlotType.Points)]
public IndicatorDataSeries Points { get; set; }

[Output("Histogram", PlotType = PlotType.Histogram)]
public IndicatorDataSeries Histogram { get; set; }

Paramètres enum

Le type enum est nécessaire pour créer des paramètres qui ont plusieurs options prédéfinies parmi lesquelles les utilisateurs peuvent choisir. Nous utilisons le type enum dans l'exemple suivant :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
public enum Options
{
    First,
    Second,
    Third,
    Fourth
}

[Parameter("Options", DefaultValue = Options.Third)]
public Options OptionsParameter { get; set; }

Si vous ajoutez ce paramètre à un indicateur ou à un cBot, vous verrez un menu interactif à options multiples vous permettant de choisir l'une des valeurs enum spécifiées.

Travailler avec le temps

Heure de la plateforme et du serveur

Vous pouvez obtenir l'heure actuelle du serveur en accédant aux propriétés Server.Time ou Server.TimeInUtc.

1
2
var currentServerTimeInIndicatorTimeZone = Server.Time;
var currentServerTimeInUtc = Server.TimeInUtc;

La propriété Server.Time représente l'heure actuelle dans le fuseau horaire de votre indicateur ou cBot établi via la propriété TimeZone.

Heure d'ouverture de la barre

Utilisez la collection Bars.OpenTime pour obtenir les heures d'ouverture des barres. Le fuseau horaire sera basé sur le fuseau horaire que vous avez spécifié dans l'attribut de classe TimeZone.

1
2
3
4
public override void Calculate(int index)
{
    var barTime = Bars.OpenTimes[index];
}

Décalage horaire de la plateforme

Utilisez la propriété Application.UserTimeOffset pour obtenir le fuseau horaire de la plateforme de l'utilisateur. Ceci est principalement utilisé pour convertir l'heure de votre indicateur dans le fuseau horaire de l'utilisateur.

1
var userPlatformTimeOffset = Application.UserTimeOffset;

La propriété Application.UserTimeOffset renvoie un objet TimeSpan représentant le décalage horaire défini par l'utilisateur dans sa plateforme cTrader par rapport à l'heure UTC.

Vous pouvez également choisir d'être notifié(e) lorsqu'un utilisateur modifie le décalage horaire de sa plateforme. Pour ce faire, utilisez l'événement Application.UserTimeOffsetChanged.

1
2
3
4
5
6
7
8
9
protected override void Initialize()
{
    Application.UserTimeOffsetChanged += Application_UserTimeOffsetChanged;
}

private void Application_UserTimeOffsetChanged(UserTimeOffsetChangedEventArgs obj)
{
    var platformTimeOffset = obj.UserTimeOffset;
}

Obtenir l'heure avec un paramètre

cTrader prend en charge des types de paramètres de date et d'heure dédiés qui vous permettent d'obtenir des valeurs de date et d'heure fortement typées en entrée pour vos algos au lieu d'utiliser le type de paramètre string.

En utilisant les nouveaux types de paramètres de date et d'heure, vous pouvez obtenir des valeurs dans le fuseau horaire de votre algo avec une validation minimale et maximale intégrée et une prise en charge complète de l'optimisation, tout comme les autres types de paramètres.

Pour obtenir une certaine valeur de temps via un paramètre personnalisable, vous pouvez utiliser ces types C# :

  • DateTime
  • DateOnly
  • TimeSpan

Voici un exemple de la façon dont cela peut être fait :

 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
using cAlgo.API;
using System;

namespace cAlgo
{
    [Indicator(IsOverlay = true, TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class Sample : Indicator
    {
        [Parameter("DateTime Parameter", MinValue = "1970-01-01T00:00:00", MaxValue = "2025-11-01T00:00:00", DefaultValue = "2025-01-01T10:00:00")]
        public DateTime DateTimeParameter { get; set; }

        [Parameter("DateOnly Parameter", MinValue = "1970-01-01", MaxValue = "2025-11-01", DefaultValue = "2025-01-01")]
        public DateOnly DateOnlyParameter { get; set; }

        [Parameter("TimeSpan Parameter", MinValue = "00:00:00", MaxValue = "23:59:59", DefaultValue = "04:10:20")]
        public TimeSpan TimeSpanParameter { get; set; }

        protected override void Initialize()
        {
            Print($"DateTimeParameter: {DateTimeParameter:o}");
            Print($"DateOnlyParameter: {DateOnlyParameter:o}");
            Print($"TimeSpanParameter: {TimeSpanParameter}");
        }

        public override void Calculate(int index)
        {
        }
    }
}

Image title