MQL4 - Realizzazione di una Griglia di Ordini Pendenti

In questo articolo proveremo a scrivere un Expert Advisor che ci permetterà di aprire, gestire e chiudere numerosi Ordini Pendenti contemporaneamente.
Siccome non è affatto provato che tale EA sia profittevole, questo articolo viene scritto con finalità soprattutto didattiche e formative.
Specifiche dell' Expert Advisor
Il nostro EA deve:
(1) aprire N ordini Buy Stop sopra il prezzo corrente, ad una distanza di 20 pips l'uno dall'altro e partendo da 20 pips sopra il prezzo;
(2) aprire N ordini Sell Limit sopra il prezzo corrente, ad una distanza di 20 pips l'uno dall'altro ma partendo da 10 pips sopra il prezzo;
(3) aprire N ordini Sell Stop sotto il prezzo corrente, ad una distanza di 20 pips l'uno dall'altro e partendo da 20 pips sotto il prezzo;
(4) aprire N ordini Buy Limit sotto il prezzo corrente, ad una distanza di 20 pips l'uno dall'altro ma partendo da 10 pips sotto il prezzo;
(5) impostare uno Stop Loss ed un Take Profit per ciascun ordine;
(6) chiudere le posizioni che arrivano ad un predeterminato profitto;
(7) essere facilmente gestibile tramite dei pulsanti;
(8) essere in grado di pulire il grafico dalle frecce e dalle linee tracciate dall'operatività.
Procedura Guidata dell' MQL4
Iniziamo con il creare il file che conterrà il nostro EA tramite l' MQL4 Wizard.

Scegliamo "Expert Advisor (modello)" e clicchiamo "Avanti >"

Gli diamo un nome e clicchiamo "Avanti >"

Spuntiamo la funzione "OnChartEvent", che ci servirà per i pulsanti, e clicchiamo "Avanti >"

Lasciamo intatte le ultime opzioni e clicchiamo "Fine".
A questo punto abbiamo creato il file che conterrà il nostro EA e possiamo definire il magic number inserendo la seguente riga di codice sotto le righe #property:
#define MAGIC 135
Così facendo, abbiamo dato un valore (135) al nostro magic number senza esserci serviti di una variabile. L'abbiamo, in questo modo, definito per tutto l'ambiente di lavoro costituito dal nostro programma.
Procedura per l' Attivazione degli Ordini Pendenti
A questo punto dobbiamo scrivere un'intera funzione, che verrà richiamata quando vorremo far partire la griglia. Iniziamo con il definirla: sarà una funzione di tipo void perché la sua esecuzione non darà output, ma elaborerà semplicemente delle sotto-funzioni. La scriviamo così:
void StartGrid()
{
}
Per poter andare avanti dobbiamo stabilire quale sarà il prezzo di partenza della nostra griglia: a tal fine utilizzeremo iClose, con indice (0), che corrisponde all'ultimo prezzo dell'ultima barra. Assegnamo questo valore di iClose alla variabile price di tipo double:
void StartGrid()
{
double price=iClose(_Symbol,PERIOD_CURRENT,0);
}
Prima ancora di inviare gli Ordini Pendenti, dovremo calcolare i Lotti necessari, facendo in modo che essi non vadano in conflitto con i lotti minimi e massimi consentiti dal broker. Potremo ottenere queste informazioni utilizzando la funzione MarketInfo().
A tal fine utilizzeremo due semplici operatori ternari per sostituire due funzioni if.
La "sintassi" del ternary operator vuole che ci sia un check di tipo booleano (vero o falso) e due diversi output, uno se il check è vero, l'altro se il check è falso.
Le due domande che ci porremo saranno le seguenti:
(1) I lotti impostati in input sono maggiori dei massimi lotti consentiti?
Se vero, uso i massimi lotti consentiti; se falso, utilizzo i lotti in input.
(2) I lotti impostati in input sono minori dei minimi lotti consentiti?
Se vero, uso i minimi lotti consentiti; se falso, utilizzo i lotti in input.
Quindi, prima della funzione OnInit(), inseriamo la riga contenente una variabile di tipo double per l'input dei lotti:
input double INP_lots=0.01; // lotti della griglia
Poi nella funzione StartGrid() inseriremo il controllo dei lotti, usando due ternary operators:
void StartGrid()
{
double price=iClose(_Symbol,PERIOD_CURRENT,0);
double maxlot=MarketInfo(_Symbol,MODE_MAXLOT);
double minlot=MarketInfo(_Symbol,MODE_MINLOT);
double lots;
lots = (INP_lots>=maxlot) ? lots=maxlot : lots=INP_lots;
lots = (INP_lots<=minlot) ? lots=minlot : lots=INP_lots;
}
A questo punto saremo sicuri di non avere errori nell'istruzione OrderSend(), perché confronteremo i lotti da noi impostati con i lotti massimi e minimi previsti dal broker.
Bene, ora che siamo sicuri di non avere (almeno) questo errore, possiamo procedere con gli Ordini Pendenti.
A tal fine, sopra l' OnInit() inseriamo due variabili di tipo int, una per la distanza in punti, l'altra per il numero massimo di ordini:
input int DistanceOfGridOrders=100; // distanza in punti della grigliainput int MaxPendingOrders=5; // numero massimo di ordini (per lato, per tipo)
Con quest'ultimo input, inseriremo Ordini Pendenti alternativamente LIMIT e STOP, in entrambi i sensi, a 10 pips (100 punti) di distanza l'uno dall'altro.
Adesso mancano soltanto lo Stop Loss ed il Take Profit, altri due input di tipo integer, sempre espressi in PUNTI:
input int SL=200; // Stop Loss in Punti
input int TP=1000; // Take Profit in Punti
A questo punto abbiamo tutti i parametri d'ingresso per gestire il ciclo che creerà la nostra griglia di Ordini Pendenti.
Quando attiveremo la costruzione della griglia, vorremo inserire, sopra il prezzo corrente, prima un ordine SELL LIMIT, poi un BUY STOP, poi di nuovo un SELL LIMIT, poi ancora un BUY STOP, e così via. Ordini Pendenti tutti distanti 10 pips l'uno dall'altro.
Un discorso analogo va poi fatto, ovviamente, per la parte del grafico che si trova al di sotto del prezzo corrente.
Teniamo inoltre presente che la distanza fra due Ordini Pendenti dello stesso tipo sarà esattamente doppia della distanza che abbiamo dato in input.
Precisato questo, possiamo cominciare a scrivere il seguente ciclo:
for(int i=1; i<=MaxPendingOrders; i++)
{
}
Cominciamo a contare da 1 ed arriviamo a contare fino al numero massimo degli Ordini Pendenti dello stesso tipo che vogliamo posizionare. Se tale massimo è 5, il loop conterà da 1 a 5, elaborando il codice al suo interno per 5 volte. Partiamo da 1 e non da 0 perché utilizzeremo l'indice (int i) per far fare alla macchina i calcoli dello Stop Loss e del Take Profit, oltre che per individuare il Prezzo a cui inviare l'ordine.
Cominciamo quindi con il calcolare i tre valori (Prezzo, SL e TP).
for(int i=1; i<=MaxPendingOrders; i++)
{
double buystopprice=price+i*2*DistanceOfGridOrders*_Point; // Prezzo
double BSSL=buystopprice-SL*_Point; // SL
double BSTP=buystopprice+TP*_Point; // TP
}
buystopprice viene calcolato automaticamente partendo dal price (iClose, calcolato prima ed identico per tutta la griglia) , aggiungendo il doppio della distanza tra gli ordini moltiplicato per il numero della iterazione che stiamo eseguendo.
Per questo, alla 1a iterazione l'operazione risulta essere:
LIVELLO BUY STOP = PREZZO * 1 * 2 * DISTANZA GRIGLIA
Analogamente, alla 5a iterazione il valore sarà dato da:
LIVELLO BUY STOP = PREZZO * 5 * 2 * DISTANZA GRIGLIA
L'ultima moltiplicazione, quella per _Point, trasforma il valore intero inserito in input in un valore in pips, aggiungendo i decimali necessari per avere davvero 20 pips di distanza, e non chissà quanti, fra due ordini Buy Stop.Ora che abbiamo calcolato il Prezzo in modo dinamico, possiamo facilmente aggiungere i due livelli di SL e TP, sottraendo lo SL ed aggiungendo il TP, sempre moltiplicando il valore in input per _Point.
Lanciamo quindi il nostro ordine per ogni iterazione:
for(int i=1; i<=MaxPendingOrders; i++)
{
double buystopprice=price+i*2*DistanceOfGridOrders*_Point;
double BSSL=buystopprice-SL*_Point;
double BSTP=buystopprice+TP*_Point;
int BSticket=OrderSend(_Symbol,OP_BUYSTOP,lots,buystopprice,3,BSSL,BSTP,
_Symbol+" BUY STOP NUMBER: "+IntegerToString(i),MAGIC,0,clrGreen);
if(BSticket<=0)
Print("Error = ",GetLastError());
else
{
Print("Order sent with ticket: ",BSticket);
}
}

Clicca qui ed inizia a scrivere. Ut perspiciatis unde omnis iste natus error sit voluptatem.

Clicca qui ed inizia a scrivere. Vel eum iure reprehenderit qui in ea voluptate velit.

Clicca qui ed inizia a scrivere. Ex ea commodi consequatur quis autem vel eum iure.