Vai al contenuto

Grid cBot

Panoramica della strategia

Grid cBot implementa una strategia di trading a griglia in cui più ordini di acquisto o vendita per un simbolo vengono aperti a intervalli di prezzo regolari o "step", formando una "griglia" di posizioni. Man mano che il prezzo del simbolo cambia, nuove posizioni vengono aperte costantemente per sfruttare le fluttuazioni.

Grid cBot utilizza una combinazione di aritmetica semplice e controlli logici per aprire posizioni, calcolare i profitti e gestire le sue operazioni di trading. È più efficace nei mercati limitati a un intervallo o laterali. Funziona bene anche in condizioni di bassa volatilità e mercati con livelli di resistenza e supporto noti.

Creazione del cBot

Scopri come creare cBot, utilizzando C# o Python, nelle nostre guide dettagliate.

Il codice di Grid cBot è disponibile nei nostri repository pubblici C# e Python. Lo stesso codice è fornito come modello nella procedura guidata di creazione dell'algoritmo in cTrader Windows o Mac, oppure puoi semplicemente copiare e utilizzare lo snippet qui sotto:

 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

Integrazione dell'indicatore

Grid cBot non si basa su alcun indicatore per definire la sua strategia a griglia; non cerca di prevedere se il prezzo di un simbolo salirà o scenderà. Invece, punta a operazioni redditizie dai movimenti di prezzo in qualsiasi direzione.

Il cBot esegue operazioni in base a questa semplice regola: se il prezzo del simbolo si muove oltre un numero specificato di pip (definito dal parametro StepPips), il cBot apre una nuova posizione.

Calcolo e logica

Esecuzione dell'operazione iniziale

Quando il cBot si avvia, verifica se ci sono posizioni aperte nella griglia. Se non ci sono posizioni aperte, il cBot apre immediatamente la prima posizione tramite il metodo OpenPosition(). Questo primo passaggio assicura che la griglia inizi con un'operazione iniziale basata sul lato dell'operazione specificato (TradeType).

Monitoraggio del profitto

A ogni tick (ad esempio, ogni aggiornamento del prezzo), il cBot verifica se il profitto netto cumulativo di tutte le posizioni della griglia aperte raggiunge o supera il profitto target specificato (TargetProfit). Se il profitto target è stato raggiunto, tutte le posizioni aperte vengono chiuse e il cBot smette di funzionare.

Il profitto target è la somma del profitto netto di ciascuna posizione nella griglia.

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

\(n\) – numero di posizioni aperte nella griglia

\(ext{NetProfit}(p_i)\) – profitto netto della posizione \(i\)

Apertura delle posizioni

Se il profitto target non è stato raggiunto e ci sono posizioni aperte, il cBot calcola la distanza (in pip) tra l'ultima posizione della griglia aperta e il prezzo di mercato attuale.

Per le posizioni di acquisto:

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

Per le posizioni di vendita:

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

\(D_b\) – distanza in pip tra il prezzo di entrata e il prezzo ask attuale.

\(D_s\) – distanza in pip tra il prezzo bid attuale e il prezzo di entrata.

\(P_e\) – prezzo al quale è stata aperta l'ultima posizione di acquisto per il simbolo.

\(P_a\) – prezzo ask attuale per il simbolo.

\(P_b\) – prezzo bid attuale per il simbolo.

\(S\) – valore di un pip per il simbolo.

Se la distanza calcolata è maggiore o uguale alla dimensione del passo definita (StepPips), viene aperta una nuova posizione utilizzando il metodo OpenPosition().

Ogni volta prima di aprire una nuova posizione, il cBot verifica e conferma che ci siano fondi sufficienti per l'operazione. Se i fondi sono insufficienti, il cBot smette di tentare di aprire nuove posizioni e registra il messaggio "Not enough money to open additional positions".

Chiusura delle posizioni

Una volta raggiunto il TargetProfit, il cBot registra il messaggio "Target profit is reached. Closing all grid positions".

Il metodo CloseGridPositions() quindi scorre tutte le posizioni aperte nella griglia, le chiude e poi il cBot registra il messaggio "All grid positions are closed. Stopping cBot". Il cBot viene quindi arrestato.

Parametri

Parametro Unità Definizione Suggerimenti
Quantità Lotto Volume di ciascuna operazione. I trader conservativi possono specificare lotti di piccole dimensioni per ridurre l'esposizione e gestire il rischio con attenzione, soprattutto in un mercato volatile. In questo modo, qualsiasi potenziale perdita viene ridotta al minimo se il mercato si muove contro la griglia.

I trader aggressivi possono specificare lotti di grandi dimensioni per massimizzare i profitti quando sono fiduciosi in un mercato. Sebbene questo approccio sia più rischioso, offre rendimenti maggiori quando la griglia cattura efficacemente ampie fluttuazioni di prezzo.
Lato operazione — Direzione dell'operazione (acquisto o vendita). In un mercato in rialzo, i trader possono selezionare acquisto. Quando il simbolo ritraccia temporaneamente verso il basso, il cBot acquista a livelli inferiori. Man mano che il mercato risale, ogni posizione di acquisto diventa redditizia.

In un mercato in ribasso, i trader possono selezionare vendita. Quando il prezzo del simbolo ritraccia temporaneamente verso l'alto, il cBot vende a livelli superiori. Man mano che il mercato scende, ogni posizione di vendita diventa redditizia.
Passo Pip Distanza tra due posizioni consecutive della griglia. Più piccolo è il passo, più frequentemente vengono aperte nuove operazioni, mentre un passo più grande comporta un numero inferiore di operazioni. In un mercato laterale o a bassa volatilità, i trader possono impostare un valore piccolo. Questa impostazione garantisce che il cBot apra posizioni più frequentemente e catturi piccole fluttuazioni di prezzo, soprattutto quando il prezzo si muove all'interno di una banda ristretta.

In mercati in trend o più volatili, i trader possono impostare un valore grande. Questa impostazione riduce il numero di operazioni aperte, consente al cBot di catturare movimenti più ampi e aiuta a evitare un eccesso di trading durante trend forti.
Profitto target — Profitto cumulativo nella valuta del conto che deve essere raggiunto prima che il cBot chiuda tutte le posizioni aperte e interrompa il trading. I trader che cercano profitti rapidi e piccoli possono impostare un valore basso. Questa impostazione garantisce che la griglia si chiuda non appena viene realizzato un piccolo profitto, riducendo al minimo il rischio che le posizioni vengano mantenute troppo a lungo in mercati volatili.

I trader che preferiscono attendere profitti elevati possono impostare un valore alto. Questa impostazione consente alla griglia di rimanere aperta più a lungo, permettendo al cBot di accumulare profitti su una serie di movimenti di mercato più ampi prima che tutte le posizioni vengano chiuse.

Applicazione

Mercati range-bound o laterali

Il cBot Grid è più efficace nei mercati range-bound in cui il prezzo oscilla tra livelli di supporto e resistenza. In tali mercati, poiché i prezzi si muovono frequentemente su e giù all'interno di un intervallo definito, il cBot apre posizioni regolarmente e capitalizza sulle fluttuazioni.

Caso d'uso

Considera uno scenario in cui EURUSD rimane nell'intervallo tra 1,1000 e 1,1100. Il cBot apre posizioni di acquisto quando il prezzo scende più vicino a 1,1000 e apre posizioni di vendita vicino a 1,1100. Man mano che il prezzo oscilla tra questi livelli, il cBot cattura profitti da ogni oscillazione.

Buona pratica

  • Imposta una dimensione del passo piccola per catturare frequenti oscillazioni di prezzo.
  • Imposta un profitto target modesto in modo che la griglia si chiuda frequentemente, consentendoti di assicurarti profitti piccoli e costanti.
  • Monitora le notizie di mercato o gli eventi imminenti che potrebbero portare a una rottura dell'intervallo e causare grandi drawdown.

Mercati a bassa volatilità

Nei mercati a bassa volatilità, i movimenti di prezzo tendono a essere lenti e meno pronunciati. Poiché il prezzo si muove gradualmente, Grid cBot ha tutto il tempo di aprire più posizioni senza affrontare il rischio di movimenti di mercato ampi e rapidi.

Caso d'uso

Considera uno scenario in cui USDJPY mostra una bassa volatilità, come spesso accade durante la sessione di trading asiatica. Grid cBot può aprire posizioni con un intervallo ridotto e catturare i piccoli movimenti di prezzo graduali che si verificano durante quelle ore tranquille.

Buona pratica

  • Usa un intervallo ridotto per capitalizzare i movimenti di prezzo più piccoli tipici dei mercati a bassa volatilità.
  • Imposta un volume di trading basso per ridurre il rischio nel caso in cui la volatilità aumenti inaspettatamente.
  • Tieni d'occhio le condizioni di mercato, notizie o eventi imprevisti e preparati a interrompere il cBot rapidamente.

Mercati con livelli noti

Grid cBot può funzionare bene nei mercati con livelli di supporto e resistenza forti e ben definiti. Questi livelli agiscono come barriere di prezzo e fanno sì che il mercato rimbalzi frequentemente, creando un intervallo che il cBot può sfruttare.

Caso d'uso

Considera uno scenario in cui il prezzo dell'oro (XAUUSD) oscilla tra un forte livello di supporto a 2.000 USD e un livello di resistenza a 2.050 USD. Grid cBot apre ordini di acquisto vicino a 2.000 USD e ordini di vendita vicino a 2.050 USD, traendo profitto dal prezzo che rimbalza tra questi livelli.

Buona pratica

  • Imposta l'intervallo in base alla volatilità del mercato. Un mercato ad alta volatilità potrebbe richiedere intervalli più ampi, mentre i mercati a bassa volatilità possono utilizzare intervalli più piccoli.
  • Usa Grid cBot in mercati con livelli di supporto e resistenza ben consolidati per evitare di rimanere intrappolato in una rottura.
  • Fai attenzione a eventi o notizie che potrebbero causare una rottura per evitare grandi perdite. Il cBot non è preparato a gestire il mercato che supera i livelli di supporto o resistenza.

Mercati non direzionali

Alcune coppie di valute mostrano un movimento non direzionale con frequenti fluttuazioni di prezzo, ma il loro prezzo non mostra un forte trend a lungo termine. Grid cBot funziona bene in tali mercati perché può catturare frequenti fluttuazioni senza il rischio di rimanere intrappolato in un trend a lungo termine.

Caso d'uso

Considera uno scenario in cui EURCHF si muove in modo non direzionale, un evento comune data la stabilità dell'Eurozona e dell'economia svizzera. Grid cBot può aprire posizioni con un intervallo ridotto, ottenendo profitti dalle frequenti fluttuazioni senza preoccuparsi di grandi trend direzionali.

Buona pratica

  • Usa un intervallo ridotto per catturare i frequenti movimenti di prezzo.
  • Considera di impostare un volume di trading basso per gestire il rischio nel caso in cui il mercato si trasformi in un trend.

Grid cBot opera partendo dal presupposto che durante i mercati sia rialzisti che ribassisti ci saranno ritracciamenti o pullback. Compra basso e vende alto nei mercati rialzisti e vende alto e compra basso nei mercati ribassisti; il cBot ottiene profitti quando il mercato riprende il trend primario dopo i ritracciamenti.

Poiché il cBot non utilizza indicatori, non può valutare se il mercato è in trend o in range. Apre semplicemente posizioni basandosi esclusivamente sul movimento del prezzo, ignorando il sentiment di mercato o la forza del trend.

L'assenza di indicatori rende il processo di trading puramente meccanico; il cBot si basa solo su regole predefinite per aprire posizioni a intervalli regolari. Sebbene questo approccio possa essere redditizio nei mercati range-bound, tende a soffrire nei mercati in trend, altamente volatili o in rapido cambiamento.

Oltre a configurare il cBot per applicare le proprie strategie personali, i trader potrebbero considerare l'introduzione di indicatori per filtrare le operazioni in base alle condizioni di mercato:

  • Le Moving Averages (MA) possono aiutare a identificare il trend di mercato, consentendo al cBot di operare solo nella direzione del trend.
  • Il Relative Strength Index (RSI) può segnalare condizioni di ipercomprato o ipervenduto, aiutando il cBot a evitare di aprire nuove posizioni quando il mercato è esteso in una direzione.
  • Le Bollinger Bands possono fornire informazioni sulla volatilità del prezzo, consentendo al cBot di regolare la spaziatura della griglia o di sospendere il trading durante periodi di alta volatilità.