Ciao, in questo articolo ti parlo di una semplicissima strategia automatizzata che può portare buoni profitti, se accettiamo i compromessi.

Ciao sono Drilon e sono un programmatore con la passione per la finanza personale, questo è il mio blog dove racconto il mio percorso. Questa strategia si basa semplicemente sull’indicatore relative strength index (RSI).

Idea di base

La logica è molto semplice, quando l’rsi arriva in zona di ipervenduto, chiude tutte le posizioni in sell e ne apre una in buy. Quando l’rsi arriva in zona di ipercomprato, chiude tutte le posizioni in buy e ne apre una in sell.

Da qui possiamo anche capire quali sono i parametri della strategia. Ah una cosa importante, questa strategia è senza stoploss, quindi da fare attenzione e da valutare bene!

Processo

Partendo dall’ottimizzazione dei parametri in un periodo che va dal 2019 al 2023 trovo le migliori combinazioni in questo lasso di tempo. Dopodiché la testo in un range più ampio che va dal 2011 al 2023.

Se in entrambe le situazioni la strategia si comporta bene ed ha un andamento che reputo valido a quel punto la metto in live.

Ottimizzazione

I migliori parametri che ho ottenuto dopo l’ottimizzazione sono:

  • takeProfit: 100000 (non ottimizzato, non si utilizza)
  • stopLoss: 100000 (non ottimizzato, non si utilizza)
  • overBougth: 81
  • overSell:31
  • period: 5
  • lotti: 0.1 (non ottimizzato)
  • maxOrder: 1 (non ottimizzato, il numero di ordini aperti nello stesso momento)

Questo è il risultato invece:

Un bel 560%! Però vediamo un po’ i dati statistici che sono molto importanti per la valutazione di una strategia. Non facciamoci fregare dalle performance!

Possiamo vedere che ha avuto un discreto drawdown che, personalmente, non sono disposto a subire. Abbiamo un profit factor maggiore di 1, quindi non male e vediamo anche che la perdita maggiore è di circa -450$. Il tutto è stato fatto con un portafoglio da 1000$ di partenza.

Problemi

Come possiamo notare dal backtest ci sono dei momenti in cui la strategia ha dei drawdown notevoli. Andando ad analizzare nel dettaglio, si vede che la strategia apre una posizione nel verso sbagliato, quando siamo vicini a un’inversione di trend, ed l’indicatore non arriva mai nella zona opposta per poter chiudere.

Questo è un po’ il problema generale dell’RSI, che magari è in zona di ipervenduto, ma prima di arrivare in ipercomprato passa del tempo perché siamo in un trend fortemente ribassista.

Questa cosa si può migliorare introducendo magari una media mobile o qualche altro indicatore. Da valutare.

Conclusione

Ora che abbiamo i dati alla mano possiamo valutare al meglio e decidere se metterla in live oppure no. Le domande che mi faccio sono:

  • Sono disposto a subire un drawdown maggiore del 50%?
  • Posso gestire emotivamente una perdita di -450$?
  • Quanti loss di fila posso sopportare?

Rispondendo a queste domande ti fai già un’idea se la strategia va bene per te oppure no!

Io personalmente posso metterla in live ma riducendo i lotti, perché comunque vedo che nel lungo termine è una strategia profittevole, però non sono disposto a rischiare così tanto.

Posso gestire invece una perdita di -45$ invece di -450$, riducendo i lotti a 0.01. Di conseguenza diminuisce anche il guadagno, invece del 560% sarà circa il 56% in 11 anni, però mi va comunque bene!

Sisi ora ti do il codice, però ricorda che è importante capire come funziona una strategia, utilizzarla sapendo cosa aspettarci!

Da qui puoi vedere come utilizzare cTrader (piattaforma che utilizzo): LINK

Se hai dubbi o domande fammele pure su Telegram: https://t.me/+0xQYD3WKIAA5Mjg8

Seguimi su instagram: https://www.instagram.com/investoinvestigando.it/

Codice

using System;
using System.Linq;
using cAlgo.API;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;
using cAlgo.Indicators;

namespace cAlgo.Robots
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class IIRsi: Robot
    {

        [Parameter("Source", Group = "Data series")]
        public DataSeries Source { get; set; }

        [Parameter(DefaultValue = 100000)]
        public double takeProfit { get; set; }

        [Parameter(DefaultValue = 100000)]
        public double stopLoss { get; set; }

        [Parameter(DefaultValue = 70)]
        public int overBougth { get; set; }

        [Parameter(DefaultValue = 30)]
        public int overSell { get; set; }

        [Parameter(DefaultValue = 60)]
        public int period { get; set; }

        [Parameter(DefaultValue = 0.01)]
        public double lots { get; set; }

        [Parameter(DefaultValue = 1)]
        public int maxOrder { get; set; }

        private RelativeStrengthIndex rsi;


        protected override void OnStart()
        {
            // Put your initialization logic here

        }

        protected override void OnBar()
        {
            // Put your core logic here
            rsi = Indicators.RelativeStrengthIndex(Source, period);
            
            
            int currentBar = Bars.Count - 1;
            bool check = true; //checkTime();
            var positions = Positions.FindAll("Order");
            if (check == true)
            {
                

                if (rsi.Result.LastValue < overSell)
                {
                    Close(TradeType.Sell);
                    Open(TradeType.Buy, lots);
                }

                if (rsi.Result.LastValue > overBougth)
                {
                    Close(TradeType.Buy);
                    Open(TradeType.Sell, lots);
                }

            }
           
        }


        private void Close(TradeType tradeType)
        {
            foreach (var position in Positions.FindAll("OrderRSI", SymbolName, tradeType))
                ClosePosition(position);
        }

        private void Open(TradeType tradeType, double lots)
        {
            var position = Positions.FindAll("OrderRSI", SymbolName, tradeType);
            var volumeInUnits = Symbol.QuantityToVolumeInUnits(lots);
            if (position == null || position.Length < maxOrder)
                ExecuteMarketOrder(tradeType, SymbolName, (double)volumeInUnits, "OrderRSI", stopLoss, takeProfit);
        }
    }
}