English Русский 中文 Español Deutsch 日本語 Português 한국어 Français
preview
Comprendere le funzioni in MQL5 con le applicazioni

Comprendere le funzioni in MQL5 con le applicazioni

MetaTrader 5Trading |
19 23
Mohamed Abdelmaaboud
Mohamed Abdelmaaboud

Introduzione

Nel mondo della programmazione c'è un termine molto popolare che viene usato e sentito molto spesso per la sua importanza in qualsiasi software: la Funzione. In questo articolo ne parleremo in dettaglio per imparare a creare un software molto funzionale e di alta qualità. Cercheremo di trattare questo importante argomento per capire cosa sono le funzioni, perché è necessario usarle e come utilizzarle nelle nostre applicazioni. In seguito, condivideremo alcune semplici funzioni che possono essere utilizzate in qualsiasi sistema di trading come esempi per applicare quanto appreso in questo articolo. I punti seguenti sono le idee principali che condivideremo in questo articolo per trattare questo interessante argomento:

Avvertenza: Tutte le informazioni sono fornite "così come sono" solo a scopo didattico e non sono preparate per scopi commerciali o di consulenza. Le informazioni non garantiscono alcun tipo di risultato. Se scegliete di utilizzare questi materiali su uno qualsiasi dei vostri conti di trading, lo farete a vostro rischio e pericolo e sarete gli unici responsabili.


Definizione di funzione

In questa parte, identificheremo le funzioni nella programmazione, i loro tipi e il motivo per cui è necessario utilizzarle. La funzione è un blocco di codice dichiarato con un nome esplicito e significativo che può essere utilizzato in qualsiasi altra parte del software richiamandolo più volte per eseguire un compito specifico. Se abbiamo un compito specifico che abbiamo bisogno che il software esegua in molte parti del nostro software o in molti software, creiamo una funzione o un blocco di codice per eseguire questo compito e poi lo chiamiamo solo in queste parti senza riscrivere di nuovo il codice completo; possiamo dire che la funzione è un metodo per astrarre il nostro codice senza avere un sacco di codice disordinato, come vedremo in questo articolo. Esistono due tipi principali di queste funzioni: le funzioni integrate e le funzioni definite dall'utente. La funzione integrata è la funzione già pronta del linguaggio di programmazione stesso, mentre la funzione definita dall'utente è la funzione che può essere creata dall'utente in base alle sue esigenze o ai compiti che deve svolgere il software. In questo articolo ci concentreremo sulle funzioni definite dall'utente. Per questo motivo, impareremo a conoscere questo tipo di funzione in dettaglio per capire perché è necessario utilizzarla e qual è la sua importanza o le caratteristiche del suo utilizzo.

Supponiamo di aver bisogno che il software esegua l'operazione di chiusura di tutti gli ordini aperti se l'equity ha raggiunto un drawdown massimo e di dover eseguire questa operazione in molte parti del software, sarebbe meglio qui, creare una funzione e includere tutto il codice o la logica necessari per eseguire questa operazione e poi richiamare questa funzione in altre parti, poiché non sarebbe bello o eccessivo scrivere e ripetere lo stesso codice in molte parti per eseguire l'operazione.

Se vi state chiedendo perché dobbiamo usare questo tipo di funzione, la risposta a questa domanda ci porterà a conoscere le caratteristiche dell'uso delle funzioni definite dall'utente:

  • Aiutano ad applicare il concetto di DRY (non ripetersi): L'uso di funzioni definite dall'utente ci aiuterà a non ripetere sempre lo stesso codice, ma a creare una funzione in grado di eseguire il nostro compito una sola volta e di richiamarla in qualsiasi parte del software.
  • Riutilizzabilità: Dopo aver creato la nostra funzione, possiamo riutilizzarla in qualsiasi momento.
  • Aiuta ad applicare il concetto di "divide et impera": Quando creiamo un software, il codice può essere complesso per risolvere un problema, ma se dividiamo il grande problema in piccoli problemi e risolviamo ognuno di essi attraverso le funzioni, questo può essere molto utile per raggiungere il nostro obiettivo di risolvere il grande problema.
  • Aiuta a rendere il codice più leggibile e comprensibile: L'uso delle funzioni aiuta a rendere leggibile il codice, che diventa più organizzato grazie alla loro presenza, e ognuno gestisce un problema specifico e ha un compito specifico.
  • Aiuta ad applicare il concetto di astrazione: L'uso delle funzioni fornisce un metodo per astrarre il nostro codice, perché se non le usiamo possiamo scoprire che è necessario scrivere più righe di codice rispetto all'uso delle funzioni.
  • Aiuta ad applicare il concetto di incapsulamento: L'uso delle funzioni ci permette di proteggere e gestire il nostro codice e i nostri dati in modo più efficace rispetto a quando non le usiamo.
  • Migliora il processo di debug: L'uso delle funzioni aiuta a migliorare l'esplorazione degli errori e a risolverli in modo molto più semplice.

In base a quanto detto a proposito delle caratteristiche dell'uso delle funzioni, possiamo facilmente capire quanto sia vantaggioso utilizzare queste funzioni definite dall'utente nel nostro software.


Struttura della funzione

In questa parte, impareremo maggiori dettagli sulle funzioni e sulla struttura delle funzioni, attraverso i due passi seguenti:

  • Dichiarazione o definizione di funzione
  • Chiamata di funzione

Per prima cosa, dobbiamo definire o dichiarare una nuova funzione, quindi dobbiamo fare qualcosa di simile alla struttura seguente:

returnedDataType functionName(param1, param2)
{
        bodyOfFunction
}
  • (returnedDataType): è il tipo di dato che la funzione deve restituire dopo l'esecuzione.
  • (functionName): è il nome della funzione, che viene assegnato in base al compito che la funzione svolge.
  • (param1, param2): qui aggiungiamo le variabili o i placeholder che ci servono, se sono essenziali, perché potremmo non specificarne nessuno.
  • (bodyOfFunction): si specifica tutto il codice che eseguirà il nostro compito. 

Applichiamolo a un semplice esempio, se abbiamo bisogno di creare una semplice funzione per eseguire un'addizione di due valori, possiamo farlo con il seguente blocco di codice:

//addition function
// returned data type is an integer - the name of the function is add - parameters or arguments are two int variables val1 and val2
int add(int val1, int val2)
  {
   //body of function that we need the function to perform when calling it
   //create a result new variable to be assigned by the result of val1 and val2 addition
   int result = val1+val2;
   //Print result in the experts tab
   Print(result);
   //returning value
   return result;
  }

Dopo aver definito la nostra funzione, dobbiamo eseguire il secondo passaggio, che consiste nel richiamare la funzione; possiamo farlo richiamando il nome della funzione e specificando i parametri desiderati in base alla nostra funzione nella parte desiderata del codice software. Tornando al nostro esempio, se vogliamo chiamare la nostra funzione, sarà come segue:

   //calling our defined function by its name and specifying arguments
   add(5,15);

Quando la chiamiamo, possiamo ottenere il risultato del valore 20 nella scheda expert, in base alla funzione e agli argomenti specificati, come nell'immagine seguente.

 risultato della funzione add

L'esempio precedente è solo una prova di ciò che possiamo fare utilizzando le funzioni, ma ci sono molte caratteristiche disponibili che possiamo utilizzare nelle funzioni e le seguenti sono alcune di esse.

Funzione con argomenti

Nell'ultimo esempio di funzione add abbiamo utilizzato due variabili intere, val1 e val2, che vengono considerate come argomenti della nostra funzione. Questi argomenti possono essere dati di tipo intero, stringa, ecc. Nel nostro ultimo esempio, si trattava di variabili intere, come abbiamo visto, e possiamo vedere un altro esempio di argomenti stringa, come il seguente:

//sayHello function
// returned data type is string - name of function is sayHello - parameters or arguments are two string variables greeting and name
string sayHello(string greeting, string name)
  {
   //body of function that we need the function to perform when calling it
   //create a result new variable to be assigned by the result of greeting and name addition
   string result = greeting+name;
   //Print result in the experts tab
   Print(result);
   //returning value
   return result;
  }

Possiamo chiamare questa funzione come abbiamo detto e trovare il suo risultato dopo l'esecuzione come segue:

risultato della funzione sayhello

Possono anche essere un mix di questi tipi di dati, in base a ciò che serve alla nostra funzione come parametri o argomenti per eseguire il corpo della funzione. Questi argomenti possono anche rappresentare il numero di cui abbiamo bisogno in base alle nostre esigenze.

Funzione senza argomenti

La funzione può essere dichiarata o definita senza specificare parametri o argomenti; inoltre, è sufficiente dare un nome significativo alla funzione e lasciare gli argomenti vuoti, quindi completare il corpo della funzione per eseguire il compito e chiamare la funzione senza specificare gli argomenti, come nel caso seguente:

//sayHello function
// returned data type is a string - the name of the function is sayHello - no parameters
string sayHello()
  {
   //body of the function that we need the function to perform when calling it
   //create a result new variable to be assigned by the result of greeting and name addition
   string greeting= "Hello, ";
   string name= "World!";
   string result = greeting+name;
   //Print the result in the experts' tab
   Print(result);
   //returning value
   return result;
  }

Quando chiamiamo la funzione, sarà uguale al seguente:

sayHello();

Il risultato sarà lo stesso di quello indicato in precedenza nella funzione con argomenti, poiché il corpo della funzione è lo stesso.

Funzione con valori predefiniti

Definiamo anche una funzione e diamo dei valori iniziali o predefiniti per i parametri, ma siamo ancora in grado di modificarli o aggiornarli con i valori desiderati e questo può essere come il seguente applicando lo stesso esempio

//defining function with default values
string sayHello(string greeting= "Hello, ", string name="World!")
  {
   string result = greeting+name;
   Print(result);
   return result;
  }

Quindi possiamo richiamare la funzione due volte per identificare la differenza tra i valori predefiniti e se li aggiorniamo, devo anche menzionare che possiamo specificare i parametri aggiornandoli, ma se non li specifichiamo la funzione restituirà i valori predefiniti, come nel caso seguente:

   sayHello();
   sayHello("Hi, ", "Developer!");

Il risultato sarà il seguente:

risultato funzione sayhello valori di default

Passaggio dei parametri

Possiamo passare alla funzione dei valori e questi valori possono essere qualsiasi tipo di dati, come abbiamo detto int, string, array, ecc. Passando i parametri per valori, le variabili originali della funzione rimarranno uguali o invariate, poiché abbiamo passato il valore dei parametri alla funzione. Possiamo anche passare i parametri alla funzione per riferimento, se abbiamo bisogno di aggiornare le variabili originali.

Quello che segue è un semplice esempio per capire cosa abbiamo detto sul passaggio per riferimento.

//passing by reference
void updateNums(int &val1, int &val2)
  {
   val1*=2;
   val2/=2;
  }

Quindi creeremo nuove variabili, stamperemo i loro valori e chiameremo la nostra funzione con queste nuove variabili come parametri e stamperemo i loro valori dopo la chiamata per notare la differenza:

//new variables
   int firstNum = 10;
   int secondNum = 20;
   
//before calling function
   Print("before calling: ");
   Print(firstNum, " - " ,secondNum, "\n"); 
   
// calling   
   updateNums(firstNum, secondNum);

// after calling  
   Print("after calling: ");
   Print(firstNum, " - " ,secondNum, "\n"); 

Quindi, il risultato dei due print sarà il primo, i valori delle nuove variabili 10 e 20, e dopo la chiamata troveremo i valori dopo l'aggiornamento di 20 e 10 come da corpo della funzione. Il risultato è il seguente:

passaggio per riferimento

Operatore return

Se una funzione restituisce un valore, deve avere un operatore return. Possiamo avere più di un operatore return nella funzione in base al compito della funzione stessa, ma se la funzione restituisce un valore, deve avere almeno un return nell'ultima riga della funzione. L'operatore return può essere di qualsiasi tipo, ma non può essere un array, mentre si può restituire un elemento dell’array. Se vogliamo che la funzione restituisca un array, possiamo passare l'array alla funzione per riferimento, come abbiamo detto prima.

Di seguito è riportato un esempio di ciò che abbiamo menzionato in precedenza che ha un operatore return

string sayHello(string greeting= "Hello, ", string name="World!")
  {
   string result = greeting+name;
   Print(result);
   return result;
  }

Funzione di tipo Void

Se abbiamo una funzione che non restituisce un valore, utilizziamo la funzione di tipo void, poiché questo tipo non restituisce alcun valore. A questo tipo di funzione si possono passare normalmente dei parametri, ma non ha bisogno di un operatore return. Di seguito è riportato un esempio di questo tipo di funzioni.

void add(int val1, int val2)
  {
   int result= val1+val2;
  }

Sovraccarico di funzioni

In alcuni casi, quando si definiscono le funzioni, è necessario definire molte funzioni con lo stesso nome per eseguire lo stesso compito ma con parametri differenti. Ad esempio, se abbiamo un compito di addizione, ma dobbiamo eseguire l'addizione su due valori e dobbiamo eseguire lo stesso compito su tre valori, in questo caso creiamo due funzioni con lo stesso nome, ma cambieremo i parametri in base al compito. Ciò significa che abbiamo un sovraccarico di funzione, quindi il sovraccarico di funzione è una funzione che esegue lo stesso compito ma con parametri diversi.

Questi diversi parametri possono essere diversi tipi di dati, numeri dello stesso tipo di dati o entrambi. Di seguito è riportato un esempio di sovraccarico di una funzione con lo stesso tipo di dati, ma con un numero diverso di parametri:

void overloadingFun(int val1, int val2)
{
   int result=val1+val2;
}

void overloadingFun(int val1, int val2, int val3)
{
   int result=val1+val2+val3;
}

Come possiamo vedere, abbiamo la stessa funzione, ma i parametri sono diversi. Quando chiamiamo la funzione, quando digitiamo il nome della funzione, vediamo che appaiono queste due funzioni e possiamo scegliere quella di cui abbiamo bisogno in base ai dettagli del nostro compito. Di seguito è riportato un esempio di sovraccarico di una funzione con parametri diversi a seconda del tipo di dati:

void overloadingFun(int val1, int val2)
{
   int result=val1+val2;
}

void overloadingFun(string message, int val1, int val2)
{
   int result=message+val1+val2;
}

Possiamo anche scegliere la funzione di cui abbiamo bisogno in base ai parametri quando chiamiamo la funzione.


Applicazioni di Funzioni

In questa parte, creeremo semplici applicazioni per le quali potremo utilizzare la funzione per trarre vantaggio dalla funzione definita dall'utente e rendere più semplice il processo di codifica. Dopo aver creato queste applicazioni, possiamo richiamarle in diverse parti del software o anche in un altro software includendole.

App di allerta notizie

Sappiamo tutti che il trading durante le notizie economiche è molto rischioso e molti professionisti consigliano di non fare trading durante le notizie. Se non sapete cos'è il calendario economico, si tratta di un calendario già pronto che contiene notizie e indicatori macroeconomici con la descrizione, la data, l'ora e il grado di importanza, nonché i valori rilasciati di questi eventi economici e ci sono molte fonti che possono essere utilizzate per ottenere questi valori importanti per essere aggiornati su ciò che può influenzare il mercato e fare trading di conseguenza. Questo calendario è presente anche nel terminale di trading MetaTrader 5, trovate la sua scheda nella finestra BoxAttrezzi e si può controllare ciò che si desidera visualizzare in termini di importanza, valute e paesi. Esistono anche funzioni integrate per lavorare con il calendario economico e si possono consultare nella documentazione di MQL5 al seguente link:

Funzioni del Calendario Economico

Quindi, dobbiamo controllare manualmente il calendario economico delle notizie per evitare di fare trading durante le notizie o creare un'applicazione che ci avvisi quando ci stiamo avvicinando alle notizie per interrompere il trading. Questo compito è permanente, quindi ne avremo bisogno in qualsiasi sistema di trading o in molte parti del software. Quindi, possiamo creare una funzione per questo e chiamarla facilmente, come faremo in questa parte attraverso i seguenti passaggi:

Questa applicazione sarà un EA, nell’ambito globale creeremo un tipo bool per il nome della nostra funzione che è (isNewsComing) e poi non aggiungeremo parametri ()

bool isNewsComing()

Il corpo della funzione crea un array con il nome dei valori e il suo tipo sarà (MqlCalendarValue) che saranno i valori del rilascio delle notizie, come il valore attuale, ad esempio

MqlCalendarValue values[];

Dobbiamo definire il giorno corrente definendo l'ora di inizio del giorno utilizzando (iTime) che restituisce l'ora di apertura della barra dopo aver dichiarato una nuova variabile datetime con il nome di (startTime) e l'ora di fine del giorno che deve essere uguale all'ora di inizio definita e il numero di secondi del giorno utilizzando la funzione (PeriodSeconds) dopo aver dichiarato una nuova variabile datetime per (endTime).

   datetime startTime=iTime(_Symbol,PERIOD_D1,0);
   datetime endTime=startTime+PeriodSeconds(PERIOD_D1);

Ottenere l'array dei valori di tutti gli eventi del giorno utilizzando l'ora di inizio e l'ora di fine per determinare l'intervallo di tempo e l'ordinamento in base al paese e alla valuta corrente utilizzando la funzione CalendarValueHistory e i parametri sono l'array per i valori, l'ora di inizio, l'ora di fine, il paese e la valuta.

CalendarValueHistory(values,startTime,endTime,NULL,NULL);

Creeremo un ciclo che inizierà con un valore di (0) per la variabile int (i) creata e continuerà il ciclo se (i) è inferiore alla dimensione dell'array dei valori e incrementerà il valore di (i) di un valore.

for(int i=0; i<ArraySize(values); i++)

Il corpo del ciclo for crea una variabile event e il suo tipo è (MqlCalendarEvent) per le descrizioni dell'evento e può essere utilizzata in (CalendarEventById).

MqlCalendarEvent event;

Ottenere la descrizione dell'evento in base al suo ID utilizzando (CalendarEventById), i cui parametri sono event_id e l'evento

CalendarEventById(values[i].event_id,event);

Creare una variabile country e il suo tipo sarà (MqlCalendarCountry) per le descrizioni dei paesi e potrà essere usata con (CalendarCountryById).

MqlCalendarCountry country;

Ottenere le descrizioni dei paesi in base al loro ID utilizzando la funzione (MqlCalendarCountry), i cui parametri sono country_id e il paese.

CalendarCountryById(event.country_id,country);

Impostazione delle condizioni per filtrare gli eventi in base al simbolo corrente o alle notizie sulla valuta, all'importanza della notizia se media o alta e se c'è qualcos'altro continua

      if(StringFind(_Symbol,country.currency)<0)
         continue;

      if(event.importance==CALENDAR_IMPORTANCE_NONE)
         continue;
      if(event.importance==CALENDAR_IMPORTANCE_LOW)
         continue;

Impostando una condizione con l'intervallo di tempo di cui abbiamo bisogno, l'avviso sarà 30 secondi prima dell'ora della notizia.

      if(TimeCurrent()>=values[i].time-30*PeriodSeconds(PERIOD_M1) &&
         TimeCurrent()<values[i].time+30*PeriodSeconds(PERIOD_M1))

Poi dobbiamo far stampare un messaggio nella scheda expert con il nome dell'evento e il testo ( is coming! Stop Trading...)

Print(event.name, " is coming! Stop Trading...");

Il valore restituito sarà true

return true;

Se le condizioni sono false, termina il ciclo e restituisce false per terminare la funzione.

return false;

Quindi possiamo richiamare la funzione nella funzione OnTick e se restituisce true abbiamo bisogno di un messaggio stampato del tipo (News is coming...!)

   if(isNewsComing())
     {
      Print("News is comming...!");
     }

Ora, abbiamo creato la funzione e l'abbiamo chiamata e possiamo usarla in qualsiasi parte del nostro software in base alle nostre esigenze di seguito è riportato il codice completo in un unico blocco in modo che sia facile da leggere di nuovo e troverete i file dei codici sorgente di tutte le applicazioni allegati all'articolo

//+------------------------------------------------------------------+
//| News Alert Function                                              |
//+------------------------------------------------------------------+ 
void OnTick()
  {
   if(isNewsComing())
     {
      Print("News is comming...!");
     }
  }
//+------------------------------------------------------------------+
bool isNewsComing()
  {
   MqlCalendarValue values[];
   datetime startTime=iTime(_Symbol,PERIOD_D1,0);
   datetime endTime=startTime+PeriodSeconds(PERIOD_D1);
   CalendarValueHistory(values,startTime,endTime,NULL,NULL);
   for(int i=0; i<ArraySize(values); i++)
     {
      MqlCalendarEvent event;
      CalendarEventById(values[i].event_id,event);
      MqlCalendarCountry country;
      CalendarCountryById(event.country_id,country);
      if(StringFind(_Symbol,country.currency)<0)
         continue;
      if(event.importance==CALENDAR_IMPORTANCE_NONE)
         continue;
      if(event.importance==CALENDAR_IMPORTANCE_LOW)
         continue;
      if(TimeCurrent()>=values[i].time-30*PeriodSeconds(PERIOD_M1) &&
         TimeCurrent()<values[i].time+30*PeriodSeconds(PERIOD_M1))
        {
         Print(event.name, " is coming! Stop Trading...");
         return true;
        }
     }
   return false;
  }
//+------------------------------------------------------------------+

App Calcolo Dimensione del Lotto

Dobbiamo creare un'applicazione che sia in grado di calcolare la dimensione ottimale del lotto dopo aver determinato la percentuale di rischio e la perdita massima in pip e dobbiamo creare un sovraccarico di funzione per calcolare la dimensione ottimale del lotto dopo aver determinato la percentuale di rischio, il prezzo di ingresso e il prezzo di stop loss. Creeremo questa applicazione come script, come indicato nei passaggi seguenti:

Creare la funzione con il nome OptimalLotSize come double e i parametri saranno due per la prima funzione, la variabile double per la percentuale di rischio massimo e la variabile double per la perdita massima in pips, come di seguito indicato.

double OptimalLotSize(double maxRiskPrc, double maxLossInPips)

Quindi specifichiamo cosa dobbiamo eseguire per questi parametri, per prima cosa, definiremo il valore del capitale del conto utilizzando la funzione (AccountInfoDouble) che restituisce il valore della proprietà del conto appropriata, che in questo caso è l'identificatore del capitale del conto (ENUM_ACCOUNT_INFO_DOUBLE) e creeremo un avviso con il valore

   double accEquity = AccountInfoDouble(ACCOUNT_EQUITY);
   Alert("accEquity: ", accEquity);

Definire la dimensione del contratto del simbolo utilizzando la funzione (SymbolInfoDouble) che restituisce la proprietà corrispondente di un simbolo specificato con la sua variante del nome del simbolo che sarà (_Symbol) per restituire il simbolo corrente e prop_id che sarà (SYMBOL_TRADE_CONTRACT_SIZE) come uno dei valori (ENUM_SYMBOL_INFO_DOUBLE) dopo di che è necessario un avviso con il valore restituito

   double lotSize = SymbolInfoDouble(_Symbol,SYMBOL_TRADE_CONTRACT_SIZE);
   Alert("lotSize: ", lotSize);

Calcolo del valore del pip e ricezione di un avviso con tale valore

   double tickValue = SymbolInfoDouble(_Symbol,SYMBOL_TRADE_TICK_VALUE);
   Alert("tickValue: ", tickValue);

Calcolo del valore massimo della perdita dal patrimonio netto del conto definito e ricezione di un avviso con questo valore

   double maxLossDollar = accEquity * maxRiskPrc;
   Alert("maxLossDollar: ", maxLossDollar);

Calcolare il valore massimo nella valuta di quotazione in base al valore della perdita massima calcolata e restituire un avviso con questo valore

   double maxLossInQuoteCurr = maxLossDollar / tickValue;
   Alert("maxLossInQuoteCurr: ", maxLossInQuoteCurr);

Calcolo della dimensione ottimale del lotto e restituzione di un avviso con il valore

   double OptimalLotSize = NormalizeDouble(maxLossInQuoteCurr / (maxLossInPips * 0.0001)/ lotSize,2);
   Alert("OptimalLotSize: ", OptimalLotSize);

L'operatore return restituirà OptimalLotSize come valore di tipo double

return OptimalLotSize;

Dopodiché, creeremo la funzione di sovraccarico passando tre parametri di tipo double per la percentuale di rischio massimo, il prezzo di ingresso e il prezzo di stop loss

double OptimalLotSize(double maxRiskPrc, double entryPrice, double stopLoss)

Definire la perdita massima in pip come valore assoluto in base ai parametri di ingresso del prezzo di entrata e del prezzo di stop loss e dividere per 0,0001.

double maxLossInPips = MathAbs(entryPrice - stopLoss)/0.0001;

L'operatore return sarà la funzione OptimalLotSize creata con i suoi parametri, la percentuale di rischio massimo e la perdita massima in pip.

return OptimalLotSize(maxRiskPrc,maxLossInPips);

Poi possiamo chiamare una qualsiasi delle due funzioni nella parte OnStart() in base a ciò che ci serve, ad esempio come segue

OptimalLotSize(0.01, 1.12303, 1.11920);

Di seguito è riportato il codice completo per creare questo tipo di funzione per creare tale applicazione

//+------------------------------------------------------------------+
//| lotSize Calc Function                                            |
//+------------------------------------------------------------------+
void OnStart()
  {
   OptimalLotSize(0.01, 1.12303, 1.11920);
  }
//+------------------------------------------------------------------+
double OptimalLotSize(double maxRiskPrc, double maxLossInPips)
  {
   double accEquity = AccountInfoDouble(ACCOUNT_EQUITY);
   Alert("accEquity: ", accEquity);
   double lotSize = SymbolInfoDouble(_Symbol,SYMBOL_TRADE_CONTRACT_SIZE);
   Alert("lotSize: ", lotSize);
   double tickValue = SymbolInfoDouble(_Symbol,SYMBOL_TRADE_TICK_VALUE);
   Alert("tickValue: ", tickValue);
   double maxLossDollar = accEquity * maxRiskPrc;
   Alert("maxLossDollar: ", maxLossDollar);
   double maxLossInQuoteCurr = maxLossDollar / tickValue;
   Alert("maxLossInQuoteCurr: ", maxLossInQuoteCurr);
   double OptimalLotSize = NormalizeDouble(maxLossInQuoteCurr / (maxLossInPips * 0.0001)/ lotSize,2);
   Alert("OptimalLotSize: ", OptimalLotSize);
   return OptimalLotSize;
  }
//+------------------------------------------------------------------+
double OptimalLotSize(double maxRiskPrc, double entryPrice, double stopLoss)
  {
   double maxLossInPips = MathAbs(entryPrice - stopLoss)/0.0001;
   return OptimalLotSize(maxRiskPrc,maxLossInPips);
  }
//+------------------------------------------------------------------+

Eseguendo questo script si otterrà il seguente avviso

 app lotSize

Come nell'applicazione precedente, abbiamo la funzione lotSize Calc che possiamo usare e chiamare in diverse parti del software per eseguire facilmente il compito senza riscrivere il codice.

App per Chiudere Tutto

Dobbiamo creare uno script che possa chiudere gli ordini aperti e pendenti, creando una funzione che possa essere utilizzata o richiamata in qualsiasi parte del software per svolgere questo compito. Possiamo farlo attraverso i seguenti passaggi:

Includere la classe Trade nel codice utilizzando il preprocesso #include per includere tutte le funzioni di trading nel file (Trade.mqh)

#include <Trade/Trade.mqh>

Creare un oggetto con il tipo di classe CTrade da utilizzare nel software.

CTrade trade;

Anche nell'ambito globale è necessario creare una funzione void closeAll senza argomenti

void closeAll()

Il corpo della funzione crea un ciclo for per verificare la presenza di ordini aperti.

for(int i=PositionsTotal()-1; i>=0; i--)

 Il corpo del ciclo, crea la variabile ulong posTicket e le assegna il ticket degli ordini aperti

ulong posTicket=PositionGetTicket(i);

Chiudere il trade aperto utilizzando trade.PositionClose(posTicket)

trade.PositionClose(posTicket);

Elimineremo gli ordini pendenti creando un altro ciclo for per rilevare questi ordini, assegnando i loro ticket alla variabile ulong posTicket, cancellando l'ordine pendente in base al ticket rilevato

   for(int i=OrdersTotal()-1; i>=0; i--)
     {
      ulong posTicket=OrderGetTicket(i);
      trade.OrderDelete(posTicket);
     }

Dopodiché, possiamo chiamare questa funzione nella parte OnStart()

closeAll();

L'esecuzione di questo script comporta la chiusura e la cancellazione di tutti gli ordini. Di seguito è riportato il codice completo per creare questa closeAllApp in un unico blocco:

//+------------------------------------------------------------------+
//| closeAll Function                                                |
//+------------------------------------------------------------------+ 
#include <Trade/Trade.mqh>
CTrade trade;
//+------------------------------------------------------------------+
void OnStart()
  {
   closeAll();
  }
//+------------------------------------------------------------------+
void closeAll()
  {
//close all open positions
   for(int i=PositionsTotal()-1; i>=0; i--)
     {
      ulong posTicket=PositionGetTicket(i);
      trade.PositionClose(posTicket);
     }
//delete all pending orders
   for(int i=OrdersTotal()-1; i>=0; i--)
     {
      ulong posTicket=OrderGetTicket(i);
      trade.OrderDelete(posTicket);
     }
  }
//+------------------------------------------------------------------+

Queste applicazioni sono solo esempi di ciò che possiamo creare come funzioni definite dall'utente e voi potete svilupparle o creare qualsiasi altra applicazione o funzione in base alle vostre esigenze, come il trailing stop, l'applicazione per la gestione del trading, lo strumento di sicurezza per il draw down ... ecc.


Conclusioni

In base a quanto detto in questo articolo, si suppone che abbiate trovato che è fondamentale utilizzare le funzioni nel vostro software per via di tutte le caratteristiche e i vantaggi che otterrete quando lo farete, poiché si presume che abbiate identificato le caratteristiche dell'utilizzo di tali funzioni:

  • Aiuta ad applicare il concetto di DRY (non ripetersi) nella programmazione.
  • Aiuta a ridurre al minimo qualsiasi grande problema dividendolo in piccoli problemi e affrontandoli.
  • Rende il codice più leggibile.
  • Riutilizzabilità.
  • Astrazione del codice.
  • Incapsulamento del codice.
  • Miglioramento del debug.

Si suppone inoltre che abbiate compreso bene cos'è la funzione, i suoi tipi, la funzione integrata e quella definita dall'utente, come potete creare o definire le funzioni attraverso l'apprendimento della struttura delle funzioni e di tutte le loro caratteristiche, come le funzioni con argomenti e come passare questi argomenti o parametri, senza argomenti e le funzioni con valori predefiniti. Si presume che possiate definire la vostra funzione utilizzando qualsiasi tipo di dati e gestire l'operatore return in base a questo e che sappiate come creare il sovraccarico di funzione con lo stesso nome ma con argomenti differenti per eseguire lo stesso compito.

Dopo aver condiviso le applicazioni per la creazione di funzioni come esempi, credo che questo abbia aiutato molto ad approfondire la comprensione dell'argomento, dato che abbiamo creato due funzioni diverse:

  • New Alert App: da utilizzare o richiamare in qualsiasi parte del software per ricevere avvisi quando sono in arrivo notizie importanti. In allegato troverete il codice sorgente di NewsAlertApp.
  • App di Calcolo della Dimensione del Lotto: da utilizzare o richiamare in qualsiasi parte del software per restituire la dimensione ottimale del lotto per aprire un'operazione in base alla percentuale di rischio, al prezzo di ingresso e al prezzo di stop loss definiti. Oppure, in base alla percentuale di rischio definita e alla perdita massima in pip, il che significa che abbiamo creato un sovraccarico di funzione in questa applicazione. In allegato troverete il codice sorgente di lotSizeCalcApp.
  • App Chiudere Tutto: da utilizzare o richiamare per chiudere tutti gli ordini aperti e pendenti. In allegato troverete il codice sorgente di closeAllApp.

Il mondo delle funzioni è molto interessante ed è molto importante prestarvi attenzione per poter creare pezzi di codice utili in modo semplice, fluido ed efficace. Spero che questo articolo vi sia stato utile per sviluppare le vostre capacità di codifica e migliorare la vostra carriera di trader creando strumenti utili che possano aiutarvi a fare trading. Se volete leggere altri articoli sulla programmazione o su come creare sistemi di trading basati sui più popolari indicatori tecnici come medie mobili, RSI, MACD, Stocastico, Bande di Bollinger, Parabolic Sar...ecc. Potete consultare le mie pubblicazioni e trovare articoli al riguardo e spero che anche voi li troviate utili.

Tradotto dall’inglese da MetaQuotes Ltd.
Articolo originale: https://www.mql5.com/en/articles/12970

File allegati |
newsAlertApp.mq5 (1.37 KB)
lotSizeCalcApp.mq5 (1.45 KB)
closeAllApp.mq5 (0.86 KB)
Ultimi commenti | Vai alla discussione (23)
MrBrooklin
MrBrooklin | 12 ott 2023 a 19:09
fxsaber #:

Le funzioni di Kim sono state trasferite da tempo da MQL4 a MQL5.

Scusate la mia ignoranza e credetemi, non sono sarcastico, ma cosa si intende per "porting"? Sono state riscritte per MQL5? Se sono raccolte da qualche parte in un unico posto, e se non è difficile per voi, per favore fornite un link alle funzioni di Kim portate in MQL5. Ho provato a cercare sul sito le funzioni di Kim, ma non ho trovato nulla.

Saluti, Vladimir.

fxsaber
fxsaber | 13 ott 2023 a 15:41
MrBrooklin #:

fornire un link alle funzioni di Kim portate in MQL5.

https://www.mql5.com/ru/forum/107476

Forum sul trading, sui sistemi di trading automatizzati e sulla verifica delle strategie di trading

Biblioteche: MT4Ordini

fxsaber, 2019.01.13 17:23 PM.

Le funzioni di Kim per MT4 sono piuttosto popolari, quindi ho scaricato tutti i sorgenti dal suo sito e ho scritto un semplice "convertitore" per loro sotto MT5.
#include <KimIVToMT5.mqh> // https://c.mql5.com/3/263/KimIVToMT5.mqh
MrBrooklin
MrBrooklin | 13 ott 2023 a 15:43

Grazie!

Saluti, Vladimir.

Hilario Miguel Ofarril Gonzalez
Hilario Miguel Ofarril Gonzalez | 9 dic 2023 a 16:43
Aggiungere alla conoscenza.per enceñar il punto expesifico.donde impariamo dagli altri . strategie.molto concrete .e continuare in modo preciso.è come essere in una battaglia dove i numeri sono infiniti .de ello es como digo yo sentirce soddisfatto .quando vinciamo la güera .el programa.de las defensas en el tradi.es tratar de cobertice en ganadores .sin afectar.nuestras inversiones.Mi dedico a leggere ogni articolo di ogni maestro e imparo da esso, mettendo in pratica il desiderio di diventare un grande maestro come loro e di trasmettere gli insegnamenti in modo che il mondo della tradi sia più forte, questo è ciò che definisce tutti noi...volontà e sacrificio.... e mi sacrificherò per rendere il mondo della tradi più forte.
Javid Rezaei
Javid Rezaei | 15 ago 2025 a 23:56
Grazie per questo utile articolo.
Arriva il Nuovo MetaTrader 5 e MQL5 Arriva il Nuovo MetaTrader 5 e MQL5
Questa è solo una panoramica di MetaTrader 5. Non posso descrivere tutte le nuove funzionalità del sistema per un periodo di tempo così breve: i test sono iniziati il 09.09.2009. Questa è una data simbolica e sono sicuro che sarà un numero fortunato. Sono passati alcuni giorni da quando ho ricevuto la versione beta del terminale MetaTrader 5 e MQL5. Non sono riuscito a provare tutte le sue funzionalità, ma sono già sorpreso.
Sviluppo di un robot di trading in Python (parte 3): Implementazione di un algoritmo di trading basato su un modello Sviluppo di un robot di trading in Python (parte 3): Implementazione di un algoritmo di trading basato su un modello
Continuiamo la serie di articoli sullo sviluppo di un robot di trading in Python e MQL5. In questo articolo creeremo un algoritmo di trading in Python.
Utilizza i canali MQL5.community e le chat di gruppo Utilizza i canali MQL5.community e le chat di gruppo
Il sito web MQL5.com riunisce trader di tutto il mondo. Gli utenti pubblicano articoli, condividono codici gratuiti, vendono prodotti nel Market, offrono servizi da freelance e copiano segnali di trading. Puoi comunicare con loro sul Forum, nelle chat dei trader e nei canali MetaTrader.
Sviluppo di un robot in Python e MQL5 (parte 2): Selezione, creazione e addestramento del modello, tester personalizzato in Python Sviluppo di un robot in Python e MQL5 (parte 2): Selezione, creazione e addestramento del modello, tester personalizzato in Python
Continuiamo la serie di articoli sullo sviluppo di un robot di trading in Python e MQL5. Oggi risolveremo il problema della selezione e dell'addestramento di un modello, del suo test, dell'implementazione della convalida incrociata, della ricerca a griglia, nonché il problema dell'ensemble di modelli.