English Русский 中文 Español Deutsch 日本語 Português Français
preview
Comprendere il piazzamento degli ordini in MQL5

Comprendere il piazzamento degli ordini in MQL5

MetaTrader 5Trading |
41 6
Mohamed Abdelmaaboud
Mohamed Abdelmaaboud

Introduzione

In qualsiasi sistema di trading, dobbiamo occuparci degli ordini e delle loro operazioni, come l'apertura di posizioni, il posizionamento di stop-loss e take-profit e la modifica degli ordini. Pertanto, è molto importante capire come gestire gli ordini in mql5 quando si crea un sistema di trading per MetaTrader5. L'obiettivo di questo articolo è quello di fornire una guida semplice per la maggior parte delle operazioni di ordini e posizioni, in modo da poter affrontare efficacemente tutto ciò che riguarda questo argomento. In questo articolo tratteremo i seguenti argomenti:

Spero che troviate questo articolo utile e prezioso per sviluppare il vostro sistema di trading MetaTrader5 senza problemi per quanto riguarda l'inserimento degli ordini. Tutte le applicazioni presentate in questo articolo devono essere testate prima di essere utilizzate per assicurarsi che siano profittevoli o adatte al proprio trading, perché lo scopo principale della loro menzione è solo quello di fornire un esempio di creazione di un sistema di trading utilizzando due metodi differenti per quanto riguarda l’operatività con gli ordini, le transazioni e le posizioni.

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.

Termini : Ordini, Posizioni e Transazioni

In questa parte parleremo di termini importanti per capire come gestire gli ordini in modo efficace. Capiremo le differenze tra tre termini correlati agli ordini nella MetaTrader 5. Questi termini sono ordine, transazione e posizione, che possiamo considerare come passi per l'esecuzione del trade.

Ordine: è una richiesta ricevuta dal server di trading per aprire un'operazione di acquisto o vendita con un lotto o un volume specifico a un prezzo specifico. Esistono due tipi di ordini: l'ordine a mercato e l'ordine pendente.

  • Ordine a mercato: è un ordine che può essere eseguito immediatamente al prezzo di mercato corrente.
  • Ordine pendente: è un ordine che esegue l'operazione a condizioni predeterminate riguardanti il prezzo di esecuzione dell'operazione al suo livello e il tempo di esecuzione dell'operazione. 

Questi ordini pendenti possono essere uno dei seguenti:

    • Buy stop: Piazza un ordine pendente di acquisto ad un prezzo specifico che è superiore al prezzo attuale di mercato.
    • Buy limit: Piazza un ordine pendente di acquisto ad un prezzo specifico che è inferiore al prezzo attuale di mercato.
    • Sell stop: Piazza un ordine pendente di vendita ad un prezzo specifico che è inferiore al prezzo attuale di mercato.
    • Sell limit: Piazza un ordine pendente di vendita ad un prezzo specifico che è superiore al prezzo attuale di mercato.

Una volta piazzato l'ordine, indipendentemente dal fatto che si tratti di un ordine a mercato o di un ordine pendente, è possibile trovarlo nella scheda Operazioni di Trading del BoxAttrezzi di MetaTrader 5. Di seguito è riportato un esempio:

1- scheda operazioni di trading


Quando l'ordine viene chiuso o cancellato senza essere eseguito, è possibile trovarlo nella scheda CroniStoria del BoxAttrezzi.

2 - scheda CroniStoria

Quando vogliamo modificare una posizione corrente con MQL5, dobbiamo trattare questi ordini come vedremo in seguito quando gestiremo la modifica degli ordini.

Transazione: È il risultato quando l'ordine di compravendita viene eseguito o riempito. Possiamo trovarli come azioni di entrata e uscita basate sull'esecuzione del trade. Supponiamo che sia stato eseguito un ordine di acquisto di un lotto. Successivamente, abbiamo chiuso parzialmente la posizione di 0,5 lotti, poi abbiamo chiuso i restanti 0,5 lotti. Quindi, le transazioni saranno uguali alle seguenti:

  • 1 buy in
  • 0,5 sell out
  • 0,5 sell out

Possiamo trovare queste transazioni nella scheda CroniStoria del BoxAttrezzi di MetaTrader 5, visualizzando i dati delle operazioni con un clic destro e scegliendoli.

3 - transazioni

Posizione: Si tratta del netto delle operazioni long o short basate sull'acquisto o sulla vendita dell'attività finanziaria. La possiamo trovare nella scheda Operazioni di Trading come trade attivo o nella scheda CroniStoria se scegliamo di far apparire le posizioni.

4 - posizioni

È bene ricordare che il prezzo eseguibile dell'ordine di acquisto è il prezzo Ask, mentre il prezzo eseguibile alla sua chiusura è il prezzo Bid. D'altra parte, il prezzo eseguibile dell'ordine di vendita è il prezzo Bid e il prezzo eseguibile alla sua chiusura è il prezzo Ask.

OrderSend()

Dopo aver compreso i termini importanti sull'esecuzione delle operazioni in MetaTrader 5, dobbiamo imparare come eseguire gli ordini automaticamente in MQL5. In primo luogo, per maggiori informazioni sulle funzioni destinate alla gestione delle attività, è possibile consultare il riferimento MQL5 Funzioni di Trade.

Discuteremo la funzione OrderSend(), che può essere utilizzata per eseguire operazioni di trade inviando richieste a un server di trade. In altre parole, può essere utilizzata per piazzare, modificare e chiudere ordini.

Il formato di questa funzione è il seguente:

bool  OrderSend(
   MqlTradeRequest&  request,      
   MqlTradeResult&   result        
   );

Come si può notare, la funzione ha due parametri:

  • Struttura MqlTradeRequest: Contiene i parametri dell'ordine e tutti i campi o le variabili necessarie per eseguire le transazioni del trade. Oggetti passati per riferimento come da &. TradeRequest è il metodo di interazione tra il terminale client e il server di trade per l'esecuzione degli ordini.
  • Struttura MqlTradeResult: TradeResult restituisce i risultati della richiesta dell’ordine. Anche qui gli oggetti sono passati per riferimento.

La struttura MqlTradeRequest:

La struttura è un insieme di dati correlati di diverso tipo. La definizione della struttura MqlTradeRequest è la seguente:

struct MqlTradeRequest
  {
   ENUM_TRADE_REQUEST_ACTIONS    action;           // Trade operation type
   ulong                         magic;            // Expert Advisor ID (magic number)
   ulong                         order;            // Order ticket
   string                        symbol;           // Trade symbol
   double                        volume;           // Requested volume for a deal in lots
   double                        price;            // Price
   double                        stoplimit;        // StopLimit level of the order
   double                        sl;               // Stop Loss level of the order
   double                        tp;               // Take Profit level of the order
   ulong                         deviation;        // Maximal possible deviation from the requested price
   ENUM_ORDER_TYPE               type;             // Order type
   ENUM_ORDER_TYPE_FILLING       type_filling;     // Order execution type
   ENUM_ORDER_TYPE_TIME          type_time;        // Order expiration type
   datetime                      expiration;       // Order expiration time (for the orders of ORDER_TIME_SPECIFIED type)
   string                        comment;          // Order comment
   ulong                         position;         // Position ticket
   ulong                         position_by;      // The ticket of an opposite position
  };

Se vogliamo dichiarare un oggetto MqlTradeRequest, possiamo farlo con la seguente riga di codice:

MqlTradeRequest request;

Quindi, si possono assegnare i parametri del trade alle variabili dell'oggetto request creato, aggiungendo un punto (.) dopo l'oggetto, come mostrato nell'esempio seguente:

request.symbol = _Symbol;
request.volume = 0.01;
request.type = ORDER_TYPE_BUY;

Di seguito sono elencati tutti i membri o le variabili della struttura MqlTradeRequest, insieme ai valori accettati per l'assegnazione.

Variabile Descrizione Valore accettato per l'assegnazione
action Rappresenta il tipo di operazione di trade

Uno degli ENUM_TRADE_REQUEST_ACTIONS (TRADE_ACTION_DEAL, TRADE_ACTION_PENDING, TRADE_ACTION_SLTP, TRADE_ACTION_MODIFY, TRADE_ACTION_REMOVE, TRADE_ACTION_CLOSE_BY).

magic Rappresenta l'ID dell’expert advisor per identificare gli ordini effettuati da un determinato expert advisor Qualsiasi valore ulong
order Rappresenta il ticket dell'ordine. È necessario quando si utilizza TRADE_ACTION_MODIFY o TRADE_ACTION_REMOVE nella variabile action.  Qualsiasi valore ulong
symbol Il simbolo specificato o lo strumento da negoziare. (_SYMBOL) si riferisce a quello corrente. Qualsiasi simbolo di tipo string
volume Specifica il volume di trade o i lotti  Qualsiasi valore double consentito
price Il prezzo di apertura Valore double
stoplimit Il prezzo di apertura dell'ordine pendente limite. Action deve essere TRADE_ACTION_PENDING e la variabile type deve essere ORDER_TYPE_BUY_STOP_LIMIT o ORDER_TYPE_SELL_STOP_LIMIT ed è necessaria per gli ordini stop limit. Valore double
sl Il prezzo di stop loss dell'operazione Valore double
tp Il prezzo di take profit dell'operazione Valore double
deviation La deviazione massima del prezzo in punti valore ulong
type Il tipo di ordine Uno degli ENUM_ORDER_TYPE (ORDER_TYPE_BUY, ORDER_TYPE_SELL, ORDER_TYPE_BUY_STOP, ORDER_TYPE_SELL_STOP), 
ORDER_TYPE_BUY_LIMIT, ORDER_TYPE_SELL_LIMIT,  ORDER_TYPE_BUY_STOP_LIMIT, ORDER_TYPE_SELL_STOP_LIMIT)
type_filling Tipo di esecuzione dell'ordine o politica di riempimento dell'ordine Uno degli ENUM_ORDER_TYPE_FILLING (ORDER_FILLING_FOK, ORDER_FILLING_IOC, ORDER_FILLING_BOC, ORDER_FILLING_RETURN)
type_time Il tipo di scadenza dell'ordine pendente Uno degli ENUM_ORDER_TYPE_TIME (ORDER_TIME_GTC, ORDER_TIME_DAY, ORDER_TIME_SPECIFIED, ORDER_TIME_SPECIFIED_DAY).
expiration L’ora di scadenza dell'ordine pendente. È necessario quando type_time è ORDER_TIME_SPECIFIED valore datetime
comment Il commento all'ordine valore string
position Il ticket di una posizione. È necessario quando una posizione viene modificata o chiusa per identificarla. valore ulong
position_by Il ticket di una posizione opposta. Si utilizza quando la posizione è chiusa da una posizione aperta in direzione opposta per lo stesso simbolo. valore ulong

Ora citeremo alcune azioni importanti da utilizzare quando si piazzano ordini in MQL5.

  • Ordine a mercato
  • Aggiunta di stop-loss e take-profit
  • Ordine pendente
  • Modifica di ordine pendente
  • Rimuovere l'ordine pendente

Ordine a mercato:

In questo tipo di azione, dobbiamo piazzare un ordine a mercato, il che significa che l'ordine sarà piazzato al prezzo di mercato corrente; useremo l’azione (TRADE_ACTION_DEAL). Se si tratta di un ordine di acquisto, l'ordine verrà piazzato al prezzo ask corrente o se si tratta di un ordine di vendita, l'ordine verrà piazzato al prezzo sell corrente. Ecco come fare: 

Dopo aver dichiarato gli oggetti MqlTradeRequest e MqlTradeResult, possiamo assegnare i seguenti valori alle seguenti variabili:

request.action = TRADE_ACTION_DEAL;                    &nbsthe p;   //market order palcement
request.type = ORDER_TYPE_BUY;                             //type of order is buy
request.symbol = _Symbol;                                  //applied for the cuurrent symbol
request.volume = 0.1;                                      //the lot size
request.type_filling = ORDER_FILLING_FOK;                  //the filling policy fill or kill
request.price = SymbolInfoDouble(_Symbol,SYMBOL_ASK);      //the price is the current ask for buy
request.sl = 0;                                            //stop loss is 0
request.tp = 0;                                            //take profit is 0
request.deviation = 50;                                    //slippage is 50
OrderSend(request, result);                                //calling the OrderSend function

Come possiamo vedere nel codice precedente, non abbiamo aggiunto i valori di stop loss e take profit. Possiamo aggiungere i loro valori al codice insieme alle altre variabili, oppure possiamo aggiungerli attraverso un'altra azione, come vedremo nel prossimo punto.

Aggiunta di stop-loss e take-profit:

Quando dobbiamo aggiungere stop-loss e take-profit, assegniamo la TRADE_ACTION_SLTP alla variabile action, come mostrato nell'esempio seguente.

request.action = TRADE_ACTION_SLTP;          //adding sl and tp
request.symbol = _Symbol;                    //applied for the cuurrent symbol
request.sl = 1.07000;                        //sl price
request.sl = 1.09000;                        //tp price
OrderSend(request, result);                  //calling the OrderSend function


Ordine pendente:

Se vogliamo piazzare un ordine pendente, possiamo utilizzare un'altra azione (TRADE_ACTION_PENDING). Quindi, si determina il tipo di ordine. Possiamo impostare l'ora se abbiamo bisogno di un’ora di scadenza per l'ordine pendente.

request.action = TRADE_ACTION_PENDING;          //pending order placement
request.type = ORDER_TYPE_BUY_STOP;             //type of order is buy stop
request.symbol = _Symbol;                       //applied for the cuurrent symbol
request.volume = 0.1;                           //the lot size
request.price = 1.07000;                        //opening price
request.sl = 1.06950;                           //stop loss
request.tp = 1.07100;                           //take profit
request.type_time = ORDER_TIME_SPECIFIED;       //to set an expiration time
request.expiration = D'2023.08.31 00.00';       //expiration time - datetime constant          
request.type_filling = ORDER_FILLING_FOK;       //the filling policy fill or kill
request.stoplimit = 0;                          //for stoplimit order only
OrderSend(request, result);                     //calling the OrderSend function


Modifica dell’ordine pendente:

Se dobbiamo modificare un ordine pendente, dobbiamo ottenere il numero di ticket dell'ordine pendente che dobbiamo modificare. Possiamo utilizzare la funzione OrderGetTicket per ottenere il ticket dell'ordine. Questa funzione restituisce il ticket dell'ordine corrispondente, che può essere utilizzato per selezionare l'ordine e lavorarci.

ulong  OrderGetTicket( 
   int  index      // Number in the list of orders 
   );

Consideriamo di avere una variabile denominata (ticket) che contiene il numero del ticket dell'ordine. Possiamo usare questa variabile per assegnare il numero del ticket dell'ordine alla variabile order dell'oggetto request. Possiamo quindi modificare l'ordine utilizzando l'azione (TRADE_ACTION_MODIFY), come nell'esempio seguente.

request.action = TRADE_ACTION_MODIFY;           //pending order modyfying
request.order = ticket;                         //ticket variable that holds the pending order ticket to modify
request.price = 1.07050;                        //new opening price
request.sl = 1.07000;                           //new stop loss
request.tp = 1.07150;                           //new take profit
request.type_time = ORDER_TIME_SPECIFIED;       //to set an expiration time
request.expiration = D'2023.09.01 00.00';       //new expiration time - datetime constant        
OrderSend(request, result);                     //calling the OrderSend function

Rimuovere l’Ordine Pendente:

Se dobbiamo rimuovere l'ordine pendente, possiamo farlo utilizzando l'azione (TRADE_ACTION_REMOVE). Abbiamo bisogno anche del numero di ticket dell'ordine pendente che dobbiamo rimuovere. Possiamo usare la variabile ticket, supponendo che contenga il numero di ticket necessario.

request.action = TRADE_ACTION_REMOVE;           //pending order remove
request.order = ticket;                         //ticket variable that holds the pending order ticket to remove
OrderSend(request, result);                     //calling the OrderSend function

La struttura MqlTradeResult:

La struttura MqlTradeResult restituisce il risultato che indica se l'ordine è andato o meno a buon fine dopo aver piazzato un ordine tramite la funzione OrderSend(). Contiene le informazioni sull'operazione provenienti dal server di trade, come il numero del ticket, il volume e il prezzo.

Di seguito è riportata la definizione della struttura MqlTradeResult:

struct MqlTradeResult
  {
   uint     retcode;          // Operation return code
   ulong    deal;             // Deal ticket, if it is performed
   ulong    order;            // Order ticket, if it is placed
   double   volume;           // Deal volume, confirmed by broker
   double   price;            // Deal price, confirmed by broker
   double   bid;              // Current Bid price
   double   ask;              // Current Ask price
   string   comment;          // Broker comment to operation (by default it is filled by description of trade server return code)
   uint     request_id;       // Request ID set by the terminal during the dispatch 
   int      retcode_external; // Return code of an external trading system
  };

Possiamo dichiarare un oggetto chiamato result per passarlo come secondo parametro dopo il primo (request) alla chiamata della funzione OrderSend().

MqlTradeResult result;

Come si può vedere nelle variabili della struttura MqlTradeResult, la variabile retcode è molto importante perché restituisce il codice del server di trade per indicare se la richiesta ha avuto successo o meno.

Se l'operazione non viene piazzata, il codice di ritorno indica uno stato di errore. Puoi consultare l'elenco dei codici di ritorno nel riferimento MQL5 per maggiori informazioni. È fondamentale includere un codice nel nostro sistema di trading per segnalare se viene restituito un errore o meno, come nell'esempio seguente:

   if(result.retcode == TRADE_RETCODE_DONE || result.retcode == TRADE_RETCODE_PLACED)
     {
      Print("Trade Placed Successfully");
     }
   else
     {
      Print("Trade Not Placed, Error ", result.retcode);
     }

Come si può vedere nel codice precedente, dopo la request viene stampato un messaggio con il risultato e vengono compilate le variabili result. Se l'operazione è stata effettuata, ci invierà un messaggio di conferma; se invece c'è un problema, stamperà un messaggio di errore e restituirà il codice di errore per aiutarci a risolvere il problema.

Applicazione OrderSend()

Dobbiamo creare un semplice sistema di trading che possa eseguire operazioni utilizzando la funzione OrderSend(). Il sistema di trading che dobbiamo creare è un semplice crossover di medie mobili e l'azione consiste nel piazzare un ordine a mercato.

L'obiettivo è quello di comprendere le differenze nella creazione dello stesso sistema di trading utilizzando OrderSend() e la classe CTrade. Di seguito sono illustrati i passaggi per creare questo crossover MA utilizzando la funzione OrderSend().

Nell’ambito globale creare due variabili integer (simpleMA, barsTotal) senza assegnazione, verranno assegnate successivamente nella parte OnInit.

int simpleMA;
int barsTotal;

La simpleMA sarà assegnata alla funzione iMA che restituisce l'handle dell'indicatore tecnico della media mobile. I suoi parametri sono:

  • symbol: Per specificare il nome del simbolo, _Symbol si riferisce allo strumento corrente.
  • period: Per specificare il time frame, utilizzeremo PERIOD_H1, che si riferisce al time frame di un'ora.
  • ma_period: il periodo della media mobile, che sarà di 50.
  • ma_shift: per specificare lo spostamento orizzontale necessario.
  • ma_method: Per specificare il tipo di media mobile, specificheremo quella semplice.
  • applied_price: Per specificare il tipo di prezzo che verrà utilizzato nel calcolo della MA, imposteremo il prezzo di chiusura.

barsTotal verrà assegnato alla funzione iBars che restituisce il numero di barre. I suoi parametri sono:

  • symbol: Il nome del simbolo
  • timeframe: il periodo del time frame
   simpleMA = iMA(_Symbol, PERIOD_H1, 50, 0, MODE_SMA, PRICE_CLOSE);
   barsTotal=iBars(_Symbol,PERIOD_H1);

Nella parte OnTick, creeremo due array, uno per il prezzo, utilizzando il tipo MqlRates, che memorizza le informazioni su prezzo, volume e spread, e l'altro per la media mobile, utilizzando il tipo di variabile double.

   MqlRates priceArray[];
   double mySMAArray[];

Definizione dei prezzi ask e bid

   double Ask = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_ASK),_Digits);
   double Bid = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_BID),_Digits);

Creare due oggetti per la funzione OrderSend(), uno per la richiesta utilizzando MqlTradeRequest e l'altro per il risultato utilizzando MqlTradeResult, quindi resettare la variabile request per riferimento

ZeroMemory(request);

Impostare il flag AS_SERIES su questi due array creati, priceArray e mySMAArray utilizzando la funzione ArraySetAsSeries. I suoi parametri sono:

  • array[]: Per specificare l'array necessario
  • flag: Direzione di indicizzazione dell’array.
   ArraySetAsSeries(priceArray,true);
   ArraySetAsSeries(mySMAArray,true);

Ottenere i dati storici MqlRates utilizzando la funzione CopyRates. I suoi parametri sono:

  • symbol: il nome del simbolo o _Symbol per il simbolo o lo strumento corrente.
  • time frame: periodo del time frame o _period per il time frame corrente.
  • start position: la posizione da cui partire.
  • count: numero dei dati da copiare.
  • rates_array: l'array di destinazione in cui copiare.
int Data=CopyRates(_Symbol,_Period,0,3,priceArray);

Ottenere il buffer dei dati dell'indicatore utilizzando la funzione CopyBuffer. I suoi parametri sono:

  • indicator_handle: Per specificare l’handle dell'indicatore MA.
  • buffer_num: Per specificare il numero di buffer dell'indicatore.
  • start_pos: la posizione iniziale da cui contare.
  • count: quantità da copiare.
  • buffer[]: l'array di destinazione.
CopyBuffer(simpleMA,0,0,3,mySMAArray);

Definizione dell'ultimo prezzo di chiusura, del prezzo di chiusura precedente, dell'ultimo valore SMA e del valore SMA precedente

   double lastClose=(priceArray[1].close);
   double prevClose=(priceArray[2].close);
   double SMAVal = NormalizeDouble(mySMAArray[1],_Digits);
   double prevSMAVal = NormalizeDouble(mySMAArray[2],_Digits);

Creare una variabile intera bars e assegnarle iBars.

int bars=iBars(_Symbol,PERIOD_H1);

Controllo delle barre, se barsTotal non è uguale alla variabile bars

if(barsTotal != bars)

Aggiornare il valore di barsTotal in modo che sia uguale a bars se non sono uguali tra loro

barsTotal=bars;

Verifica della condizione della strategia per aprire un'operazione, se l'ultima chiusura è superiore all'ultimo valore SMA dopo che la chiusura precedente era inferiore al valore SMA precedente

if(prevClose<prevSMAVal && lastClose>SMAVal)

Apertura di un ordine di acquisto a mercato utilizzando le variabili appropriate relative alla funzione MqlTradeRequest.

         request.action = TRADE_ACTION_DEAL;
         request.type = ORDER_TYPE_BUY;
         request.symbol = _Symbol;
         request.volume = 0.1;
         request.type_filling = ORDER_FILLING_FOK;
         request.price = SymbolInfoDouble(_Symbol,SYMBOL_ASK);
         request.sl = Ask-(500*_Point);
         request.tp = Ask+(1000*_Point);
         request.deviation = 50;
         OrderSend(request, result);

Verifica della condizione della strategia per aprire un'operazione di vendita, se l'ultima chiusura è inferiore all'ultimo valore SMA dopo che la chiusura precedente era maggiore del valore SMA precedente

if(prevClose>prevSMAVal && lastClose<SMAVal)
Apertura di un ordine di vendita a mercato utilizzando le variabili appropriate relative alla funzione MqlTradeRequest.
         request.type = ORDER_TYPE_SELL;
         request.symbol = _Symbol;
         request.volume = 0.1;
         request.type_filling = ORDER_FILLING_FOK;
         request.price = SymbolInfoDouble(_Symbol,SYMBOL_BID);
         request.sl = Bid+(500*_Point);
         request.tp = Bid-(1000*_Point);
         request.deviation = 50;
         OrderSend(request, result);

Di seguito è riportato il codice completo in un unico blocco per creare questo tipo di sistema di trading utilizzando la funzione OrderSend()

//+------------------------------------------------------------------+
//|                                     OrderSend_Trading_system.mq5 |
//+------------------------------------------------------------------+
int simpleMA;
int barsTotal;
int OnInit()
  {
   simpleMA = iMA(_Symbol, PERIOD_H1, 50, 0, MODE_SMA, PRICE_CLOSE);
   barsTotal=iBars(_Symbol,PERIOD_H1);
   return(INIT_SUCCEEDED);
  }
void OnTick()
  {
   MqlRates priceArray[];
   double mySMAArray[];
   double Ask = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_ASK),_Digits);
   double Bid = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_BID),_Digits);
   MqlTradeRequest request;
   MqlTradeResult result;
   ZeroMemory(request);
   ArraySetAsSeries(priceArray,true);
   ArraySetAsSeries(mySMAArray,true);
   int Data=CopyRates(_Symbol,_Period,0,3,priceArray);
   CopyBuffer(simpleMA,0,0,3,mySMAArray);
   double lastClose=(priceArray[1].close);
   double prevClose=(priceArray[2].close);
   double SMAVal = NormalizeDouble(mySMAArray[1],_Digits);
   double prevSMAVal = NormalizeDouble(mySMAArray[2],_Digits);
   int bars=iBars(_Symbol,PERIOD_H1);
   if(barsTotal != bars)
     {
      barsTotal=bars;
      if(prevClose<prevSMAVal && lastClose>SMAVal)
        {
         request.action = TRADE_ACTION_DEAL;
         request.type = ORDER_TYPE_BUY;
         request.symbol = _Symbol;
         request.volume = 0.1;
         request.type_filling = ORDER_FILLING_FOK;
         request.price = SymbolInfoDouble(_Symbol,SYMBOL_ASK);
         request.sl = Ask-(500*_Point);
         request.tp = Ask+(1000*_Point);
         request.deviation = 50;
         OrderSend(request, result);
        }
      if(prevClose>prevSMAVal && lastClose<SMAVal)
        {
         request.action = TRADE_ACTION_DEAL;
         request.type = ORDER_TYPE_SELL;
         request.symbol = _Symbol;
         request.volume = 0.1;
         request.type_filling = ORDER_FILLING_FOK;
         request.price = SymbolInfoDouble(_Symbol,SYMBOL_BID);
         request.sl = Bid+(500*_Point);
         request.tp = Bid-(1000*_Point);
         request.deviation = 50;
         OrderSend(request, result);
        }
     }
  }

Classe CTrade

Dopo aver appreso come piazzare gli ordini tramite la funzione OrderSend(), abbiamo un metodo semplice per accedere alle funzioni di trading. Possiamo utilizzare la classe CTrade già pronta fornita da MQL5, oppure possiamo creare la nostra classe per preferenze più personali. Ora, si parlerà di come utilizzare la classe CTrade già pronta in MQL5. Per ulteriori informazioni, è possibile consultare la classe CTrade dal riferimento MQL5.

Per prima cosa, possiamo trovare il file include della classe CTrade nella cartella Trade della cartella include nei file di installazione di MetaTrader 5. È sufficiente includere questo file nell'expert advisor per richiamare e utilizzare tutte le funzioni di trade, come di seguito indicato:

#include <Trade\Trade.mqh>

Creare un oggetto per la classe CTrade

CTrade trade;

In seguito saremo in grado di utilizzare tutte le funzioni di trade della classe CTrade, utilizzando trade prima del punto(.) e della funzione desiderata. Possiamo utilizzare tutte le funzioni per le operazioni con ordini, operazioni con posizioni, accesso ai parametri dell'ultima richiesta, accesso ai risultati della verifica dell'ultima richiesta, accesso ai risultati dell'esecuzione dell'ultima richiesta e altre ancora.

Citeremo alcune funzioni importanti come abbiamo fatto con OrderSend() per capire le differenze tra i due metodi. Capiremo come fare in base a quanto segue:

  • Ordine a mercato
  • Aggiunta di stop-loss e take-profit
  • Ordine pendente
  • Modifica di ordine pendente
  • Rimuovere l'ordine pendente

Ordine a mercato:

Dopo aver creato il nostro oggetto trade, possiamo utilizzare la funzione PositionOpen per piazzare un ordine a mercato; i suoi parametri sono:

  • symbol: per specificare il simbolo necessario
  • order_type: per specificare il tipo di ordine per aprire una posizione
  • volume: per specificare la dimensione del lotto
  • price: per specificare il prezzo di apertura della posizione
  • sl: per specificare il prezzo dello stop loss
  • tp: per specificare il prezzo del take profit
  • comment: per specificare un commento o NULL

Il seguente è un esempio di ciò:

trade.PositionOpen(
   _Symbol,             //to be applied for the current symbol
   ORDER_TYPE_BUY,      //to place buy order
   0.1,                 //lot size or volume
   Ask,                 //opening price of the order - current ask
   Ask-(500*_Point),    //sl
   Ask+(1000*_Point),   //tp
   NULL                 //NULL
);

Per aprire un ordine a mercato possiamo anche utilizzare i metodi aggiuntivi di CTrade come Buy, Sell invece di PositionOpen.

Aggiunta di stop-loss e take-profit:

È possibile modificare la posizione in base al simbolo o al numero del ticket utilizzando la funzione PositionModify. I suoi parametri sono:

  • symbol o ticket: per specificare la posizione da modificare, se si modifica per simbolo si specifica il nome del simbolo o se si modifica per ticket si specifica il numero del ticket.
  • sl: il nuovo prezzo dello stop loss
  • tp: il nuovo prezzo di take profit

Esempio di modifica per simbolo:

trade.PositionModify(
   EURUSD,       //the symbol name
   1.06950,      //the new sl
   1.07100,      //the new tp
);

Esempio di modifica per ticket:

trade.PositionModify(
   ticket,       //the ticket variable that holds the needed ticket number to modify
   1.06950,      //the new sl
   1.07100,      //the new tp
);

Ordine pendente:

Se dobbiamo piazzare un ordine pendente utilizzando la classe CTrade, possiamo utilizzare la funzione OrderOpen. I suoi parametri sono:

  • symbol: per determinare il nome del simbolo
  • order_type: per determinare il tipo di ordine pendente
  • volume: per specificare la dimensione del lotto
  • limit_price: per specificare il prezzo stop limit
  • price: per specificare il prezzo di esecuzione dell'ordine pendente
  • sl: per specificare lo stop loss
  • tp: per specificare il prezzo di take profit
  • type_time: per specificare il tipo di scadenza
  • expiration: per specificare la variabile datetime di scadenza
  • comment: per specificare un commento, se necessario

L'esempio seguente riguarda l'inserimento di un ordine pendente buy limit utilizzando la funzione OrderOpen

         trade.OrderOpen(
            "EURUSD",                 // symbol
            ORDER_TYPE_BUY_LIMIT,     // order type
            0.1,                      // order volume
            0,                        // StopLimit price
            1.07000,                  // execution price
            1.06950,                  // Stop Loss price
            1.07100,                  // Take Profit price
            ORDER_TIME_SPECIFIED,     // type by expiration
            D'2023.08.31 00.00',      // expiration
            ""                        // comment
         );

Modifica dell’ordine pendente:

Se abbiamo bisogno di modificare l'ordine pendente piazzato, possiamo farlo utilizzando la classe CTrade tramite la funzione OrderModify. I suoi parametri sono:

  • ticket: per specificare il ticket dell'ordine pendente da modificare
  • price: il nuovo prezzo di esecuzione
  • sl: il nuovo prezzo di stop loss
  • tp: il nuovo prezzo di take profit
  • type_time: per specificare il tipo di scadenza
  • expiration: per specificare la variabile datatime di scadenza
  • stoplimit: per determinare il prezzo dell'ordine limit

Di seguito è riportato un esempio di modifica di un ordine pendente

         trade.OrderModify(
            ticket,                   // ticket number of the pending order to modify
            1.07050,                  // execution price
            1.07000,                  // Stop Loss price
            1.07150,                  // Take Profit price
            ORDER_TIME_SPECIFIED,     // type by expiration
            D'2023.08.31 00.00',      // expiration
            0,                        // StopLimit price
         );

Cancellare l'ordine pendente:

Se è necessario eliminare un ordine pendente, è possibile farlo utilizzando la funzione OrderDelete, che richiede il numero di ticket dell'ordine pendente da eliminare. Di seguito è riportato un esempio di tale funzione.

         trade.OrderDelete(
            ticket,                 // tick number of the pending order to delete
         );

Applicazione della classe CTrade

Dobbiamo creare lo stesso sistema di trading creato con OrderSend(). Utilizzeremo la classe CTrade per capire le differenze di funzionamento delle funzioni di entrambe.

Di seguito sono riportati gli unici passaggi diversi per creare questo sistema di trading utilizzando la classe CTrade, mentre i restanti passaggi sono gli stessi già eseguiti in precedenza.

Includere il file include Trade utilizzando il preprocessore #include

#include <Trade\Trade.mqh>

Creare l'oggetto trade della classe CTrade

CTrade trade;

Quando la condizione di acquisto è soddisfatta, possiamo utilizzare PositionOpen e il tipo di ordine sarà ORDER_TYPE_BUY o il metodo aggiuntivo Buy, come il seguente codice

trade.Buy(0.1,_Symbol,Ask,Ask-(500*_Point),Ask+(1000*_Point),NULL);

Quando la condizione di vendita è soddisfatta, possiamo utilizzare PositionOpen con il tipo di ordine ORDER_TYPE_SELL o il metodo aggiuntivo Sell, come il seguente codice

trade.Sell(0.1,_Symbol,Bid,Bid+(500*_Point),Bid-(1000*_Point),NULL);

Di seguito è riportato il codice completo per creare il sistema di trading utilizzando la classe CTrade:

//+------------------------------------------------------------------+
//|                                        CTrade_Trading_System.mq5 |
//+------------------------------------------------------------------+
#include <Trade\Trade.mqh>
int simpleMA;
int barsTotal;
CTrade trade;
int OnInit()
  {
   simpleMA = iMA(_Symbol, PERIOD_H1, 50, 0, MODE_SMA, PRICE_CLOSE);
   barsTotal=iBars(_Symbol,PERIOD_H1);
   return(INIT_SUCCEEDED);
  }
void OnTick()
  {
   MqlRates priceArray[];
   double mySMAArray[];
   double Ask = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_ASK),_Digits);
   double Bid = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_BID),_Digits);
   ArraySetAsSeries(priceArray,true);
   ArraySetAsSeries(mySMAArray,true);
   int Data=CopyRates(_Symbol,_Period,0,3,priceArray);
   CopyBuffer(simpleMA,0,0,3,mySMAArray);
   double lastClose=(priceArray[1].close);
   double prevClose=(priceArray[2].close);
   double SMAVal = NormalizeDouble(mySMAArray[1],_Digits);
   double prevSMAVal = NormalizeDouble(mySMAArray[2],_Digits);
   int bars=iBars(_Symbol,PERIOD_H1);
   if(barsTotal != bars)
     {
      barsTotal=bars;
      if(prevClose<prevSMAVal && lastClose>SMAVal)
        {
         trade.Buy(0.1,_Symbol,Ask,Ask-(500*_Point),Ask+(1000*_Point),NULL);
        }
      if(prevClose>prevSMAVal && lastClose<SMAVal)
        {
         trade.Sell(0.1,_Symbol,Bid,Bid+(500*_Point),Bid-(1000*_Point),NULL);
        }
     }
  }

Conclusioni

Se avete completato la lettura di questo articolo, si suppone che abbiate capito come funzionano gli ordini, le posizioni e le transazioni in MQL5. Oltre a capire come creare un sistema di trading senza problemi utilizzando i due metodi per le operazioni di trade, il metodo OrderSend e il metodo CTrade.

Abbiamo identificato il modo in cui piazziamo gli ordini a mercato e gli ordini pendenti, aggiunta di stop-loss e take-profit, modifica degli ordini pendenti e rimozione o cancellazione degli ordini pendenti utilizzando i due metodi.

Si presume che abbiate capito come applicare tutti i precedenti per creare un'applicazione, perché abbiamo fornito due semplici applicazioni per creare lo stesso sistema di trading con crossover della media mobile utilizzando i due metodi.

  • OrderSend_Trading_System
  • CTrade_Trading_System

L'obiettivo delle applicazioni citate è solo quello di capire le differenze tra di esse a livello pratico, quindi, fate attenzione, dovete testarle prima di utilizzarle in un conto live per assicurarvi che siano redditizie e adatte al vostro trading.

Credo che abbiate capito quanto sia facile usare la classe già pronta CTrade quando si lavora con le operazioni di trade, perché vi fa risparmiare molto tempo e fatica. Oltre ad altre caratteristiche, quando si utilizzano le classi nella programmazione in generale.

Se volete saperne di più su questo aspetto e sulla programmazione orientata agli oggetti in MQL5, potete leggere il mio precedente articolo Capire la programmazione orientata agli oggetti (OOP) in MQL5; spero che vi sia utile. MQL5 ha fatto un lavoro e uno sforzo molto apprezzati per fornirci gli strumenti per sviluppare e creare software di trading in modo semplice e agevole.

Spero che abbiate trovato utile questo articolo e che abbiate ottenuto molti spunti utili per capire e svolgere facilmente il vostro lavoro dopo questi approfondimenti. Se volete leggere altri miei articoli, potete consultare le mie pubblicazioni per trovare molti articoli su come creare sistemi di trading utilizzando gli indicatori tecnici più popolari e altro e spero che li troviate utili.

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

Ultimi commenti | Vai alla discussione (6)
Mohamed Abdelmaaboud
Mohamed Abdelmaaboud | 24 ott 2023 a 01:11
gunther64 #:

ciao,


grande testo, tyvm.

Ho trovato un piccolo bug:

nella casella sottoTRADE_ACTION_SLTP avete scritto due volte request.sl, la seconda dovrebbe essere request.tp, come indicato nel commento alla fine della riga.


Cordiali saluti,

Gunther

Salve,

Grazie per il suo gentile commento. Hai ragione, è un errore e sarà preso in considerazione.


Saluti,

rurubest
rurubest | 8 apr 2024 a 12:45
ciao!
Utilizzando il tuo codice sto scrivendo un semplice ordine per uno strumento!


double price = 94500;

double stopLoss = prezzo - (500 * _Punto);

double takeProfit = prezzo + (1000 * _Point);


ulong ticket = trade.OrderOpen(

"SiM4", // simbolo

ORDER_TYPE_BUY, // tipo di ordine
1.0, // volume dell'ordine
prezzo, // prezzo StopLimit
stopLoss, // prezzo di esecuzione
takeProfit, // prezzo dello Stop Loss
NULLO
);
restituisce GetLastError() = 0 e l'ordine non viene piazzato e non c'è alcun accordo
È necessario specificare un token di accesso speciale quando si effettua un ordine dal broker?

Rashid Umarov
Rashid Umarov | 8 apr 2024 a 13:12
rurubest #:
restituisce GetLastError() = 0 e l'ordine non viene piazzato e non c'è alcuna transazione
È necessario specificare un token di accesso speciale quando si effettua un ordine dal broker?
Guardate i log e analizzate il risultato dell'esecuzione di OrderSend.
Ahmad Juniar
Ahmad Juniar | 8 nov 2024 a 10:53

Ciao Abdel Maaboud,

grazie per la gentilezza con cui hai scritto questo tutorial.

Questo tutorial fornisce solo il posizionamento degli ordini. C'è qualche codice per chiudere la posizione(take profit o cut loss) nel tuo articolo?

Cordiali saluti,

Ahmad Juniar

2020_fusaroli.it
2020_fusaroli.it | 19 nov 2024 a 15:25
Grazie mille per il tuo prezioso e dettagliato tutorial. Mi hai risparmiato tonnellate di tempo e ricerche. Grazie ancora!
Passaggio a MQL5 Algo Forge (parte 1): Creazione del repository principale Passaggio a MQL5 Algo Forge (parte 1): Creazione del repository principale
Quando si lavora su progetti in MetaEditor, gli sviluppatori si trovano spesso a dover gestire le versioni del codice. MetaQuotes ha recentemente annunciato la migrazione a GIT e il lancio di MQL5 Algo Forge con funzionalità di controllo delle versioni del codice e di collaborazione. In questo articolo discuteremo come utilizzare in modo più efficiente i nuovi strumenti e quelli già esistenti.
Testare i diversi tipi di media mobile per vedere quanto sono efficaci Testare i diversi tipi di media mobile per vedere quanto sono efficaci
Conosciamo tutti l'importanza per molti trader dell'indicatore Media Mobile. Esistono altri tipi di Media Mobile che possono essere utili nel trading; in questo articolo le identificheremo e faremo un semplice confronto tra ognuno di loro e il tipo di media mobile semplice più popolare per vedere quale può mostrare i risultati migliori.
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.
Introduzione a MQL5 Algo Forge Introduzione a MQL5 Algo Forge
Stiamo introducendo MQL5 Algo Forge - un portale dedicato agli sviluppatori di trading algoritmico. Combina la potenza di Git con un'interfaccia intuitiva per gestire e organizzare i progetti all'interno dell'ecosistema MQL5. Qui è possibile seguire autori interessanti, formare team e collaborare a progetti di trading algoritmico.