Zum Inhalt

Grid cBot

Strategieübersicht

Grid cBot implementiert eine Grid-Handelsstrategie, bei der mehrere Kauf- oder Verkaufsorders für ein Symbol in regelmäßigen Preisintervallen oder „Schritten" platziert werden und ein „Raster" von Positionen bilden. Wenn sich der Symbolpreis ändert, werden ständig neue Positionen eröffnet, um Schwankungen auszunutzen.

Grid cBot verwendet eine Kombination aus einfacher Arithmetik und logischen Prüfungen, um Positionen zu eröffnen, Gewinne zu berechnen und seine Handelsoperationen zu verwalten. Er ist am effektivsten in bereichsgebundenen oder seitwärts gerichteten Märkten. Er funktioniert auch gut bei Bedingungen mit geringer Volatilität und in Märkten mit bekannten Widerstands- und Unterstützungsniveaus.

cBot-Erstellung

Erfahren Sie in unseren Schritt-für-Schritt-Anleitungen, wie Sie cBots erstellen, entweder mit C# oder Python.

Der Grid cBot-Code ist in unseren öffentlichen C#- und Python-Repositories verfügbar. Derselbe Code wird als Vorlage im Erstellungsassistenten für Algorithmen in cTrader Windows oder Mac bereitgestellt, oder Sie können einfach den folgenden Codeausschnitt kopieren und verwenden:

 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

Indikatorintegration

Grid cBot verlässt sich nicht auf einen Indikator, um seine Grid-Strategie zu definieren; er versucht nicht vorherzusagen, ob ein Symbolpreis steigen oder fallen wird. Stattdessen zielt er auf profitable Transaktionen aus Preisbewegungen in jede Richtung ab.

Der cBot führt Transaktionen basierend auf dieser einfachen Regel aus: Wenn sich der Symbolpreis über eine bestimmte Anzahl von Pips hinaus bewegt (definiert durch den Parameter StepPips), eröffnet der cBot eine neue Position.

Berechnung und Logik

Erste Handelsausführung

Wenn der cBot startet, prüft er, ob offene Positionen im Raster vorhanden sind. Wenn keine offenen Positionen vorhanden sind, eröffnet der cBot sofort die erste Position über die Methode OpenPosition(). Dieser erste Schritt stellt sicher, dass das Raster mit einer anfänglichen Transaktion basierend auf der angegebenen Handelsseite (TradeType) beginnt.

Gewinnüberwachung

Bei jedem Tick (z. B. bei jeder Preisaktualisierung) prüft der cBot, ob der kumulierte Nettogewinn aller offenen Rasterpositionen dem angegebenen Zielgewinn (TargetProfit) entspricht oder diesen überschreitet. Wenn der Zielgewinn erreicht wurde, werden alle offenen Positionen geschlossen und der cBot stoppt.

Der Zielgewinn ist die Summe des Nettogewinns aus jeder Position im Raster.

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

\(n\) – Anzahl der offenen Positionen im Raster

\(\text{NetProfit}(p_i)\) – Nettogewinn der Position \(i\)

Eröffnung von Positionen

Wenn der Zielgewinn nicht erreicht wurde und offene Positionen vorhanden sind, berechnet der cBot den Abstand (in Pips) zwischen der zuletzt eröffneten Rasterposition und dem aktuellen Marktpreis.

Für Kaufpositionen:

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

Für Verkaufspositionen:

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

\(D_b\) – Abstand in Pips zwischen dem Einstiegskurs und dem aktuellen Briefkurs.

\(D_s\) – Abstand in Pips zwischen dem aktuellen Geldkurs und dem Einstiegskurs.

\(P_e\) – Kurs, zu dem die letzte Kaufposition für das Symbol eröffnet wurde.

\(P_a\) – aktueller Briefkurs für das Symbol.

\(P_b\) – aktueller Geldkurs für das Symbol.

\(S\) – Wert eines Pips für das Symbol.

Wenn die berechnete Distanz größer oder gleich der definierten Schrittgröße (StepPips) ist, wird eine neue Position mit der Methode OpenPosition() eröffnet.

Jedes Mal, bevor eine neue Position eröffnet wird, prüft und bestätigt der cBot, dass ausreichend Mittel für die Operation vorhanden sind. Wenn die Mittel nicht ausreichen, stoppt der cBot den Versuch, neue Positionen zu eröffnen, und protokolliert die Meldung „Not enough money to open additional positions".

Positionen schließen

Sobald der TargetProfit erreicht ist, protokolliert der cBot die Meldung „Target profit is reached. Closing all grid positions".

Die Methode CloseGridPositions() durchläuft dann alle offenen Positionen im Grid, schließt sie und der cBot protokolliert die Meldung „All grid positions are closed. Stopping cBot". Der cBot wird dann gestoppt.

Parameter

Parameter Einheit Definition Tipps
Menge Lot Volumen jeder Transaktion. Konservative Händler können kleine Lotgrößen angeben, um das Risiko zu reduzieren und das Risiko sorgfältig zu verwalten, insbesondere in einem volatilen Markt. Auf diese Weise wird jeder potenzielle Verlust minimiert, wenn sich der Markt gegen das Grid bewegt.

Aggressive Händler können große Lotgrößen angeben, um Gewinne zu maximieren, wenn sie von einem Markt überzeugt sind. Obwohl dieser Ansatz riskanter ist, liefert er größere Renditen, wenn das Grid große Preisschwankungen effektiv erfasst.
Handelsseite — Richtung der Transaktion (Kauf oder Verkauf). In einem steigenden Markt können Händler Kauf wählen. Wenn das Symbol vorübergehend nach unten zurückgeht, kauft der cBot auf niedrigeren Niveaus. Wenn sich der Markt wieder nach oben bewegt, wird jede Kaufposition profitabel.

In einem fallenden Markt können Händler Verkauf wählen. Wenn der Symbolpreis vorübergehend nach oben zurückgeht, verkauft der cBot auf höheren Niveaus. Wenn sich der Markt wieder nach unten bewegt, wird jede Verkaufsposition profitabel.
Schritt Pip Abstand zwischen zwei aufeinanderfolgenden Grid-Positionen. Je kleiner der Schritt, desto häufiger werden neue Transaktionen eröffnet, während ein größerer Schritt zu weniger Transaktionen führt. In einem seitwärts gerichteten oder wenig volatilen Markt können Händler einen kleinen Wert festlegen. Diese Einstellung stellt sicher, dass der cBot häufiger Positionen eröffnet und kleine Preisschwankungen erfasst, insbesondere wenn sich der Preis innerhalb einer engen Spanne bewegt.

In Trend- oder volatileren Märkten können Händler einen großen Wert festlegen. Diese Einstellung reduziert die Anzahl der eröffneten Transaktionen, ermöglicht es dem cBot, größere Bewegungen zu erfassen, und hilft, Überhandel während starker Trends zu vermeiden.
Zielgewinn — Kumulativer Gewinn in der Kontowährung, der erreicht werden muss, bevor der cBot alle offenen Positionen schließt und den Handel stoppt. Händler, die schnelle, kleine Gewinne anstreben, können einen niedrigen Wert festlegen. Diese Einstellung stellt sicher, dass das Grid geschlossen wird, sobald ein kleiner Gewinn erzielt wurde, wodurch das Risiko minimiert wird, dass Positionen in volatilen Märkten zu lange gehalten werden.

Händler, die lieber auf große Gewinne warten, können einen hohen Wert festlegen. Diese Einstellung ermöglicht es dem Grid, länger geöffnet zu bleiben, sodass der cBot Gewinne über eine Reihe größerer Marktbewegungen ansammeln kann, bevor alle Positionen geschlossen werden.

Anwendung

Bereichsgebundene oder seitwärts gerichtete Märkte

Grid cBot ist am effektivsten in bereichsgebundenen Märkten, in denen der Preis zwischen Unterstützungs- und Widerstandsniveaus oszilliert. In solchen Märkten eröffnet der cBot regelmäßig Positionen und profitiert von Schwankungen, da die Preise häufig innerhalb einer definierten Spanne auf und ab gehen.

Anwendungsfall

Betrachten Sie ein Szenario, in dem EURUSD in der Spanne zwischen 1,1000 und 1,1100 bleibt. Der cBot eröffnet Kaufpositionen, wenn der Preis näher an 1,1000 fällt, und eröffnet Verkaufspositionen nahe 1,1100. Während der Preis zwischen diesen Niveaus oszilliert, erfasst der cBot Gewinne aus jeder Schwankung.

Bewährte Praktiken

  • Legen Sie eine kleine Schrittgröße fest, um häufige Preisschwankungen zu erfassen.
  • Legen Sie einen bescheidenen Zielgewinn fest, damit das Grid häufig geschlossen wird, sodass Sie kleine, konsistente Gewinne sichern können.
  • Überwachen Sie Marktnachrichten oder bevorstehende Ereignisse, die zu einem Ausbruch aus der Spanne führen und große Drawdowns verursachen könnten.

Märkte mit geringer Volatilität

In Märkten mit geringer Volatilität sind Preisbewegungen tendenziell langsam und weniger ausgeprägt. Während sich der Preis allmählich bewegt, hat Grid cBot ausreichend Zeit, mehrere Positionen zu eröffnen, ohne dem Risiko großer, schneller Marktbewegungen ausgesetzt zu sein.

Anwendungsfall

Betrachten Sie ein Szenario, in dem USDJPY eine geringe Volatilität aufweist, wie es häufig während der asiatischen Handelszeit der Fall ist. Grid cBot kann Positionen mit einer kleinen Schrittgröße eröffnen und kleine, allmähliche Preisbewegungen erfassen, die während dieser ruhigen Stunden auftreten.

Bewährte Praktiken

  • Verwenden Sie eine enge Schrittgröße, um von den kleineren Preisbewegungen zu profitieren, die typisch für Märkte mit geringer Volatilität sind.
  • Legen Sie ein niedriges Handelsvolumen fest, um das Risiko zu reduzieren, falls die Volatilität unerwartet zunimmt.
  • Behalten Sie die Marktbedingungen, unerwartete Nachrichten oder Ereignisse im Auge und seien Sie bereit, den cBot schnell zu stoppen.

Märkte mit bekannten Niveaus

Grid cBot kann in Märkten mit starken, klar definierten Unterstützungs- und Widerstandsniveaus gut funktionieren. Diese Niveaus fungieren als Preisbarrieren und führen dazu, dass der Markt häufig zurückprallt, was zu einer Spanne führt, die der cBot ausnutzen kann.

Anwendungsfall

Betrachten Sie ein Szenario, in dem der Preis von Gold (XAUUSD) zwischen einem starken Unterstützungsniveau bei 2.000 USD und einem Widerstandsniveau bei 2.050 USD oszilliert. Grid cBot eröffnet Kauforders nahe 2.000 USD und Verkaufsorders nahe 2.050 USD und profitiert davon, dass der Preis zwischen diesen Niveaus hin und her springt.

Bewährte Praktiken

  • Legen Sie die Schrittgröße basierend auf der Marktvolatilität fest. Ein Markt mit hoher Volatilität erfordert möglicherweise größere Schrittgrößen, während Märkte mit geringer Volatilität kleinere Schritte verwenden können.
  • Verwenden Sie Grid cBot in Märkten mit gut etablierten Unterstützungs- und Widerstandsniveaus, um nicht in einen Ausbruch zu geraten.
  • Seien Sie vorsichtig bei Ereignissen oder Nachrichten, die einen Ausbruch verursachen könnten, um große Verluste zu vermeiden. Der cBot ist nicht darauf vorbereitet, damit umzugehen, dass der Markt durch Unterstützungs- oder Widerstandsniveaus bricht.

Nicht-direktionale Märkte

Bestimmte Währungspaare zeigen eine nicht-direktionale Bewegung mit häufigen Kursschwankungen, aber ihr Kurs weist keinen starken langfristigen Trend auf. Grid cBot funktioniert in solchen Märkten gut, da er häufige Schwankungen erfassen kann, ohne das Risiko einzugehen, in einem langfristigen Trend gefangen zu werden.

Anwendungsfall

Betrachten Sie ein Szenario, in dem sich EURCHF nicht-direktional bewegt, was angesichts der Stabilität der Eurozone und der Schweizer Wirtschaft häufig vorkommt. Grid cBot kann Positionen mit einer kleinen Schrittgröße eröffnen und Gewinne aus häufigen Schwankungen erzielen, ohne sich um große direktionale Trends sorgen zu müssen.

Bewährte Praktiken

  • Verwenden Sie eine kleine Schrittgröße, um häufige Kursbewegungen zu erfassen.
  • Erwägen Sie, ein niedriges Handelsvolumen festzulegen, um das Risiko zu steuern, falls der Markt in einen Trend ausbricht.

Zusammenfassung

Grid cBot arbeitet unter der Annahme, dass es sowohl in bullischen als auch in bärischen Märkten Rücksetzer oder Pullbacks geben wird. Er kauft niedrig und verkauft hoch in bullischen Märkten und verkauft hoch und kauft niedrig in bärischen Märkten; der cBot erzielt Gewinne, wenn der Markt nach Rücksetzern den primären Trend wieder aufnimmt.

Da der cBot keine Indikatoren verwendet, kann er nicht beurteilen, ob der Markt im Trend oder in einer Spanne liegt. Er eröffnet einfach Positionen, die ausschließlich auf Kursbewegungen basieren, und ignoriert die Marktstimmung oder Trendstärke.

Das Fehlen von Indikatoren macht den Handelsprozess rein mechanisch; der cBot verlässt sich nur auf vordefinierte Regeln für das Eröffnen von Positionen in regelmäßigen Abständen. Während dieser Ansatz in spannengebundenen Märkten profitabel sein kann, leidet er tendenziell in trendigen, hochvolatilen oder sich schnell verändernden Märkten.

Zusätzlich zur Konfiguration des cBots zur Anwendung ihrer persönlichen Strategien können Händler erwägen, Indikatoren einzuführen, um Transaktionen basierend auf Marktbedingungen zu filtern:

  • Moving Averages (MA) können helfen, den Markttrend zu identifizieren, sodass der cBot nur in Richtung des Trends handelt.
  • Der Relative Strength Index (RSI) kann überkaufte oder überverkaufte Bedingungen signalisieren und dem cBot helfen, das Eröffnen neuer Positionen zu vermeiden, wenn der Markt in eine Richtung überdehnt ist.
  • Die Bollinger Bands können Einblick in die Kursvolatilität geben und dem cBot ermöglichen, den Gitterabstand anzupassen oder während Phasen hoher Volatilität vom Handel abzusehen.