Tag: trading automatico

Hello World in Pine Script: La Guida Definitiva – 04

Benvenuti, intrepidi programmatori e curiosi trader, nel meraviglioso mondo di Pine Script! Se avete mai desiderato creare i vostri indicatori su TradingView, siete nel posto giusto. Oggi vi guiderò attraverso il vostro primo script in Pine Script, il classico “Hello World”. Pronti a fare il primo passo? Partiamo!


Cos’è Pine Script?

Prima di tutto, un po’ di contesto. Pine Script è un linguaggio di scripting sviluppato da TradingView, una delle piattaforme di analisi tecnica più popolari al mondo. Questo linguaggio è pensato per permettere ai trader di creare indicatori personalizzati e strategie di trading in modo semplice e intuitivo.

Perché “Hello World”?

Il “Hello World” è il tipico primo programma che si scrive quando si impara un nuovo linguaggio di programmazione. È il modo perfetto per familiarizzare con la sintassi di Pine Script senza sentirsi sopraffatti. Iniziamo!


Passo 1: Aprire l’Editor Pine Script

  1. Accedi a TradingView: Se non l’hai già fatto, crea un account su TradingView.
  2. Apri un grafico: Seleziona qualsiasi asset su cui desideri lavorare.
  3. Apri l’Editor Pine Script: Clicca sull’icona dell’editor Pine Script nella parte inferiore della pagina.

Passo 2: Scrivere il Codice

Ora che abbiamo aperto l’editor, è il momento di scrivere il nostro primo script. Ecco il codice completo:

pinescriptCopy code//@version=4
study("Hello World", overlay=true)
plot(close)

Spiegazione del Codice

  1. //@version=4: Questo indica la versione di Pine Script che stiamo utilizzando. TradingView aggiorna regolarmente Pine Script, quindi assicurati di specificare la versione corretta.
  2. study("Hello World", overlay=true): La funzione study crea un nuovo indicatore. Il primo parametro è il nome dell’indicatore, mentre overlay=true significa che il nostro indicatore verrà visualizzato sul grafico del prezzo.
  3. plot(close): Questa funzione traccia una linea basata sui prezzi di chiusura (close) delle candele.

Passo 3: Applicare lo Script al Grafico

  1. Salvare lo script: Clicca sul pulsante “Save” nell’editor Pine Script. Dagli un nome accattivante come “Hello World”.
  2. Aggiungere al grafico: Dopo aver salvato, clicca su “Add to Chart”. Vedrai una linea che segue il prezzo di chiusura delle candele.

Passo 4: Personalizzare lo Script

Ora che abbiamo il nostro “Hello World”, possiamo divertirci un po’ personalizzandolo. Aggiungiamo un tocco di colore e un titolo più interessante:

pinescriptCopy code//@version=4
study("Hello World - Personalizzato", overlay=true)
plot(close, color=color.blue, linewidth=2, title="Prezzo di Chiusura")

Spiegazione delle Modifiche

  1. color=color.blue: Cambia il colore della linea a blu.
  2. linewidth=2: Aumenta lo spessore della linea.
  3. title="Prezzo di Chiusura": Aggiunge un titolo alla nostra linea.

Passo 5: Aggiungere un Indicatore Semplice

Per rendere il nostro script ancora più utile, aggiungiamo una Media Mobile Semplice (SMA):

pinescriptCopy code//@version=4
study("Hello World - Con SMA", overlay=true)
length = input(14, title="Lunghezza SMA")
sma = sma(close, length)
plot(sma, color=color.red, linewidth=2, title="SMA 14")
plot(close, color=color.blue, linewidth=1, title="Prezzo di Chiusura")

Spiegazione delle Aggiunte

  1. length = input(14, title="Lunghezza SMA"): Crea un input per l’utente per specificare la lunghezza della SMA. Il valore predefinito è 14.
  2. sma = sma(close, length): Calcola la Media Mobile Semplice basata sulla lunghezza specificata.
  3. plot(sma, color=color.red, linewidth=2, title="SMA 14"): Disegna la SMA sul grafico in rosso.

Conclusione

Congratulazioni! Avete scritto il vostro primo script Pine Script e lo avete anche personalizzato con una media mobile. Non è stato così difficile, vero? Pine Script è uno strumento potente e flessibile che può migliorare notevolmente la vostra analisi tecnica.

Continuate a esplorare e sperimentare con Pine Script. Presto sarete in grado di creare indicatori complessi e strategie di trading automatizzate. Buona programmazione!


Risorse Aggiuntive

  • Documentazione Ufficiale: Pine Script Reference
  • Corsi e Tutorial: Cercate su YouTube e piattaforme di e-learning per ulteriori tutorial e corsi su Pine Script.

Se questo articolo ti è stato utile, condividilo con altri aspiranti programmatori e trader! Seguimi per ulteriori guide e consigli su Pine Script e il mondo del trading. Buona fortuna e buon trading! 🚀

Se hai dubbi o domande a riguardo puoi farmele pure su

Instagram: https://www.instagram.com/investoinvestigando.it/

Qui puoi trovare tutta la guida: LINK

Cosa sono gli Array – 03

Cosa sono gli Array? In parole semplici, un array è una collezione ordinata di dati dello stesso tipo, come numeri, stringhe o colori. Immaginalo come un foglio di calcolo (excel) con righe e colonne, dove ogni cella contiene un valore specifico.

In poche parole è un insieme di variabili messe insieme, se ti sei perso la spiegazione sulle variabili recupera perché è fondamentale: LINK

Creazione di Array

Esistono diversi modi per creare un array in PineScript:

  • Funzione array.new: specifica il tipo di dati e la dimensione dell’array.
  • Assegnazione diretta: inserisci i valori tra parentesi quadre.
  • Funzione array.from: converte una serie di valori in un array.

Esempio:

Pine Script

// Crea un array di 5 numeri
float[] myArray = array.new_float(size=5);

// Assegna valori all'array
myArray[0] = 10.5;
myArray[1] = 22.2;
myArray[2] = 3.14;
myArray[3] = 99.9;
myArray[4] = 7.77;

// Stampa il secondo elemento
print(myArray[1]); // Stampa: 22.2

Quindi qui abbiamo creato un array con dimensione 5, quindi ha 5 posti dove mettere dei valori.

Funzionalità avanzate

PineScript offre una vasta gamma di funzioni per manipolare e analizzare gli array:

  • Ricerca e ordinamento: trova valori specifici o ordina l’array in base a criteri predefiniti.
  • Calcoli statistici: calcola media, mediana, deviazione standard e altri valori statistici.
  • Funzioni matematiche: applica operazioni matematiche come somma, prodotto e media su interi array.
  • Indicatori personalizzati: crea indicatori tecnici complessi sfruttando la flessibilità degli array.

Esempio:

Pine Script

// Calcola la media mobile di un array
float[] myArray = array.new_float(size=10);
...
float avg = array.avg(myArray);

Ovviamente è un esempio eh, non ti aspettare di fare i soldi con questo codice.

Vantaggi dell’utilizzo di Array

  • Efficienza: memorizza e gestisci grandi quantità di dati in modo efficiente.
  • Flessibilità: esegui calcoli complessi su più dati contemporaneamente.
  • Personalizzazione: crea strategie di trading avanzate e indicatori personalizzati.

Conclusione

Gli array sono uno strumento potente che può portare il tuo trading a un livello superiore. Imparare a usarli correttamente ti permetterà di analizzare i mercati in modo più approfondito e di sviluppare strategie di trading più efficaci.

Risorse aggiuntive:

Sfrutta il potere degli array per potenziare il tuo trading! Dai che piano piano stai imparando tante cose e tra poco sarai autonomo (ci vorrà ancora un po’ di studio…)

Se hai dubbi o domande a riguardo puoi farmele pure su Telegram: https://t.me/+0xQYD3WKIAA5Mjg8

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

Qui puoi trovare tutta la guida: LINK

Dynamic Range Revert Money Management

Ciao, la strategia Dynamic Range Revert Money Management è una miglioria alla strategia Dynamic Range Revert! (Pazzesco vero?! 😀 ) Si tratta della stessa strategia dove però i lotti cambiano in percentuale.

Ciao sono Drilon e sono un programmatore con la passione per la finanza personale. In questa strategia si imposta quanto del nostro capitale si vuole rischiare ad ogni trade, ad esempio l’1%! La logica che c’è sotto poi è la stessa che trovi qui (no dovevi cliccare QUI, c’è il link, non in questo, dai te lo rimetto qui, stasera mi è presa così…non sono simpatico scusa)

Risultati

Andiamo al sodo e vediamo il risultato!

dynamic range revert money management – risultati

Questo grafico è l’equityline, ovvero l’andamento. Partendo da 450$ si arriva a circa 3400$.

Aspetta non è così semplice, questa vale solo per EURCAD a timeframe 1 minuto!

Niente male lo so, ma non farti ingannare dai, ovviamente questo è un backtest, in live i risultati non saranno così, per via dello spread e le commissioni che qui è sono statiche (non zero, non mi ricordo che valore di preciso).

Ok abbiamo visto il grafico, vediamo più nel dettaglio però.

Un dato molto importante per me è sempre il Drawdown poiché devo essere in grado di sostenerlo sia economicamente che mentalmente (terribile veder scendere il valore dei soldi). In questo caso si tratta di circa un 12% di drawdown.

Non è tantissimo, però non è nemmeno poco, anche se per un guadagno del genere ne potrebbe valere la pena!

Vediamo che ha aperto circa 3000 ordini, quindi i dati sono abbastanza affidabile. Se un backtest di una strategia si fa su 10 ordini i dati che ottieni puoi evidenziarli, sottolinearli, accartocciare il foglio e buttare tutto! NON SONO ABBASTANZA! NON è ATTENDIBILE!

Un altro valore importante sono gli ordini consecutivi che sono andati in stopLoss, anche questo principalmente per una questione mentale (il rischio rendimento vedrai che non è come ti aspetti).

Personalmente, preferisco fare piccoli profitti costanti e prendere una batosta raramente, rispetto a prendere tanti stopLoss e un grande takeProfit. Mentalmente mi ammazza e mi porterebbe a fare cazzate!

Vabbè basta, io il mio l’ho detto, tieni il codice!

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 IIDynamicRangeBreakoutREVERTMM : Robot
    {
        [Parameter(DefaultValue = 10)]
        public double takeProfit { get; set; }

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

        [Parameter(DefaultValue = 8)]
        public int hourEnter { get; set; }

        [Parameter(DefaultValue = 18)]
        public int hourExit { get; set; }
        
        [Parameter(DefaultValue = 8)]
        public int hourClosingOpen{ get; set; }

        [Parameter(DefaultValue = 18)]
        public int hourClosingExit { get; set; }
        
        [Parameter(DefaultValue = 1)]
        public int maxOrder { get; set; }
        
        [Parameter(DefaultValue = 0)]
        public double maxRange { get; set; }
        
        [Parameter(DefaultValue = 999999)]
        public double minRange { get; set; }
        
        [Parameter(DefaultValue = 0.01)]
        public double lots { get; set; }
        
        [Parameter(DefaultValue = 3)]
        public int stopLossRiskPercent { get; set; }
        
        protected override void OnStart()
        {
            Positions.Closed += OnPositionsClosed;
        }

        protected override void OnTick()
        {
            // Handle price updates here
            if(!checkTime()){
                // Break Range
                if(Bars.LastBar.Close > maxRange && maxRange != 0){
                    // Open BUY
                    lots = DisplayPositionSizeRiskOnChart();
                    if(lots >= 0.00){
                        Open(TradeType.Sell, lots);
                        maxRange = 0;
                        minRange = 999999;
                    }
                }  
                
                if(Bars.LastBar.Close < minRange && minRange != 999999){
                    // Open SELL
                    lots = DisplayPositionSizeRiskOnChart();
                    if(lots >= 0.00){
                        Open(TradeType.Buy, lots);
                        maxRange = 0;
                        minRange = 999999;
                    }
                }
            }
            
            /*if(checkClosingTime()){
                CloseAll();
            }*/
        }
        
        protected override void OnBar()
        {
        
            if(checkTime()){
                // Set Range
                if(Bars.LastBar.High > maxRange ){
                    maxRange = Bars.LastBar.High;
                }  
                
                if(Bars.LastBar.Low < minRange ){
                    minRange = Bars.LastBar.Low;
                }
            }    
        }

        protected override void OnStop()
        {
            CloseAll();
        }
        
        private bool checkTime()
        {
            DateTime date = Server.Time;
            if (date.Hour >= hourEnter && date.Hour <= hourExit && hourEnter <= hourExit)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        
        private bool checkClosingTime()
        {
            DateTime date = Server.Time;
            if (date.Hour >= hourClosingOpen && date.Hour <= hourClosingExit && hourClosingOpen <= hourClosingExit)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        
        private void CloseAll()
        {
            foreach (var position in Positions.FindAll("DynamicRangeBreakoutREVERT", SymbolName))
            {
                ClosePosition(position);
            }
        }
        
        private void Close(TradeType tradeType)
        {
            foreach (var position in Positions.FindAll("DynamicRangeBreakoutREVERT", SymbolName, tradeType))
                ClosePosition(position);
        }

        private void Open(TradeType tradeType, double lots)
        {
            var position = Positions.FindAll("DynamicRangeBreakoutREVERT", SymbolName, tradeType);
            var volumeInUnits = Symbol.QuantityToVolumeInUnits(lots);
            if (position == null || position.Length < maxOrder)
                ExecuteMarketOrder(tradeType, SymbolName, volumeInUnits, "DynamicRangeBreakoutREVERT", stopLoss, takeProfit);
        }
        
        private void OnPositionsClosed(PositionClosedEventArgs args)
        {
            Print("Closed positions");
            var position = args.Position;

           /* if (position.NetProfit > 0)
            {
                lots = 0.03;
            }
            else
            {
                lots *= 2;
            }*/
        }
        
        
        private double DisplayPositionSizeRiskOnChart()
        {
            double costPerPip = (double)((int)(Symbol.PipValue * 10000000)) / 100;
 
            double positionSizeForRisk = (Account.Balance * stopLossRiskPercent / 100) / (stopLoss * costPerPip);
            Print(Account.Balance, " ",positionSizeForRisk, " ",(stopLoss * costPerPip));
            
            string text = stopLossRiskPercent + "% x " + stopLoss + "pip = " + Math.Round(positionSizeForRisk, 2) + " lot";
 
            ChartObjects.DrawText("positionRisk", text, StaticPosition.TopRight, Colors.Yellow);
            return Math.Round(positionSizeForRisk, 2);
        }
    }
} 

questi sono i parametri che devi impostare:

  • takeProfit: 15
  • stopLoss: 40
  • hourEnter: 18
  • hourExit: 19
  • hourClosingEnter: 18
  • hourClosingExit: 23
  • maxOrder: 1
  • minRange: 99999
  • lots: 0.01
  • stopLossRisk: 1

Mi raccomando, la strategia può funzionare anche con altre valute, ma con questi parametri specifici funziona sono in EURCAD a 1 minuto!

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/

Come iniziare a programmare

Ciao, se sei arrivato qui è perché vuoi imparare a programmare e magari vuoi programmare qualcosa inerente al trading!

Ci sono diversi step, secondo me, prima di diventare autonomi, vediamoli insieme.

1) La mentalità da programmatore

Come prima cosa bisogna che inizi a pensare come ragiona un programmatore, come affronta i problemi che può incontrare. Molto spesso i programmatori hanno anche una grande capacità di problem solving, ma non è un caso.

Per sviluppare una giusta mentalità è fondamentale andare sul pratico, scrivere codice, imbattersi nei problemi e cercare di risolverli. Grazie al c***o dirai, ma non è scontato poiché molti pensano che guardando un tutorial su youtube di 8 ore poi diventano programmatori.

2) Da dove iniziare?

Per apprendere la giusta mentalità bisogna partire dalle basi, quindi il primo linguaggio con cui approcciarsi è sicuramente il C++ poiché è uno dei linguaggi più completi… c’è un motivo se partono da esso anche nelle facoltà.

Per chi conosce l’inglese può seguire questo corso e fare ciò che viene spiegato, è lungo ma è completo!

tutorial c++ inglese

Per chi volesse qualcosa in italiano può seguire questo: https://www.html.it/guide/guida-c2/

oppure questo:

tutorial c++ italiano

Per chi volesse mettersi alla prova può provare a fare questi esercizi (ci sono anche le soluzioni): https://ticoprof.wordpress.com/esercizi-cplusplus/

Sarebbe utile, ma so che non li farai… (sorprendimi!)

Se hai dubbi o difficoltà contattatemi pure:

Telegram: https://t.me/+0xQYD3WKIAA5Mjg8

Instagram: https://www.instagram.com/investoinvestigando.it/

3) Facciamo trading!

Adesso che hai un’idea di cosa vuol dire programmare andiamo a fare trading! No, non proprio, piano piano.

Un aspetto importante da tener conto quando ci si sposta da una programmazione lineare, dove il codice viene eseguito dall’alto verso il basso, ad una programmazione “sequenziale” è che il codice viene letto tutte le volte, ogni secondo, quindi va gestito in modo diverso.

Faccio un esempio, C++:

....
cout<<"Ciao come stai?";
cin>>x;
cout<<x;
....
return;

In questo caso vedremo la domanda, inseriremo la risposta e vedremo la risposta che abbiamo dato! Vediamo adesso un codice per il trading:

onBar(){
 if(a>b){
   print("Nuova candela");
 }
}

Questo codice invece verrà eseguito alla generazione di ogni nuova candela! Non si interrompe a fine esecuzione.

Fatta questa piccola parentesi cosa devi fare? TradingView, o meglio PineScript

Qui c’è la documentazione generale: https://it.tradingview.com/pine-script-reference/v5/

Questo video può essere un buon punto di partenza:

pinescript

Consiglio questo video per capire di più i dati per il backtest e valutare se una strategia funziona oppure no!

backtest

4) AlgoTrading avanzato

Adesso facciamo sul serio! MQL oppure C#, sono due linguaggi molto usati nelle piattaforma per fare trading automatico!

Il primo è il linguaggio di programmazione per MetaTrader, è un linguaggio più grezzo e articolato ma permette di creare ottime strategie.

Questo video per avere un’idea generale:

mql generale

Mentre questo video per vedere un’esempio di strategia:

mql5 – stochastic

Personalmente questi sono tutti gli step che io ho fatto e i linguaggi che mi sono dovuto imparare (più altri per lavoro ma quello è un altro capitolo :D).

Alla fine ho scelto cTrader come piattaforma e C# come linguaggio di programmazione.

Più semplice, linguaggio un po’ più di alto livello e piattaforma decisamente migliore rispetto a MetaTrader!

Purtroppo non si trova praticamente niente online per imparare a fare trading automatico su cTrader ma questo video ve lo consiglio:

ctrader

Come ultima fonte c’è questa guida/documentazione: https://clickalgo.com/ctrader-learn-programming

Se fate tutti questi step (sono tante ore di studio e lavoro) alla fine sarete autonomi nel creare le vostre strategie di trading automatico!

Se hai dubbi o difficoltà contattatemi pure:

Telegram: https://t.me/+0xQYD3WKIAA5Mjg8

Instagram: https://www.instagram.com/investoinvestigando.it/

Se vuoi esempi di strategia automatiche: https://www.investoinvestigando.it/category/algotrading/

Una strategia per sempre? – AlgoTrading

Ciao, oggi torno a parlarti di una strategia automatica che ho scritto e testato personalmente, siamo sempre a una strategia da utilizzare sempre. Sono Drilon e sono un programmatore con la passione per la finanza personale!

La strategia ha dato risultati veramente interessanti, utilizzabile per ogni tipologia di portafoglio.

Idea

L’idea di base è quella di una “toccata e fuga” poiché noi siamo dei piccoli pesci per il mercato, non possiamo immaginare di combattere gli squali. L’imitiamoci a prendere il nostro e stare tranquilli.

Attenzione però, non è scalping perché non si punta tanto in pochissimo tempo per poter guadagnare qualcosa.

L’idea è di prendere una piccola parte di un grande movimento, infatti l’obiettivo è quello di prendere 10/15 pips e fine.

Vedi questo grafico? Indica la probabilità di arrivare al target (lato sinistro asse delle Y) in un numero di candele (lato basso asse delle X). Quindi perchè puntare a fare 200 pips se statisticamente è provato che è molto difficile? Andiamo a fare operazioni quasi certe!

Quindi, tornando alla strategia, l’idea è di utilizzare un qualcosa che ci indichi il trend principale (Media Mobile Esponenziale) e qualcosa che ci indichi quando entrare a mercato e per quanto starci, il 100% di probabilità di arrivare a target non c’è! Utilizzerò lo Stochastic! Quindi avremo qualcosa del genere:

Come si opera?

Allora si entra a mercato quando le medie mobili esponenziali sono verso lo stesso trend e lo stochastic incrocia ed entra nella zona azzurra, con un piccolo dettaglio però, bisogna entrare a mercato solo se l’intreccio attuale dello stochastic è avvenuto seguendo il trend rispetto all’intreccio precedente.

Mi spiego meglio!

Esempio di operazione di SELL

Abbiamo le medie mobili esponenziali tutte tendenti verso il basso, entriamo nel punto 3 perché l’intreccio precedente dello stochastic è avvenuto nel punto 2 ed il prezzo nel punto 2 era maggiore rispetto al punto 3, quindi conferma il trend ribassista sul quale noi vogliamo puntare.

Nel punto 2 non si entra poiché c’è stato un intreccio precedente nel punto 1 che è avvenuto a un prezzo più basso, quindi nel punto 2 poteva esserci un’inversione (Poi è sceso ma è l’incertezza del mercato).

Se si guarda più indietro in realtà noi si sarebbe entrati nel punto 1 perché il precedente intreccio dello stochastic era a un prezzo più alto, ma questo era giusto per farti un esempio e capire la strategia.

Ma quando esco? L’obiettivo è 10 pips di target oppure quando lo stochastic arriva nella zona opposta alla nostra, nel caso del sell si esce quando lo stochastic arriva sotto i 20.

Stessa cosa, capovolta, per quanto riguarda il buy

Codice

Dopo aver fatto l’optimization questo è il risultato:

In 11 anni ha eseguito 181 ordini, di cui 170 andati a target e 11 chiusi in negativo!

Non male eh? Il profitto però, come vedi, non è altissimo, è di 228$ che in 11 anni fanno abbastanza schifo, però questo a noi ci serve solo come test per capire se la strategia funziona o no! Questo è stato fatto puntando sempre il minimo (0.01 lotti)

Vuoi sapere la cosa bella? Che ha un drawdown di soli 33$!

Quindi se hai un capitale di 100$ puoi già partire con questa strategia, se hai un capitale di 1k puoi aumentare i lotti e utilizzarne (0.1) e otterresti un guadagno di circa 2280$ rischiando 330$.

Quindi dipende anche dal budget personale!

Questi sono i parametri da utilizzare:

Poi comunque puoi sbizzarrirti come più credi, facendo altri test e altri parametri.

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 IIScalping : Robot
    {

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

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

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

        [Parameter(DefaultValue = 8)]
        public int hourEnter { get; set; }

        [Parameter(DefaultValue = 18)]
        public int hourExit { get; set; }

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

        [Parameter(DefaultValue = 240)]
        public int slowPeriod { get; set; }

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

        [Parameter(DefaultValue = 2)]
        public int multiplier { get; set; }

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

        [Parameter(DefaultValue = 8)]
        public int stochLength { get; set; }

        [Parameter(DefaultValue = 3)]
        public int stochParams { get; set; }

        private ExponentialMovingAverage emaFast;
        private ExponentialMovingAverage emaSlow;
        private StochasticOscillator stoch;
        
        double stochLevel = 0.0;


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

        }

        protected override void OnBar()
        {
            // Put your core logic here
            emaFast = Indicators.ExponentialMovingAverage(Source, fastPeriod);
            emaSlow = Indicators.ExponentialMovingAverage(Source, slowPeriod);
            stoch = Indicators.StochasticOscillator(stochLength, stochParams, stochParams, MovingAverageType.Exponential);
            
            
            int currentBar = Bars.Count - 1;
            bool check = checkTime();
            var positions = Positions.FindAll("Order");
            if (check == true)
            {
                

                //Open(TradeType.Buy, lots);
                
                if(emaFast.Result.LastValue > emaSlow.Result.LastValue && stoch.PercentK[currentBar] > stoch.PercentD[currentBar] && stoch.PercentK[currentBar - 1] <= 20 && stochLevel == 0.0){
                    stochLevel = Bars.LastBar.Close;
                }
                
                if(emaFast.Result.LastValue < emaSlow.Result.LastValue && stoch.PercentK[currentBar] < stoch.PercentD[currentBar] && stoch.PercentK[currentBar - 1] >= 80 && stochLevel == 0.0){
                    stochLevel = Bars.LastBar.Close;
                }

                if (emaFast.Result.LastValue > emaSlow.Result.LastValue && stoch.PercentK[currentBar] > stoch.PercentD[currentBar] && stoch.PercentK[currentBar - 1] <= 20 && Bars.LastBar.Close > stochLevel)
                {
                    stochLevel = 0.0;
                    //stopLoss = (Bars[currentBar-1].Close - Bars[currentBar-1].Low)*100000;
                    Open(TradeType.Buy, lots);
                }

                if (emaFast.Result.LastValue < emaSlow.Result.LastValue && stoch.PercentK[currentBar] < stoch.PercentD[currentBar] && stoch.PercentK[currentBar - 1] >= 80 && Bars.LastBar.Close < stochLevel)
                {
                    stochLevel = 0.0;
                    //stopLoss = (Bars[currentBar-1].High - Bars[currentBar-1].Close)*100000;
                    Open(TradeType.Sell, lots);
                }

            }
            
            if(positions.Length>0 && (positions[0].TradeType == TradeType.Buy)){
                if(stoch.PercentK[currentBar] >= 80){
                    Close(TradeType.Buy);
                }
            }
            
            
            if(positions.Length>0 && (positions[0].TradeType == TradeType.Buy)){
                if(stoch.PercentK[currentBar] <= 20){
                    Close(TradeType.Sell);
                }
            }

        }

        protected override void OnStop()
        {
            // Put your deinitialization logic here
        }

        private bool checkTime()
        {
            DateTime date = Server.Time;
            if (date.Hour >= hourEnter && date.Hour <= hourExit)
            {
                return true;
            }
            else
            {
                return false;
            }
        }

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

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


}

Questo è il broker che utilizzo: https://www.icmarkets.eu/en/

Questa è un’altra strategia: https://www.investoinvestigando.it/algotrading-macd-ema/