Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
programmazione
La creazione di sistemi automatizzati di trading
in MQL per MetaTrader 4
Andrew R. Young
Edgehill Publishing
SECONDO LA STAMPA
Esclusione di garanzia: Anche se abbiamo cercato di garantire che il materiale in questo libro è preciso, l'editore non si assume alcuna
responsabilità per l'accuratezza o la completezza di questo libro, e in particolare non riconosce alcuna garanzia implicita di di
commerciabilità o idoneità per uno scopo particolare. Né l'autore né l'editore potranno essere ritenuti responsabili per qualsiasi perdita di
profitto o altri danni non commerciali o commerciali, compreso ma non limitato a consequenziali, incidentali, speciali o altri danni.
"MetaTrader 4", "MQL" e "consulente esperto" sono marchi di MetaQuotes Software Corp.
Questo libro ed è editore non è in alcun modo approvato da o affiliati a MetaQuotes Software Corp.
Per ulteriori informazioni su questo libro, inclusi gli aggiornamenti, notizie e nuove edizioni, si prega di visitare il nostro sito web all'indirizzo
http://www.expertadvisorbook.com/.
ISBN: 978-0-9826459-0-1
Sommario
introduzione 1
A proposito di questo libro 2
Una nota sulla MQL 5 2
Convenzioni usate in questo libro 3
Un'introduzione a MQL 4
Introduzione alla MetaEditor 4
Concetti basilari 7
Layout di un file MQ4 14
Predisporre un ordine 20
Differenza tra domanda e offerta 20
Tipi di ordine 20
L'Ordine di processo Placement 21
OrderSend () 22
Calcolo Stop Loss & Take Profit 25
Recupero Informazioni per l'ordine 32
Gli ordini di chiusura 34
A Simple Expert Advisor 36
Appendice A 154
Semplice Expert Advisor 154
Semplice Expert Advisor con ordini pendenti 156
Appendice B 160
Avanzato Expert Advisor 160
Avanzato Expert Advisor con ordini pendenti 166
Appendice C 172
Expert Advisor con funzioni 172
Expert Advisor con funzioni - Ordini in sospeso 175
Appendice D 180
Includi file 180
Appendice E 198
indicatore personalizzato 198
introduzione
introduzione
Il mercato dei cambi è rapidamente diventato uno dei mercati più popolari al commercio negli ultimi anni. A causa delle sue ore
round-the-clock, ad alta leva e bassi requisiti di margine, migliaia di persone comuni sono diventati operatori attivi.
MetaTrader 4 (comunemente abbreviato in MT4) è diventata una delle piattaforme di trading più popolari per forex. Sviluppato da
MetaQuotes Software Corporation, MetaTrader è offerto da centinaia di broker forex in tutto il mondo, tra cui grandi nomi come
plusvalenza, al FXCM, Alpari e Interbank FX.
La popolarità di MetaTrader deriva dal fatto che è gratuito, mediatore sostenuto, e include molti strumenti utili di analisi tecnica. Ma
probabilmente il più grande motivo per il successo di MetaTrader è il potente linguaggio di programmazione MQL.
MQL ha reso possibile per i commercianti di programmare i propri indicatori personalizzati e strategie di trading automatizzati senza pagare
un centesimo per il software. pacchetti di negoziazione simili per i titoli azionari e futures può costare più di $ 1000. Una comunità mondiale di
operatori e programmatori ha sviluppato, offrendo centinaia di consulenti liberi e commerciali esperti e gli indicatori, così come i servizi di
programmazione e consigli.
La somiglianza di MQL per linguaggi come C rende relativamente facile per i programmatori esperti di pick up, e il linguaggio stesso è
ben documentato. Ma imparare a programmare in modo efficace le strategie di trading in MQL è un processo di tentativi ed errori.
MQL è un linguaggio di livello relativamente basso, e, come tale, è necessario che il programmatore di creare procedure personalizzate
per gestire molte funzioni di trading comune. Coding qualcosa di semplice come un trailing stop, per esempio, può essere scoraggiante per
Ci sono molti fattori che devono essere presi in considerazione quando si programma una solida strategia di trading automatico, e MetaTrader
per sé ha molte idiosincrasie che il programmatore ha bisogno di essere a conoscenza. Si può richiedere decine di ore di risoluzione dei
problemi e pratica per imparare le tecniche necessarie per consulenti esperti programma.
Questo libro spera di ridurre la curva di apprendimento per i nuovi programmatori consulente esperto. Qui mi limiterò a presentare molti dei
suggerimenti e trucchi che ho imparato nelle centinaia di ore che ho trascorso codifica consulenti esperti nel corso degli ultimi anni.
1
E XPERT UN dvisor P ROGRAMMAZIONE
Con il tempo di finire questo libro, è necessario possedere le conoscenze necessarie per creare le proprie solide strategie di trading
automatizzato in MQL, incluse le funzioni di trading comuni come trailing stop, la gestione del denaro e molto altro ancora. Potrai anche
imparare a costruire un indicatore semplice, utilizzando le funzioni di indicatore di built-in.
Questo libro presuppone che il lettore è informato circa forex trading e di analisi tecnica in generale. Il lettore dovrebbe già essere
esperto nell'uso di consulenti esperti e gli indicatori in MetaTrader. Mentre nessuna conoscenza di programmazione precedente si
presume, il lettore beneficiare di avere alcune competenze di programmazione di base, e la familiarità con concetti come variabili,
strutture di controllo, funzioni e moderna sintassi del linguaggio di programmazione.
Saremo a destra tuffarsi in codifica soluzioni a problemi specifici. Ogni tentativo è fatto per spiegare i nuovi concetti appena
vengono introdotti, ma questo libro non è inteso come un riferimento al linguaggio. Il riferimento a MQL http://docs.mql4.com fa
un ottimo lavoro a questo. Il riferimento MQL è anche costruito in MetaEditor IDE che viene fornito con MetaTrader.
Mentre si cercherà di toccare tutto ciò che è necessario e rilevante per lo sviluppo consulente esperto, non saremo in grado di coprire
ogni elemento del linguaggio MQL. Ci sono molte funzioni specializzate in MQL che non sono generalmente utilizzati nella
programmazione esperto consulente. In particolare, non discuteremo funzioni di matrice, manipolazione dei file, oggetti, finestre, e la
maggior parte delle funzioni di stringa o conversione.
Il sito ufficiale MQL4 a http://www.mql4.com ha un libro gratuito sulla programmazione MQL che può servire come una risorsa utile e
complementare. Ci sono molti articoli informativi che riguardano i concetti di programmazione di base e avanzate in MQL, una libreria di
codice con indicatori supplementari ed esempi, e un forum in cui è possibile chiedere aiuto con le vostre domande di programmazione.
Gli esempi di codice e le tecniche che insegno in questo libro sono ciò che ha funzionato per me. Cerco di mantenere le cose il più
semplice possibile, senza sacrificare la funzionalità. Detto questo, c'è sempre più di un modo per realizzare qualcosa, e questo è
particolarmente vero nella programmazione. Ci sono ugualmente metodi validi di ottenere lo stesso risultato, ed è possibile si può
scoprire un modo migliore di fare qualcosa.
Molti degli esempi di codice sorgente di questo libro, così come le appendici complete, sono disponibili per il download sul sito
ufficiale del libro, http://www.expertadvisorbook.com/. In questo modo, è possibile risparmiare il tempo di digitare tutti gli esempi da
soli. Sentitevi liberi di modificare il codice sorgente per le proprie esigenze.
2
introduzione
Momento in cui scriviamo, la prossima versione della piattaforma MetaTrader è in beta testing aperto. Ci saranno alcuni
cambiamenti significativi per l'ultima versione di MQL. MetaQuotes ha riferito che MetaTrader 5 non sarà compatibile con
MetaTrader 4 programmi. Così, tutti i programmi scritti in MQL 4 dovranno essere riscritti o aggiornati per MQL 5.
Questo libro si occupa di MetaTrader 4, in quanto è la versione che ho Programmazione in negli ultimi anni ed è attualmente
la versione che viene utilizzato da broker Forex. Dopo il rilascio di MetaTrader 4 nel 2005, Forex trading è esploso in
popolarità. MetaTrader è diventata la piattaforma di trading forex più popolare, e ci sono stati migliaia di strategie di trading e
gli indicatori scritti in MQL 4.
Prevedo la migrazione verso MetaTrader 5 sarà un graduale. Brokers continueranno a sostenere MetaTrader 4 per un certo tempo, in
modo che i programmi che si scrivono in MQL 4 non diventeranno obsolete immediatamente. I concetti di questo libro rimarranno gli stessi,
anche se alcune delle funzioni e la sintassi cambierà. La sfida sarà quella di imparare le nuove MQL 5 caratteristiche e incorporarlo nel
vostro codice esistente.
Una seconda edizione di questo libro sarà rilasciato qualche tempo dopo la versione finale di MetaTrader 5. Per coloro che hanno
acquistato questo libro, il codice sorgente aggiornato e un MQL4 alla guida MQL5 saranno disponibili sul nostro sito web, http://www.expertadvisorbook.com
Elementi MQL linguaggio, esempi di codice sorgente, e le posizioni dei file e URL saranno visualizzati in un
carattere a larghezza fissa. Un testo in grassetto più grande sarà usato per il testo in linea. I blocchi di codice sorgente saranno rientrate. Qualsiasi
testo in grassetto appare in un blocco di codice sorgente indentato indica il codice che è stato aggiornato o modificato da un precedente esempio.
parole in corsivo indicare un nuovo concetto che viene introdotta o definito. I riferimenti alle sezioni e argomenti nel MQL di riferimento
verranno visualizzati in corsivo. I riferimenti a elementi dell'interfaccia MetaTrader 4, comprese le finestre, finestre di dialogo, pulsanti o voci
di menu, verranno visualizzate anche in corsivo.
3
E XPERT UN dvisor P ROGRAMMAZIONE
Capitolo 1
Un'introduzione a MQL
un Expert Advisor?
Un consulente esperto è un programma di trading automatizzato scritto in MQL. consulenti esperti (comunemente abbreviato come EA) possono
effettuare, modificare e chiudere ordini in base ad un algoritmo di sistema di trading. EA generalmente usano indicatori per generare segnali di trading.
Questi indicatori possono essere quelli che vengono con MetaTrader, oppure possono essere indicatori personalizzati.
Un indicatore è uno strumento di analisi tecnica che calcola i dati sui prezzi a dare un'interpretazione di attività di mercato. Un indicatore
traccia linee o oggetti sul grafico. Gli indicatori non possono disporre, modificare o chiudere gli ordini. Esempi di indicatori includono la
media mobile e stocastico.
UN copione è un consulente esperto semplificata che svolge una sola operazione, come l'immissione di un ordine in corso o chiudere tutti gli
Formati di file
I file con il. mq4 estensione sono codice sorgente File. Questi sono i file che modificare in MetaEditor. Quando un. mq4 file viene compilato,
I file con il. ex4 estensione sono eseguibile File. Questi sono i file che abbiamo eseguito in MetaTrader. Questi file non possono essere
aperti in MetaEditor. Se avete solo il. ex4 file per un EA o di un indicatore, l'icona accanto al nome del file in MetaTrader di Navigatore la
finestra sarà disattivata.
I file con il. MQH estensione sono includere File. Questi file contengono funzioni creati dall'utente cui si fa riferimento in una. mq4 file.
Durante la compilazione, il compilatore "comprende" il contenuto del. MQH depositare in. ex4 file. Impareremo di più su include i file più
tardi.
Il . MQT estensione viene utilizzata per i file di modello. Mentre questi file possono essere aperti in MetaTrader, il tipo di file non è associato con
il programma in Windows. I modelli sono utilizzati per creare nuovi file utilizzando il consulente guidata Esperto in MetaEditor.
4
Un'introduzione a MQL
È possibile creare i propri modelli, se lo si desidera, ma non sarà che copre la creazione di template in questo libro. La
documentazione MetaTrader vi dirà tutto quello che dovete sapere sulla creazione di modelli.
Indicatori, consulenti esperti, le biblioteche e gli script tutti condividono la. mq4 estensione. L'unico modo per dire loro a parte è sia
per la loro posizione di salvataggio, o aprendo il file e esaminarli. Con il tempo di finire questo libro, si dovrebbe essere in grado di
identificare la differenza tra i tipi di programma solo guardando il codice sorgente.
Tutti i file MetaEditor vengono memorizzati all'interno del cartella esperti. Il \ esperti cartella è contenuto nella directory di installazione di
MetaTrader, che è in C: \ Program Files \. Se il vostro broker è FX interbancario, per esempio, la cartella di installazione MT4 sarebbe C:
\ Program Files \ Interbank FX Trader 4 \.
Il \ esperti cartella contiene il codice sorgente e file eseguibili per i consulenti esperti. Utilizzando l'esempio precedente, il \ esperti cartella
sarebbe situato a C: \ Program Files \ Interbank FX Trader 4 \ esperti \.
Ci sono numerose cartelle all'interno della \ esperti cartella che contiene altri tipi di codice sorgente e file eseguibili. Ecco un elenco
dei luoghi di salvataggio per tutti i tipi di file:
• \ experts \ indicatori - Il codice sorgente e file eseguibili per i vostri indicatori sono memorizzati qui.
• \ Esperti \ INCLUDE - Il codice sorgente include i file con il. MQH estensione vengono memorizzati qui.
• \ experts \ scripts - Il codice sorgente e file eseguibili per gli script sono memorizzati qui.
• \ experts \ Modelli - Modelli per file di codice sorgente sono memorizzati qui.
Ci sono un paio di altre cartelle all'interno della cartella esperti che si vorrà essere a conoscenza di troppo:
• \ experts \ logs - i registri di attività per i vostri consulenti esperti sono memorizzati qui. Questi saranno utili per il debug
consulenti esperti.
• \ experts \ preset - impostazioni Expert Advisor che vengono salvate o caricate da MetaTrader di
• \ esperti \ files - Tutti i file utilizzati per l'ingresso o l'uscita devono essere conservati qui.
5
E XPERT UN dvisor P ROGRAMMAZIONE
MetaEditor
MetaEditor è un ambiente di sviluppo integrato (IDE) per MQL che viene fornito con MetaTrader. Esso comprende utile di riferimento, strumenti
di reperibilità e di completamento automatico che rende la codifica in MQL molto più facile.
Il editore finestra vi permette di avere più file aperti contemporaneamente. È possibile ridurre, ingrandire e scheda tra più finestre
aperte. Il Navigatore finestra offre utili funzioni l'individuazione dei file e di riferimento. Il cassetta degli attrezzi vetrine aiutano
contenuti, errori di compilazione, risultati di ricerca di file e l'accesso on-line per articoli e file a MQL4.com.
Una delle funzioni di editing più utili è l'assistente. È sufficiente digitare i primi caratteri di una funzione MQL, operatore o altro
elemento del linguaggio, e apparirà un elenco a discesa. Premere Invio per accettare il suggerimento evidenziato e
auto-completano la frase.
Fig. 1.1 - L'interfaccia MetaEditor. In senso orario da sinistra in alto: Finestra Editor, Window Navigator, e la finestra Toolbox.
6
Un'introduzione a MQL
Il File scheda nella finestra Navigator è un semplice browser di file che consente di aprire e modificare qualsiasi file MQL nella cartella \ esperti
cartella. Il Dizionario scheda presenta un built-in MQL riferimento, mentre la
Ricerca scheda è una funzione di ricerca per il riferimento MQL.
l'argomento della Guida verrà visualizzata nella finestra Casella degli strumenti.
strumenti.
Fig. 1.2 - Assistente automatico completa di
funzioni di MetaEditor.
Il Compilare Pulsante compila il file corrente nell'editor. Se ci sono errori di compilazione,
saranno visualizzati nella finestra degli strumenti. Il
terminale pulsante apre il terminale di trading per il test.
Concetti basilari
Stiamo andando a rivedere alcuni concetti di programmazione di base che faranno il resto di questo libro più facile da capire per i nuovi
programmatori. Se sei un programmatore esperto, sentitevi liberi di passare direttamente alla sezione successiva, Layout di un file MQL.
Sintassi
Se si ha familiarità con la programmazione in linguaggi come C ++, PHP o una delle molte lingue la cui sintassi è derivato dal C, sarete
programmazione molto confortevole in MQL. Se la vostra esperienza di programmazione precedente, è in un linguaggio come Visual
Basic, quindi potrebbe essere necessario fare qualche aggiustamento.
In MQL, ogni istruzione termina con un punto e virgola. Questo viene chiamato espressione. Un'espressione può più righe, ma
ci deve essere una virgola alla fine.
7
E XPERT UN dvisor P ROGRAMMAZIONE
Se sei nuovo di programmazione, o abituati alla programmazione in un linguaggio che non pone fine le espressioni con un punto e
virgola, è necessario assicurarsi che si sta posizionando il punto e virgola alla fine di ogni istruzione. Non terminare le linee con un
punto e virgola è un errore comune newbie.
Ci sono alcune eccezioni a questo: gli operatori composti non hanno bisogno di un punto e virgola. UN operatore composto è un blocco
di codice che contiene molteplici espressioni tra parentesi graffe {}. Esempi di operatori composti includono operatori di controllo ( se,
se (Composto == true)
{Stampa ( "Questa è un'espressione composto"); }
Si noti che non v'è alcun punto e virgola dopo l'iniziale Se operatore, né v'è una virgola dopo la parentesi di chiusura. C'è un punto e virgola
dopo la Stampare() funzione, tuttavia. Non ci può essere una o più espressioni all'interno delle parentesi. Ognuno deve conclude con una
virgola.
Commenti
I commenti sono utili per documentare il codice, così come per la rimozione temporanea di codice durante il test e il
debug. Puoi commentare una singola linea con due barre:
// Questo è un commento
Un commento su più righe inizia con / * e termina con * /. Un commento multi-linea può estendersi qualsiasi numero di linee,
e tutto tra / * e * / è commentata.
Identifiers
Gli identificatori sono nomi dati alle variabili e funzioni personalizzate. Un identificatore può essere una combinazione di numeri, lettere, e il
carattere di sottolineatura (_). Gli identificatori possono essere fino a 31 caratteri di lunghezza.
Ti consigliamo i dati identificativi di essere descrittivo della loro funzione, ma essere sicuri l'identificativo non corrisponde a un elemento del
linguaggio MQL (chiamato anche un parola riservata). Ecco un esempio di un identificatore di variabile e un identificatore funzione personalizzata.
L'identificatore è in corsivo:
8
Un'introduzione a MQL
Doppio StopLoss;
int N.ORDER_COUNT ()
Gli identificatori in MQL sono che tiene conto del maiuscolo o minuscolo. Ciò significa che StopLoss e stoploss sono diverse variabili! Questo è un
variabili
UN variabile è l'unità di memorizzazione di base di qualsiasi linguaggio di programmazione. Le variabili contengono i dati necessari per il nostro programma di
Le variabili devono essere dichiarate prima del loro utilizzo. Per dichiarare una variabile, si specifica che è tipo di dati, un identificatore, e facoltativamente
un valore predefinito. Se si dichiara una variabile più di una volta, o non del tutto, si otterrà un errore di compilazione.
Il tipo di dati specifica il tipo di informazioni contenuto nella variabile stessa, che si tratti di un numero, una stringa di testo, una data o un
• int - Un numero intero (numero intero) come 0, 3, o -5. Qualsiasi numero assegnato a una variabile intera viene
• Doppio - Un numero frazionario come 1,5765, 0,03 o -2,376. Utilizzare questi per dati sui prezzi, o in espressioni matematiche che
coinvolgono divisione.
• stringa - Una stringa di testo come " La volpe marrone veloce saltò sul cane pigro".
• booleano - A vero falso valore. Può anche essere rappresentato come 1 (true) o 0 (falso). Utilizzare questi in qualsiasi momento è necessario
• appuntamento - Un ora e valore di data come 2009.01.01 00:00. Internamente, una variabile datetime è
• colore - Una costante che rappresenta un colore, ad esempio Rosso o Darkslateblue. Questi sono generalmente utilizzati per cambiare
Ecco un esempio di una dichiarazione di variabile. Questa è una variabile intera, con l'identificatore
MyVariable e un valore predefinito di 1.
int MyVariable = 1;
9
E XPERT UN dvisor P ROGRAMMAZIONE
Una volta che una variabile è stata dichiarata, è possibile modificare il valore assegnando un nuovo valore ad esso. Ecco un esempio in cui si
MyVariable = 5;
Variabile associata deve essere dello stesso tipo di dati. Se un doppio viene assegnato ad una variabile intera, per esempio, il doppio
viene arrotondato al numero intero più vicino. Questo può portare ad un risultato indesiderato.
costanti
Proprio come suggerisce il nome, un costante è un valore di dati che non cambia mai. Ad esempio, il numero
5 è una costante intera, la lettera ' UN' è una costante carattere, e 2009.01.01 è una costante datetime per 1 gennaio, 2009.
MQL ha una grande varietà di costanti standard per cose come i dati sui prezzi, periodi del grafico, i colori e le operazioni commerciali. Per esempio PERIOD_H1
è una costante per il periodo di tempo tabella H1, OP_BUY si riferisce a un ordine di mercato acquisto, e Rosso è una costante di colore per il colore
rosso.
È anche possibile creare i propri costanti utilizzando il # definire direttiva del preprocessore. Noi arriveremo a breve. Potete saperne
di più sulle costanti standard di di MQL nella Costanti standard sezione del MQL riferimento.
funzioni
Le funzioni sono gli elementi costitutivi dei moderni linguaggi di programmazione. Una funzione è un blocco di codice che è stato
progettato per svolgere un certo compito, come un ordine o calcolare uno stop loss. MQL ha decine di funzioni incorporate per tutto da
indicatori tecnici per ordinare il posizionamento.
Funzioni sono progettati per essere riutilizzato più e più volte. Imparare a creare funzioni per le attività di trading comuni è
essenziale per la programmazione produttiva. Lavoreremo sulla creazione di funzioni riutilizzabili per molte delle attività che
impareremo in questo libro.
10
Un'introduzione a MQL
Cominciamo con una semplice funzione chiamata PipPoint (), che calcola il numero di punti decimali nella coppia corrente e regola
automaticamente per 3 e 5 broker cifre in modo che il risultato è sempre uguale a un pip. Per accoppiamenti di Yen (2 o 3 cifre), la
funzione restituisce 0,01. Per tutte le altre coppie (4 e 5 cifre), la funzione restituisce 0,0001. Ecco come vorremmo chiamare la funzione
dal codice:
Si dichiara una variabile di tipo Doppio di nome UsePoint. Poi noi chiamiamo il PipPoint () funzionare e assegnare il risultato a UsePoint. Ora
possiamo usare il valore memorizzato in UsePoint per calcolare uno stop loss, per esempio.
doppia PipPoint ()
{If (cifre == 2 || cifre == 3) doppio UsePoint = 0.01;
La prima linea è la nostra dichiarazione di funzione. Come le variabili, le dichiarazioni di funzione hanno un tipo di dati e un identificatore. Funzioni
utilizzano gli stessi tipi di dati come variabili fanno. Il tipo di dati dipende dal tipo di dati che la funzione restituisce. Dal momento che questa
Il corpo della funzione è contenuta all'interno delle parentesi {}. Abbiamo un se altro dichiarazione che valuta il numero di
cifre dopo il punto decimale, e assegna il valore appropriato per la
UsePoint variabile. In seguito, abbiamo la ritorno operatore, che restituisce il valore di
C'è uno speciale tipo di dati per le funzioni che non restituiscono un valore. Il vuoto tipo di dati viene utilizzato per le funzioni che svolgono un compito
specifico, ma non hanno bisogno di restituire un valore alla funzione chiamante. vuoto
Consideriamo una funzione semplice per l'immissione di un ordine di acquisto. Questa funzione ha argomenti che necessità di essere passato alla funzione.
Questa funzione sarà posto un ordine di acquisto di mercato sul simbolo corrente con la dimensione del lotto specificato, stop loss e take profit.
11
E XPERT UN dvisor P ROGRAMMAZIONE
int OpenBuyOrder (doppia Misura di lotto, Doppio StopLoss, Doppio Avere un profitto)
{Int biglietteria = OrderSend (Simbolo (), OP_BUY, Misura di lotto, Chiedi, StopLoss, TakeProfit);
biglietto di ritorno); }
Questa funzione ha tre argomenti, Misura di lotto, StopLoss e Avere un profitto. Gli argomenti sono variabili che vengono utilizzati solo all'interno della
funzione. Il loro valore viene assegnato dalla funzione di richiamo. Ecco come vorremmo chiamare questa funzione in costanti di codice utilizzando:
Questo sarà posto un ordine di acquisto di 2 lotti, con uno stop loss di 1,5550 e un take profit di 1,6050. Ecco un altro esempio
utilizzando le variabili. Si suppone che le variabili UseLotSize, BuyStopLoss e
BuyTakeProfit hanno i valori appropriati assegnati:
In questo esempio, stiamo assegnando il valore di ritorno di OpenBuyOrder () alla variabile getticket,
che il numero del biglietto d'ordine che abbiamo appena messo. Assegnare l'uscita di una funzione di una variabile è opzionale. In questo caso, è
necessario solo se avete intenzione di fare un'ulteriore elaborazione utilizzando il numero del biglietto del ordine effettuato.
Gli argomenti possono avere valori standard, il che significa che se un parametro non è esplicitamente passato alla funzione,
l'argomento avrà il valore di default. argomenti valore di default sarà sempre alla fine della lista degli argomenti. Ecco un esempio di
una funzione con diversi valori di default:
int DefaultValFunc (int Biglietto, Doppio Prezzo, int Number = 0, string commento = NULLO)
Questa funzione ha due argomenti con valori predefiniti, Numero e Commento, con valori di default di 0
e NULLO rispettivamente. Se vogliamo utilizzare i valori di default per entrambi Numero e Commento, abbiamo semplicemente omettere tali argomenti
Si noti che abbiamo specificato solo i primi due argomenti. Numero e Commento utilizzare i valori di default di 0
e NULLO. Se vogliamo specificare un valore per Numero, ma non per Commento, abbiamo semplicemente omettere l'ultimo argomento:
12
Un'introduzione a MQL
Ancora, Commento utilizza il valore predefinito di NULLO. Ma, se vogliamo specificare un valore per Commento,
a prescindere dal fatto che si vuole utilizzare il valore di default per Numero, dobbiamo specificare un valore per Numero anche:
In questo esempio, abbiamo utilizzato 0 come valore per Numero, che è uguale al valore di default, e una stringa costante
come valore per Commento. Ricorda che quando hai a che fare con argomenti multipli con valori di default, è possibile
omettere solo argomenti se si desidera utilizzare i valori di default per tutti i restanti argomenti!
Mirino variabile
Il scopo di una variabile determina quali funzioni è disponibile a, e per quanto tempo rimane in memoria. In MQL, scope può essere Locale
UN Locale variabile è uno che viene dichiarata all'interno di una funzione. Le variabili locali sono disponibili solo all'interno della funzione si è dichiarata in. La
variabile viene inizializzata ogni volta che la funzione viene eseguito. Una volta che la funzione termina, la variabile ei suoi dati vengono cancellati dalla
memoria.
Un'eccezione a questo sarebbe un statico variabile locale. Le variabili statiche rimangono in memoria anche dopo le uscite di funzione. Quando la
funzione viene eseguito di nuovo, la variabile non è reinizializzata, ma invece mantiene il suo valore precedente.
Una variabile statica è dichiarata digitando statico davanti alla dichiarazione di variabile. Ecco un esempio di una dichiarazione di variabile
statica:
Se una variabile statica deve essere reso disponibile per più di una funzione, utilizzare una variabile globale invece. In questo caso
UN globale variabile è uno che è disponibile per tutte le funzioni all'interno di un programma. Fino a quando il programma è in esecuzione, viene mantenuto il
valore della variabile globale. Le variabili globali vengono dichiarate al di fuori di una funzione, generalmente nella parte superiore del file di codice sorgente.
13
E XPERT UN dvisor P ROGRAMMAZIONE
Non esiste un metodo speciale per inizializzare una variabile globale. La sintassi è identica a quella di una variabile locale.
Il Advisor guidata Expert nel MetaEditor è il modo più rapido per iniziare a creare un consulente esperto. È possibile avviare la procedura
guidata selezionando Nuovo dal File menù, premendo il tasto Nuovo sulla barra degli strumenti, oppure premendo Ctrl + N sulla tastiera.
La finestra di dialogo si presenta con diverse opzioni. È possibile creare indicatori, script, librerie e file include utilizzando la procedura
guidata. È anche possibile scegliere un modello per la generazione di un file. Il file risultante verrà salvato nella directory appropriata, a
14
Un'introduzione a MQL
Verrà richiesto per un Nome, Autore e link, così come alcuni parametri opzionali. Il campo Nome sarà il nome del file del
programma. La EA verrà salvato nella cartella \ esperti cartella sotto quel nome di file.
Il contenuto del campo Autore appariranno accanto al nome di EA nel Tester strategia, e come suggerimento quando il mouse
sopra il nome di EA nella finestra Navigator. Il campo Link è un URL al tuo sito web, ma non appare da nessuna parte al di fuori del
file di codice sorgente.
È anche possibile inserire i parametri commerciali qui. Per ora, aggiungere un parametro o due, ma non si preoccupano di loro regolazione. E 'meglio
Il modello consulente esperto di default è piuttosto minimale, ma contiene la struttura di base di un consulente esperto. Cerchiamo di identificare il
layout di un file MQL utilizzando il modello consulente esperto come la nostra guida.
La prima cosa ad apparire in qualsiasi file MQL sono le direttive del preprocessore. Questi sono preceduti da un #. Il modello di
default esperto consulente ha due: # protette da copyright, che è il nome dell'autore immesso nella Advisor guidata di esperti, e # Link
proprietà, che è il link che hai inserito nella procedura guidata.
Ci sono altri # proprietà direttive, ma quasi tutti sono legati a indicatori e script. Il solo # proprietà La direttiva si dovrebbe
includere nel vostro consulente esperto è # protette da copyright,
che identifica il EA come la vostra creazione.
Un secondo tipo di direttiva del preprocessore è probabile che utilizzare è il # includere direttiva. Come accennato in precedenza, un file di
inclusione si compone di funzioni e codice sorgente che saranno inclusi nel progetto quando viene compilato. La sintassi per la direttiva
comprendere è:
Il file stdlib.mqh nel nostro esempio a pagina 19 è uno standard di file include che viene fornito con MetaTrader. Esso comprende
diverse funzioni varie che i programmatori possono trovare utili. Come tutti includere file, si trova nella cartella \ \ include esperti cartella.
Il # definire direttiva viene utilizzato per dichiarare le costanti per l'utilizzo nel nostro programma. Ad esempio, invece di digitare una stringa di testo
lungo ogni volta che avete bisogno di usarlo, è possibile definire una costante e digitare che, invece:
15
E XPERT UN dvisor P ROGRAMMAZIONE
In questo esempio, possiamo utilizzare l'identificatore costante MYCONSTANT al posto della stringa di testo nel nostro codice. La convenzione per i
nomi di costante è quello di utilizzare tutte le lettere maiuscole. Anche se non è assolutamente necessario, per coerenza si dovrebbe definire tutti
A volte, una funzione è necessario utilizzare è già compilato in un altro file, ad esempio un altro consulente esperto, un file di libreria (. ex4) o
un file DLL di Windows (. dll). È possibile importare le funzioni direttamente in un progetto che utilizza # importare direttive.
Le biblioteche sono simili a includere i file, ma invece di includere il codice sorgente nel nostro progetto, abbiamo eseguirà l'altro file e
chiamare la funzione da esso. Parleremo utilizzando le librerie più avanti nel libro.
Importa direttive sono in genere collocati in includono file, soprattutto se ci sono molte funzioni per importare. Ma se avete solo
bisogno di importare una o due funzioni, e un file di inclusione per loro non esiste già, poi andare avanti e importarli direttamente
nel progetto.
Per esempi dettagliati del # importare direttiva, vedere la pagina di riferimento MQL Importazione delle funzioni,
e guardare i file di inclusione nella \ \ include esperti cartella. Ecco la sintassi per il # importare
direttiva:
# importazione "library.ex4"
doppio MyImportedFunction ();
# importare
In questo esempio, il file della libreria stiamo importando la funzione (s) da è library.ex4. Stiamo importando una singola funzione di tipo
double, chiamato MyImportedFunction (). L'identificatore funzione deve corrispondere al nome della funzione nel file di libreria di origine. Si
noti la virgola alla fine della dichiarazione di funzione.
La sezione successiva nel nostro file di codice sorgente consulente esperto sono le variabili esterne. Questi sono i parametri regolabili per il nostro
sistema di trading. Questo include le impostazioni di fabbrica (stop loss, take profit, dimensione del lotto) e le impostazioni degli indicatori. Quando si
apre il Proprietà Expert finestra di dialogo per un consulente esperto, si visualizzano le variabili esterne per quel programma.
Specifichiamo una variabile esterna con l'aggiunta di extern davanti alla variabile. Questo specifica che la variabile apparirà nella
finestra di dialogo Expert Proprietà e sarà visibile e regolabile dall'utente.
16
Un'introduzione a MQL
Assicurarsi che l'identificatore per la variabile esterna è descrittivo di ciò che fa in realtà. ( "StopLoss" è meglio di "stop" o "SL", per esempio).
Hai 31 caratteri per descrivere la variabile, in modo da rendere la maggior parte di esso. Il valore predefinito per la variabile sarà anche il
valore predefinito per quel parametro, in modo da scegliere un valore predefinito logico.
Variabili globali
Dichiariamo tutte le variabili globali nella parte superiore del nostro file di codice sorgente, in genere dopo le variabili esterne. La
posizione non importa, purché entrambe le variabili globali ed esterne sono poste al di fuori e prima di qualsiasi funzione.
Una variabile globale è uno che è disponibile a qualsiasi funzione del programma. Fino a quando il programma è in esecuzione, la variabile
globale ed è soggiorni di valore in memoria, e può fare riferimento e modificata da qualsiasi funzione del programma.
Tecnicamente, variabili esterne sono globali pure, ma le variabili globali che stiamo a discutere in questa sezione sono interni, il
che significa che non sono visualizzabili o modificabili dall'utente.
Funzioni speciali
MQL ha 3 funzioni incorporate per controllare l'esecuzione del programma: init (), deinit () e inizio(). Il
dentro() funzione comprende codice che viene eseguito una volta, quando l'EA viene iniziato. Il dentro()
Il deinit () funzione consiste di codice che viene eseguito una volta, quando l'EA è fermo. Questa funzione è opzionale, ed è improbabile
Il inizio() funzione contiene il codice del programma principale, ed è necessario nel vostro EA. Ogni volta che si esegue la funzione di avviamento, le vostre
condizioni di transazione non vengono controllati, e gli ordini vengono inseriti o chiusi a seconda di come vengono valutate le condizioni.
Il inizio() funzione viene eseguito su ogni tick. UN zecca è un movimento di prezzo, o il cambiamento nel Bid o chiedere prezzo per una coppia di
valute. Durante mercati attivi, ci possono essere diverse tick per secondo. Durante mercati lenti, minuti può passare senza un segno di spunta.
17
E XPERT UN dvisor P ROGRAMMAZIONE
altre funzioni
Tutte le altre funzioni che il vostro EA può utilizzare devono essere dichiarati dopo la inizio() funzione. Queste funzioni saranno
chiamati dal start (), init () o deinit () funzioni, o da altre funzioni che sono chiamati dal programma principale. Parleremo funzioni
personalizzate più avanti nel libro.
18
Un'introduzione a MQL
# includere <stdlib.mqh>
{ // codice di avvio
ritorno (0); }
{ // Codice Shutdown
ritorno (0); }
ritorno (0); }
ritorno (0); }
19
E XPERT UN dvisor P ROGRAMMAZIONE
capitolo 2
Predisporre un ordine
Come un operatore Forex, probabilmente siete già familiarità con l'offerta e chiedere i prezzi. Ma si potrebbe non essere a conoscenza del
loro ruolo nella fase di ordine. E 'molto importante utilizzare il prezzo corretto per aprire o chiudere ordini.
Il Offerta il prezzo è quello che si vede nelle classifiche MetaTrader. Di solito è quello che pensiamo di quando pensiamo al "prezzo
corrente". Il Chiedere prezzo è generalmente a pochi pip al di sopra del prezzo di offerta. La differenza tra l'offerta e la Fai è la la diffusione,
che è commissione del broker per effettuare l'ordine.
Il prezzo chiedo è dove apriamo ordini di acquisto, e chiudere ordini di vendita. Il prezzo di offerta è dove abbiamo aperto gli ordini di vendita, e
chiudere ordini di acquisto. Avrete bisogno di indicare il prezzo corretto quando si apre un ordine di mercato, o quando si chiude un ordine al mercato,
Tipi di ordine
Ci sono tre tipi di ordini che possono essere messi in MetaTrader: mercato, stop e ordini limite. Gli ordini di mercato sono i più comuni.
UN ordine di mercato apre una posizione immediatamente a prevalente Bid o Richiedi prezzo.
Quando si effettua un ordine di mercato in MQL, dobbiamo specificare un prezzo di apertura (in genere l'ultima Bid o Richiedi preventivo). Se il
prezzo di apertura specificato è obsoleto, a causa di un mercato rapido movimento o ritardata esecuzione del programma, il terminale tenterà di
ordinare al prezzo di mercato, a condizione che sia all'interno della massima lo slittamento.
Se si inserisce un ordine di mercato utilizzando il Nuovo ordine dialogo in MetaTrader, vedrete un ambiente in fondo con l'etichetta "Enable
massima deviazione dal prezzo quotato." Quando questa opzione è selezionata, è possibile specificare la deviazione massima in pips. Questo è
lo slittamento massimo.
Se il prezzo corrente cade fuori del nostro prezzo di partenza specificato, più o meno lo slittamento, un errore requote si verificherà e l'ordine
non sarà posto. Avrete notato questo quando si tenta di inserire un ordine di mercato nel corso di un mercato in rapida evoluzione. Si noti che i
broker ECN / STP non utilizzano un ambiente slittamento, e gli ordini di mercato sarà sempre aperto al prezzo corrente.
20
Predisporre un ordine
UN fermare ordine è un tipo di ordine pendente. in attesa di gli ordini sono una richiesta di aprire un ordine di mercato ad un certo prezzo. UN buy
Stop ordine è disposto sopra il prezzo corrente, mentre un sell Stop dell'ordine di sotto del prezzo corrente. L'aspettativa è che il prezzo alla
fine salire o scendere a quel livello e continuare in quella direzione, con un conseguente profitto.
UN limite ordine è l'opposto di un ordine di arresto. UN acquistare limite dell'ordine di sotto del prezzo corrente, mentre un sell limit ordine è
disposto sopra il prezzo corrente. Si prevede che il prezzo salirà o scenderà a quel livello, innescando l'ordine, quindi inverte. Gli ordini
limite non vengono utilizzati molto spesso in trading automatico.
Un scadenza tempo può essere impostato per gli ordini in sospeso. Se l'ordine non è riempito da tempo di scadenza, l'ordine viene automaticamente
Il processo di immissione di un ordine in MQL richiede diversi passi. Dobbiamo determinare quanto segue prima di ordinare:
• La dimensione del lotto. Questo può essere un dimensione del lotto fisso, o uno che è calcolato utilizzando una routine di gestione del denaro.
• Il prezzo di apertura ordine. Per ordini di mercato, questa sarà la corrente Bid o Richiedi prezzo. Per gli ordini in attesa, il prezzo di
apertura deve essere una distanza minima dal prezzo corrente, e dovrebbe essere al di sopra o al di sotto del prezzo corrente
• Il prezzo di stop loss. La perdita di arresto può essere un prezzo prefissato, un valore indicatore, un numero fisso di pip dal prezzo di
apertura ordine, oppure può essere calcolato dinamicamente utilizzando una routine di gestione del rischio. La perdita di arresto può
essere posizionato con l'ordine, oppure può essere aggiunto all'ordine dopo.
• Il prezzo di take profit. Questo è generalmente un numero fisso di pip dal prezzo di apertura ordine, anche se può essere
calcolata utilizzando altri metodi pure. Il take profit può essere posizionato con l'ordine, oppure può essere aggiunto all'ordine
dopo.
• Ordinare identificatori come ad esempio un commento ordine, o di un "numero magico", che identifica un ordine come di essere immessi da uno
21
E XPERT UN dvisor P ROGRAMMAZIONE
OrderSend ()
int OrderSend (string Simbolo, int Genere, Doppio Molte, Doppio Prezzo,
int slittamento, Doppio StopLoss, Doppio Avere un profitto, stringa commento = NULL, int MagicNumber = 0, datetime scadenza
= 0, il colore freccia = CLR_NONE);
• Simbolo - Una stringa che rappresenta la coppia di valute per il commercio, per esempio GBPUSD. Il
• genere - Il tipo di ordine di posto: comprare o vendere; mercato, stop o limite. Questo è un valore intero, rappresentato dalle
seguenti costanti:
• Molte - Il numero di lotti per il commercio. È possibile specificare mini lotti (0,1) o micro lotti (0,01) se il broker lo supporta.
• Prezzo - Il prezzo al quale per aprire l'ordine. Per un ordine di acquisto di mercato, questo sarà il Chiedere.
Per un ordine di mercato vendere, questo sarà il Offerta. Per gli ordini in sospeso, questa sarà valida qualsiasi prezzo che è al di sopra o al di
• slittamento - Lo slittamento massima in punti. Utilizzare un numero sufficientemente ampio impostazione quando trading automatico. Broker che
• StopLoss - Il prezzo di perdita di arresto. Per un ordine di acquisto, il prezzo stop loss è al di sotto del prezzo di apertura ordine, e per un ordine
• Avere un profitto - Il prezzo take profit. Per un ordine di acquisto, il take profit è al di sopra del prezzo di apertura ordine, e per un ordine di
• Commento - Una stringa opzionale che servirà come un commento ordine. I commenti sono mostrati sotto il Commercio linguetta nel terminale
finestra. commenti ordine può essere utilizzato anche come un identificatore ordine.
22
Predisporre un ordine
• MagicNumber - Un valore intero facoltativo che identificherà l'ordine di essere immessi da uno specifico consulente
esperto. Si consiglia vivamente di utilizzare questo.
• Scadenza - Un tempo di scadenza facoltativa per gli ordini in sospeso. Non tutti i broker accettare tempi di scadenza del commercio - per
questi mediatori, verrà generato un errore se viene specificata una data di scadenza.
• Freccia - Un colore facoltativo per la freccia che verrà utilizzata nel grafico, indicante il prezzo di apertura e tempo. Se non
Il OrderSend () funzione restituisce il numero del biglietto d'ordine che è stato appena messo. Se nessun ordine è stato effettuato, a causa di una
Possiamo salvare il biglietto per una variabile globale o statico per un uso successivo. Se l'ordine non è stato posto a causa di una condizione di
errore, possiamo analizzare l'errore e prendere i provvedimenti opportuni in base al codice di errore restituito.
Ecco un esempio di un ordine di acquisto di mercato. Si suppone che le variabili Misura di lotto, lo slittamento, BuyStopLoss, BuyTakeProfit
e MagicNumber hanno già calcolato o assegnato e sono validi.
OrderSend (Simbolo (), OP_BUY, Misura di lotto, Chiedi, lo slittamento, BuyStopLoss, BuyTakeProfit,
"Buy Order", MagicNumber, 0, verde);
Il Simbolo() funzione restituisce il simbolo grafico corrente. Saremo ordini sulla corrente coppia di tabella il 99% del tempo. OP_BUY indica
che si tratta di un ordine di acquisto di mercato. Chiedere è una variabile predefinita in MQL che memorizza l'ultima citazione Chiedi.
(Ricordiamo che acquistare ordini aperti al prezzo Chiedi!)
Il slittamento è impostato utilizzando una variabile esterna. Il parametro slittamento è un numero intero che indica il numero di punti per
consentire lo slittamento prezzo. Se il vostro broker utilizza 4 citazioni cifra (2 per le coppie Yen), 1 punto sarebbe pari a 1 pip. Se il vostro
broker offre 3 e 5 citazioni cifra però, poi 1 punto sarebbe di 0,1 pips. In questo caso, avresti bisogno di aggiungere uno zero aggiuntivo alla fine
Abbiamo aggiunto il commento generico " Buy Order" a questo ordine. Dal momento che non v'è alcuna scadenza per gli ordini di mercato, il
parametro di scadenza è 0. Infine, specificare il colore costante verde per disegnare una freccia verde sul grafico.
Ecco un esempio di un ordine di mercato vendita, utilizzando gli stessi parametri di cui sopra:
23
E XPERT UN dvisor P ROGRAMMAZIONE
OrderSend (Simbolo (), OP_SELL, Misura di lotto, Offerta, Slittamento, SellStopLoss, SellTakeProfit,
"Vendere Ordine", MagicNumber, 0, Rosso);
Noi usiamo OP_SELL come il tipo di ordine, per specificare un ordine di mercato sell. Noi usiamo Offerta come il prezzo di apertura ordine, in modo da riflettere il
fatto che vendono gli ordini aperti al prezzo di offerta. " Vendi Ordine" è il nostro commento ordine, e usiamo Rosso come la freccia di colore per differenziare da
ordini di acquisto.
La differenza tra gli ordini in corso e gli ordini di mercato è che il prezzo di apertura ordine sarà qualcosa di diverso dal
prezzo corrente di mercato. La stop loss e take profit valori devono essere calcolati rispetto al prezzo di apertura ordine
pendente.
In questi esempi, useremo la variabile PendingPrice per il nostro prezzo ordine pendente. Può essere calcolato sulla base della nostra algoritmo di
Per un ordine di acquisto di arresto, PendingPrice deve essere superiore alla corrente Chiedi prezzo. Si suppone che
BuyStopLoss e BuyTakeProfit sono stati correttamente calcolati rispetto al PendingPrice. Ecco un esempio di un collocamento buy
ordine di arresto:
Si noti che usiamo OP_BUYSTOP per indicare un ordine di stop buy, e PendingPrice per il nostro prezzo di apertura ordine. Non c'è tempo di
Per un ordine sell stop, PendingPrice deve essere inferiore al prezzo di offerta corrente. In questo esempio, aggiungeremo un tempo di
scadenza ordine, usando la variabile Scadenza. Il tempo di scadenza deve essere superiore al tempo corrente del server. Ecco un esempio di
Gli ordini limite sono simili a fermare gli ordini, salvo che il prezzo ordine pendente è invertito, rispetto al prezzo corrente e il tipo di ordine. Per
gli ordini di acquisto limite, il prezzo ordine in corso deve essere inferiore al prezzo di offerta corrente. Ecco un esempio di un ordine di acquisto
limite:
24
Predisporre un ordine
Si noti che abbiamo usato OP_BUYLIMIT per indicare un ordine di acquisto limite. In caso contrario, i nostri parametri sono identici a quelli per gli ordini di arresto.
Per un ordine sell limit, il prezzo ordine in corso deve essere maggiore della corrente Chiedi prezzo. Ecco un esempio di un ordine sell
limit:
Ci sono diversi modi per calcolare stop loss e prendere i prezzi di profitto. Il metodo più comune è quello di specificare il numero di pips di
distanza dal prezzo di apertura al fine di inserire il vostro arresto. Per esempio, se abbiamo un ambiente stop loss di 50 pips, che significa che
il prezzo stop loss sarà 50 pips di distanza dal nostro prezzo di apertura ordine.
Possiamo anche utilizzare un valore indicatore, un parametro esterno o qualche altro tipo di calcolo prezzo. Tutti abbiamo bisogno di fare è quindi
Calcolo in Pips
Per questo, il metodo più comune di calcolo fermate, useremo una variabile esterna in cui l'utente specifica il numero di semi
per la stop loss e prendere profitto. Abbiamo poi calcoliamo le fermate rispetto al prezzo di apertura ordine.
Per ordini di mercato comprare, il prezzo di apertura sarà il Chiedere, e per gli ordini di mercato vendita, il prezzo di apertura sarà il Offerta. Per
in attesa di stop e limitare gli ordini, assegniamo aa prezzo di apertura valido che è qualcosa di diverso dal prezzo corrente di mercato.
OpenPrice.
Qui ci sono le variabili esterne useremo per il nostro stop loss e prendere profitto impostazioni:
25
E XPERT UN dvisor P ROGRAMMAZIONE
In questo esempio, siamo entrati in uno stop loss di 50 pips, e un take profit di 100 pip. Probabilmente avete visto impostazioni simili a
questi in gli EA che hai usato.
Per calcolare il nostro stop loss, abbiamo bisogno di aggiungere o sottrarre 50 pips dal nostro prezzo di apertura ordine. In primo luogo, abbiamo bisogno
di convertire il valore intero di 50 al valore frazionario useremo per aggiungere o sottrarre dal prezzo di apertura. Per accoppiamenti di Yen, 50 pip è pari a
Per convertire un intero al valore frazionario del caso, abbiamo bisogno di moltiplicare la nostra esterna StopLoss
Punto
Punto è una variabile predefinita in MQL che restituisce la più piccola unità prezzo di una valuta, a seconda del numero di cifre decimali.
Per una coppia di valute posto 4 decimale, il punto è 0,0001. Per una coppia Yen, è 0,01.
Calcoliamo lo stop loss per un ordine di acquisto di mercato. Vi verrà assegnato l'attuale proposta in vendita a OpenPrice,
e l'uso che come il nostro prezzo di apertura ordine. Noi controlleremo per vedere se la nostra StopLoss impostazione è maggiore di zero. Se è
così, ci moltiplichiamo il StopLoss dal Punto. Poi ci sottraiamo che dal OpenPrice. Il risultato sarà memorizzato nella variabile BuyStopLoss.
if (StopLoss> 0) doppia BuyStopLoss = OpenPrice - (StopLoss * Point); // 1,4600 - (50 * 0,0001) = 1,4550
Se StopLoss non è maggiore di zero, allora BuyStopLoss viene inizializzato con un valore di 0, e nessuna perdita di arresto viene montata
con l'ordine. Supponendo che Punto è pari a 0,0001, se il prezzo di apertura ordine è 1.4600, e il nostro stop loss è di 50 pips, allora il
prezzo stop loss per l'ordine di acquisto sarà 1,4600 (0,0050) = 1,4550.
Recentemente, molti broker sono state muovendo verso preventivi pip frazionali, con 3 cifre decimali per le coppie di yen e 5 cifre decimali
per tutte le altre coppie. Se il nostro mediatore usa citazioni pip frazionali, quindi nel nostro esempio precedente, Punto sarebbe pari a
0,00001.
Se si usa un valore punto di 0,00001 nell'esempio calcolo stop loss sopra, lo stop loss sarebbe calcolato come 5 pip dal prezzo di
apertura, invece di 50 pip. Questo pone un problema. Per ottenere il valore corretto, avremmo dovuto aggiungere uno zero in più al
nostro ambiente stop loss - vale a dire StopLoss = 500.
Invece di richiedere all'utente di aggiungere uno zero supplementare per il loro stop loss e prendere le impostazioni di profitto ogni volta che il commercio
su una frazione broker di pip, creeremo una funzione che restituisce sempre 0,01 o 0,0001,
26
Predisporre un ordine
a prescindere dal fatto che il broker utilizza pip frazionali. Chiameremo questa funzione PipPoint,
perché sarà sempre restituire il valore del punto che è uguale a un pip.
L'argomento stringa Moneta è il simbolo della coppia di valute che vogliamo recuperare il punto di partenza per. Il MarketInfo () funzione
con la MODE_DIGITS parametro restituisce il numero di cifre decimali (cifre) per quella coppia. Il se altro istruzione assegna il
valore del punto appropriato al
CalcPoint variabile, a seconda del numero di cifre.
Ecco un esempio di utilizzo di questa funzione. Si prevede di utilizzare il grafico corrente accoppiare la stragrande maggioranza del
tempo, in modo da passerà il Simbolo() funzione come argomento. Ciò restituirà il punto per il grafico corrente.
Useremo questa funzione per trovare il valore del punto pip unico per il resto di questo libro. Come abbiamo dimostrato, il Punto variabile
non funzionerà correttamente sui broker pip frazionari nel calcolo del valore di un singolo pip. Non si può mai supporre che l'EA sarà
usato solo su un broker 2 e 4 cifre, quindi è necessario determinare automaticamente il valore del punto di un singolo pip usando
PipPoint ().
Slittamento e Point
Facciamo divagando per un minuto e creare una funzione per ridimensionare il parametro di slittamento corretto. Come accennato in precedenza
in questo capitolo, su un broker con le citazioni pip frazionari, il parametro di slittamento per la OrderSend () funzione dovrà essere aumentata di un
27
E XPERT UN dvisor P ROGRAMMAZIONE
Questa funzione imposta automaticamente il parametro slittamento al numero di punti specificato dal esterna slittamento parametro:
Passiamo il simbolo di valuta e il parametro slittamento esterno come argomenti. Se la valuta usa 2 o 4 cifre citazioni, usiamo il
invariata SlippagePips argomento come la nostra impostazione di slittamento. Se la valuta utilizza 3 o 5 preventivi cifre, moltiplichiamo SlippagePips
per 10. Ecco come si usa questa funzione in OrderSend ():
// Predisporre un ordine
OrderSend (Simbolo (), OP_BUY, Misura di lotto, Ask, GetSlippage (Simbolo (), lo slittamento), BuyStopLoss,
BuyTakeProfit, "Buy Order", MagicNumber, 0, verde);
Lo slittamento in questo esempio sarà di 5 pips, e il parametro lo slittamento sarà regolata automaticamente in base al numero di
cifre del preventivo valuta.
Lo svantaggio di usare una funzione per restituire il punto o il valore slittamento è la tipizzazione più richiesto per gli argomenti della funzione.
Creeremo le variabili globali che conterranno i valori del punto e slittamento appropriate per la nostra coppia di valute, e useremo quelle in qualsiasi
Dal momento che questi valori non cambieranno mai durante l'esecuzione del programma ed calcolare questi valori nella
dentro() funzione. Supponiamo che la variabile intera esterna slittamento è già presente:
int init ()
{UsePoint = PipPoint (Simbolo ());
28
Predisporre un ordine
D'ora in poi, useremo UsePoint e UseSlippage fare riferimento a questi valori. Il codice di cui sopra presuppone che il EA sta
mettendo ordini in una sola valuta. Questo sarà il caso il 98% del tempo, ma se si sta creando un consulente esperto che pone
gli ordini su più valute (o su una valuta diversa dalla tabella corrente), è necessario utilizzare il PipPoint () e GetSlippage () funzioni
ogni volta che è necessario calcolare questi valori.
MarketInfo ()
Abbiamo usato il MarketInfo () funzione di cui sopra per recuperare il valore Point e il numero di cifre del preventivo valuta. Il MarketInfo
() funzione ha molti usi, e verrà utilizzato per recuperare le informazioni di prezzo necessario nei vostri programmi. Ecco la
Il Simbolo argomento è semplicemente il simbolo di valuta che si desidera recuperare le informazioni relative. Per il simbolo grafico corrente,
la Simbolo() funzione può essere utilizzata. Per gli altri simboli, è necessario specificare il simbolo di valuta, come ad esempio EURJPY.
Tipo di richiesta è una costante intera, che rappresenta le informazioni che si richiede dalla funzione. Ecco un elenco dei più utili MarketInfo
() costanti. Un elenco completo può essere trovato nel MQL di riferimento, sotto Costanti standard - MarketInfo.
• MODE_DIGITS - Il numero di cifre decimali del prezzo. Saranno 2 o 3 per accoppiamenti di Yen e 4 o 5 per tutte le altre coppie.
Questi identificatori di richiesta sono generalmente utilizzati durante il controllo i prezzi in un'altra valuta, o dovunque dove il
simbolo può essere altro che il simbolo grafico corrente:
29
E XPERT UN dvisor P ROGRAMMAZIONE
Ora che abbiamo stabilito il valore del punto corretto, è il momento di calcolare il nostro stop loss. Per ordini di acquisto, lo stop loss sarà al di sotto
del prezzo di apertura ordine, e per ordini di vendita, lo stop loss sarà al di sopra del prezzo di apertura ordine.
Ecco il nostro calcolo stop loss ordine di acquisto da prima, con la UsePoint variabili aggiunto. Si noti che abbiamo assegnato il Chiedere
prezzo al OpenPrice variabile:
Ed ecco il calcolo per un ordine di vendita. Si noti che abbiamo assegnato il Offerta prezzo da OpenPrice, e che stiamo semplicemente
Per gli ordini in attesa, lo stop loss sarà calcolato in relazione al prezzo ordine pendente. In questo caso, utilizzare la variabile OpenPrice per
memorizzare il prezzo ordine in attesa invece del prezzo corrente di mercato. La logica sarà identico agli esempi precedenti.
Il calcolo del prezzo take profit è simile al calcolo della perdita di arresto, ad eccezione saremo invertendo addizione e sottrazione. Per un
ordine di acquisto, il prezzo take profit sarà al di sopra del prezzo di apertura ordine, e per un ordine di vendita, il prezzo di take profit sarà al
di sotto del prezzo di apertura ordine. Si suppone che il prezzo appropriato è stato assegnato a OpenPrice:
Ci sono altri modi di determinare stop loss e prendere i prezzi di profitto. Ad esempio, un recente, o un valore alto o basso indicatore potrebbe
essere utilizzato per determinare una perdita di arresto. Cerchiamo di dimostrare come si possa calcolare questi.
30
Predisporre un ordine
Diciamo che stiamo usando un sistema commerciale che pone lo stop loss 2 pips al di sotto del minimo della barra corrente. Usiamo la matrice
prezzo predefinito Basso[] per recuperare il basso di un bar. Basso [0] è il basso della barra corrente, Basso [1] è il minimo della barra precedente,
e così via.
Una volta che abbiamo determinato il minimo della barra corrente, si moltiplica 2 per UsePoint per ottenere un valore decimale, e sottrarre che dal nostro
basso:
Quindi, se il minimo della barra è 1,4760, lo stop loss sarà collocato a 1,4758.
Ma forse si vuole inserire il vostro stop loss al basso più basso degli ultimi X numero di barre. C'è una funzione incorporata in MetaTrader solo
per questo. iLowest () restituisce il valore di spostamento che indica il bar con il valore più basso in un intervallo di tempo specificato. Possiamo
Ecco un esempio di come useremmo iLowest () per trovare il basso più basso degli ultimi 10 bar:
Il primo parametro di iLowest () è il simbolo di valuta - NULLO significa che stiamo usando il simbolo corrente. Molte funzioni in MQL
utilizzare la stringa costante NULLO per riferirsi al simbolo grafico corrente. Il secondo parametro è il periodo del grafico - 0 si riferisce al
telaio grafico corrente.
MODE_LOW è una costante intera che specifica il basso matrice serie di prezzi. In altre parole, stiamo cercando per il basso più
basso degli ultimi CountBars. Se volessimo trovare il vicino più basso, ad esempio, useremmo MODE_CLOSE. Potete trovare tutte le
costanti serie matrice nella Reference MQL sotto
Costanti standard - array.
CountBars è il numero di barre che vogliamo cercare, in questo caso 10. Infine, l'ultimo parametro è il nostro luogo di partenza. 0 è la barra
corrente. Per iniziare ad una barra precedente, contando a partire dalla barra corrente
L'uscita del iLowest () funzione è un intero che indica lo spostamento all'indietro della barra con il valore più basso nella serie prezzo.
Nell'esempio di cui sopra, se iLowest () restituisce un 6, che significa che il basso più basso è di 6 bar indietro. Memorizziamo questo valore nella
variabile LowestShift. Per trovare il prezzo effettivo, abbiamo semplicemente recuperare il valore del prezzo di Basso [LowestShift], o in altre
31
E XPERT UN dvisor P ROGRAMMAZIONE
Se si voleva calcolare uno stop loss per un ordine di vendita con questo metodo, il iHighest () la funzione funziona allo stesso modo.
Riferimento al precedente esempio, si usa MODE_HIGH per il parametro serie array.
Ecco un esempio mediante un indicatore. Diciamo che abbiamo una media mobile, e vogliamo utilizzare la linea di media mobile come il nostro
stop loss. Useremo la variabile MA per rappresentare il valore di media mobile per la barra corrente. Tutto quello che devi fare è assegnare il
Se la linea di media mobile è attualmente a 1,6894, che poi sarà il nostro stop loss.
Questi sono semplicemente i metodi più comuni di determinare uno stop loss o prendere prezzo profitto. Altri metodi possono essere sviluppate
Una volta che abbiamo messo con successo un ordine, abbiamo bisogno di recuperare alcune informazioni circa l'ordine se vogliamo
modificare o chiudere. Lo facciamo con il OrderSelect () funzione. Usare OrderSelect (),
siamo in grado di utilizzare il numero del biglietto del ordine, o possibile scorrere il pool di ordini aperti e selezionare ciascuno di essi in
ordine.
Una volta che abbiamo selezionato un ordine utilizzando OrderSelect (), siamo in grado di utilizzare una serie di funzioni di informazione al fine di restituire
informazioni circa l'ordine, compreso lo stop loss corrente, prendere profitto, ordine prezzo di apertura, prezzo di chiusura e altro ancora.
OrderSelect ()
• Indice - Questo è sia il numero del biglietto dell'ordine che vogliamo selezionare, o la posizione in piscina ordine. Il Selezionare
parametro indica quale di questi stiamo usando.
• Selezionare - Una costante che indica se la Indice parametro è un numero di biglietti o un pool position ordine:
32
Predisporre un ordine
• Piscina - Un costante opzionale che indica la piscina ordine: sospeso / ordini aperti, o ordini chiusi.
◦ MODE_TRADES - Per impostazione predefinita, stiamo esaminando il pool degli ordini attualmente aperte.
Se la OrderSelect () la funzione localizza l'ordine con successo, il valore di ritorno sarà vero,
in caso contrario, il valore restituito sarà falsa.
Ecco un esempio di OrderSelect () funzione con un numero di biglietto di ordine. Il Biglietto variabile deve contenere un biglietto di
ordine valido:
Dopo il OrderSelect () la funzione è stata chiamata, possiamo usare una qualsiasi delle funzioni di informazione al fine di recuperare le informazioni
relative a tale ordine. Un elenco completo di funzioni che possono essere utilizzati con
OrderSelect () si possono trovare nella Guida di riferimento sotto MQL Funzioni di Trading. Ecco un elenco delle funzioni di informazione ordine più
comunemente usati:
• OrderSymbol () - Il simbolo dello strumento che l'ordine selezionato è stato immesso sul.
• OrderType () - Il tipo di ordine dell'ordine selezionato: compravendita; mercato, stop o limite. Il valore di ritorno è un numero
• OrderTicket () - Il numero del biglietto dell'ordine selezionato. Generalmente utilizzato quando in bicicletta attraverso il pool
• OrderMagicNumber () - Il numero magico di ordine selezionato. Quando in bicicletta attraverso gli ordini, è necessario utilizzare
• OrderComment () - Il commento che è stato posto con l'ordine. Questo può essere usato come un identificatore di ordine
secondario.
• OrderClosePrice () - Il prezzo del ordine selezionato di chiusura. L'ordine deve essere già chiusa ( vale a dire presenti nel pool
33
E XPERT UN dvisor P ROGRAMMAZIONE
Avremo bisogno di usare OrderSelect () prima di chiudere o modificare un ordine. Illustriamo come usiamo
OrderSelect () per chiudere un ordine.
Quando chiudiamo un ordine di mercato, stiamo uscendo il commercio al prezzo di mercato corrente. Per ordini di acquisto, chiudiamo al prezzo di offerta, e
per ordini di vendita, chiudiamo alla chiedere. Per gli ordini in attesa, abbiamo semplicemente cancellare l'ordine dalla piscina commercio.
OrderClose ()
bool OrderClose (int Biglietto, Doppio Molte, Doppio Prezzo, int slittamento, colore Freccia);
• Molte - Il numero di lotti per chiudere. La maggior parte broker consentono chiude parziali.
• Prezzo - Il prezzo preferito al quale per chiudere il commercio. Per ordini di acquisto, questo sarà il prezzo di offerta corrente, e
• Colore - Una costante di colore per la freccia di chiusura. Se nessun colore è indicato, nessuna freccia verrà disegnata.
È possibile chiudere parte di un commercio specificando una dimensione parziale molto. Ad esempio, se avete un commercio aperto con una dimensione del lotto
di 2,00, e si desidera chiudere la metà del commercio, quindi specificare 1 lotto per la Molte
È consigliabile che se avete bisogno di chiudere una posizione in più parti, è necessario posizionare ordini multipli invece di fare chiude
parziali. Utilizzando l'esempio precedente, si potrebbe inserire due ordini di 1,00 sacco ciascuna, quindi è sufficiente chiudere uno degli
ordini quando si vuole chiudere la metà della posizione. In questo libro, ci sarà sempre di chiusura l'ordine completo.
34
Predisporre un ordine
Il CloseTicket variabile è il numero del biglietto d'ordine che vogliamo chiudere. Il OrderSelect ()
funzione seleziona l'ordine, e ci permette di recuperare le informazioni di ordine. Noi usiamo
OrderCloseTime () controllare l'ordine temporale di chiusura per vedere se l'ordine è già stato chiuso. Se
OrderCloseTime () restituisce 0, allora sappiamo che l'ordine non è stato ancora chiuso.
Dobbiamo anche controllare il tipo di ordine, in quanto il tipo ordine determina la chiusura per l'ordine. Il OrderType () restituisce un
intero che indica il tipo di ordine. Se si tratta di un ordine di acquisto di mercato, indicato da OP_BUY, continueremo chiudere l'ordine.
Avanti, recuperiamo la dimensione ordine molto con OrderLots (), e memorizzare tale valore in CloseLots. Assegniamo la corrente Offerta prezzo
Si precisa impostazione la nostra Unità con UseSlippage, e indicare un Rosso freccia da stampare sulla carta. Un valore restituito
booleano viene memorizzato nella variabile Chiuso. Se l'ordine è stato chiuso con successo, il valore di Chiuso sarà vero, altrimenti falsa.
Per chiudere un ordine di mercato vendere, tutto quello che dovete fare è cambiare il tipo di ordine per OP_SELL e assegnare l'attuale Chiedere prezzo da ClosePrice:
OrderDelete ()
C'è una funzione separata per la chiusura di ordini pendenti. OrderDelete () ha due argomenti, il numero del biglietto e la freccia di colore. Non è richiesta
alcuna prezzo di chiusura, la dimensione del lotto o di slittamento. Ecco il codice per chiudere un ordine di acquisto di arresto in attesa:
35
E XPERT UN dvisor P ROGRAMMAZIONE
Come abbiamo fatto con il OrderClose () funzione di cui sopra, abbiamo bisogno di controllare il tipo di ordine per essere sicuri che si tratta di un ordine
OP_SELLLIMIT. Per chiudere altri tipi di ordini in sospeso, è sufficiente modificare il tipo di ordine.
Se l'ordine è stato riempito, allora è ora un ordine di mercato, e deve essere chiuso mediante OrderClose ()
anziché.
Vediamo come il codice che abbiamo discusso finora funzionerebbe in un consulente esperto. Questo è un sistema semplice croce media
mobile. Un ordine di acquisto viene aperto quando la media mobile a 10 periodo è maggiore della media mobile a 20 periodo. Quando la
media mobile a 10 periodo è inferiore al periodo di 20 media mobile, un ordine di vendita viene aperto.
Questo EA si alterneranno tra l'apertura acquisto e in vendita. Ordini verranno chiuse quando un ordine aperto nella
direzione opposta, o stop loss o prendere profitto. Useremo le variabili globali
Comprare un biglietto e SellTicket per memorizzare l'ultimo biglietto ordine. Quando un nuovo ordine aperto, l'ultimo biglietto ordine è
36
Predisporre un ordine
// Acquistare ordine
if (FastMA> SlowMA && BuyTicket == 0)
{OrderSelect (SellTicket, SELECT_BY_TICKET);
// Chiudi ordine
if (OrderCloseTime () == 0 && SellTicket> 0)
{doppie CloseLots = OrderLots ();
SellTicket = 0; }
// Sell Order
if (FastMA <SlowMA && SellTicket == 0)
{OrderSelect (BuyTicket, SELECT_BY_TICKET);
37
E XPERT UN dvisor P ROGRAMMAZIONE
ClosePrice = Bid;
OpenPrice = Bid;
if (StopLoss> 0) doppia SellStopLoss = OpenPrice + (StopLoss * UsePoint); if (TakeProfit> 0) doppia SellTakeProfit = OpenPrice -
(TakeProfit * UsePoint);
BuyTicket = 0; }
ritorno (0); }
Si comincia con il nostro # protette da copyright direttiva del preprocessore che identifica il codice come appartenenti a noi. Le variabili esterne sono
SellTicket come variabili globali - in questo modo il biglietto ordine memorizzato tra le esecuzioni di programma. Potremmo anche li abbiamo
Noi aggiungiamo UsePoint e UseSlippage come variabili globali - ci calcolare il valore di questi prossimi. Nostro
dentro() funzione viene eseguito per primo. Chiamiamo il PipPoint () e GetSlippage () funzioni (dichiarati al
38
Predisporre un ordine
fine del file) e assegnare i valori di ritorno per le nostre variabili globali. Useremo questi valori in virgola o slittamento quando si fa
Successivo è il inizio() la funzione, la nostra esecuzione del programma principale. Abbiamo lasciato fuori deinit (), dal momento che non abbiamo alcun uso
per esso qui. Il io sono un() funzione calcola la media mobile L' FastMA variabile contiene la nostra media mobile a 10 periodo, che viene impostato utilizzando
il FastMAPeriod variabile. Il SlowMA variabile è il nostro 20 periodo media mobile, impostata mediante SlowMAPeriod. Tutto il resto è impostato sul valore
predefinito (un no spostamento, media mobile semplice calcolata sul prezzo di chiusura).
Noi usiamo il Se all'operatore di definire le nostre condizioni di apertura ordine. Se l'attuale periodo di 10 media mobile (la FastMA) è
maggiore del periodo di 20 media mobile (la SlowMA), e se Comprare un biglietto
è uguale a 0, si aprirà un ordine di acquisto.
Prima di aprire l'ordine di acquisto, chiuderemo l'ordine di vendita corrente, se esiste. Noi usiamo OrderSelect ()
per recuperare la corrente SellTicket. Se l'ordine vicino ora è 0 (che indica che l'ordine non è ancora stato chiuso), e SellTicket è
maggiore di 0 (che indica che il SellTicket è probabile valido), andremo avanti e chiudere l'ordine di vendita. Recuperiamo la
dimensione del lotto di ordine di vendita e la corrente
Chiedere prezzo, che sarà il prezzo di chiusura per l'ordine di vendita. Poi, chiudiamo l'ordine di vendita utilizzando
OrderClose ().
Successivamente, si assegna l'attuale Chiedere prezzo al OpenPrice variabili - questo sarà il prezzo del nostro ordine di acquisto di apertura. Calcoliamo
il nostro stop loss e take profit rispetto al prezzo di apertura, controllando prima per assicurarsi che abbiamo specificato un StopLoss o Avere un profitto il
valore nelle impostazioni. Poi, abbiamo posto l'ordine utilizzando il OrderSend () la funzione, e conservare il biglietto in ordine Comprare un biglietto. Infine,
abbiamo chiaro il valore di SellTicket, permettendo il posizionamento di un altro ordine di vendita quando la condizione di ordine diventa valido.
Il blocco di ordine di vendita segue la stessa logica del blocco di ordine di acquisto. Chiudiamo l'ordine di acquisto prima, e utilizzare il Offerta come
il OpenPrice e l'ordine di acquisto ClosePrice. Lo stop loss e prendere i calcoli di profitto sono invertiti.
Il inizio() funzione termina con un ritorno operatore. Il nostro personalizzato PipPoint () e GetSlippage ()
funzioni sono definite alla fine dopo la inizio() funzione. Noi includere queste funzioni in tutti gli esempi in questo libro.
Andiamo a modificare il nostro EA di utilizzare ordini pendenti. Useremo ordini di arresto in questo esempio. Quando la media in rapido movimento
è superiore alla media in movimento lento, ci sarà posto un ordine di stop buy 10 pips
39
E XPERT UN dvisor P ROGRAMMAZIONE
sopra la corrente elevata. Quando è vero il contrario, avremo posto un ordine sell stop 10 pips al di sotto della bassa corrente. Facciamo dichiarare
Stiamo aggiungendo il OrderDelete () funzione per il nostro acquisto e ordine di vendita blocco per chiudere gli ordini in sospeso non riempiti.
Dobbiamo controllare il tipo di ordine di ordine indicato dalla SellTicket per garantire che stiamo usando la funzione corretta per chiudere
l'ordine.
// Chiudi Ordina
if (OrderCloseTime () == 0 && SellTicket> 0 && OrderType () == OP_SELL)
{doppie CloseLots = OrderLots ();
bool Chiuso = OrderClose (SellTicket, CloseLots, ClosePrice, UseSlippage, Rosso); se (== Closed vero) SellTicket = 0; }
// Delete Order
altro if (OrderCloseTime () == 0 && SellTicket> 0 && OrderType () == OP_SELLSTOP)
{Bool Deleted = OrderDelete (SellTicket, Rosso);
Noi usiamo OrderType () per verificare se l'ordine di vendita selezionato è un ordine di mercato o di un ordine di arresto. Se si tratta di un ordine di mercato,
OrderDelete ().
Ecco la nostra attesa di calcolo del prezzo ordine. Abbiamo semplicemente convertire PendingPips ad un valore frazionario con
UsePoint, e aggiungerlo alla corrente Vicino prezzo. Ci memorizzare questo valore nel PendingPrice variabile. Successivamente, si calcola lo stop loss e
take profit rispetto al nostro prezzo di ordine in attesa. Infine, abbiamo posto il nostro ordine in attesa utilizzando OrderSend (), memorizzare il risultato
40
Predisporre un ordine
SellTicket = 0;
// Chiudi Ordina
if (OrderCloseTime () == 0 && BuyTicket> 0 && OrderType () == OP_BUY)
{CloseLots = OrderLots ();
ClosePrice = Offerta;
Chiuso = OrderClose ( Comprare un biglietto, CloseLots, ClosePrice, UseSlippage, Rosso); se (== Closed vero) BuyTicket
= 0; }
// Delete Order
else if (OrderCloseTime () == 0 && BuyTicket> 0 && OrderType () == OP_BUYSTOP)
{Chiuso = OrderDelete ( Comprare un biglietto, Rosso);
BuyTicket = 0;
41
E XPERT UN dvisor P ROGRAMMAZIONE
capitolo 3
Avanzata Ordine Placement
ECN Compatibilità
Come dimostrano gli esempi di collocamento ordine nell'ultimo capitolo spettacolo, il metodo di default di mettere uno stop loss e take profit con un ordine di
mercato è quello di mettere loro utilizzando il OrderSend () funzione. Anche se questo funziona bene per la maggior parte dei broker, il broker ECN / STP più
In questo caso, abbiamo bisogno di mettere lo stop loss e take profit dopo che l'ordine è stato collocato, utilizzando il OrderModify () funzione.
Questo vale solo per ordini di mercato - per gli ordini in corso, è ancora possibile posizionare lo stop loss e take profit con la OrderSend
() funzione.
Ordinare modifica
Dopo aver effettuato un ordine, è possibile modificare il take profit, stop loss, in attesa di prezzo dell'ordine o alla scadenza momento tramite
il OrderModify () funzione. Usare OrderModify (), avremo bisogno del numero del biglietto dell'ordine che vogliamo modificare. Ecco la sintassi
bool OrderModify (int Biglietto, Doppio Prezzo, Doppio StopLoss, Doppio Avere un profitto,
appuntamento Scadenza, colore freccia = CLR_NONE)
• Freccia - Un colore opzionale per la freccia per indicare un ordine modificato. Se non indicato, non verrà visualizzata alcuna
freccia.
Se la modifica ordine è riuscita, OrderModify () restituirà un valore booleano vero. Se la modifica dell'ordine non è riuscita, il
valore restituito sarà falsa.
42
Avanzata Ordine Placement
Quando si modificano ordini, dobbiamo essere sicuri che i valori stiamo passando alla funzione sono valide. Ad esempio, l'ordine deve essere
ancora aperta - non possiamo modificare un ordine chiuso. Quando si modifica ordini pendenti con il Prezzo parametro, l'ordine non deve aver già
Il prezzo dell'ordine modificato, inoltre, non deve essere troppo vicino alla corrente Bid o Richiedi prezzo. Dobbiamo anche controllare per
assicurarsi che lo stop loss e take profit sono validi. Siamo in grado di farlo usando le routine di verifica dei prezzi che tratteremo più avanti in
questo capitolo.
prezzo dell'ordine attuale e prendere profitto utilizzando OrderSelect () , e trasmettere quei valori al OrderModify () funzione.
Se si tenta di modificare un ordine senza specificare eventuali valori modificati, si otterrà un errore 1: "nessun risultato". È necessario
verificare il motivo per cui il codice sta passando valori invariati alla funzione, ma per il resto questo errore è innocuo e può essere
ignorato.
In primo luogo, abbiamo bisogno di verificare che l'ordine è stato posizionato correttamente. Facciamo questo esaminando il valore di ritorno della OrderSend
() la funzione, che è il numero del biglietto d'ordine che è stato appena messo. Se l'ordine non è stato posto a causa di una condizione di errore, il
Successivamente, si usa il OrderSelect () funzione per recuperare le informazioni per l'ordine che è stato appena messo.
Useremo il OrderOpenPrice (), OrderTakeProfit (), OrderStopLoss () e facoltativamente il OrderExpiration () funzioni quando
passate valori invariati al OrderModify () funzione. Infine, useremo OrderModify () aggiungere lo stop loss e take profit per
l'ordine.
Ecco un esempio in cui abbiamo impostato lo stop loss e take profit per un ordine di acquisto utilizzando il
OrderModify () funzione. Abbiamo spostato lo stop loss e prendere profitto dopo il calcolo
OrderSend () funzione, in modo che esso viene calcolato prima di modificare l'ordine:
int BuyTicket = OrderSend (Simbolo (), OP_BUY, Misura di lotto, Ask, UseSlippage, 0,0,
"Buy Order", MagicNumber, 0, verde);
if (BuyTicket> 0)
{OrderSelect (BuyTicket, SELECT_BY_TICKET);
43
E XPERT UN dvisor P ROGRAMMAZIONE
if (BuyStopLoss> 0 || BuyTakeProfit> 0)
{Bool TicketMod = OrderModify (BuyTicket, OrderOpenPrice (), BuyStopLoss,
BuyTakeProfit, 0); }}
Il OrderSend () funzione è identica a nostro esempio precedente, tranne che usiamo un valore pari a 0 per la stop loss e prendere i parametri di
profitto. Un valore di zero indica che non v'è alcuna perdita di arresto o prendere profitto viene montata con l'ordine. Il Comprare un biglietto negozi
Usiamo un Se dichiarazione per verificare che il Comprare un biglietto numero è valido - vale a dire maggiore di zero. Se è così, che noi chiamiamo il OrderSelect
() funzione che utilizza il nostro Comprare un biglietto numero. Recuperiamo il prezzo di apertura per l'ordine utilizzando OrderOpenPrice (), e assegnare che
al OpenPrice variabile.
Successivamente, si calcola lo stop loss e take profit, rispetto al prezzo dell 'ordine che abbiamo appena messo apertura. Controlliamo
prima per vedere se la StopLoss e Avere un profitto variabili esterne sono maggiori di zero. Se è così, si calcola il nuovo stop loss e / o
Infine, noi chiamiamo il OrderModify () funzione per aggiungere il nostro stop loss e take profit per l'ordine. Controlliamo prima per
assicurarsi che il BuyStopLoss o BuyTakeProfit le variabili sono qualcosa di diverso da zero. Se tentiamo di modificare l'ordine con i
valori invariati, otterremo un codice di errore 1 dal
OrderModify () funzione.
Il primo parametro per OrderModify () è nostro Comprare un biglietto numero. Potremmo anche utilizzare OrderTicket ()
anche. Il secondo parametro è il nuovo prezzo dell'ordine. Dal momento che non stiamo modificando il prezzo di ordine, usiamo il OrderOpenPrice
() funzione, per indicare che il prezzo ordine è invariato.
Ricorda che noi possiamo solo modificare i prezzi di ordine per gli ordini in sospeso. Se stiamo modificando un ordine di mercato, possiamo passare
qualsiasi valore per il Prezzo parametro, dal momento che non è possibile modificare il prezzo ordine di un ordine di mercato. Ma non possiamo pensare
che saremo sempre a modificare le ordini di mercato, così saremo sempre usare OrderOpenPrice ().
Il BuyStopLoss e BuyTakeProfit variabili passano lo stop loss cambiato e assumono valori di profitto al OrderModify () funzione. Se si pensa
di utilizzare i tempi ordine di scadenza per i vostri ordini in sospeso, è possibile utilizzare OrderExpiration () come parametro di scadenza
invariato. In caso contrario, basta usare 0.
Anche se questo metodo aggiunge un paio di passi in più, si consiglia di utilizzare questo metodo di mettere stop loss e prendere i profitti per
gli ordini di mercato nei vostri consulenti esperti per assicurare che essi sono compatibili con tutti i broker. Questo metodo ha anche il
vantaggio di che ci permette di mettere stop loss accurati e prendere i prezzi di profitto senza gli effetti di slittamento.
44
Avanzata Ordine Placement
OrderModify () può anche essere utilizzato per modificare il prezzo ordine di un ordine pendente. Se il prezzo ordine in attesa è già stato
colpito e l'ordine è stato riempito, non è più un ordine pendente, e il prezzo non può essere modificato.
Useremo la variabile NewPendingPrice a rappresentare il nostro prezzo ordine modificato. Si suppone che il prezzo è già stato calcolato
ed è valida. Ecco come modifichiamo un prezzo ordine pendente:
Come sempre, recuperiamo le informazioni di ordine usando OrderSelect (). In questo modo siamo in grado di passare lo stop loss invariato
e prendere i prezzi di profitto al OrderModify () funzione. Prima di modificare l'ordine, controlleremo fare in modo che il nostro nuovo prezzo
Per OrderModify (), specifichiamo il nostro biglietto ordine, il nuovo prezzo ordine memorizzato in NewPendingPrice,
Stop loss, take profit e in attesa di prezzi di ordine deve essere una distanza minima dalla offerta e chiedere i prezzi. Se un arresto o il
prezzo ordine pendente è troppo vicino al prezzo corrente, verrà generato un errore, e l'ordine non verrà inserito. Questo è uno degli
errori più comuni di trading, e può essere facilmente evitato se il commerciante è attento a impostare le loro fermate e gli ordini in attesa
di una distanza sufficiente dal prezzo.
Ma durante periodi di rapido movimento dei prezzi, validi prezzi stop loss possono essere effettuate valido allargando spread. Diversi broker
hanno diversi livelli di arresto, in modo da uno stop loss che è valida su un broker può essere troppo vicino per un altro. Alcuni sistemi di trading
saranno impostare fermate e prezzi di ordine in attesa sulla base di valori degli indicatori, alti o bassi, o qualche altro metodo di calcolo in cui una
45
E XPERT UN dvisor P ROGRAMMAZIONE
Per queste ragioni, è sempre necessario verificare che uno stop loss, take profit o in attesa di prezzo dell'ordine è valido, e non troppo vicino al
prezzo corrente di mercato. Verifichiamo questo controllando la valuta del smettere di livello.
Livelli di stop
Il livello di arresto è il numero di pips di distanza dagli attuali bid o ask prezzo che tutte le fermate e gli ordini in sospeso devono essere collocati.
Per la maggior parte broker, il livello di arresto è di circa 3-4 pip. ECN broker hanno generalmente livelli di stop molto stretti, mentre altri mediatori
Figura 3.1 illustra i livelli di arresto in relazione ai prezzi. Pensate al prezzo di non essere Livello Livello di stop
solo un singolo valore (come il Bid), ma piuttosto una spessa linea la larghezza della
diffusione.
Chiedere
Su entrambi i lati di questa linea di prezzo sono limiti, indicati dai livelli di stop. Tutti stop
Diffusione
loss, take profit e ordini pendenti deve essere posto al di fuori di questi confini.
Offerta
Per una valuta a 4 cifre con un livello di arresto di 3 pips, il MarketInfo () funzione con MODE_STOPLEVEL
restituirà un 3. Per una moneta 5 cifre con un livello di stop di 3 pip, MarketInfo () restituirà 30, a causa della cifra decimale in più.
Ecco il codice per recuperare il livello di arresto e convertirlo in un valore decimale:
Si noti che usiamo il predefinito Punto variabile, invece della PipPoint () la funzione che abbiamo creato in precedenza. Questo perché
abbiamo bisogno di moltiplicare il livello di arresto per il valore punto reale. Per una valuta a 4 cifre, il Punto sarà 0,0001, e per una
moneta di 5 cifre, il Punto sarà 0,00001. Se il livello di arresto è 3 pip come dimostrato sopra, allora il valore frazionario sarà 0,0003.
Ora che abbiamo capito come trovare il livello di arresto, abbiamo bisogno di calcolare il valore minimo e massimo per il nostro stop
loss, take profit e prezzi ordine in attesa. Lo facciamo aggiungendo o sottraendo il livello di arresto dalla nostra attuale offerta e
chiedere i prezzi.
46
Avanzata Ordine Placement
Questo codice calcolerà il prezzo minimo consentito per un buy prendere profitto, vendere stop loss, comprare ordine di arresto, o vendere ordine limite.
Se il nostro Chiedere prezzo è 1.4650, e la StopLevel è 0.0003 pip calcolato sopra, allora il prezzo minimo livello di stop sarà 1,4653. Se stiamo
mettendo un take profit acquistare con questo ordine, allora deve essere di sopra di questo prezzo. Chiameremo questo il UpperStopLevel, dal
Questo codice calcolerà il prezzo massimo consentito per un take profit vendere, comprare stop loss, vendere ordine arrestare o vendere ordine limite. Si
noti che stiamo semplicemente usando il Offerta anziché la Chiedere, e sottraendo invece di aggiungere.
Chiameremo questo il LowerStopLevel, dal momento che è al di sotto del prezzo. Prima di effettuare un ordine, utilizzare il
UpperStopLevel e LowerStopLevel I valori sopra per verificare il tuo stop loss, take profit e prezzi ordine in attesa. Tenete a mente che i prezzi
possono cambiare rapidamente, e si vorrà vostri arresti effettivi, dei profitti e degli ordini in corso di essere ben al di fuori di questi livelli.
Il take profit minima in pips sarà pari al prezzo di apertura ordine, più o meno il livello di arresto. Se il livello di arresto è 3 pips, e il
prezzo di apertura ordine è 1,4500, il prezzo take profit per un ordine di acquisto dovrà essere al di sopra 1,4503.
La perdita minima sosta in pips per un ordine di mercato, però, includerà l'attuale diffusione, in modo che la perdita minima tappa sarà
maggiore del take profit minimo. Ad esempio, se il livello di arresto è 3 pips, lo spread è 2 pips, e il prezzo di apertura ordine è 1,4500,
lo stop loss per un ordine di mercato acquisto dovrà essere inferiore a 1,4495.
Ciò non vale per gli ordini in corso, in modo che quando la verifica uno stop loss per un ordine in corso, non è necessario per capire nella diffusione.
Quindi, se si sta posizionando un ordine pendente a 1.4500, e il livello di arresto è 3 pips, poi lo stop loss può essere posizionato ovunque al di sotto
1,4497.
Ecco un esempio in cui controlliamo lo stop loss e take profit per un ordine di acquisto per assicurarsi che i prezzi sono validi. Se lo stop loss o
prendere prezzo profitto non è valido, si regola automaticamente in modo che esso sia diversi pips al di fuori del livello di arresto.
47
E XPERT UN dvisor P ROGRAMMAZIONE
la variabile MinStop aggiunge o sottrae 5 pip dal livello di arresto, per garantire che i nostri prezzi convalidati non diventino validi a causa di
slittamento. È possibile regolare questo valore per imporre un livello di arresto / profitto minimo sufficiente, o anche utilizzare una variabile esterna
La seconda linea paragona il nostro stop loss al nostro LowerStopLevel. Se lo stop loss è più grande del nostro livello di battuta inferiore, sappiamo
che lo stop loss non è valido. In questo caso, abbiamo regolare lo stop loss di essere a pochi pips sotto il nostro livello di arresto. La terza linea fa la
Per controllare lo stop loss e take profit per un ordine di vendita, abbiamo semplicemente invertire i calcoli:
Invece di regolare automaticamente un prezzo non valida, si potrebbe anche visualizzare un messaggio di errore e interrompere l'esecuzione del
programma. In questo modo l'utente è tenuto a riadattare il loro stop loss o prendere profitto impostazione prima di continuare. Ecco un esempio di
if (BuyStopLoss> LowerStopLevel)
{Alert ( "L'impostazione di stop loss è troppo piccolo!");
ritorno (0); }
Se la perdita di arresto calcolata è superiore al livello di arresto, e quindi troppo vicino al prezzo, la Mettere in guardia()
la funzione verrà visualizzato un messaggio pop-up per l'utente. Il ritorno operatore esce dalla funzione corrente e assicura che
l'ordine non verrà inserito.
In questo libro, ci sarà la regolazione automatica dei prezzi non validi, con il presupposto che sia è meglio inserire un ordine corretto rispetto
di non mettere uno a tutti. Può essere utile per documentare quando questo accade stampando un messaggio al registro:
if (BuyStopLoss> LowerStopLevel)
{BuyStopLoss = LowerStopLevel - MinStop;
48
Avanzata Ordine Placement
Ecco come abbiamo verificare il prezzo ordine in attesa per un acquisto di arresto o vendiamo ordine limite. Il PendingPrice
Si noti che la logica qui è identico al codice di cui sopra che controlla il nostro take profit acquisto e in vendita di stop loss. Ed ecco il codice per
controllare il prezzo ordine in attesa per una sosta di vendere o comprare ordine limite:
Oltre a scegliere adatto stop loss e prendere livelli di profitto, utilizzando un formato molto appropriato è uno dei migliori strumenti di gestione del rischio
che avete. Specificando una dimensione molto può essere semplice come dichiara una variabile esterna e utilizzando una dimensione del lotto fisso per
ogni ordine. In questa sezione, esploreremo un metodo più sofisticato che calcola la dimensione del lotto in base alla quantità massima che sei disposto a
Over-leveraging è uno dei grandi assassini di commercianti di forex. Utilizzando lotti che sono troppo grandi in relazione al vostro capitale può
spazzare via il vostro conto con la stessa facilità come si può produrre grandi guadagni. Si consiglia di utilizzare non più del 2-3% del vostro
capitale per il commercio. Con questo, intendiamo dire che l'importo massimo che si può perdere per il commercio non sarà più che il 2-3% del
vostro conto.
Per calcolare la dimensione del lotto utilizzando questo metodo, abbiamo bisogno di specificare una percentuale di azioni da utilizzare e lo stop loss in pips.
Useremo la variabile esterna EquityPercent per impostare la percentuale di patrimonio da utilizzare. Si suppone che viene utilizzato uno stop loss di 50 pips.
In primo luogo, abbiamo bisogno di calcolare l'importo del patrimonio netto indicato dal EquityPercent. Se abbiamo un equilibrio di $ 10.000, e che
49
E XPERT UN dvisor P ROGRAMMAZIONE
AccountEquity () è una funzione MQL che restituisce il conto corrente del patrimonio netto. dividiamo
EquityPercent da 100 a noi dare un valore frazionario (0.02). Poi, si moltiplica che entro
AccountEquity () per calcolare l'importo del patrimonio netto da usare. 2% di $ 10.000 è di $ 200, e questo verrà memorizzato nella variabile RiskAmount.
Quindi, dobbiamo trovare il tick valore. Questo è il profitto per pip se ci sono state scambiate un lotto della valuta desiderata. Ad
esempio, se ci stiamo trading 1 lotto di EURUSD su un account standard (100k lotti), l'utile per pip sarebbe $ 10. Su un conto mini
(10k lotti), l'utile per pip sarebbe $ 1.
Possiamo usare la MarketInfo () funzione con la MODE_TICKVALUE parametro per restituire il profitto per pip per la valuta specificata. Il valore
deve essere segno di spunta in pips, quindi se stiamo negoziazione su un broker pip frazionale (3 o 5 cifre decimali), si deve moltiplicare il
valore tick per 10.
Supponendo che stiamo trading un account standard, il valore di segno di spunta per EURUSD sarà 10. Questo sarà memorizzato nella TickValue
variabile. Se questo è un broker pip frazionata, quindi TickValue sarà 1. Dovremo moltiplicare questo dal 10 per renderlo equivalente a un
pip. Se la Punto variabile indica che la moneta è di 3 o 5 cifre decimali, poi TickValue sarà moltiplicato per 10 per renderlo uguale ad un
valore posto 2 o 4 decimali.
Il passo successivo è quello di calcolare la nostra dimensione del lotto. In primo luogo, si divide il RiskAmount dal StopLoss ambientazione. Questo ci darà il nostro
profitto per tick per questo ordine. $ 200 diviso per il nostro stop loss di 50 ci darà 4 $. Ora tutto quello che dobbiamo fare è dividere che, TickValue per ottenere la
La nostra dimensione del lotto calcolato su un conto standard sarà di 0,4 lotti. Su un conto mini, la dimensione del lotto calcolato sarà di 4 lotti. Questo
Se si utilizza corretta gestione del denaro, la percentuale di capitale che si sta utilizzando sarà abbastanza consistente. (1-2% per il rischio
conservativa, fino al 5% per il rischio più elevato). Il tuo stop loss, d'altra parte, può variare in base al periodo di tempo e il vostro sistema di
trading. La dimensione del lotto varierà notevolmente a seconda del tuo stop loss.
Uno stop loss stretto genererà una dimensione molto più grande, che fornisce un sacco di beneficio a testa se il vostro ordine raggiunge il take profit. D'altra parte,
se si sta utilizzando un grande stop loss, la vostra dimensione del lotto sarà abbastanza piccola. Questo metodo beneficerà migliore da utilizzare arresti abbastanza
50
Avanzata Ordine Placement
Se è necessario utilizzare un grande stop loss, o del tutto assenti, una dimensione molto fisso sarebbe probabilmente più vantaggioso. Dobbiamo essere in grado di
scegliere tra il calcolo della dimensione del lotto o utilizzando una dimensione molto fisso. Usiamo una variabile booleana esterna chiamata DynamicLotSize di
// Le variabili esterne
extern bool DynamicLotSize = true; extern double
EquityPercent = 2; extern double FixedLotSize = 0,1;
// funzione di avvio
if (DynamicLotSize == true)
{Double RiskAmount = AccountEquity () * (EquityPercent / 100);
Se DynamicLotSize è impostata su true, calcoleremo la dimensione del lotto in base alla perdita di arresto, e assegnare tale valore al Misura di lotto variabile.
FixedLotSize a Misura di lotto. Il Misura di lotto variabile sarà passato al OrderSend () funzionano come la dimensione del lotto per l'ordine.
Proprio come lo stop loss, prendere i prezzi di profitto e di ordine in attesa, la dimensione del lotto dovrebbe anche essere verificato per assicurarsi che sia
accettabile per il vostro broker. Questo significa che la dimensione del lotto non deve essere troppo grande o troppo piccolo, e non dovrebbe essere
specificato in micro lotti (0,01) se il broker non supporta quelli. Si dovrebbe anche normalizzare la vostra dimensione del lotto al decimale appropriata.
lotto. Se la dimensione del lotto non è valido, esso verrà automaticamente ridimensionata al minimo o massimo.
51
E XPERT UN dvisor P ROGRAMMAZIONE
Confrontiamo semplicemente il valore di Misura di lotto, il nostro calcolato o fisso dimensione del lotto dall'alto, per la dimensione minima e massima
sacco. Se Misura di lotto è inferiore alla dimensione minima lotto, o maggiore della dimensione massima lotto, verrà assegnato il minimo appropriato o
il valore massimo.
Quindi, abbiamo bisogno di confrontare la nostra dimensione molto al valore di passo. Il valore di passo indica se il broker consente micro lotti
(0,01) o mini lotti (0,1). Se si tenta di utilizzare una dimensione micro molto su un broker che permette solo mini lotti, si otterrà un errore e il
commercio non sarà collocato. Ecco il codice per controllare il valore del passo:
Il NormalizeDouble () funzione arrotonda il valore di Misura di lotto al numero di cifre specificato nel secondo argomento. Nella prima
riga, se la dimensione del passo è di 0,1, indicando il broker solo usa mini lotti, Misura di lotto sarà arrotondato al primo decimale.
Altrimenti, Misura di lotto sarà arrotondato a 2 cifre decimali.
Se in futuro vi capita di imbattersi in un broker che permette sacco di dimensioni fino a tre cifre decimali, allora si potrebbe facilmente
modificare il codice qui sopra per verificare che pure. Ma al momento, praticamente tutti i broker MetaTrader utilizza uno o due cifre decimali
Contesto
MetaTrader ha un singolo thread di esecuzione commercio per consulenti esperti. Ciò significa che solo un consulente esperto può commerciare
in qualsiasi momento, indipendentemente dal numero di consulenti esperti sono in esecuzione nel terminale. Prima di iniziare con eventuali
La funzione IsTradeContextBusy () restituirà true se il thread di esecuzione commerciale è occupato, altrimenti false. Chiameremo questa
52
Avanzata Ordine Placement
int biglietteria = OrderSend (Simbolo (), OP_BUY, Misura di lotto, Chiedi, UseSlippage, 0,0,
"Buy Order", MagicNumber, 0, verde);
Usiamo un mentre ciclo di valutare IsTradeContextBusy (). Se la funzione restituisce vero, che indica che il filo esecuzione commercio
è occupato, il consulente esperto sarà Dormire per 10 millisecondi. Il mentre
ciclo continuerà ad eseguire il più a lungo IsTradeContextBusy () restituisce true. Una volta che il filo commercio viene liberato, il commercio
avrà inizio.
Se i tentativi consulente esperto al commercio mentre il thread di esecuzione delle negoziazioni è occupato, un errore 147: "contesto commerciale
occupato" si tradurrà. Anche se questo metodo è abbastanza affidabile ad evitare l'errore "contesto commerciale occupato", non è infallibile, soprattutto
quando più consulenti esperti stanno tentando di negoziare allo stesso tempo. Più tardi nel libro, esploreremo modi per riprovare le operazioni di
I valori delle variabili predefinite come Offerta e Chiedere sono impostate quando il consulente esperto inizia la sua esecuzione. La quantità di
tempo necessario per eseguire il codice esperto consulente è molto breve, e può essere misurata in millisecondi. Ma quando si figura in ritardi
per il commercio di risposta del server, e il fatto che i prezzi possono cambiare molto rapidamente, è molto importante che sempre di utilizzare i
Il RefreshRates () funzione aggiorna il contenuto delle variabili predefinite con gli ultimi prezzi dal server. Si raccomanda che
si chiama questa funzione ogni volta che si utilizza la Offerta o Chiedere
variabili, specialmente dopo l'esecuzione scambi prima.
Si noti che se si recupera il prezzo con il MarketInfo () funzione, non è necessario utilizzare
RefreshRates (). abbiamo coperto MarketInfo () a pagina 29. Quando arriviamo al capitolo sulla creazione di funzioni, useremo MarketInfo
() per recuperare i prezzi invece di utilizzare variabili predefinite. Tuttavia, si può ancora voglia di usare Offerta e Chiedere nel tuo inizio()
Quando si posiziona, la modifica o la chiusura degli ordini, gli errori possono verificarsi a causa di parametri non validi commerciali, requotes, o problemi del
server. Abbiamo fatto del nostro meglio per fare in modo che i parametri commerciali che usiamo sono validi e sono stati controllati per prevenire comuni,
errori evitabili. Ma quando si verificano errori, abbiamo bisogno di avvertire l'utente dell'errore e registrare tutte le informazioni utili per la risoluzione dei
problemi.
53
E XPERT UN dvisor P ROGRAMMAZIONE
Controlliamo per eventuali errori esaminando l'uscita di funzioni come OrderSend (), OrderModify () e OrderClose (). Se la
funzione non è stata completata correttamente, la funzione restituirà - 1 per OrderSend (), o falso per OrderModify () e OrderClose
().
In questa sezione, creeremo una routine di gestione per l'errore OrderSend () funzione. Se il valore di ritorno di OrderSend () è -1, corriamo
un errore routine di gestione per visualizzare un avviso per l'utente, e parametro di stampa commerciali pertinenti e informazioni sui
prezzi al registro.
In primo luogo, dobbiamo prima recuperare il codice di errore. Questo viene fatto usando il GetLastError () funzione. Abbiamo bisogno di
memorizzare il valore di ritorno di GetLastError () in una variabile, perché una volta GetLastError () è stato chiamato, il codice di errore viene
cancellata e la prossima chiamata di GetLastError () restituirà 0. Ci dichiarare una variabile globale chiamata Codice di errore e usarlo per
Quindi, abbiamo bisogno di ottenere alcune informazioni descrittive sull'errore. Il file di inclusione stdlib.mqh
contiene una funzione denominata Descrizione dell'errore(). Questa funzione restituisce una stringa con una descrizione dell'errore. In realtà non
Poi ci stampiamo un avviso per schermo dell'utente utilizzando il built-in Mettere in guardia() funzione. Queste informazioni saranno anche essere
stampato nel log. L'avviso includerà il codice di errore, la descrizione dell'errore, e una breve descrizione del funzionamento che abbiamo appena cercato
di svolgere. In questo modo saprete esattamente quale sezione nel proprio programma ha generato l'errore.
Infine, stamperemo rilevanti informazioni sui prezzi al registro utilizzando il Stampare() funzione. Insieme con l'attuale Bid & Ask prezzi,
// sezione preprocessore
# includere <stdlib.mqh>
// Predisporre un ordine
int biglietteria = OrderSend (Simbolo (), OP_BUYSTOP, Misura di lotto, PendingPrice, UseSlippage, 0,0,
"Buy Stop Order", MagicNumber, 0, verde);
if (biglietteria == -1)
{ErrorCode = GetLastError ();
54
Avanzata Ordine Placement
Nella parte superiore, includiamo la stdlib.mqh file. Aggiungiamo il Codice di errore variabile globale per memorizzare il nostro codice di errore. Il OrderSend () pone un
ordine di acquisto di arresto. Se la funzione non viene eseguita correttamente, viene eseguito il nostro codice di gestione degli errori.
In primo luogo, abbiamo memorizzare il valore di GetLastError () nel Codice di errore. Poi noi chiamiamo il Descrizione dell'errore()
funzione, utilizzando Codice di errore come l'argomento. Successivamente, si usa il StringConcatenate () funzione per creare il nostro messaggio di
StringConcatenate () è una funzione MQL che ti permette di creare stringhe complessi utilizzando variabili e costanti. Ogni
elemento stringa da unire (o "concatenate") insieme è separato da una virgola. Provate a digitare gli esempi sopra in MetaEditor
per vederlo con evidenziazione della sintassi.
È inoltre possibile concatenare le stringhe combinandole con un segno più (+). utilizzando
StringConcatenate () è più chiaro e più efficiente, ma se si desidera concatenare semplicemente una breve stringa, utilizzare il segno
stringa PlusCat = "Il prezzo attuale porsi è" + Chiedi; // Esempio di output: L'attuale
proposta in vendita è 1.4320
Il Mettere in guardia() funzione visualizza un pop-up sul desktop dell'utente, che contiene il contenuto della
ErrAlert variabile. Figura 3.2 mostra l'uscita del Mettere in guardia() funzione.
Costruiamo un'altra stringa con il nostro prezzo e commerciali parametri, e lo immagazzinano nel ErrLog variabile, che si passa alla Stampare()
funzione. Stampare() stampe il contenuto del argomento di funzione agli esperti log. Il registro esperti può essere visualizzato dal Gli
esperti linguetta all'interno del terminale finestra o dal rivista linguetta nel Tester finestra, se si sta utilizzando il Tester strategia.
55
E XPERT UN dvisor P ROGRAMMAZIONE
Ecco il contenuto del registro. La prima linea è l'uscita dal Mettere in guardia() funzione. La seconda linea è l'uscita del Stampare() funzione. Si
noti l'errore, "il volume degli scambi non valido", e il fatto che la dimensione del lotto riportato nel registro è 0. In questo caso, il problema è
16:47:54 Profit Buster EURUSD, H1: Alert: Aperto Buy Stop Order - Errore 131:
volume degli scambi non valida
16:47:54 Profit Buster EURUSD, H1: Offerta: 1,5046, Ask: 1,5048, Lotti: 0
È possibile creare simili routine di gestione degli errori per le altre funzioni, nonché, in particolare per la
OrderModify () e OrderClose () funzioni. È inoltre possibile creare più sofisticate routine di gestione degli errori che forniscono messaggi di
errore personalizzati sulla base del codice di errore, o eseguire altre azioni.
Ad esempio, se si riceve l'errore 130: "fermate non validi", è possibile visualizzare un messaggio del tipo "Lo stop loss o prendere profitto prezzo
stringa ErrDesc;
if (ErrorCode == 129) ErrDesc = "prezzo di apertura ordine è valido!"; if (ErrorCode == 130) ErrDesc = "stop loss o take
profit non è valido!"; if (ErrorCode == 131) ErrDesc = "Superficie del terreno non è valido!";
stringa ErrAlert = StringConcatenate ( "Open Buy Order - Errore", ErrorCode, ":", ErrDesc); Alert (ErrAlert);
56
Avanzata Ordine Placement
Stiamo per aggiungere tutte le caratteristiche che abbiamo coperto in questa sezione per il semplice consulente esperto che abbiamo creato a
pagina 36. Aggiungeremo modifica ordine, stop di verifica livello, il contesto commercio controllo, predefinito rinfrescante variabile e dimensione
del lotto verifica al nostro EA. Ecco il nostro file, partendo dall'inizio:
// Le variabili esterne
extern bool DynamicLotSize = true; extern double
EquityPercent = 2; extern double FixedLotSize = 0,1;
int CodiceErrore;
// medie mobili
doppio FastMA = iMA (NULL, 0, FastMAPeriod, 0,0,0,0); doppio SlowMA = iMA
(NULL, 0, SlowMAPeriod, 0,0,0,0);
57
E XPERT UN dvisor P ROGRAMMAZIONE
Il calcolo dimensione del lotto e il codice di verifica a partire da pagina 51 vengono aggiunti all'inizio della nostra funzione di avvio. Dato che il nostro
livello di stop loss si sa in anticipo, questo è un buon posto come un altro per metterlo. Il codice rimanente è la nostra routine ordine di mercato buy
modificato:
// Acquistare Order
if (FastMA> SlowMA && BuyTicket == 0)
{// Chiudi Ordina
RefreshRates ();
doppia ClosePrice = Chiedi;
58
Avanzata Ordine Placement
BuyTicket = OrderSend (Simbolo (), OP_BUY, Misura di lotto, Chiedi, UseSlippage, 0,0,
"Buy Order", MagicNumber, 0, verde);
RefreshRates ();
doppia UpperStopLevel = Chiedi + StopLevel; doppia
LowerStopLevel = Bid - StopLevel;
59
E XPERT UN dvisor P ROGRAMMAZIONE
// Modifica ordine
if (IsTradeContextBusy ()) del sonno (10);
if (BuyStopLoss> 0 || BuyTakeProfit> 0)
{Bool TicketMod = OrderModify (BuyTicket, OpenPrice, BuyStopLoss,
BuyTakeProfit, 0);
SellTicket = 0; }
Il resto del nostro codice contiene il blocco dell'ordine mercato vendita, così come il
PipPoint () e GetSlippage () funzioni. È possibile visualizzare il codice completo per questo consulente esperto in Appendice B.
Si noti che abbiamo aggiunto il IsTradeContextBusy () funzione prima di ogni operazione di commercio. Vogliamo fare in modo che il thread
è libero commercio prima di tentare di commercio. Noi usiamo il RefreshRates ()
60
Avanzata Ordine Placement
funzione prima di ogni riferimento della Offerta o Chiedere variabili, per garantire che siamo sempre utilizzando le più recenti prezzi.
Iniziamo selezionando il precedente ordine di vendita di biglietti e la chiusura utilizzando OrderClose (). Se la funzione fallisce, il blocco di
OrderSend (). Se la funzione fallisce, è blocco di gestione degli errori viene eseguito. Altrimenti, continuiamo a blocco modifica ordine.
Selezioniamo l'ordine che è stato appena messo usando OrderSelect (), e assegnare prezzo di apertura dell'ordine al OpenPrice variabile.
Abbiamo quindi calcolare il livello di arresto ei prezzi superiore e inferiore livello di arresto. Avanti, calcoliamo il nostro stop loss e prendere
profitto prezzi, verificare quelli, e, infine, modifichiamo l'ordine utilizzando OrderModify (). Un errore finale movimentazione offerte blocco con
Ecco come abbiamo modificare il codice per un ordine di acquisto di arresto in attesa:
// Chiudi ordine
OrderSelect (SellTicket, SELECT_BY_TICKET);
61
E XPERT UN dvisor P ROGRAMMAZIONE
// Delete ordine
else if (OrderCloseTime () == 0 && SellTicket> 0 && OrderType () == OP_SELLSTOP)
{Bool Deleted = OrderDelete (SellTicket, Rosso);
Abbiamo aggiunto il codice di cancellare le proposte in sospeso utilizzando OrderDelete () dopo il OrderClose ()
funzione. Il tipo di ordine di ordine di vendita precedente determina quale funzione è utilizzata per chiudere l'ordine.
La differenza principale tra il seguente codice ed il codice ordine di mercato è che non abbiamo un blocco di modifica ordine.
Non è necessario posizionare lo stop loss e take profit a parte per gli ordini in sospeso. Pertanto calcoleremo lo stop loss e take
profit prima di ordinare con
OrderSend ().
62
Avanzata Ordine Placement
SellTicket = 0;
In primo luogo, si calcola il livello di battuta superiore. Abbiamo poi calcolare e verificare il nostro prezzo ordine pendente, che è memorizzato in PendingPrice.
in modo che siano in relazione al prezzo ordine in attesa. Si noti che non abbiamo bisogno di utilizzare ASK o fare offerte prezzi, o una figura di
Infine, abbiamo posto il nostro ordine in attesa utilizzando OrderSend (), ponendo lo stop loss e take profit con esso. Abbiamo la funzione di
gestione degli errori di serie a che fare con gli errori di posizionamento ordine.
Nonostante tutto il codice in più, questi consulenti esperti stanno usando la stessa strategia come quella alla fine del capitolo 2. Questo codice deve
semplicemente caratteristiche extra per il calcolo e la verifica dimensione del lotto, smettere di livelli, stop loss, take profit e in attesa di prezzi di ordine. Abbiamo
anche aggiunto controlli contesto commerciale e il codice di gestione degli errori. Nel prossimo capitolo, impareremo come creare funzioni in modo che
63
E XPERT UN dvisor P ROGRAMMAZIONE
capitolo 4
Lavorare con le funzioni
Stiamo andando a convertire il codice che abbiamo discusso nei capitoli precedenti in funzioni riutilizzabili. Questo ci farà risparmiare un sacco di lavoro, in
quanto siamo in grado di concentrarsi sui dettagli del nostro sistema di trading al posto della meccanica di trading.
L'idea alla base di creazione di funzioni è quello di creare un blocco di codice che svolge un compito molto specifico. Il codice dovrebbe essere
sufficientemente flessibile per essere riutilizzati in una varietà di situazioni di trading. Eventuali variabili esterne o calcoli dovranno essere passato alla
funzione. Non possiamo assumere che i valori necessari saranno disponibili per la nostra funzione in caso contrario, dal momento che la funzione può
Per coerenza, manterremo gli stessi nomi per le variabili esterne che abbiamo usato finora. Ci premette queste variabili con
" arg", per indicare che sono gli argomenti della funzione.
Cominciamo con i nostri calcoli dimensione del lotto, come definito a pagina 51:
La prima linea è la nostra dichiarazione di funzione. Chiamiamo questa funzione CalcLotSize (). Confronta questo per il codice a pagina
51. Si noti che DynamicLotSize, EquityPercent, StopLoss e FixedLotSize sono tutti argomenti delle funzioni ora. Le variabili esterne con
questi nomi esistono ancora nel nostro programma, ci sarà solo passarli alla funzione come argomenti ora.
64
Lavorare con le funzioni
Gli argomenti per la nostra funzione sono evidenziate in grassetto. A parte il fatto che stiamo usando argomenti ora, il codice è
ritorno dichiarazione alla fine della funzione - questo restituirà il valore di Misura di lotto alla nostra funzione di chiamata.
La funzione stessa sarà collocato da qualche parte nel nostro file di programma, al di fuori della inizio() e dentro()
funzioni, o sarà situato in un esterno includono file. In quest'ultimo caso, un # includere istruzione nella parte superiore del programma dovrebbe
Ecco come vorremmo utilizzare questa funzione nel codice. In primo luogo, cerchiamo di elencare le variabili esterne useremo per le nostre impostazioni di dimensione
molto:
Ed ecco come chiamiamo la funzione. Questa linea di codice sarebbe situato all'interno inizio() funzione:
Le nostre variabili esterne sono passati alla funzione come argomenti. La funzione calcola la nostra dimensione del lotto, e il valore verrà
salvato nella variabile Misura di lotto. Si noti che questa variabile è diversa da quella
Misura di lotto variabile che si trova all'interno del CalcLotSize () funzione. Entrambe le variabili sono locali alle loro funzioni,
Continuiamo con il codice di verifica molto da pagina 51. Questa sarà una funzione separata, nel caso in cui si decide di utilizzare un metodo
alternativo di calcolo dimensione del lotto. Indipendentemente dal metodo di determinazione dimensione del lotto, ti consigliamo di verificarla
65
E XPERT UN dvisor P ROGRAMMAZIONE
ritorno (argLotSize);
}
Per questa funzione, passeremo la variabile con la dimensione del lotto abbiamo calcolato utilizzando CalcLotSize () come l'argomento. La
variabile argomento argLotSize viene poi elaborato e restituito di nuovo alla funzione chiamante.
Ora è il momento di assemblare la nostra funzione dell'ordine buy mercato. Ci saranno alcune differenze tra la nostra funzione dell'ordine
e il codice che abbiamo recensito in precedenza. Per uno, non ci sarà la chiusura degli ordini nelle nostre funzioni dell'ordine. Tratteremo
la chiusura degli ordini separatamente. Creeremo una funzione di chiudere gli ordini nel prossimo capitolo.
Ci sarà anche il calcolo e modificare il nostro stop loss e prendere profitto i prezzi al di fuori della funzione dell'ordine. Poiché
esistono diversi modi per calcolare fermate, dobbiamo mantenere la nostra funzione dell'ordine più flessibile possibile, e non
legarlo a un metodo di calcolo predeterminato fermate. Il codice di modifica ordine è stato spostato in una funzione separata.
Metteremo il nostro ordine di acquisto al prezzo corrente di mercato utilizzando OrderSend (), e se l'ordine non è stato collocato, ci corriamo il codice
di gestione a partire da pagina 54. In ogni caso errori, torneremo il numero del biglietto alla funzione chiamante, o - 1 se l'ordine non è stato collocato.
Stiamo specificando il simbolo dell'ordine utilizzando il argSymbol argomentazione, invece di utilizzare il simbolo grafico corrente. In questo
modo, se si decide di effettuare un ordine su un altro simbolo, si può fare così facilmente. Invece di usare il predefinito Offerta e Chiedere variabili,
funzione con la MODE_ASK e MODE_BID parametri per recuperare l'offerta e chiedere prezzo per quel particolare simbolo.
Abbiamo anche specificato un valore predefinito per il commento ordine. L'argomento argComment ha un valore di default, " Buy Order". Se nessun
valore è specificato per questo argomento, il valore predefinito viene utilizzato. Si suppone che la dimensione del lotto e lo slittamento sono stati
66
Lavorare con le funzioni
// Luogo Buy Order int biglietteria = OrderSend ( argSymbol, OP_BUY, argLotSize, MarketInfo (argSymbol, MODE_ASK),
biglietto di ritorno); }
Nel OrderSend () la funzione, si noti che abbiamo usato il MarketInfo () funzione con la MODE_ASK
parametro, al posto del predefinito Chiedere variabile. Questo recupererà la corrente Chiedi prezzo per il simbolo di valuta
indicato da argSymbol.
Se il commercio non è stato inserito correttamente, l'errore di manipolazione di routine verrà eseguito. In caso contrario, il biglietto ordine sarà
restituito alla funzione chiamante, o - 1 se l'ordine non è stato collocato. La funzione completa dell'ordine per ordini di mercato vendita si trova in
Appendice D.
Per effettuare ordini in attesa, abbiamo bisogno di passare i parametri per il prezzo ordine in corso, così come il tempo di ordine di
scadenza. Il argPendingPrice e argExpiration argomenti verranno aggiunti alla funzione.
Si suppone che il prezzo ordine in corso, così come lo stop loss e take profit, sono stati calcolati e verificati prima di chiamare
questa funzione. Le funzioni di collocamento ordine in attesa metterà lo stop loss e take profit con l'ordine in corso, quindi non è
necessaria alcuna funzione di modifica ordine separato.
67
E XPERT UN dvisor P ROGRAMMAZIONE
biglietto di ritorno); }
Si noti che abbiamo specificato un valore predefinito 0 per argExpiration. Se non si utilizza un tempo di scadenza ordine in attesa, e si desidera
utilizzare il commento ordine predefinito, si può semplicemente omettere gli argomenti a favore argExpiration e argComment quando si chiama la
funzione. L'esempio seguente verrà inserito un ordine di acquisto di arresto con il tempo di scadenza e il commento ordine predefinito, "Buy
Stop Order":
int biglietteria = OpenBuyStopOrder (Simbolo (), Misura di lotto, PendingPrice, StopLoss, TakeProfit,
UseSlippage, MagicNumber);
Abbiamo aggiunto il prezzo in attesa per il registro nella nostra funzione di gestione degli errori, così come la data di scadenza, se
specificata. Il TimeToStr () funzione converte una variabile datetime in un formato leggibile stringa.
Le funzioni di arresto aprono vendere, comprare e vendere limite ordini limite sono identici a questo. L'unica differenza è che il parametro tipo di
ordine per la OrderSend () funzione viene modificata di conseguenza. È possibile visualizzare tutte le funzioni di collocamento ordine in corso
nell'Appendice D.
68
Lavorare con le funzioni
Infine, creiamo una funzione per la chiusura di un singolo ordine. Useremo il blocco di chiusura ordine dal codice a pagina 58. Nel prossimo
capitolo, esamineremo modi di chiusura ordini multipli dello stesso tipo, che è un metodo più semplice di ordini di chiusura. Ma nel caso in
cui è necessario chiudere un solo ordine, questa funzione farà il trucco:
if (OrderCloseTime () == 0)
{doppie CloseLots = OrderLots ();
if (Closed == false)
{Int ErrorCode = GetLastError ();
ritorno (chiuso); }
Per il ClosePrice variabile, usiamo MarketInfo () per recuperare il prezzo Chiedi corrente per la valuta indicata da argSymbol. Usiamo gli
argomenti della funzione argCloseTicket e argSlippage per il biglietto ordine di chiusura e lo slittamento, rispettivamente. Se l'ordine non è
stato chiuso con successo, si corre il blocco di gestione degli errori, che stampa il numero del biglietto e la corrente proposta in vendita al
registro.
Il codice per chiudere un ordine di vendita sarà identico, tranne che usereste il prezzo di offerta per il
ClosePrice variabile. È possibile visualizzare la funzione di chiusura del mercato sell nell'Appendice D.
69
E XPERT UN dvisor P ROGRAMMAZIONE
Ecco una funzione per chiudere un unico ordine pendente. Questo funziona su tutti i tipi di ordini in sospeso, comprare e vendere.
if (OrderCloseTime () == 0)
{While (IsTradeContextBusy ()) del sonno (10);
if (eliminata == false)
{Int ErrorCode = GetLastError ();
ritorno (soppresso); }
Stiamo andando a creare alcune funzioni brevi per il calcolo stop loss e take profit come discusso nelle pagine 25-30. Passeremo le nostre
variabili esterne che indicano lo stop loss o prendere profitto in pips alla nostra funzione, così come il prezzo di apertura ordine. Il valore di
ritorno della nostra funzione sarà lo stop loss attuale o prendere prezzo profitto.
70
Lavorare con le funzioni
In primo luogo, controlleremo per vedere se un livello di stop loss valida è stata approvata con la funzione. Se la
argStopLoss argomento è 0, allora si ritorna un valore pari a 0 alla funzione chiamante, indicando che è stato specificato alcun stop loss.
Successivamente, si calcola lo stop loss sottraendo lo stop loss in pips dal prezzo di apertura ordine. moltiplichiamo argStopLoss
di PipPoint () per calcolare il valore frazionario, e sottrarre che dal
argOpenPrice. Useremo sia l'offerta o Chiedi prezzo (per ordini di mercato) o il prezzo di ordine pendente previsto.
Si noti che noi non controlliamo il livello di arresto o in altro modo di verificare che lo stop loss è valido. Useremo un'altra serie di comandi per verificare o
regolare il prezzo di perdita di arresto come necessario. Si potrebbe, ovviamente, modificare facilmente questa funzione per verificare il prezzo di perdita di
Le funzioni di calcolo stop loss e prendere profitto per ordini di vendita sono elencati nell'Appendice D. Si noti che la funzione di calcolo
stop loss vendita è quasi identica a quella sopra per il calcolo acquistare prendere profitto, e così per la perdita di acquisto stop e vendere
prendere profitto.
Stiamo andando a creare due insiemi di funzioni per calcolare e verificare i livelli di stop. Il primo sarà semplicemente calcolare il livello di stop
superiore o inferiore un determinato prezzo, e restituire un valore booleano che indica se il prezzo indicato è all'interno o all'esterno del livello di
stop. Una seconda serie di funzioni calibrerà automaticamente un prezzo in modo che sia al di fuori del livello di arresto, più o meno un numero
specificato di vinaccioli.
La seguente funzione verifica se un prezzo è sopra il livello superiore di arresto (il prezzo di apertura ordine più il livello di stop). In tal
caso, la funzione restituisce true, altrimenti false:
71
E XPERT UN dvisor P ROGRAMMAZIONE
ritorno (StopVerify); }
Passiamo il simbolo di valuta, il prezzo di verificare, e il prezzo di apertura ordine (opzionale) come argomenti. Per impostazione predefinita, il
livello di arresto è calcolato in relazione al prezzo Ask. Se argOpenPrice è specificato, il livello di arresto sarà calcolato rispetto a tale prezzo invece.
(Usare questo durante la verifica di stop loss e prendere profitto i prezzi per gli ordini in sospeso).
La funzione di verifica per vedere se argVerifyPrice è maggiore del UpperStopLevel. Se lo è, il valore di ritorno sarà vero. In caso contrario, false. È
possibile utilizzare questa funzione per verificare la presenza di una perdita di arresto valido, prendere profitto o il prezzo ordine pendente, senza
modificare il prezzo originale. Ecco un esempio in cui controlliamo un prezzo di perdita di arresto e mostrare un messaggio di errore se il prezzo non è
valido:
Il codice per controllare il livello di arresto al di sotto del prezzo corrente o in corso si trova in Appendice D. La nostra seconda serie di funzioni è
simile, tranne che essi regolare automaticamente lo stop loss non valida, prendere profitto o il prezzo ordine pendente ad uno valido:
doppia AdjustAboveStopLevel (string argSymbol, Doppio argAdjustPrice, int argAddPips = 0, doppio argOpenPrice = 0) { doppia StopLevel =
72