Sei sulla pagina 1di 80

Expert Advisor di

programmazione
La creazione di sistemi automatizzati di trading
in MQL per MetaTrader 4

Andrew R. Young

Edgehill Publishing
SECONDO LA STAMPA

Copyright © 2010, Andrew R. Young. Tutti i diritti riservati.

Pubblicato da Edgehill Publishing, Nashville, TN.

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

Avanzata Ordine Placement 42


Ordinare modifica 42
Verifica delle fermate e in attesa di ordine Prezzi 45
Calcolo Superficie lotto 49
altre considerazioni 52
Mettere tutto insieme 57

Lavorare con le funzioni 64


Aggiungere Stop Loss e Take Profit 73
Utilizzando Includi file 74
Utilizzo delle librerie 74
Un consulente esperto semplice (con le funzioni) 75
Gestione degli ordini 80
L'Ordine Loop 80
ordine di conteggio 82
Trailing Stop 87
Aggiornamento del Expert Advisor 92

Ordine Condizioni e indicatori 94


I dati sui prezzi 94
indicatori 95
indicatore Costanti 102
Valutare Condizioni commerciali 103
Confrontando i valori degli indicatori Across Bar 108

Lavorare con ora e data 112


Variabili datetime 112
Data e ora 114
Creazione di un timer semplice 115
Eseguire su Bar Aperto 117

Suggerimenti e trucchi 122


caratteri di escape 122
Utilizzando Grafico Commenti 122
Controllare le impostazioni 123
Demo o conto dei limiti 124
Casella dei messaggi() 125
Avvisi e-mail 127
Riprova in caso di errore 128
Utilizzando Order commenti come un identificatore 131
margine Controllare 132
diffusione Controllare 132
ordini multipli 133
Variabili globali 136
Controllare Order Profit 137
Martingale 138
Debug Expert Advisor 141
Indicatori personalizzati e script 146
buffer 146
Creazione di un indicatore personalizzato 146
Script 152

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

il nuovo programmatore MQL.

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

A proposito di questo libro

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

Una nota sulla MQL 5

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

Convenzioni usate in questo libro

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.

blocco di codice sorgente


Aggiornato il codice sorgente

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

Introduzione a MetaEditor Che cosa è

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

ordini su un grafico. Alcuni script utili sono inclusi con MetaTrader.

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,

un. ex4 file viene prodotta.

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.

Posizione dei file

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.

• \ Esperti \ librerie - librerie di funzioni e DLL sono 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

Proprietà dialogo sono memorizzati qui.

• \ 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.

Il riferimento MQL incorporato e l'aiuto sensibile al contesto vi farà risparmiare

un sacco di tempo in cui la codifica. Se hai bisogno di aiuto ricordare la sintassi

di un particolare elemento del linguaggio, selezionare o posizionare il cursore

del testo sull'elemento nella finestra dell'editor. Premere F1 sulla tastiera e

l'argomento della Guida verrà visualizzata nella finestra Casella degli strumenti.

La barra degli strumenti in MetaEditor presenta il complemento standard

funzioni di file e modifica. Le finestre Navigator e Toolbox possono essere

visualizzate o nascoste usando i loro rispettivi pulsanti sulla barra degli

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.

doppio LastHigh = Alto [1];

stringa multilinea = StringConcatenate ( "Questa è una dichiarazione multilinea.",


"Per chiarezza, ci sarà il rientro più righe di questo libro");

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,

switch), gli operatori del ciclo ( for, while) e dichiarazioni di funzione.

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.

/ * Questo è un commento al blocco


Tutto qui è 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

altro errore comune newbie, in modo da controllare quei nomi di identificatore!

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

funzione, come i prezzi, le impostazioni ei valori degli indicatori.

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

colore. Qui ci sono i tipi di dati in MQL:

• int - Un numero intero (numero intero) come 0, 3, o -5. Qualsiasi numero assegnato a una variabile intera viene

arrotondato al numero intero.

• 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".

Le stringhe devono essere circondati da virgolette.

• booleano - A vero falso valore. Può anche essere rappresentato come 1 (true) o 0 (falso). Utilizzare questi in qualsiasi momento è necessario

valutare un binario, oppure on / off condizione.

• appuntamento - Un ora e valore di data come 2009.01.01 00:00. Internamente, una variabile datetime è

rappresentato come il numero di secondi trascorsi dal 1 gennaio 1970.

• colore - Una costante che rappresenta un colore, ad esempio Rosso o Darkslateblue. Questi sono generalmente utilizzati per cambiare

indicatore o oggetti colori.

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

assegna il numero 5 per MyVariable:

MyVariable = 5;

È inoltre possibile assegnare il valore di una variabile ad un'altra variabile:

int YourVariable = 2; MyVariable =


YourVariable; // MyVariable è 2

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:

doppio UsePoint; UsePoint = PipPoint


();

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.

Ecco il codice per la PipPoint () funzione:

doppia PipPoint ()
{If (cifre == 2 || cifre == 3) doppio UsePoint = 0.01;

else if (cifre == 4 || cifre == 5) UsePoint = 0,0001; ritorno (UsePoint); }

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

funzione restituisce un numero frazionario, si usa il Doppio tipo di dati.

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

UsePoint alla funzione chiamante.

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

funzioni non richiedono un ritorno operatore nel corpo della funzione.

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:

OpenBuyOrder (2, 1.5550, 1,6050);

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:

int = getticket OpenBuyOrder (UseLotSize, BuyStopLoss, BuyTakeProfit);

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

quando si chiama la funzione:

DefaultValFunc (TicketNum, UsePrice);

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

DefaultValFunc (TicketNum, UsePrice, UseNumber);

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:

DefaultValFunc (TicketNum, UsePrice, 0, "Commento String");

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

o globale. Una variabile locale può anche essere statico.

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:

int MyStaticVar statica;

Se una variabile statica deve essere reso disponibile per più di una funzione, utilizzare una variabile globale invece. In questo caso

non è necessario dichiarare la variabile come statica.

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.

Layout di un file MQ4 Creazione di un

nuovo Expert Advisor

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

seconda del tipo. Assicurarsi Expert Advisor è scelto e premere Il prossimo.

Fig. 1.3 - Expert Advisor Wizard proprietà generali.

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

aggiungere semplicemente questi manualmente al codice sorgente in seguito. premi il finire

bottone e un modello di consulente esperto si aprirà con le informazioni già aggiunto.

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.

direttive del preprocessore

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 è:

# includere < nome del file. MQH>

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

# definire MYCONSTANT “Questa è una costante”

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

gli identificatori per le costanti con i tappi.

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.

Parametri e variabili esterne

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

extern double StopLoss = 50;

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()

funzione è opzionale e può essere lasciato fuori se non lo si utilizza.

Il deinit () funzione consiste di codice che viene eseguito una volta, quando l'EA è fermo. Questa funzione è opzionale, ed è improbabile

che sarà necessario utilizzare in un consulente esperto.

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

// direttive del preprocessore


# protette da copyright "Andrew Young"
# Link immobili "Http://www.expertadvisorbook.com"

# includere <stdlib.mqh>

# definire MYCONSTANT "Questa è una costante"

// parametri esterni extern int Parametro1 = 1; extern


double Parametro2 = 0.01;

// variabili globali int


GlobalVariable1;

// Init funzione int init ()

{ // codice di avvio

ritorno (0); }

// Deinit funzione int deinit ()

{ // Codice Shutdown

ritorno (0); }

// Avvia funzione di avvio int


()
{ // codice principale

ritorno (0); }

// funzioni personalizzate int


MyCustomFunction ()
{ // Codice personalizzato

ritorno (0); }

Fig 1.4 - Esempio di disposizione Expert Advisor

19
E XPERT UN dvisor P ROGRAMMAZIONE

capitolo 2
Predisporre un ordine

Differenza tra domanda e offerta

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,

in modo da ricordare la differenza tra i due.

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

cancellato. Non tutti i broker supportano il commercio di scadenza.

L'Ordine di processo Placement

Il processo di immissione di un ordine in MQL richiede diversi passi. Dobbiamo determinare quanto segue prima di ordinare:

• Il tipo di ordine da posizionare - acquistare o vendere; fermarsi, di mercato o limitare.

• La coppia di valute al commercio - in generale il grafico che l'EA è attaccato.

• 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

come richiesto dal tipo di ordine.

• 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

specifico consulente esperto.

• Un prezzo di scadenza facoltativa per gli ordini in corso, se il broker lo supporta.

21
E XPERT UN dvisor P ROGRAMMAZIONE

OrderSend ()

Il OrderSend () funzione consente di ordinare in MQL. La sintassi è la seguente:

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

Simbolo() funzione serve per coppia di valute del grafico corrente.

• genere - Il tipo di ordine di posto: comprare o vendere; mercato, stop o limite. Questo è un valore intero, rappresentato dalle
seguenti costanti:

◦ OP_BUY - ordine di acquisto di mercato (valore intero 0).

◦ OP_SELL - ordine di vendita del mercato (valore intero 1).

◦ OP_BUYSTOP - Comprare ordine di arresto (valore intero 2).

◦ OP_SELLSTOP - ordine di vendita stop (valore intero 3).

◦ OP_BUYLIMIT - Comprare ordine limite (valore intero 4).

◦ OP_SELLLIMIT - ordine di vendita limite (valore intero 5).

• 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

sotto del prezzo corrente.

• slittamento - Lo slittamento massima in punti. Utilizzare un numero sufficientemente ampio impostazione quando trading automatico. Broker che

non utilizzano lo slittamento ignoreranno questo parametro.

• 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

di vendita, al di sopra. Se impostato a 0, non verrà utilizzato alcun stop loss.

• 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

vendita, di seguito. Se impostato a 0, non verrà utilizzato alcun take profit.

• 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

viene specificato nessun colore, la freccia non verrà disegnata.

Il OrderSend () funzione restituisce il numero del biglietto d'ordine che è stato appena messo. Se nessun ordine è stato effettuato, a causa di una

condizione di errore, il valore di ritorno sarà - 1.

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.

Posizionamento di un ordine di mercato

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

del tuo slittamento ambientazione.

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.

Posizionamento di un arresto ordine pendente

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

negoziazione, oppure può essere impostato come un parametro esterno.

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:

OrderSend (Simbolo (), OP_BUYSTOP, Misura di lotto, PendingPrice, Slittamento, BuyStopLoss,


BuyTakeProfit," Buy Stop Order", MagicNumber, 0, verde);

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

scadenza è stato indicato per questo ordine.

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

un collocamento vendita ordine di arresto:

OrderSend (Simbolo (), OP_SELLSTOP, Misura di lotto, PendingPrice, lo slittamento, SellStopLoss,


SellTakeProfit," Sell ​Stop Order", MagicNumber, Scadenza, Rosso);

Esecuzione di un'attesa Limit Order

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

OrderSend (Simbolo (), OP_BUYLIMIT, Misura di lotto, PendingPrice, lo slittamento, BuyStopLoss,


BuyTakeProfit," Comprare Limit Order", MagicNumber, 0, verde);

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:

OrderSend (Simbolo (), OP_SELLLIMIT, Misura di lotto, PendingPrice, lo slittamento, SellStopLoss,


SellTakeProfit," Sell ​Limit Order", MagicNumber, scadenza, Rosso);

Calcolo Stop Loss & Take Profit

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

verificare che lo stop loss o prendere prezzo profitto è valido.

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.

Noi assegnare il prezzo adeguato alla variabile

OpenPrice.

Qui ci sono le variabili esterne useremo per il nostro stop loss e prendere profitto impostazioni:

extern int StopLoss = 50; extern int TakeProfit =


100;

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

0,50. Per tutte le altre coppie, è 0,0050.

Per convertire un intero al valore frazionario del caso, abbiamo bisogno di moltiplicare la nostra esterna StopLoss

variabile dal Punto.

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.

doppia OpenPrice = Chiedi;

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.

doppia PipPoint (valuta di stringa)


{Int CalcDigits = MarketInfo (valuta, MODE_DIGITS);

if (CalcDigits == 2 || CalcDigits == 3) doppio CalcPoint = 0.01; else if (CalcDigits == 4 || CalcDigits == 5)


CalcPoint = 0,0001; ritorno (CalcPoint); }

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.

doppia UsePoint = PipPoint (Simbolo ());

Ecco una serie di esempi che utilizzano specifiche coppie:

doppio UsePoint = PipPoint (EURUSD); // Il risultato è


0,0001

doppio UsePoint = PipPoint (USDJPY); // Il risultato è 0,01

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

fattore 10 per ottenere il valore corretto slittamento.

27
E XPERT UN dvisor P ROGRAMMAZIONE

Questa funzione imposta automaticamente il parametro slittamento al numero di punti specificato dal esterna slittamento parametro:

int GetSlippage (string valuta, SlippagePips INT)


{Int CalcDigits = MarketInfo (valuta, MODE_DIGITS);

if (CalcDigits == 2 || CalcDigits == 4) letto CalcSlippage = SlippagePips; else if (CalcDigits == 3 || CalcDigits == 5) CalcSlippage =


SlippagePips * 10; ritorno (CalcSlippage); }

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 ():

// esterno int parametri extern Unità = 5;

// 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.

Slittamento e Point come variabili globali

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

momento abbiamo bisogno di fare riferimento a quei valori.

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:

// Le variabili globali doppia


UsePoint; int UseSlippage;

int init ()
{UsePoint = PipPoint (Simbolo ());

UseSlippage = GetSlippage (Simbolo (), lo slittamento); }

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

sintassi per la MarketInfo () funzione:

doppia MarketInfo (string Simbolo, int Tipo di richiesta);

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_POINT - Il valore del punto. Ad esempio, 0,01 o 0,00001.

• 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.

• MODE_SPREAD - La diffusione attuale. Ad esempio, 3 pip (o 30 per un mediatore pip frazionaria).

• MODE_STOPLEVEL - Il livello di arresto. Ad esempio, 3 pip (o 30 per un mediatore pip frazionaria).

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:

• MODE_BID - Il prezzo di offerta corrente del simbolo selezionato.

• MODE_ASK - L'attuale prezzo della domanda del simbolo selezionato.

• MODE_LOW - Il minimo della barra attuale del simbolo selezionato.

• MODE_HIGH - Il massimo della barra attuale del simbolo selezionato.

29
E XPERT UN dvisor P ROGRAMMAZIONE

Calcolo del Stop Loss

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:

doppia OpenPrice = Chiedi;


if (StopLoss> 0) doppia BuyStopLoss = OpenPrice - (StopLoss * UsePoint);

Ed ecco il calcolo per un ordine di vendita. Si noti che abbiamo assegnato il Offerta prezzo da OpenPrice, e che stiamo semplicemente

aggiungendo invece di sottrarre:

doppia OpenPrice = un'offerta;


if (StopLoss> 0) doppia SellStopLoss = OpenPrice + (StopLoss * UsePoint);

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.

Calcolo del Take Profit

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:

if (TakeProfit> 0) doppia BuyTakeProfit = OpenPrice + (TakeProfit * UsePoint);

if (TakeProfit> 0) doppia SellTakeProfit = OpenPrice - (TakeProfit * UsePoint);

Alternate metodi di perdita di arresto

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:

doppia BuyStopLoss = Basso [0] - (2 * UsePoint);

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

usare valori alti, bassi, aprire o chiudere.

Ecco un esempio di come useremmo iLowest () per trovare il basso più basso degli ultimi 10 bar:

int CountBars = 10;


int = LowestShift iLowest (NULL, 0, MODE_LOW, CountBars, 0); doppia BuyStopLoss =
Basso [LowestShift];

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

- la barra precedente è 1, la barra prima che sia 2, etc.

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

parole, Basso [6].

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

corrente movimento valore medio per lo stop loss:

doppia BuyStopLoss = MA;

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

utilizzando la vostra conoscenza di analisi tecnica o la vostra immaginazione.

Recupero Informazioni per l'ordine

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 ()

Ecco la sintassi per la OrderSelect () funzione:

bool OrderSelect (int Indice, int Selezionare, int Pool = MODE_TRADES)

• 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:

◦ SELECT_BY_TICKET - Il valore della Indice parametro è un numero di biglietto d'ordine.

◦ SELECT_BY_POS - Il valore della Indice parametro è 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.

◦ MODE_HISTORY - Esamina la piscina ordine chiuso (la cronologia degli ordini).

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:

OrderSelect (biglietteria, SELECT_BY_TICKET);

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

intero corrispondente alle costanti di tipo di ordine a pagina 22.

• OrderOpenPrice () - Il prezzo del ordine selezionato di apertura.

• OrderLots () - La dimensione del lotto dell'ordine selezionato.

• OrderStopLoss () - Il prezzo della perdita di arresto nell'ordine selezionato.

• OrderTakeProfit () - Il prezzo profitto take dell'ordine selezionato.

• OrderTicket () - Il numero del biglietto dell'ordine selezionato. Generalmente utilizzato quando in bicicletta attraverso il pool

ordine con il SELECT_BY_POS parametro.

• OrderMagicNumber () - Il numero magico di ordine selezionato. Quando in bicicletta attraverso gli ordini, è necessario utilizzare

questo per identificare gli ordini effettuati dal vostro EA.

• 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

cronologia degli ordini).

• OrderOpenTime () - Il tempo dell'ordine selezionato apertura.

• OrderCloseTime () - Il momento dell'ordine selezionato di chiusura.

33
E XPERT UN dvisor P ROGRAMMAZIONE

• OrderProfit () - Restituisce il profitto (nella valuta di deposito) per l'ordine selezionato.

Avremo bisogno di usare OrderSelect () prima di chiudere o modificare un ordine. Illustriamo come usiamo
OrderSelect () per chiudere un ordine.

Gli ordini di chiusura

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 ()

Chiudiamo ordini di mercato che utilizzano il OrderClose () funzione. Ecco la sintassi:

bool OrderClose (int Biglietto, Doppio Molte, Doppio Prezzo, int slittamento, colore Freccia);

• Biglietto - Il numero del biglietto del l'ordine di mercato per chiudere.

• 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

per ordini di vendita, l'attuale prezzo Ask.

• slittamento - Lo slittamento consentita dal prezzo di chiusura, in pips.

• 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

discussione. Si noti che non tutti i broker supportano chiude parziali.

È 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.

L'esempio seguente chiude un ordine di acquisto di mercato:

OrderSelect (CloseTicket, SELECT_BY_TICKET);

34
Predisporre un ordine

if (OrderCloseTime () == 0 && OrderType () == OP_BUY)


{doppie CloseLots = OrderLots ();

doppia ClosePrice = un'offerta;

bool Chiuso = OrderClose (CloseTicket, CloseLots, ClosePrice, UseSlippage, Rosso); }

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

da ClosePrice. Poi noi chiamiamo il OrderClose () funzione di chiudere il nostro ordine.

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:

if (OrderCloseTime () == 0 && OrderType () == OP_SELL)


{doppie CloseLots = OrderLots ();

double ClosePrice = Chiedere;

bool Chiuso = OrderClose (CloseTicket, CloseLots, ClosePrice, UseSlippage, Rosso); }

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

OrderSelect (CloseTicket, SELECT_BY_TICKET);

if (OrderCloseTime () == 0 && OrderType () == OP_BUYSTOP)


{ bool Deleted = OrderDelete (CloseTicket, Rosso);

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

pendente. Il tipo di ordine costanti in sospeso sono OP_BUYSTOP, OP_SELLSTOP, OP_BUYLIMIT e

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é.

A Simple Expert Advisor

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 è

eliminato. Questo impedisce che più ordini consecutivi apertura.

# protette da copyright "Andrew Young"

// Le variabili esterne extern doppia Misura di lotto =


0.1; extern double StopLoss = 50; extern double
TakeProfit = 100;

extern int Unità = 5; extern int MagicNumber =


123;

extern int FastMAPeriod = 10; extern int


SlowMAPeriod = 20;

// Le variabili globali int


BuyTicket; int SellTicket;

36
Predisporre un ordine

doppio UsePoint; int


UseSlippage;

// Init funzione int init ()

{UsePoint = PipPoint (Simbolo ());

UseSlippage = GetSlippage (Simbolo (), lo slittamento); }

// Avvia funzione di avvio int


()
{// medie mobili

doppio FastMA = iMA (NULL, 0, FastMAPeriod, 0,0,0,0); doppio SlowMA = iMA


(NULL, 0, SlowMAPeriod, 0,0,0,0);

// Acquistare ordine
if (FastMA> SlowMA && BuyTicket == 0)
{OrderSelect (SellTicket, SELECT_BY_TICKET);

// Chiudi ordine
if (OrderCloseTime () == 0 && SellTicket> 0)
{doppie CloseLots = OrderLots ();

doppia ClosePrice = Chiedi;

bool Chiuso = OrderClose (SellTicket, CloseLots, ClosePrice, UseSlippage, Rosso); }

doppia OpenPrice = Chiedi;

// Calcola stop loss e take profit


if (StopLoss> 0) doppia BuyStopLoss = OpenPrice - (StopLoss * UsePoint); if (TakeProfit> 0) doppia BuyTakeProfit = OpenPrice +
(TakeProfit * UsePoint);

// buy ordine aperto


BuyTicket = OrderSend (Simbolo (), OP_BUY, Misura di lotto, OpenPrice, UseSlippage,
BuyStopLoss, BuyTakeProfit, "Buy Order", MagicNumber, 0, verde);

SellTicket = 0; }

// Sell Order
if (FastMA <SlowMA && SellTicket == 0)
{OrderSelect (BuyTicket, SELECT_BY_TICKET);

37
E XPERT UN dvisor P ROGRAMMAZIONE

if (OrderCloseTime () == 0 && BuyTicket> 0)


{CloseLots = OrderLots ();

ClosePrice = Bid;

Chiuso = OrderClose (BuyTicket, CloseLots, ClosePrice, UseSlippage, Rosso); }

OpenPrice = Bid;

if (StopLoss> 0) doppia SellStopLoss = OpenPrice + (StopLoss * UsePoint); if (TakeProfit> 0) doppia SellTakeProfit = OpenPrice -
(TakeProfit * UsePoint);

SellTicket = OrderSend (Simbolo (), OP_SELL, Misura di lotto, OpenPrice, UseSlippage,


SellStopLoss, SellTakeProfit, "Sell Ordine", MagicNumber, 0, Rosso);

BuyTicket = 0; }

ritorno (0); }

// funzione PIP Point


doppia PipPoint (valuta di stringa)
{Int CalcDigits = MarketInfo (valuta, MODE_DIGITS);

if (CalcDigits == 2 || CalcDigits == 3) doppio CalcPoint = 0.01; else if (CalcDigits == 4 || CalcDigits == 5)


CalcPoint = 0,0001; ritorno (CalcPoint); }

// Get slittamento Funzione


int GetSlippage (string valuta, SlippagePips INT)
{Int CalcDigits = MarketInfo (valuta, MODE_DIGITS);

if (CalcDigits == 2 || CalcDigits == 4) letto CalcSlippage = SlippagePips; else if (CalcDigits == 3 || CalcDigits == 5) CalcSlippage =


SlippagePips * 10; ritorno (CalcSlippage); }

Si comincia con il nostro # protette da copyright direttiva del preprocessore che identifica il codice come appartenenti a noi. Le variabili esterne sono

accanto, e dovrebbero essere auto-esplicativo. dichiariamo Comprare un biglietto e

SellTicket come variabili globali - in questo modo il biglietto ordine memorizzato tra le esecuzioni di programma. Potremmo anche li abbiamo

dichiarato come statico variabili all'interno della inizio() funzione.

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

riferimento nel resto del nostro consulente esperto.

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.

Utilizzando Ordini in sospeso

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

una variabile esterna per regolare questa impostazione, chiamato PendingPips.

extern PendingPips int = 10;

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.

OrderSelect (SellTicket, SELECT_BY_TICKET);

// Chiudi Ordina
if (OrderCloseTime () == 0 && SellTicket> 0 && OrderType () == OP_SELL)
{doppie CloseLots = OrderLots ();

doppia ClosePrice = Chiedi;

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);

se (== soppresso true) SellTicket = 0; }

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,

chiudiamo utilizzando OrderClose (). Se si tratta di un ordine pendente, chiudiamo utilizzando

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

nella variabile commercio Comprare un biglietto:

doppie PendingPrice = Chiudi [0] + (PendingPips * UsePoint);

if (StopLoss> 0) doppia BuyStopLoss = PendingPrice - ( StopLoss * UsePoint);

if (TakeProfit> 0) doppia BuyTakeProfit = PendingPrice + ( TakeProfit * UsePoint);

BuyTicket = OrderSend (Simbolo (), OP_BUYSTOP, Misura di lotto, PendingPrice, UseSlippage,


BuyStopLoss, BuyTakeProfit, "Buy Stop Order", MagicNumber, 0, verde);

40
Predisporre un ordine

SellTicket = 0;

Il codice seguente mostra le modifiche per il blocco di vendita ordine di arresto:

OrderSelect ( Comprare un biglietto, SELECT_BY_TICKET);

// 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);

se (== Closed vero) BuyTicket = 0; }

PendingPrice = Chiudi [0] - (PendingPips * UsePoint);

Doppio SellStopLoss = PendingPrice + (StopLoss * UsePoint); Doppio SellTakeProfit = PendingPrice -


(TakeProfit * UsePoint);

SellTicket = OrderSend (Simbolo (), OP_SELLSTOP, Misura di lotto, PendingPrice, UseSlippage,


SellStopLoss, SellTakeProfit, "Sell Stop Order", MagicNumber, 0, Rosso);

BuyTicket = 0;

Il codice completo per entrambi questi consulenti esperti è in Appendice A.

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ù

recenti che utilizzano MetaTrader non supportano questo comportamento.

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

per la OrderModify () funzione:

bool OrderModify (int Biglietto, Doppio Prezzo, Doppio StopLoss, Doppio Avere un profitto,
appuntamento Scadenza, colore freccia = CLR_NONE)

• Biglietto - Il numero del biglietto della fine di modificare.

• Prezzo - Il nuovo prezzo ordine pendente.

• StopLoss - Il nuovo prezzo di stop loss.

• Avere un profitto - Il nuovo prezzo take profit.

• Scadenza - Il nuovo tempo di scadenza per gli ordini in sospeso.

• 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à

stato riempito - vale a dire ha colpito il suo prezzo ordine.

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.

Se non si modifica di un parametro particolare, dobbiamo passare il valore originale sul


OrderModify () funzione. Ad esempio, se stiamo modificando solo la perdita di arresto per un ordine pendente, allora dobbiamo recuperare il

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.

L'aggiunta di Stop Loss e Take Profit ad un ordine esistente

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

numero del biglietto sarà pari a - 1.

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);

doppio OpenPrice = OrderOpenPrice ();

if (StopLoss> 0) doppia BuyStopLoss = OpenPrice - (StopLoss * UsePoint); if (TakeProfit> 0) doppia BuyTakeProfit =


OpenPrice + (TakeProfit * UsePoint);

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

variabile il numero del biglietto dell'ordine.

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

prendere prezzo profitto.

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

Modifica di un prezzo Ordine Pendente

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:

OrderSelect (biglietteria, SELECT_BY_TICKET);

if (NewPendingPrice! = OrderOpenPrice ())


{Bool TicketMod = OrderModify (biglietteria, NewPendingPrice, OrderStopLoss (),

OrderTakeProfit (), 0);


}

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

ordine pendente, non è lo stesso che l'attuale prezzo di ordine pendente.

Per OrderModify (), specifichiamo il nostro biglietto ordine, il nuovo prezzo ordine memorizzato in NewPendingPrice,

e lo stop loss invariato e prendere i valori di profitto rappresentati da OrderStopLoss () e


OrderTakeProfit (). Non stiamo usando un tempo di scadenza per questo ordine, in modo da utilizzare 0 per il parametro di scadenza.

Verifica delle fermate e in attesa di ordine Prezzi

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

distanza minima non è garantita.

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

come Alpari dispongono di più livelli di arresto (almeno 8 pip).

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

Il MarketInfo () funzione con la MODE_STOPLEVEL parametro viene utilizzato per recuperare


Smettere di
il livello di stop per un simbolo di valuta. Il livello di stop è espresso come numero intero, e
deve essere convertito in un valore frazionario utilizzando Punto. Fig. 3.1 - i livelli di stop

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:

doppia StopLevel = MarketInfo (Simbolo (), MODE_STOPLEVEL) * Point;

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.

Useremo il StopLevel valore abbiamo calcolato in precedenza.

doppia UpperStopLevel = Chiedi + StopLevel;

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

momento che è superiore al prezzo.

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.

doppia LowerStopLevel = Bid ​- StopLevel;

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.

Verifica Stop Loss e Take Profit prezzi

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

doppio MinStop = 5 * UsePoint;

if (BuyStopLoss> LowerStopLevel) BuyStopLoss = LowerStopLevel - MinStop; if (BuyTakeProfit <UpperStopLevel) BuyTakeProfit


= UpperStopLevel + MinStop;

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

per regolare questo importo.

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

stessa cosa per il nostro take profit.

Per controllare lo stop loss e take profit per un ordine di vendita, abbiamo semplicemente invertire i calcoli:

if (SellTakeProfit> LowerStopLevel) SellTakeProfit = LowerStopLevel - MinStop; if (SellStopLoss <UpperStopLevel) SellStopLoss =


UpperStopLevel + MinStop;

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

come fare questo:

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;

Stampa ( "stop loss non è valido ed è stato regolato automaticamente"); }

48
Avanzata Ordine Placement

Verifica In attesa di ordine Prezzi

Ecco come abbiamo verificare il prezzo ordine in attesa per un acquisto di arresto o vendiamo ordine limite. Il PendingPrice

negozi di variabili Il nostro prezzo ordine pendente:

if (PendingPrice <UpperStopLevel) PendingPrice = UpperStopLevel + MinStop;

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:

if (PendingPrice> UpperStopLevel) PendingPrice = UpperStopLevel - MinStop;

Calcolo Superficie lotto

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

perdere per il commercio.

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.

Gestione del denaro

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.

extern double EquityPercent = 2; extern double


StopLoss = 50;

In primo luogo, abbiamo bisogno di calcolare l'importo del patrimonio netto indicato dal EquityPercent. Se abbiamo un equilibrio di $ 10.000, e che

stiamo usando 2% del nostro capitale, quindi il calcolo è il seguente:

doppio RiskAmount = AccountEquity () * (EquityPercent / 100);

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.

doppia TickValue = MarketInfo (Simbolo (), MODE_TICKVALUE); if (Point == 0.001 || Point ==


0,00001) TickValue * = 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

dimensione del lotto:

doppie CalcLots = (RiskAmount / StopLoss) / TickValue;

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

valore viene memorizzato nella CalcLots variabile.

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

stretti e / o grandi valori di prendere profitto.

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

trasformare il nostro calcolo dimensione del lotto e si spegne:

// 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);

doppia TickValue = MarketInfo (Simbolo (), MODE_TICKVALUE); if (cifre == 3 || cifre == 5)


TickValue * = 10; doppie CalcLots = (RiskAmount / StopLoss) / TickValue; Misura di doppia =
CalcLots; }

Misura di altro = FixedLotSize;

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.

Se DynamicLotSize è falso, semplicemente assegna il valore di

FixedLotSize a Misura di lotto. Il Misura di lotto variabile sarà passato al OrderSend () funzionano come la dimensione del lotto per l'ordine.

Dimensioni Verifica Lot

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.

Controlliamo la dimensione minima e massima molto prima. Il MarketInfo () funzione, utilizzando il


MODE_MINLOT e MODE_MAXLOT parametri, verranno utilizzati per confrontare la dimensione del lotto corrente alla dimensione minima e massima

lotto. Se la dimensione del lotto non è valido, esso verrà automaticamente ridimensionata al minimo o massimo.

if (Misura di lotto <MarketInfo (Simbolo (), MODE_MINLOT))


{Misura di lotto = MarketInfo (Simbolo (), MODE_MINLOT); }

51
E XPERT UN dvisor P ROGRAMMAZIONE

else if (Misura di lotto> MarketInfo (Simbolo (), MODE_MAXLOT))


{Misura di lotto = MarketInfo (Simbolo (), MODE_MAXLOT); }

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:

if (MarketInfo (Simbolo (), MODE_LOTSTEP) == 0,1)


{Misura di lotto = NormalizeDouble (Misura di lotto, 1); }

Misura di altro = NormalizeDouble (Misura di lotto, 2);

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

per molto dimensionamento.

Altre considerazioni commerciale

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

operazioni commerciali, dobbiamo verificare se il filo esecuzione commercio è attualmente utilizzato.

La funzione IsTradeContextBusy () restituirà true se il thread di esecuzione commerciale è occupato, altrimenti false. Chiameremo questa

funzione è sufficiente prima di chiamare qualsiasi funzione di trading, tra cui

OrderSend (), OrderClose (), OrderDelete () o OrderModify ().

52
Avanzata Ordine Placement

Ecco come controlliamo il thread di esecuzione negoziazione utilizzando IsTradeContextBusy ():

while (IsTradeContextBusy ()) del sonno (10);

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

commercio dopo certe condizioni di errore.

Variabili predefinite rinfrescanti

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

prezzi più attuali.

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()

funzione di riferimento i prezzi attuali grafico.

Gestione degli errori

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

memorizzare il valore di GetLastError ().

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

è molto descrittivo, ma è meglio di niente. Avremo bisogno di aggiungere un

# includere economico stdlib.mqh nella parte superiore del nostro file.

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,

includeremo parametri commerciali come la dimensione del lotto e il prezzo dell'ordine.

// sezione preprocessore
# includere <stdlib.mqh>

// int CodiceErrore variabile


globale;

// 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 ();

stringa ErrDesc = ErrorDescription (ErrorCode);

stringa ErrAlert = StringConcatenate ( "Open Buy Stop Order - Errore",


ErrorCode, ":", ErrDesc); Alert (ErrAlert);

54
Avanzata Ordine Placement

stringa ErrLog = StringConcatenate ( "Offerta", Bid, "Chiedi:" Chiedi, "Prezzo:",


PendingPrice, "Lotti:", Misura di lotto); Print (ErrLog); }

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

avviso, che viene memorizzato nella variabile stringa ErrAlert.

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

più per coniugare costanti stringa e variabili:

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

Fig. 3.2 - Messaggio di avviso

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 è

che la dimensione del lotto è valido.

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

non è valido." Ecco un esempio di come si può fare questo:

ErrorCode = GetLastError ();

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

Mettere tutto insieme

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:

# protette da copyright "Andrew Young"


# includere <stdlib.mqh>

// Le variabili esterne
extern bool DynamicLotSize = true; extern double
EquityPercent = 2; extern double FixedLotSize = 0,1;

extern double StopLoss = 50; extern double


TakeProfit = 100;

extern int Unità = 5; extern int MagicNumber =


123;

extern int FastMAPeriod = 10; extern int


SlowMAPeriod = 20;

// Le variabili globali int


BuyTicket; int SellTicket;

doppio UsePoint; int


UseSlippage;

int CodiceErrore;

Abbiamo aggiunto la # includere economico del stdlib.mqh file che contiene il


Descrizione dell'errore() funzione per la nostra routine di gestione degli errori. Abbiamo aggiunto tre variabili esterne per il dimensionamento molto, e una

variabile globale per il codice di errore.

Il codice seguente va all'inizio del inizio() funzione:

// 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

// calcolo della dimensione del lotto se


(DynamicLotSize == true)
{Double RiskAmount = AccountEquity () * (EquityPercent / 100);

doppia TickValue = MarketInfo (Simbolo (), MODE_TICKVALUE); if (Point == 0.001 ||


Point == 0,00001) TickValue * = 10; doppie CalcLots = (RiskAmount / StopLoss) /
TickValue; Misura di doppia = CalcLots; }

Misura di altro = FixedLotSize;

// verifica Superficie del terreno


if (Misura di lotto <MarketInfo (Simbolo (), MODE_MINLOT))
{Misura di lotto = MarketInfo (Simbolo (), MODE_MINLOT); }

else if (Misura di lotto> MarketInfo (Simbolo (), MODE_MAXLOT))


{Misura di lotto = MarketInfo (Simbolo (), MODE_MAXLOT); }

if (MarketInfo (Simbolo (), MODE_LOTSTEP) == 0,1)


{Misura di lotto = NormalizeDouble (Misura di lotto, 1); }

Misura di altro = NormalizeDouble (Misura di lotto, 2);

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

OrderSelect (SellTicket, SELECT_BY_TICKET);

if (OrderCloseTime () == 0 && SellTicket> 0)


{doppie CloseLots = OrderLots ();

while (IsTradeContextBusy ()) del sonno (10);

RefreshRates ();
doppia ClosePrice = Chiedi;

bool Chiuso = OrderClose (SellTicket, CloseLots, ClosePrice, UseSlippage, Rosso);

58
Avanzata Ordine Placement

// Gestione degli errori se


(Closed == false)
{ErrorCode = GetLastError ();

stringa ErrDesc = ErrorDescription (ErrorCode);

stringa ErrAlert = StringConcatenate ( "Chiudi Sell Order - Errore",


ErrorCode, ":", ErrDesc); Alert
(ErrAlert);

stringa ErrLog = StringConcatenate ( "Chiedi:", chiediamo: "Lotti:", Misura di lotto,


"Biglietto:", SellTicket); Print (ErrLog);
}

// buy ordine aperto


while (IsTradeContextBusy ()) del sonno (10); RefreshRates
();

BuyTicket = OrderSend (Simbolo (), OP_BUY, Misura di lotto, Chiedi, UseSlippage, 0,0,
"Buy Order", MagicNumber, 0, verde);

// Gestione degli errori se


(BuyTicket == -1)
{ErrorCode = GetLastError ();

ErrDesc = ErrorDescription (ErrorCode);


ErrAlert = StringConcatenate ( "Open Buy Order - Errore",
ErrorCode, ":", ErrDesc); Alert
(ErrAlert);

ErrLog = StringConcatenate ( "Chiedi:" Chiedi, "Lotti:", Misura di lotto); Print (ErrLog); }

// Order modifica il resto

{OrderSelect (BuyTicket, SELECT_BY_TICKET);

doppio OpenPrice = OrderOpenPrice ();

// Calcola livello di arresto


doppia StopLevel = MarketInfo (Simbolo (), MODE_STOPLEVEL) * Point;

RefreshRates ();
doppia UpperStopLevel = Chiedi + StopLevel; doppia
LowerStopLevel = Bid ​- StopLevel;

doppio MinStop = 5 * UsePoint;

59
E XPERT UN dvisor P ROGRAMMAZIONE

// Calcola stop loss e take profit


if (StopLoss> 0) doppia BuyStopLoss = OpenPrice - (StopLoss * UsePoint); if (TakeProfit> 0) doppia BuyTakeProfit =
OpenPrice + (TakeProfit * UsePoint);

// Verifica stop loss e take profit


if (BuyStopLoss> 0 && BuyStopLoss> LowerStopLevel)
{BuyStopLoss = LowerStopLevel - MinStop; }

if (BuyTakeProfit> 0 && BuyTakeProfit <UpperStopLevel)


{BuyTakeProfit = UpperStopLevel + MinStop; }

// Modifica ordine
if (IsTradeContextBusy ()) del sonno (10);

if (BuyStopLoss> 0 || BuyTakeProfit> 0)
{Bool TicketMod = OrderModify (BuyTicket, OpenPrice, BuyStopLoss,

BuyTakeProfit, 0);

// Gestione degli errori se


(TicketMod == false)
{ ErrorCode = GetLastError ();

ErrDesc = ErrorDescription (ErrorCode);


ErrAlert = StringConcatenate ( "Modifica Buy Order - Errore",
ErrorCode, ":", ErrDesc); Alert
(ErrAlert);

ErrLog = StringConcatenate ( "Chiedi:" Chiedi, "Bid:", Bid, "Biglietto:",


BuyTicket, "Stop", BuyStopLoss, "Profit:", BuyTakeProfit); Print (ErrLog); }}}

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

errore viene eseguito. Quindi, apriamo l'ordine di acquisto di mercato utilizzando

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

errori dal modifica ordine.

Ecco come abbiamo modificare il codice per un ordine di acquisto di arresto in attesa:

// Chiudi ordine
OrderSelect (SellTicket, SELECT_BY_TICKET);

if (OrderCloseTime () == 0 && SellTicket> 0 && OrderType () == OP_SELL)


{doppie CloseLots = OrderLots ();

while (IsTradeContextBusy ()) del sonno (10);

RefreshRates (); doppia ClosePrice =


Chiedi;

bool Chiuso = OrderClose (SellTicket, CloseLots, ClosePrice, UseSlippage, Rosso);

// Gestione degli errori se


(Closed == false)
{ErrorCode = GetLastError ();

stringa ErrDesc = ErrorDescription (ErrorCode);

stringa ErrAlert = StringConcatenate ( "Chiudi Sell Order - Errore", ErrorCode,


":", ErrDesc); Alert
(ErrAlert);

stringa ErrLog = StringConcatenate ( "Chiedi:", chiediamo: "Lotti:", Misura di lotto,


"Biglietto:", SellTicket); Print (ErrLog); }}

61
E XPERT UN dvisor P ROGRAMMAZIONE

// Delete ordine
else if (OrderCloseTime () == 0 && SellTicket> 0 && OrderType () == OP_SELLSTOP)
{Bool Deleted = OrderDelete (SellTicket, Rosso);

se (== soppresso true) SellTicket = 0;

// l'uso, se errore (eliminata ==


false)
{ErrorCode = GetLastError ();

ErrDesc = ErrorDescription (ErrorCode);

ErrAlert = StringConcatenate ( "Elimina Sell Stop Order - Errore", ErrorCode,


":", ErrDesc); Alert
(ErrAlert);

ErrLog = StringConcatenate ( "Chiedi:" Chiedi, "Biglietto:", SellTicket); Print (ErrLog); }}

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 ().

// Calcola livello di arresto


doppia StopLevel = MarketInfo (Simbolo (), MODE_STOPLEVEL) * Point; RefreshRates ();

doppia UpperStopLevel = Chiedi + StopLevel; doppio MinStop =


5 * UsePoint;

// Calcola il prezzo in attesa


doppio PendingPrice = Alto [0] + (PendingPips * UsePoint); if (PendingPrice <UpperStopLevel) PendingPrice =
UpperStopLevel + MinStop;

// Calcola stop loss e take profit


if (StopLoss> 0) doppia BuyStopLoss = PendingPrice - (StopLoss * UsePoint); if (TakeProfit> 0) doppia BuyTakeProfit =
PendingPrice + (TakeProfit * UsePoint);

// Verifica stop loss e take profit UpperStopLevel = PendingPrice + StopLevel;


doppia LowerStopLevel = PendingPrice - StopLevel;

62
Avanzata Ordine Placement

if (BuyStopLoss> 0 && BuyStopLoss> LowerStopLevel)


{ BuyStopLoss = LowerStopLevel - MinStop; }

if (BuyTakeProfit> 0 && BuyTakeProfit <UpperStopLevel)


{ BuyTakeProfit = UpperStopLevel + MinStop; }

// Luogo ordine pendente


if (IsTradeContextBusy ()) del sonno (10);

BuyTicket = OrderSend (Simbolo (), OP_BUYSTOP, Misura di lotto, PendingPrice, UseSlippage,


BuyStopLoss, BuyTakeProfit, "Buy Stop Order", MagicNumber, 0, verde);

// Gestione degli errori se


(BuyTicket == -1)
{ErrorCode = GetLastError ();

ErrDesc = ErrorDescription (ErrorCode);

ErrAlert = StringConcatenate ( "Apri Buy stop Order - Errore", ErrorCode,


":", ErrDesc); Alert
(ErrAlert);

ErrLog = StringConcatenate ( "Chiedi:" Chiedi, "Lotti:" Misura di lotto," Prezzo:", PendingPrice,


"Stop:", BuyStopLoss, "Profit:", BuyTakeProfit); Print (ErrLog); }

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.

Abbiamo poi ricalcolare UpperStopLevel e calcolare il LowerStopLevel

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

diffusione durante la verifica lo stop loss e prendere i prezzi di profitto.

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

possiamo riutilizzare e semplificare il codice.

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ò

risiedere in un esterno includere file o una biblioteca.

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.

Funzione Lot Sizing

Cominciamo con i nostri calcoli dimensione del lotto, come definito a pagina 51:

doppia CalcLotSize (bool argDynamicLotSize, doppia argEquityPercent, doppia argStopLoss,


doppia argFixedLotSize)
{If (argDynamicLotSize == true)

{ doppio RiskAmount = AccountEquity () * (argEquityPercent / 100);

doppia TickValue = MarketInfo (Simbolo (), MODE_TICKVALUE); if (Point == 0.001 || Point ==


0,00001) TickValue * = 10; Misura di doppia = (RiskAmount / argStopLoss) / TickValue; }

Misura di altro = argFixedLotSize;

ritorno (Misura di lotto); }

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 è

identico al codice di calcolo dimensione del lotto da prima. Abbiamo aggiunto un

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

includere il file per l'utilizzo nel nostro programma.

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:

extern bool DynamicLotSize = true; extern double


EquityPercent = 2; extern double FixedLotSize = 0,1;
extern double StopLoss = 50;

Ed ecco come chiamiamo la funzione. Questa linea di codice sarebbe situato all'interno inizio() funzione:

Misura di doppia = CalcLotSize (DynamicStopLoss, EquityPercent, StopLoss, FixedLotSize);

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,

quindi, anche se hanno lo stesso nome, non sono la stessa variabile.

Funzione di verifica Lot

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

prima di utilizzare di passarlo a una funzione dell'ordine:

doppia VerifyLotSize (doppia argLotSize)


{ Se( argLotSize < MarketInfo (Simbolo (), MODE_MINLOT))

{ argLotSize = MarketInfo (Simbolo (), MODE_MINLOT); }

else if (argLotSize> MarketInfo (Simbolo (), MODE_MAXLOT))


{ argLotSize = MarketInfo (Simbolo (), MODE_MAXLOT); }

65
E XPERT UN dvisor P ROGRAMMAZIONE

if (MarketInfo (Simbolo (), MODE_LOTSTEP) == 0,1)


{ argLotSize = NormalizeDouble (argLotSize, 1); }

altro argLotSize = NormalizeDouble (argLotSize, 2);

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.

Funzione Order Placement

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,

avremo bisogno di usare il MarketInfo ()

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

calcolati e verificati prima di chiamare questa funzione:

66
Lavorare con le funzioni

int OpenBuyOrder (string argSymbol, Doppio argLotSize, Doppio argSlippage,


Doppio argMagicNumber, stringa argComment = " Acquista Order ")
{While (IsTradeContextBusy ()) del sonno (10);

// Luogo Buy Order int biglietteria = OrderSend ( argSymbol, OP_BUY, argLotSize, MarketInfo (argSymbol, MODE_ASK),

argSlippage, 0,0, argComment, argMagicNumber, 0, verde);

// Gestione degli errori se


(biglietteria == -1)
{ int ErrorCode = GetLastError ();

stringa ErrDesc = ErrorDescription (ErrorCode);

stringa ErrAlert = StringConcatenate ( "Open Buy Order - Errore",


ErrorCode, ":", ErrDesc); Alert (ErrAlert);

stringa ErrLog = StringConcatenate ( "Bid:", MarketInfo (argSymbol, MODE_BID),


" Chiedere: ", MarketInfo (argSymbol, MODE_ASK)," Molte: ", argLotSize);
Print (ErrLog); }

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.

In attesa Order Placement

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

Ecco il codice per inserire un ordine di acquisto di arresto in attesa:

int OpenBuyStopOrder (string argSymbol, Doppio argLotSize, Doppio argPendingPrice,


Doppio argStopLoss, Doppio argTakeProfit, Doppio argSlippage, Doppio argMagicNumber,
appuntamento argExpiration = 0, string argComment = " Buy Stop Order ")
{While (IsTradeContextBusy ()) del sonno (10);

// Luogo Buy Stop Order


int biglietteria = OrderSend (argSymbol, OP_BUYSTOP, argLotSize, argPendingPrice,
argSlippage, argStopLoss, argTakeProfit, argComment, argMagicNumber,
argExpiration, Verde);

// Gestione degli errori se


(biglietteria == -1)
{ int ErrorCode = GetLastError ();

stringa ErrDesc = ErrorDescription (ErrorCode);

stringa ErrAlert = StringConcatenate ( "Open Buy Stop Order - Errore", ErrorCode,


":", ErrDesc); Alert
(ErrAlert);

stringa ErrLog = StringConcatenate ( "Chiedi:", MarketInfo (argSymbol, MODE_ASK),


"Lotti:", argLotSize," Prezzo: "argPendingPrice," Stop "argStopLoss, "Profit:", argTakeProfit," scadenza:",
TimeToStr (argExpiration));
Print (ErrLog); }

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

Funzione ordine di chiusura

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:

bool CloseBuyOrder (string argSymbol, int argCloseTicket, Doppio argSlippage)


{OrderSelect (argCloseTicket, SELECT_BY_TICKET);

if (OrderCloseTime () == 0)
{doppie CloseLots = OrderLots ();

while (IsTradeContextBusy ()) del sonno (10);

double ClosePrice = MarketInfo (argSymbol, MODE_ASK);

bool Chiuso = OrderClose ( argCloseTicket, CloseLots, ClosePrice, argSlippage, Rosso);

if (Closed == false)
{Int ErrorCode = GetLastError ();

stringa ErrDesc = ErrorDescription (ErrorCode);

stringa ErrAlert = StringConcatenate ( "Chiudere Buy Order - Errore:" ErrorCode,


":", ErrDesc); Alert
(ErrAlert);

stringa ErrLog = StringConcatenate ( "biglietto:", argCloseTicket," Chiedere: ",


MarketInfo (argSymbol, MODE_ASK)); Print (ErrLog);
}}

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

In attesa Order Chiudi Funzione

Ecco una funzione per chiudere un unico ordine pendente. Questo funziona su tutti i tipi di ordini in sospeso, comprare e vendere.

bool ClosePendingOrder (string argSymbol, int argCloseTicket, Doppio argSlippage)


{OrderSelect (argCloseTicket, SELECT_BY_TICKET);

if (OrderCloseTime () == 0)
{While (IsTradeContextBusy ()) del sonno (10);

bool Deleted = OrderDelete (argCloseTicket, Rosso);

if (eliminata == false)
{Int ErrorCode = GetLastError ();

stringa ErrDesc = ErrorDescription (ErrorCode);

stringa ErrAlert = StringConcatenate ( "Chiudi Ordine Pendente - Errore:",


ErrorCode, ":", ErrDesc); Alert (ErrAlert);

stringa ErrLog = StringConcatenate ( "biglietto:", argCloseTicket,


"Bid:", MarketInfo (argSymbol, MODE_BID), "Chiedi:", MarketInfo
(argSymbol, MODE_ASK)); Print (ErrLog); }}

ritorno (soppresso); }

Stop Loss & Take Funzioni di calcolo Profit

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.

Ecco la funzione di calcolare uno stop loss vendita in pips:

doppia CalcBuyStopLoss (string argSymbol, int argStopLoss, Doppio argOpenPrice)


{If (argStopLoss == 0) return (0);

doppia BuyStopLoss = argOpenPrice - (argStopLoss * PipPoint (argSymbol)); ritorno (BuyStopLoss); }

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

arresto, visualizzare un messaggio di errore, o automaticamente adeguare il prezzo.

Qui è la funzione per calcolare un take profit vendita in pip:

doppia CalcBuyTakeProfit (string argSymbol, int argTakeProfit, Doppio argOpenPrice)


{If (argTakeProfit == 0) return (0);

doppio BuyTakeProfit = OpenPrice + (argTakeProfit * PipPoint (argSymbol)); ritorno (BuyTakeProfit); }

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.

Arresto livello di verifica

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

bool VerifyUpperStopLevel (string argSymbol, Doppio argVerifyPrice,


Doppio argOpenPrice = 0) { doppia StopLevel = MarketInfo (argSymbol, MODE_STOPLEVEL) * Point;

if (argOpenPrice == 0) doppia OpenPrice = MarketInfo (argSymbol, MODE_ASK); altro OpenPrice = argOpenPrice;

doppio UpperStopLevel = OpenPrice + StopLevel;

if (argVerifyPrice> UpperStopLevel) bool StopVerify = true; altro StopVerify = false;

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:

bool verificata = VerifyUpperStopLevel (Simbolo (), SellStopLoss);

se (Verified == false) alert ( "Sell stop loss 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 =

MarketInfo (argSymbol, MODE_STOPLEVEL) * Point;

if (argOpenPrice == 0) doppia OpenPrice = MarketInfo (argSymbol, MODE_ASK); altro OpenPrice = argOpenPrice;

doppio UpperStopLevel = OpenPrice + StopLevel;

72

Potrebbero piacerti anche