Aller au contenu

Grid cBot

Aperçu de la stratégie

Grid cBot met en œuvre une stratégie de trading en grille où plusieurs ordres d'achat ou de vente pour un symbole sont placés à intervalles de prix réguliers ou « étapes », formant une « grille » de positions. Au fur et à mesure que le cours du symbole change, de nouvelles positions sont ouvertes en permanence pour profiter des fluctuations.

Grid cBot utilise une combinaison de calculs arithmétiques simples et de vérifications logiques pour ouvrir des positions, calculer les profits et gérer ses opérations de trading. Il est plus efficace dans les marchés limités ou latéraux. Il fonctionne également bien dans des conditions de faible volatilité et sur des marchés avec des niveaux de résistance et de support connus.

Création de cBot

Découvrez comment créer des cBots, en utilisant C# ou Python, dans nos guides étape par étape.

Le code de Grid cBot est disponible dans nos dépôts publics C# et Python. Le même code est fourni comme modèle dans l'assistant de création d'algorithmes dans cTrader Windows ou Mac, ou vous pouvez simplement copier et utiliser l'extrait 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
89
90
91
92
93
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using cAlgo.API;
using cAlgo.API.Collections;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;

namespace cAlgo.Robots
{
    [Robot(AccessRights = AccessRights.None)]
    public class Grid : Robot
    {
        [Parameter("Volume (lots)", DefaultValue = 0.01, MinValue = 0.01, Step = 0.01)]
        public double VolumeInLots { get; set; }

        [Parameter("Trade Side")]
        public TradeType TradeType { get; set; }

        [Parameter("Step (pips)", DefaultValue = 5, MinValue = 0.1, Step = 0.1)]
        public double StepPips { get; set; }

        [Parameter("Target Profit", DefaultValue = 20)]
        public double TargetProfit { get; set; }

        private bool enoughMoney = true;

        protected override void OnStart()
        {
            if (GridPositions.Length == 0)
                OpenPosition();
        }

        protected override void OnTick()
        {
            if (GridPositions.Sum(p => p.NetProfit) >= TargetProfit)
            {
                Print("Target profit is reached. Closing all grid positions");
                CloseGridPositions();
                Print("All grid positions are closed. Stopping cBot");
                Stop();
            }
            if (GridPositions.Length > 0 && enoughMoney)
            {
                var lastGridPosition = GridPositions.OrderBy(p => p.Pips).Last();
                var distance = CalculateDistanceInPips(lastGridPosition);

                if (distance >= StepPips)
                    OpenPosition();
            }
        }

        private Position[] GridPositions
        {
            get
            {
                return Positions
                    .Where(p => p.SymbolName == SymbolName && p.TradeType == TradeType)
                    .ToArray();
            }
        }

        private double CalculateDistanceInPips(Position position)
        {
            if (position.TradeType == TradeType.Buy)
                return (position.EntryPrice - Symbol.Ask) / Symbol.PipSize;
            else
                return (Symbol.Bid - position.EntryPrice) / Symbol.PipSize;
        }

        private void OpenPosition()
        {
            var result = ExecuteMarketOrder(TradeType, SymbolName, Symbol.QuantityToVolumeInUnits(VolumeInLots), "Grid");
            if (result.Error == ErrorCode.NoMoney)
            {
                enoughMoney = false;
                Print("Not enough money to open additional positions");
            }
        }

        private void CloseGridPositions()
        {
            while (GridPositions.Length > 0)
            {
                foreach (var position in GridPositions)
                {
                    ClosePosition(position);
                }
            }
        }
    }
}
 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
import clr

clr.AddReference("cAlgo.API")

# Import cAlgo API types
from cAlgo.API import *

# Import trading wrapper functions
from robot_wrapper import *

class GridSample():
    def on_start(self):
        self.volumeInUnits = api.Symbol.QuantityToVolumeInUnits(api.VolumeInLots)
        self.enoughMoney = True
        if len(self.get_grid_positions()) == 0:
            self.open_position()

    def on_tick(self):
        grid_positions = self.get_grid_positions()
        net_profit_sum = sum([p.NetProfit for p in grid_positions])
        if net_profit_sum >= api.TargetProfit:
            api.Print("Target profit is reached. Closing all grid positions")
            self.close_grid_positions()
            api.Print("All grid positions are closed. Stopping cBot")
            api.Stop()

        if len(grid_positions) > 0 and self.enoughMoney == True:
            position_with_highest_pips = sorted(grid_positions, key=lambda pos: pos.Pips, reverse=True)[0]
            distance = self.get_distance_in_pips(position_with_highest_pips)          
            if distance >= api.StepPips:
                self.open_position()

    def get_grid_positions(self):
        return [pos for pos in api.Positions if pos.SymbolName == api.SymbolName and pos.TradeType == api.TradeType]

    def open_position(self):
        result = api.ExecuteMarketOrder(api.TradeType, api.SymbolName, self.volumeInUnits, "Grid")
        if result.Error == ErrorCode.NoMoney:
            self.enoughMoney = False
            api.Print("Not enough money to open additional positions")

    def close_grid_positions(self):
        for position in self.get_grid_positions():
            position.Close()

        if len(self.get_grid_positions()) > 0:
            self.close_grid_positions()

    def get_distance_in_pips(self, position):
        return (position.EntryPrice - api.Symbol.Ask if position.TradeType == TradeType.Buy else api.Symbol.Bid - position.EntryPrice) / api.Symbol.PipSize

Intégration de l'indicateur

Grid cBot ne s'appuie sur aucun indicateur pour définir sa stratégie de grille ; il n'essaie pas de prédire si le cours d'un symbole va monter ou descendre. Au lieu de cela, il cible des trades rentables à partir des mouvements de prix dans n'importe quelle direction.

Le cBot exécute des trades en fonction de cette règle simple : Si le cours du symbole se déplace au-delà d'un nombre spécifié de pips (défini par le paramètre StepPips), le cBot ouvre une nouvelle position.

Calcul et logique

Exécution du trade initial

Lorsque le cBot démarre, il vérifie s'il existe des positions ouvertes dans la grille. S'il n'y a pas de positions ouvertes, le cBot ouvre immédiatement la première position via la méthode OpenPosition(). Cette première étape garantit que la grille commence par un trade initial basé sur le sens de trade spécifié (TradeType).

Surveillance du profit

À chaque tick (par exemple, chaque mise à jour de prix), le cBot vérifie si le profit net cumulé de toutes les positions de grille ouvertes atteint ou dépasse le profit cible spécifié (TargetProfit). Si le profit cible a été atteint, toutes les positions ouvertes sont clôturées et le cBot cesse de fonctionner.

Le profit cible est la somme du profit net de chaque position dans la grille.

\[ \text{Total net profit} = \sum_{i=1}^{n} \text{NetProfit}(p_i) \]

\(n\) – nombre de positions ouvertes dans la grille

\(\text{NetProfit}(p_i)\) – profit net de la position \(i\)

Ouverture de positions

Si le profit cible n'a pas été atteint et qu'il existe des positions ouvertes, le cBot calcule la distance (en pips) entre la dernière position de grille ouverte et le cours actuel du marché.

Pour les positions d'achat :

\[ D_b = \frac{P_e - P_a}{S} \]

Pour les positions de vente :

\[ D_s = \frac{P_b - P_e}{S} \]

\(D_b\) – distance en pips entre le cours d'entrée et le cours acheteur actuel.

\(D_s\) – distance en pips entre le cours vendeur actuel et le cours d'entrée.

\(P_e\) – cours auquel la dernière position d'achat pour le symbole a été ouverte.

\(P_a\) – cours acheteur actuel pour le symbole.

\(P_b\) – cours vendeur actuel pour le symbole.

\(S\) – valeur d'un pip pour le symbole.

Si la distance calculée est supérieure ou égale à la taille d'étape définie (StepPips), une nouvelle position est ouverte à l'aide de la méthode OpenPosition().

Chaque fois avant d'ouvrir une nouvelle position, le cBot vérifie et confirme qu'il y a suffisamment de fonds pour l'opération. Si les fonds sont insuffisants, le cBot cesse de tenter d'ouvrir de nouvelles positions et enregistre le message « Pas assez d'argent pour ouvrir des positions supplémentaires ».

Clôture de positions

Une fois que le TargetProfit est atteint, le cBot enregistre le message « Le profit cible est atteint. Clôture de toutes les positions de grille ».

La méthode CloseGridPositions() parcourt ensuite toutes les positions ouvertes dans la grille, les clôture, puis le cBot enregistre le message « Toutes les positions de grille sont clôturées. Arrêt du cBot ». Le cBot est ensuite arrêté.

Paramètres

Paramètre Unité Définition Conseils
Quantité Lot Volume de chaque trade. Les traders conservateurs peuvent spécifier de petites tailles de lot pour réduire l'exposition et gérer le risque avec prudence, en particulier dans un marché volatil. De cette façon, toute perte potentielle est minimisée si le marché évolue à l'encontre de la grille.

Les traders agressifs peuvent spécifier de grandes tailles de lot pour maximiser les profits lorsqu'ils sont confiants dans un marché. Bien que cette approche soit plus risquée, elle génère de meilleurs rendements lorsque la grille capture efficacement de grandes fluctuations de prix.
Côté du trade — Sens du trade (achat ou vente). Dans un marché haussier, les traders peuvent sélectionner achat. Lorsque le symbole recule temporairement vers le bas, le cBot achète à des niveaux inférieurs. Lorsque le marché remonte, chaque position d'achat devient rentable.

Dans un marché baissier, les traders peuvent sélectionner vente. Lorsque le cours du symbole recule temporairement vers le haut, le cBot vend à des niveaux supérieurs. Lorsque le marché redescend, chaque position de vente devient rentable.
Étape Pip Distance entre deux positions de grille consécutives. Plus le pas est petit, plus les nouveaux trades sont ouverts fréquemment, tandis qu'un pas plus grand entraîne moins de trades. Dans un marché latéral ou à faible volatilité, les traders peuvent définir une valeur faible. Ce paramètre garantit que le cBot ouvre des positions plus fréquemment et capture les petites fluctuations de prix, en particulier lorsque le prix évolue dans une bande étroite.

Dans les marchés en tendance ou plus volatils, les traders peuvent définir une valeur élevée. Ce paramètre réduit le nombre de trades ouverts, permet au cBot de capturer des mouvements plus importants et aide à éviter le surtrading pendant les tendances fortes.
Profit cible — Profit cumulé dans la devise du compte qui doit être atteint avant que le cBot ne ferme toutes les positions ouvertes et n'arrête le trading. Les traders à la recherche de profits rapides et modestes peuvent définir une valeur faible. Ce paramètre garantit que la grille se ferme dès qu'un petit profit est réalisé, minimisant le risque que les positions soient maintenues trop longtemps dans des marchés volatils.

Les traders qui préfèrent attendre des profits importants peuvent définir une valeur élevée. Ce paramètre permet à la grille de rester ouverte plus longtemps, permettant au cBot d'accumuler des profits sur une série de mouvements de marché plus importants avant que toutes les positions ne soient fermées.

Application

Marchés limités ou latéraux

Grid cBot est plus efficace dans les marchés limités où le prix oscille entre les niveaux de support et de résistance. Dans de tels marchés, comme les prix évoluent fréquemment à la hausse et à la baisse dans une fourchette définie, le cBot ouvre des positions régulièrement et capitalise sur les fluctuations.

Cas d'utilisation

Considérez un scénario où EURUSD reste dans la fourchette entre 1,1000 et 1,1100. Le cBot ouvre des positions d'achat lorsque le prix baisse près de 1,1000 et ouvre des positions de vente près de 1,1100. Alors que le prix oscille entre ces niveaux, le cBot capture des profits à chaque oscillation.

Meilleures pratiques

  • Définissez un pas de petite taille pour capturer les oscillations de prix fréquentes.
  • Définissez un profit cible modeste afin que la grille se ferme fréquemment, vous permettant de sécuriser des profits modestes et réguliers.
  • Surveillez les actualités du marché ou les événements à venir qui pourraient entraîner une cassure de la fourchette et provoquer des pertes importantes.

Marchés à faible volatilité

Dans les marchés à faible volatilité, les mouvements de prix ont tendance à être lents et moins prononcés. Alors que le prix évolue progressivement, Grid cBot dispose de suffisamment de temps pour ouvrir plusieurs positions sans faire face au risque de mouvements de marché importants et rapides.

Cas d'utilisation

Considérez un scénario où USDJPY présente une faible volatilité comme c'est souvent le cas pendant la session de trading asiatique. Grid cBot peut ouvrir des positions avec un pas de petite taille et capturer les petits mouvements de prix progressifs qui se produisent pendant ces heures calmes.

Meilleures pratiques

  • Utilisez un pas serré pour capitaliser sur les mouvements de prix plus petits typiques des marchés à faible volatilité.
  • Définissez un volume de trade faible pour réduire le risque en cas d'augmentation inattendue de la volatilité.
  • Gardez un œil sur les conditions du marché, les actualités ou événements inattendus et soyez prêt à arrêter le cBot rapidement.

Marchés avec des niveaux connus

Grid cBot peut bien fonctionner dans les marchés avec des niveaux de support et de résistance forts et bien définis. Ces niveaux agissent comme des barrières de prix et font rebondir fréquemment le marché, créant une fourchette que le cBot peut exploiter.

Cas d'utilisation

Considérez un scénario où le prix de l'or (XAUUSD) oscille entre un niveau de support fort à 2 000 USD et un niveau de résistance à 2 050 USD. Grid cBot ouvre des ordres d'achat près de 2 000 USD et des ordres de vente près de 2 050 USD, profitant du rebond du prix entre ces niveaux.

Meilleures pratiques

  • Définissez la taille du pas en fonction de la volatilité du marché. Un marché à forte volatilité peut nécessiter des pas plus importants, tandis que les marchés à faible volatilité peuvent utiliser des pas plus petits.
  • Utilisez Grid cBot autour de marchés avec des niveaux de support et de résistance bien établis pour éviter d'être pris dans une cassure.
  • Soyez prudent face aux événements ou actualités qui pourraient provoquer une cassure afin d'éviter des pertes importantes. Le cBot n'est pas préparé à gérer le marché franchissant les niveaux de support ou de résistance.

Marchés non directionnels

Certaines paires de devises présentent un mouvement non directionnel avec des fluctuations de prix fréquentes, mais leur prix ne montre pas de tendance forte à long terme. Grid cBot fonctionne bien dans de tels marchés car il peut capturer des fluctuations fréquentes sans le risque d'être pris dans une tendance à long terme.

Cas d'utilisation

Considérez un scénario où EURCHF évolue de manière non directionnelle, une occurrence courante compte tenu de la stabilité de la zone euro et de l'économie suisse. Grid cBot peut ouvrir des positions avec un pas de petite taille, capturant des profits à partir de fluctuations fréquentes sans se soucier de grandes tendances directionnelles.

Meilleures pratiques

  • Utilisez un pas de petite taille pour capturer les mouvements de prix fréquents.
  • Envisagez de définir un volume de trade faible pour gérer le risque au cas où le marché évoluerait vers une tendance.

Résumé

Grid cBot fonctionne en partant du principe que pendant les marchés haussiers et baissiers, il y aura des retracements ou des replis. Il achète bas et vend haut dans les marchés haussiers et vend haut et achète bas dans les marchés baissiers ; le cBot capture des profits lorsque le marché reprend la tendance principale après les retracements.

Étant donné que le cBot n'utilise pas d'indicateurs, il ne peut pas évaluer si le marché est en tendance ou limité. Il ouvre simplement des positions en se basant uniquement sur le mouvement des prix, ignorant le sentiment du marché ou la force de la tendance.

L'absence d'indicateurs rend le processus de trading purement mécanique ; le cBot s'appuie uniquement sur des règles prédéfinies pour ouvrir des positions à intervalles réguliers. Bien que cette approche puisse être rentable dans les marchés limités, elle a tendance à souffrir dans les marchés en tendance, très volatils ou en évolution rapide.

En plus de configurer le cBot pour appliquer leurs stratégies personnelles, les traders peuvent envisager d'introduire des indicateurs pour filtrer les trades en fonction des conditions du marché :

  • Moving Averages (MA) peuvent aider à identifier la tendance du marché, permettant au cBot de trader uniquement dans la direction de la tendance.
  • Le Relative Strength Index (RSI) peut signaler des conditions de surachat ou de survente, aidant le cBot à éviter d'ouvrir de nouvelles positions lorsque le marché est étiré dans une direction.
  • Les Bollinger Bands peuvent fournir un aperçu de la volatilité des prix, permettant au cBot d'ajuster l'espacement de la grille ou de suspendre le trading pendant les périodes de forte volatilité.