Você está na página 1de 36

'Guia passo a passo para iniciantes para escrever um Expert Advisor n...

1 de 36

https://www.mql5.com/pt/articles/100

Download MetaTrader 5

7 621
SAMUEL OLOWOYO

Introduo
Este artigo destinado a iniciantes que desejam aprender como escrever
Consultores Especialistas simples na nova linguagem MQL5. Ns comearemos
primeiro definindo o que queremos que o nosso CE (Consultor Especialista)
faa, e descrio ento passaremos para como ns queremos que o CE o faa.

1. Estratgia de negociao
O que o nosso CE far:
Ele ir monitorar um indicador particular e, quando uma certa condio
for alcanada (ou certas condies foram alcanadas), ele ir colocar
uma negociao (tanto uma posio curta/vendida ou longa/comprada),
dependendo da condio presente que foi alcanada.
O mencionado acima chamado de estratgia de negociao. Antes que voc
possa escrever um CE, voc precisa primeiro desenvolver a estratgia que voc
deseja automatizar no CE. Ento, neste caso, deixe-nos modificar a afirmao
acima de forma que ela reflita a estratgia que ns queremos desenvolver no
CE.
Ns utilizaremos um indicador chamado mdia mvel com um perodo de
8 (voc pode escolher qualquer perodo, mas para os propsitos da nossa
estratgia, ns usaremos 8).
Queremos que o nosso CE oferea uma negociao longa (compra)
quando a mdia mvel-8 (para o propsito neste assunto, eu irei me
referir a ela como MM-8) estiver aumentando e o preo estiver acima
dela, e oferecer uma negociao curta (venda) quando a MM-8 estiver
diminuindo e o preo estiver abaixo dela.
Tambm utilizaremos outro indicador chamado movimento direcional
mdio (ADX) com perodo 8 tambm para nos ajudar a determinar se o
mercado est em tendncia ou no. Estamos fazendo isso porque apenas
queremos entrar na negociao quando o mercado estiver em tendncia
e relaxar quando o mercado estiver variando (isto , sem tendncia).
Para alcanar isso, apenas ofereceremos a nossa negociao (comprar ou
vender) quando as condies acima forem atendidas e o valor do ADX for

08/12/2015 01:19

'Guia passo a passo para iniciantes para escrever um Expert Advisor n...

2 de 36

https://www.mql5.com/pt/articles/100

maior que 22. Se o ADX for maior do que 22 porm diminuindo, ou o ADX
for menor do que 22, no negociaremos, mesmo que a condio B tenha
sido atendida.
Tambm queremos nos proteger definindo uma ordem para parar perda
(ou stop loss) de 30 pontos, e para o nosso alvo de lucro; definiremos
como objetivo um lucro de 100 pontos.
Tambm queremos que nosso CE procure por oportunidades de
compra/venda somente quando uma nova barra tenha sido formada e
tambm queremos nos certificar que abrimos uma posio de compra, se
as condies de compra forem atendidas e j no tivermos uma em
aberto, e abrir uma posio de venda quando as condies de venda
forem atendidas e j no tivermos uma em aberto.
Agora desenvolvemos a nossa estratgia; a hora de comear a escrever o
nosso cdigo.

2. Escrever um Expert Advisor


2.1 Assistente do MQL5
Inicie com a execuo do editor de linguagem do MetaQuotes 5. Pressione
Ctrl+N ou clique no boto Novo na barra do menu.

Figura 1. Iniciando um novo documento do MQL5

Na janela do instalador do MQL5, selecione consultor especialista e clique em


"Prximo" como mostrado na figura 2:

08/12/2015 01:19

'Guia passo a passo para iniciantes para escrever um Expert Advisor n...

3 de 36

https://www.mql5.com/pt/articles/100

Figura 2. Selecionando um tipo de programa

Na prxima janela, digite o nome que voc quer dar ao seu CE na caixa Nome.
Neste caso, eu digitei My_First_EA. Voc pode ento digitar o seu nome na
caixa Autor e tambm o endereo da sua pgina da internet ou endereo de
e-mail na caixa Link (se voc tiver um).

Figura 3. Propriedades gerais do consultor especialista

J que queremos ser capazes de mudar alguns dos parmetros para o nosso CE
de forma a ver quais dos valores podem nos fornecer melhor resultado, ns
iremos adicion-los clicando no boto "Adicionar".

08/12/2015 01:19

'Guia passo a passo para iniciantes para escrever um Expert Advisor n...

4 de 36

https://www.mql5.com/pt/articles/100

Figura 4. Configurando os parmetros de entrada do CE

Em nosso CE, queremos ser capazes de experimentar com as nossas


configuraes de ordem do tipo parar perda, obter lucro, perodo ADX e perodo
de mdia mvel, ento iremos defini-los nesse momento.
Clique duas vezes sob a seo Nome e digite o nome do parmetro, ento
clique duas vezes sobre o Tipo para selecionar o tipo de dados para o
parmetro e clique duas vezes sob a seo Valor inicial e digite o valor inicial
para o parmetro.
Quando terminar, ele deve se parecer com isto:

Figura 5. Tipos de dados dos parmetros de entrada do CE

08/12/2015 01:19

'Guia passo a passo para iniciantes para escrever um Expert Advisor n...

5 de 36

https://www.mql5.com/pt/articles/100

Como pode ser visto acima, foi selecionado o tipo de dado inteiro (int) para
todos os parmetros. Vamos falar um pouco sobre tipos de dados.
char: O tipo char toma 1 byte de memria (8 bits) e permite expressar
em notao binria 2^8=256 valores. O tipo char pode conter ambos
valores positivos e negativos. A mudana de valores de -128 a 127.
uchar : O tipo inteiro uchar tambm ocupa 1 byte de memria, assim
como o tipo de char, mas ao contrrio dele o uchar destina-se apenas a
valores positivos. O valor mnimo zero, o valor mximo 255. A
primeira letra u no nome do tipo uchar a abreviao para no assinado.
short: O tamanho do tipo short de 2 bytes (16 bits) e,
consequentemente, ele segue expressando a faixa de valores igual a 2
para a potncia 16: 2^16 = 65 536. Uma vez que o tipo short um tipo
assinado, ele contm ambos valores positivos e negativos, a faixa de
valores est entre -32 768 e 32 767.
ushort: O tipo no assinado short o tipo ushort, que tambm possui
um tamanho de 2 bytes. O valor mnimo 0, e o valor mximo 65 535.
int : O tamanho do tipo int de 4 bytes (32 bits). O valor mnimo -2
147 483 648, o valor mximo 2 147 483 647.
uint : O tipo inteiro no assinado o uint. Ele toma 4 bytes de memria
e permite expressar inteiros de 0 a 4 294 967 295.
long : O tamanho do tipo long de 8 bytes (64 bits). O valor mnimo
-9 223 372 036 854 775 808, o valor mximo 9 223 372 036 854 775
807.
ulong : O tipo ulong tambm ocupa 8 bytes e pode armazenar valores
de 0 a 18 446 744 073 709 551 615.
Pela descrio acima dos vrios tipos de dados, os tipos inteiros no assinados
no so projetados para armazenar valores negativos, qualquer tentativa de
configurar um valor negativo pode levar a consequncias inesperadas. Por
exemplo, se voc quer armazenar valores negativos, voc no pode
armazen-los dentro dos tipos no assinados (isto , uchar, uint, ushort, ulong).
Voltando ao ao nosso CE. Olhando os tipos de dados, voc ir concordar que
devemos utilizar os tipos de dados char ou uchar j que os dados que
pretendemos armazenar nestes parmetros sejam menores do que 127 ou 255
respectivamente. Para bom gerenciamento da memria, essa a melhor coisa
a se fazer. Entretanto, pelo propsito desta discusso, iremos nos ater ao tipo
int.
Uma vez que tenha acabado de configurar todos os parmetros necessrios,
clique no boto Finished e o editor do MetaQuotes criar um esqueleto do
cdigo para voc como mostrado na prxima figura.

08/12/2015 01:19

'Guia passo a passo para iniciantes para escrever um Expert Advisor n...

6 de 36

https://www.mql5.com/pt/articles/100

Vamos separar o cdigo em vrias sees para melhor entendimento.


A parte superior (cabealho) do cdigo onde a propriedade do CE definida.
Voc pode ver que aqui esto os valores que voc preencheu durante o
assistente do MQL5 na figura 3.
Nesta seo do cdigo, voc pode definir parmetros adicionais como descrio
(breve descrio do texto do CE), declarar constantes, incluir arquivos adicionais
ou funes mais importantes.

Quando uma declarao comea com um smbolo #, ela chamada de diretiva


de pr-processamento e no termina com um ponto e vrgula ; outros
exemplos de diretivas de pr-processamento incluem:
#define :
A diretiva #define utilizada para uma declarao de constantes. escrita na
forma
#define identificador token_string
O que isso faz substituir cada ocorrncia de identificador no seu cdigo com o
valor token_string.

08/12/2015 01:19

'Guia passo a passo para iniciantes para escrever um Expert Advisor n...

7 de 36

https://www.mql5.com/pt/articles/100

Exemplo:
#define ABC 100
#define COMPANY_NAME "MetaQuotes Software Corp."

Ele substituir todas as ocorrncias de COMPANY_NAME pela sequncia


"MetaQuotes Software Corp." ou ele substituir todas as ocorrncias de ABC
pelo char (ou inteiro) 100 em seu cdigo.
Voc pode ler mais sobre as diretivas de pr-processamento no manual do
MQL5. Vamos agora continuar com a nossa discusso.
A segunda parte do cabealho do nosso cdigo a seo parmetros de
entrada:

Ns especificamos todos os parmetros, que sero utilizados em nosso CE nesta


seo. Estes incluem todas as variveis que sero utilizadas por todas as
funes que ns escreveremos em nosso CE.
Variveis declaradas nesse nvel so chamadas de Variveis globais porque elas
so acessveis por todas as funes em nosso CE que possam precisar delas. Os
parmetros de entrada so parmetros que podem apenas ser modificados fora
do nosso CE. Tambm podemos declarar outras variveis que iremos manipular
no curso do nosso CE mas no estaro disponveis fora do nosso CE nesta
seo.
A seguir est a funo de inicializao do CE. Essa a primeira funo que
chamada quando o CE iniciado ou anexado a um grfico e chamado apenas
uma vez.

Essa seo o melhor local para realizar algumas verificaes importantes de


forma a se certificar de que o nosso CE funciona muito bem.
Podemos decidir se o grfico possui barras suficientes para o nosso CE
funcionar, etc.
Tambm o melhor local para pegar as cotaes que utilizaremos para os
nossos indicadores (indicadores ADX e de mdia mvel).

A funo OnDeinit chamada quando o CE removido do grfico.


Para o nosso CE, ns iremos liberar as cotaes criadas para os nossos
indicadores durante a inicializao nesta seo.

08/12/2015 01:19

'Guia passo a passo para iniciantes para escrever um Expert Advisor n...

8 de 36

https://www.mql5.com/pt/articles/100

Essa funo processa o evento NewTick, que gerado quando uma nova
cotao recebida para um smbolo.
Observe que o consultor especialista no pode realizar operaes de negcios
se o uso dos consultores especialistas no terminal do cliente no estiver
permitido (boto "Auto Negociao").

Figura 6. Auto Negociao est ativada

A maior parte dos nossos cdigos que iro implementar a nossa estratgia de
de negcios, desenvolvidos anteriormente, sero escritos nessa seo.
Agora que j observamos as vrias sees do cdigo para o nosso CE, vamos
comear a adicionar mais contedo a este esqueleto.
2.2 SEO DE PARMETROS DE ENTRADA

//--- input parameters


input int
StopLoss=30;
// Stop Loss
input int
TakeProfit=100;
// Take Profit
input int
ADX_Period=8;
// ADX Period
input int
MA_Period=8;
// Moving Average Period
input int
EA_Magic=12345;
// EA Magic Number
input double
Adx_Min=22.0;
// Minimum ADX Value
input double
Lot=0.1;
// Lots to Trade
//--- Other parameters
int adxHandle; // handle for our ADX indicator
int maHandle; // handle for our Moving Average indicator
double plsDI[],minDI[],adxVal[]; // Dynamic arrays to hold the values o
double maVal[]; // Dynamic array to hold the values of Moving Average f
double p_close; // Variable to store the close value of a bar
int STP, TKP;
// To be used for Stop Loss & Take Profit values

Como voc pode ver, ns adicionamos mais parmetros. Antes de continuarmos


a discutir os novos parmetros, vamos discutir algo que voc pode ver agora. As
duas barras normais // nos permitem inserir comentrios em nossos cdigos.
Com comentrios, somos capazes de saber o que as nossas variveis significam,
ou o que ns estamos fazendo naquele momento de tempo em nosso cdigo.
Tambm fornece um melhor entendimento do nosso cdigo. H duas formas
bsicas de escrever comentrios:
// Outros parmetros ...

Esse um comentrio de uma linha:

08/12/2015 01:19

'Guia passo a passo para iniciantes para escrever um Expert Advisor n...

9 de 36

https://www.mql5.com/pt/articles/100

/*
Esse um comentrio de vrias linhas
*/

Esse um comentrio de vrias linhas. Comentrios com vrias linhas comeam


com o par de smbolos /* e terminam com o par */.
O compilador ignora todos os comentrios quando compilando o cdigo.
Utilizar comentrios de uma linha para os parmetros de entrada uma boa
forma de fazer os usurios do CE entenderem o que esses parmetros
significam. Nas propriedades de entrada do CE, nossos usurios no iro
visualizar o parmetro em si, ao invs disso vero os comentrios como
mostrados abaixo:

Figura 7. Parmetros de entrada do consultor especialista

Agora de volta para o nosso cdigo...


Ns decidimos adicionar parmetros adicionais ao nosso CE. O EA_Magic o
nmero mgico para todas as ordens pelo nosso CE. O valor ADX mnimo
(Adx_Min) declarado como um tipo de dado double. Um double utilizado
para armazenar constantes de ponto flutuante, que contm uma parte inteira,
um ponto decimal, e uma parte de frao.
Exemplo:
double mysum = 123.5678;
double b7 = 0.09876;

O lote para negociao (Lote) representa o volume do instrumento financeiro


que ns queremos negociar. Ento ns declaramos outros parmetros que
utilizaremos:
O adxHandle deve ser utilizado para armazenar a cotao do indicador ADX,
enquanto o maHandle ir armazenar a cotao para o indicador de mdia
mvel. Os plsDI[], minDI[], adxVal[] so arranjos dinmicos que iro
manter os valores de +DI, -DI e ADX principal (do indicador do ADX) para cada
barra do grfico. O maVal[] um arranjo dinmico que ir manter os valores
do indicador da mdia mvel para cada barra do grfico.
A propsito, o que so arranjos dinmicos? Um arranjo dinmico um arranjo
declarado sem uma dimenso. Em outras palavras, nenhum valor especificado
no par de colchetes. Um arranjo esttico, por outro lado, possui suas dimenses
definidas no ponto da declarao.
Exemplo:

08/12/2015 01:19

'Guia passo a passo para iniciantes para escrever um Expert Advisor n...

10 de 36

https://www.mql5.com/pt/articles/100

double allbars[20]; // this will take 20 elements

p_close uma varivel que ns utilizaremos para armazenar o preo de


fechamento para a barra que ns iremos monitorar para verificar as nossas
negociaes de compra/venda.
STP e TKP sero utilizados para armazenar os valores de stop loss e take profit
em nosso CE.
2.3. Seo de inicializao do CE

int OnInit()
{
//--- Get handle for ADX indicator
adxHandle=iADX(NULL,0,ADX_Period);
//--- Get the handle for Moving Average indicator
maHandle=iMA(_Symbol,_Period,MA_Period,0,MODE_EMA,PRICE_CLOSE
//--- What if handle returns Invalid Handle
if(adxHandle<0 || maHandle<0)
{
Alert("Error Creating Handles for indicators - error: ",GetLastEr
}

Aqui ns obtemos as cotaes do nosso indicador utilizando as funes do


indicador respectivo.
A cotao do indicador ADX obtida utilizando a funo iADX. Ele toma o
smbolo do grfico (NULL tambm significa o smbolo atual no grfico atual), o
perodo do grfico/cronograma (0 tambm significa o cronograma atual no
grfico atual), o perodo de mdia do ADX para calcular o ndice (que ns
definimos antes sob a seo de parmetros de entrada) como parmetros ou
argumentos.
int iADX(
string symbol, // symbol name
ENUM_TIMEFRAMES period, // period
int adx_period // averaging period
);

A cotao do indicador da mdia mvel obtida utilizando a funo iMA.


Ela possui os seguintes argumentos:
o smbolo do grfico (que pode ser obtido utilizando _symbol, symbol()
ou NULL para o smbolo atual no grfico atual),
o grfico do perodo/cronograma (que pode ser obtido utilizando
_period, period(), ou 0 para o cronograma atual no grfico atual),
O perodo mdio da mdia mvel (que ns definimos antes sob a seo
parmetros de entrada),
a mudana do indicador relativa ao grfico de preos (a mudana aqui
0),
o tipo de suavizao da mdia mvel (poderia ser qualquer um dos
seguintes mtodos de clculo da mdia: Mdia Simples-MODE_SMA,
Mdia exponencial-MODE_EMA, Mdia suavizada-MODE_SMMA
ou Mdia ponderada linear-MODE_LWMA), e
o preo utilizado para o clculo da mdia (aqui utilizamos o preo de
fechamento).
int iMA(
string symbol, // symbol name
ENUM_TIMEFRAMES period, // period
int ma_period, // averaging period
int ma_shift, // horizontal shift
ENUM_MA_METHOD ma_method, // smoothing type
ENUM_APPLIED_PRICE applied_price // type of price or handle
);

08/12/2015 01:19

'Guia passo a passo para iniciantes para escrever um Expert Advisor n...

11 de 36

https://www.mql5.com/pt/articles/100

Por favor, leia o manual do MQL5 para obter mais detalhes sobre essas funes
do indicador. Ele lhe dar um melhor entendimento de como utilizar cada
indicador.
Ns novamente tentamos verificar a presena de qualquer erro caso a funo
no tenha devolvido a cotao com sucesso, ns receberemos um erro
INVALID_HANDLE. Usamos a funo de alerta para exibir o erro utilizando a
funo GetlastError.
//--- Let us handle currency pairs with 5 or 3 digit prices instead of
STP = StopLoss;
TKP = TakeProfit;
if(_Digits==5 || _Digits==3)
{
STP = STP*10;
TKP = TKP*10;
}

Decidimos armazenar os valores de parar perdas e obter lucros nas variveis


STP e TKP que declaramos anteriormente. Por que estamos fazendo isso?
porque os valores armazenados nos parmetros de ENTRADA so somente
para leitura, eles no podem ser modificados. Ento aqui ns queremos nos
certificar de que o nosso CE funciona bem com todos os corretores. Digits ou
Digits() retorna o nmero de dgitos decimais determinando a preciso do preo
do smbolo do grfico atual. Para um grfico de preos com 5 dgitos ou 3
dgitos, ns multiplicamos ambos o parar perdas e o obter lucros por 10.
2.4. SEO DE DESINICIALIZAO DO CE

Uma vez que essa funo utilizada sempre que o CE desativado ou


removido de um grfico, ns iremos liberar todas as cotaes de indicadores
que foram criadas durante o processo de inicializao aqui. Ns criamos duas
cotaes, uma para o indicador do ADX e outra cotao para o indicador da
mdia mvel.
Ns utilizaremos a funo IndicatorRelease() para conseguir isso. Leva apenas
um argumento (a cotao do indicador).
bool IndicatorRelease(
int indicator_handle, // indicator handle
);

A funo remove uma cotao do indicador e libera o bloco de clculo do


indicador, se ele no foi utilizado.
2.5 A SEO ONTICK DO CE
A primeira coisa que precisamos fazer verificar se temos barras suficientes no
grfico atual. Podemos obter o total de barras no histrico de qualquer grfico
utilizando a funo Bars. So necessrios dois parmetros, o smbolo (pode ser
obtido utilizando _Symbol ou Symbol(). Esses dois retornam o smbolo atual
para o grfico atual no qual o nosso CE est anexado) e o perodo ou
cronograma do grfico presente (pode ser obtido utilizando Period ou Period().
Esses dois iro retornar o cronograma do grfico atual no qual o CE est
anexado).
Se o total disponvel de barras menos do que 60, ns queremos que o nosso

08/12/2015 01:19

'Guia passo a passo para iniciantes para escrever um Expert Advisor n...

12 de 36

https://www.mql5.com/pt/articles/100

CE relaxe at que ns tenhamos barras o suficiente disponveis no grfico. A


funo Alert exibe uma mensagem em uma janela separada. Ela toma
quaisquer valores separados por vrgulas como parmetros/argumentos. Neste
caso, ns possumos apena um valor de cadeia (string). O retorno sai da
inicializao do nosso CE.

//+------------------------------------------------------------------+
//| Expert tick function
|
//+------------------------------------------------------------------+
void OnTick()
{
// Do we have enough bars to work with
if(Bars(_Symbol,_Period)<60) // if total bars is less than 60 bars
{
Alert("We have less than 60 bars, EA will now exit!!");
return;
}
// We will use the static Old_Time variable to serve the bar time.
// At each OnTick execution we will check the current bar time with the
// If the bar time isn't equal to the saved time, it indicates that we
static datetime Old_Time;
datetime New_Time[1];
bool IsNewBar=false;

// copying the last bar time to the element New_Time[0]


int copied=CopyTime(_Symbol,_Period,0,1,New_Time);
if(copied>0) // ok, the data has been copied successfully
{
if(Old_Time!=New_Time[0]) // if old time isn't equal to new bar t
{
IsNewBar=true;
// if it isn't a first call, the new bar has
if(MQL5InfoInteger(MQL5_DEBUGGING)) Print("We have new bar her
Old_Time=New_Time[0];
// saving bar time
}
}
else
{
Alert("Error in copying historical times data, error =",GetLastEr
ResetLastError();
return;
}
//--- EA should only check for new trade if we have a new bar
if(IsNewBar==false)
{
return;
}
//--- Do we have enough bars to work with
int Mybars=Bars(_Symbol,_Period);
if(Mybars<60) // if total bars is less than 60 bars
{
Alert("We have less than 60 bars, EA will now exit!!");
return;
}

//--- Define some MQL5 Structures we will use for our trade
MqlTick latest_price;
// To be used for getting recent/latest pr
MqlTradeRequest mrequest; // To be used for sending our trade reque
MqlTradeResult mresult;
// To be used to get our trade results
MqlRates mrate[];
// To be used to store the prices, volumes
ZeroMemory(mrequest);
// Initialization of mrequest structure

O consultor especialista realizar operaes de negociao no incio de uma


nova barra, ento necessrio resolver o problema com a nova identificao da
barra. Em outras palavras, ns queremos nos certificar de que o nosso CE no
verifique as configuraes longas/curtas a cada variao, ns apenas queremos
que o nosso CE verifique as posies longas/curtas quando houver uma nova
barra.
Comeamos declarando uma varivel datetime esttica Old_Time, que ir
armazenar o tempo da barra. Declaramos ela como esttica porque ns
queremos que o valor seja retido na memria at a prxima utilizao da

08/12/2015 01:19

'Guia passo a passo para iniciantes para escrever um Expert Advisor n...

13 de 36

https://www.mql5.com/pt/articles/100

funo OnTick. Ento seremos capazes de comparar o seu valor com a varivel
New_Time (tambm do tipo de dados datetime), que um arranjo de um
elemento para manter o novo (atual) tempo da barra. Tambm declaramos
uma varivel de tipo de dados bool IsNewBar e configuramos seu valor para
false. Isto porque queremos que esse valor seja VERDADEIRO apenas quando
ns possuirmos uma nova barra.
Utilizamos a funo CopyTime para conseguir o tempo da barra atual. Ela copia
o tempo da barra para o arranjo New_Time com um elemento, se ele for bem
sucedido, ns comparamos o tempo de uma nova barra com o tempo da barra
anterior. Se os tempos no forem iguais, isso significa que temos uma nova
barra, e configuramos a varivel IsNewBar para VERDADEIRO e salvamos o
valor do tempo da barra atual para a varivel Old_Time.
A varivel IsNewBar indica que temos uma barra nova. Se for falso,
terminamos a execuo da funo OnTick.
D uma olhada no cdigo:
if(MQL5InfoInteger(MQL5_DEBUGGING)) Print("We have new bar here "

Ele verifica a execuo do modo de depurao, ele ir imprimir uma mensagem


sobre os tempos da barra quando em modo de depurao, ns iremos
consider-lo mais a frente.
A prxima coisa que queremos fazer aqui verificar se ns temos barras
suficientes para trabalhar. Por que repetir isso? S queremos nos certificar de
que o nosso CE funciona corretamente. Deve-se notar que enquanto a funo
OnInit chamada apenas uma vez quando o CE est anexado a um grfico, a
funo OnTick chamada toda vez que h um novo ponto (cotao de preo).
Voc pode notar que fizemos de forma diferente novamente aqui. Decidimos
armazenar as barras totais no histrico que obtivemos da expresso:
int Mybars=Bars(_Symbol,_Period);

em uma nova varivel, Mybars, declarada dentro da funo OnTick. Esse tipo
de varivel uma varivel local, ao contrrio da varivel que ns declaramos na
seo de PARMETROS DE ENTRADA do nosso cdigo. Enquanto as variveis,
declaradas na seo de parmetros de entrada do nosso cdigo, esto
disponveis para todas as funes dentro do nosso cdigo que possam precisar
delas, variveis declaradas dentro de uma nica funo so limitadas e
disponveis para aquela funo somente. Ela no pode ser utilizada fora daquela
funo.
A seguir, ns declaramos algumas variveis do tipo de estrutura do MQL5
que sero utilizadas nessa seo do nosso CE. O MQL5 possui um nmero
grande de estruturas integradas que torna as coisas bem fceis para os
desenvolvedores do CE. Vamos fazer as estruturas uma aps a outra.
MqlTick
Essa uma estrutura utilizada para armazenar os preos mais recentes de
smbolos.
struct MqlTick
{
datetime time; // Hora da ltima atualizao dos preos
double bid; // preo de compra (Bid) atual
double ask; // Preo de venda (Ask) atual
double last; // Preo da ltima negociao (Last)
ulong volume; // Volume para o ltimo preo atual
};

Qualquer varivel declarada como sendo do tipo MqlTick pode ser facilmente
utilizada para obter os valores atuais de Venda (Ask), Compra (Bid), ltima

08/12/2015 01:19

'Guia passo a passo para iniciantes para escrever um Expert Advisor n...

14 de 36

https://www.mql5.com/pt/articles/100

(Last) eVolume uma vez que voc chama a funo SymbolInfoTick().


Ento ns declaramos latest_price como do tipo MqlTick de forma que
pudssemos utiliz-la para conseguir os preos de venda (Ask) e compra (Bid).
MqlTradeRequest
Esta estrutura utilizada para realizar todos os pedidos de negociao para
uma operao de negociao. Ele contm, em sua estrutura, todos os campos
necessrios para realizar um acordo de negociao.
struct MqlTradeRequest
{
ENUM_TRADE_REQUEST_ACTIONS action; // Trade operation type
ulong magic; // Expert Advisor ID (magic number)
ulong order; // Order ticket
string symbol; // Trade symbol
double volume; // Requested volume for a deal in lots
double price; // Price
double stoplimit; // StopLimit level of the order
double sl; // Stop Loss level of the order
double tp; // Take Profit level of the order
ulong deviation; // Maximal possible deviation from the
requested price
ENUM_ORDER_TYPE type; // Order type
ENUM_ORDER_TYPE_FILLING type_filling; // Order execution type
ENUM_ORDER_TYPE_TIME type_time; // Order execution time
datetime expiration; // Order expiration time (for the orders
of ORDER_TIME_SPECIFIED type)
string comment; // Order comment
};

Qualquer varivel declarada como do tipo MqlTradeRequest pode ser utilizada


para enviar pedidos para nossas operaes de negociao. Aqui ns declaramos
o mrequest como do tipo MqlTradeRequest.
MqlTradeResult
O resultado de qualquer operao de negociao retornado como uma
estrutura especial pr-definida do tipo MqlTradeResult. Qualquer varivel
declarada como do tipo MqlTradeResult ser capaz de acessar os resultados do
pedido de negociao.
struct MqlTradeResult
{
uint retcode; // Operation return code
ulong deal; // Deal ticket, if it is performed
ulong order; // Order ticket, if it is placed
double volume; // Deal volume, confirmed by broker
double price; // Deal price, confirmed by broker
double bid; // Current Bid price
double ask; // Current Ask price
string comment; // Broker comment to operation (by default it
is filled by the operation description)
};

Aqui ns declaramos mresult como sendo do tipo MqlTradeResult.


MqlRates
O preo (aberto, fechado, alto, baixo), a hora, os volumes de cada barra e a
distribuio de um smbolo so armazenados nessa estrutura. Qualquer arranjo
declarado como sendo do tipo MqlRates pode ser utilizado para armazenar
preo, volumes e histrico de diferenas (spread) de um smbolo.

struct MqlRates
{
datetime time; // Period start time
double open; // Open price

08/12/2015 01:19

'Guia passo a passo para iniciantes para escrever um Expert Advisor n...

15 de 36

https://www.mql5.com/pt/articles/100

double high; // The highest price of the period


double low; // The lowest price of the period
double close; // Close price
long tick_volume; // Tick volume
int spread; // Spread
long real_volume; // Trade volume
};

Aqui ns declaramos um arranjo mrate[] que ir ser utilizado para armazenar


essas informaes.
/*

Let's make sure our arrays values for the Rates, ADX Values and MA
is store serially similar to the timeseries array
*/
// the rates arrays
ArraySetAsSeries(mrate,true);
// the ADX DI+values array
ArraySetAsSeries(plsDI,true);
// the ADX DI-values array
ArraySetAsSeries(minDI,true);
// the ADX values arrays
ArraySetAsSeries(adxVal,true);
// the MA-8 values arrays
ArraySetAsSeries(maVal,true);

Em seguida ns decidimos configurar todos os arranjos que ns utilizaremos


para armazenar os detalhes das barras como srie. Isso para nos certificar de
que os valores que sero copiados para os arranjos sero indexados como a
timeseries, isto , 0, 1, 2, 3, (para corresponder com o ndice das barras. Ento
ns utilizamos a funo ArraySetAsSeries().
bool ArraySetAsSeries(
void array[], // array by reference
bool set // true denotes reverse order of indexing
);

Deve-se notar que isso tambm pode ser feito uma vez na seo de
inicializao do nosso cdigo. No entanto, eu decidi mostrar isso nesse
momento para o bem da nossa explicao.

//--- Get the last price quote using the MQL5 MqlTick Structure
if(!SymbolInfoTick(_Symbol,latest_price))
{
Alert("Error getting the latest price quote - error:",GetLastErro
return;
}

Agora ns utilizamos a funo SymbolInfoTick para obter a cotao de preo


mais recente. Essa estrutura toma dois argumentos smbolo do grfico e a
varivel de estrutura MqlTick (latest_price). Novamente, se houver erros, ns
o reportamos.
//--- Get the details of the latest 3 bars
if(CopyRates(_Symbol,_Period,0,3,mrate)<0)
{
Alert("Error copying rates/history data - error:",GetLastError
return;
}

Em seguida, ns copiamos a informao sobre as trs ltimas barras em noso


arranjo do tipo Mqlrates utilizando a funo CopyRates. A funo CopyRates
utilizada para conseguir dados de histrico da estrutura do MqlRates de um
perodo/smbolo em quantidade especfica dentro do arranjo do tipo MqlRates.
int CopyRates(

08/12/2015 01:19

'Guia passo a passo para iniciantes para escrever um Expert Advisor n...

16 de 36

https://www.mql5.com/pt/articles/100

string symbol_name, // symbol name


ENUM_TIMEFRAMES timeframe, // period
int start_pos, // start position
int count, // data count to copy
MqlRates rates_array[] // target array to copy
);

O nome do smbolo obtido utilizando _symbol, o perodo/cronograma atual


obtido utilizando _period. Para a posio de incio, ns comearemos da barra
atual, barra 0 e ns contaremos apenas trs barras, barras 0, 1, e 2. O
resultado ser armazenado em nosso arranjo, mrate[].
O arranjo mrate[] agora contm todas as informaes de preo, tempo,
volumes e distribuio para as barras 0, 1 e 2. Dessa forma para conseguir
detalhes de qualquer barra, ns utilizaremos o seguinte:

mrate[bar_number].bar_property

Por exemplo, ns podemos ter a seguinte informao em cada barra.

mrate[1].time // Bar 1 Start time


mrate[1].open // Bar 1 Open price
mrate[0].high // Bar 0 (current bar) high price, etc

Em seguida ns copiamos todos os valores indicadores nos arranjos dinmicos


que ns declaramos utilizando a funo CopyBuffer.
int CopyBuffer(
int indicator_handle, // indicator handle
int buffer_num, // indicator buffer number
int start_pos, // start position
int count, // amount to copy
double buffer[] // target array to copy
);

A cotao do indicador a cotao que ns criamos na seo OnInit. Quanto a


nmeros de amortecimento, o indicador ADX possui trs amortecimentos:
0 - MAIN_LINE,
1 - PLUSDI_LINE,
2 - MINUSDI_LINE.
O indicador da mdia mvel possui apenas um (1) amortecimento:
0 MAIN_LINE.
Ns copiamos da barra atual (0) nas duas ltimas barras. Ento a quantidade
de registros para copiar 3 (barras 0, 1, e 2). O buffer[] so os arranjos
dinmicos alvo que ns declaramos anteriormente adxVal, plsDI, minDI e
maVal.
Como voc pode ver aqui novamente, ns tentamos capturar qualquer erro que
possa ocorrer em nosso processo de cpia. Se houver um erro, no h
necessidade de prosseguir.
importante observar que as funes CopyBuffer() e CopyRates() retornam ao
nmero total de registros copiados com sucesso enquanto ela retorna -1 em
caso de um erro. por isso que ns verificamos valores menores que 0 (zero)
nas funes verificadores de erro aqui.

//--- Copy the new values of our indicators to buffers (arrays) using t
if(CopyBuffer(adxHandle,0,0,3,adxVal)<0 || CopyBuffer(adxHandle,
|| CopyBuffer(adxHandle,2,0,3,minDI)<0)

08/12/2015 01:19

'Guia passo a passo para iniciantes para escrever um Expert Advisor n...

17 de 36

https://www.mql5.com/pt/articles/100

Alert("Error copying ADX indicator Buffers - error:",GetLastError


return;
}
if(CopyBuffer(maHandle,0,0,3,maVal)<0)
{
Alert("Error copying Moving Average indicator buffer - error:"
return;
}

Nesse momento, queremos verificar se ns j possumos uma posio de


compra ou venda aberta, em outras palavras, ns queremos nos certificar de
que ns possumos UMA negociao de compra ou venda aberta de cada vez.
Ns no queremos abrir uma nova compra se ns j possumos uma, e ns no
queremos abrir uma nova venda se ns j abrimos uma.
Para alcanar isso primeiramente declaramos dois tipos de dados bool variveis
(Buy_opened e Sell_opened) que mantero um valor REAL se j
possuirmos uma posio aberta tanto para compra ou venda.
//--- we
//--- Do
bool
bool

have no errors, so continue


we have positions opened already?
Buy_opened=false; // variable to hold the result of Buy opene
Sell_opened=false; // variable to hold the result of Sell open

if (PositionSelect(_Symbol) ==true) // we have an opened position


{
if (PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY
{
Buy_opened = true; //It is a Buy
}
else if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SEL
{
Sell_opened = true; // It is a Sell
}
}

Ns usamos a funo de negociao PositionSelect para saber se possumos


uma posio aberta. Essa funo retorna VERDADEIRA se j possumos uma
posio aberta e FALSA se no possumos nenhuma.
bool PositionSelect(
string symbol
);

// Symbol name

Ela toma, como o maior argumento/parmetro, o smbolo (par de moedas) que


ns queremos verificar. Aqui ns utilizamos _symbol porque estamos verificando
o smbolo atual (par de moedas).
Se a expresso voltar VERDADEIRA ento queremos verificar se a posio
aberta uma compra ou uma venda. Ns utilizamos a funo
PositionGetInteger para isso. Ela nos d o tipo de posio aberta quando ns
utilizamos ela com o modificadorPOSITION_TYPE. Ela retorna o Position type
identifier
que
pode
tanto
serPOSITION_TYPE_BUY
ou
POSITION_TYPE_SELL
long PositionGetInteger(
ENUM_POSITION_PROPERTY
);

property_id

// Property identifier

Em nosso caso, a utilizamos para determinar qual posio j abrimos. Se for


uma venda, armazenamos um valor VERDADEIRO em Sell_opened e se for
uma compra, armazenamos um valor VERDADEIRO em Buy_opened.
Seremos capazes de utilizar essas duas variveis posteriormente quando
verificarmos as condies de compra e venda posteriormente em nosso cdigo.
Agora hora de armazenar o preo de fechamento para a barra que
utilizaremos para a nossa configurao de compra/venda. Lembre-se que

08/12/2015 01:19

'Guia passo a passo para iniciantes para escrever um Expert Advisor n...

18 de 36

https://www.mql5.com/pt/articles/100

declaramos uma varivel para isso anteriormente

// Copy the bar close price for the previous bar prior to the current b
p_close=mrate[1].close;

// bar 1 close price

Tendo feito isso, iremos agora proceder para o prximo passo.


/*
1. Check for a long/Buy Setup : MA-8 increasing upwards,
previous price close above it, ADX > 22, +DI > -DI
*/
//--- Declare bool type
bool Buy_Condition_1
bool Buy_Condition_2
bool Buy_Condition_3
bool Buy_Condition_4

variables to hold our Buy Conditions


= (maVal[0]>maVal[1]) && (maVal[1]>maVal[
= (p_close > maVal[1]);
// previuos pri
= (adxVal[0]>Adx_Min);
// Current ADX
= (plsDI[0]>minDI[0]);
// +DI greater

//--- Putting all together


if(Buy_Condition_1 && Buy_Condition_2)
{
if(Buy_Condition_3 && Buy_Condition_4)
{
// any opened Buy position?
if (Buy_opened)
{
Alert("We already have a Buy Position!!!");
return;
// Don't open a new Buy Position
}
mrequest.action = TRADE_ACTION_DEAL;
mrequest.price = NormalizeDouble(latest_price.ask,_Digits
mrequest.sl = NormalizeDouble(latest_price.ask - STP*_Point
mrequest.tp = NormalizeDouble(latest_price.ask + TKP*_Point
mrequest.symbol = _Symbol;
mrequest.volume = Lot;
mrequest.magic = EA_Magic;
mrequest.type = ORDER_TYPE_BUY;
mrequest.type_filling = ORDER_FILLING_FOK;
mrequest.deviation=100;
//--- send order
OrderSend(mrequest,mresult);

Agora hora de iniciar a verificao para uma oportunidade de compra.


Vamos organizar a expresso acima conforme ela representa a estratgia que
ns projetamos anteriormente. Ns estamos declarando uma varivel do tipo
bool para cada uma de nossas condies que devem ser atendidas antes que
uma ordem possa ser feito. Uma varivel do tipo boll pode apenas conter
VERDADEIRO ou FALSO. Ento, a nossa estratgia de compra foi dividida em
quatro condies. Se qualquer uma das condies for atendida ou satisfeita,
ento um valor de VERDADEIRO armazenado em nossa varivel do tipo
bool, de modo contrrio, um valor de FALSO ser armazenado. Vamos olhar
pra elas mais uma vez.
bool Buy_Condition_1 = (maVal[0]>maVal[1]) && (maVal[1]>maVal[2

Aqui ns estamos olhando para os valores MA-8 nas barras 0, 1 e 2. Se o


valor de MA-8 na barra atual for maior do que seu valor na barra Barra 1
anterior e tambm o valor de MA-8 na barra 1 for maior do que sei valor na
barra 2, significa que o MA-8 est crescendo para cima. Isso satisfaz uma
das nossas condies para uma configurao de compra.
bool Buy_Condition_2 = (p_close > maVal[1]);

Essa expresso est verificando para ver se o preo de fechamento da barra 1


maior do que o valor de MA-8 no mesmo perodo (perodo da barra). Se o
preo for maior, ento a nossa segunda condio tambm foi satisfeita, e ns
podemos verificar as outras condies. No entanto, se as duas condies que

08/12/2015 01:19

'Guia passo a passo para iniciantes para escrever um Expert Advisor n...

19 de 36

https://www.mql5.com/pt/articles/100

acabamos de considerar no foram atendidas, ento no h necessidade de


verificar outras condies. por isso que decidimos incluir as prximas
expresses dentro dessas duas condies iniciais (expresses).
bool Buy_Condition_3 = (adxVal[0]>Adx_Min);

Agora queremos verificar se o valor atual de ADX (valor de ADX na barra 0)


maior do que o valor de ADX mximo declarado nos parmetros de entrada. Se
essa expresso for verdadeira, isto , o valor atual de ADX maior do que o
valor mnimo necessrio; ns tambm queremos nos certificar de que o valor
plusDI maior do que o valor minusDI. Isso o que alcanamos na prxima
expresso.
bool Buy_Condition_4 = (plsDI[0]>minDI[0]);

Se todas essas condies forem atendidas, isto , se eles retornam verdadeiras,


ento ns queremos nos certificar de que ns no vamos abrir uma nova
posio de compra se ns j possumos uma. hora de verificar o valor da
varivel Buy_opened que declaramos anteriormente em nosso cdigo.
// any opened Buy position?
if (Buy_opened)
{
Alert("We already have a Buy Position!!!");
return;
// Don't open a new Buy Position
}

Se Buy_opened for verdadeira, ns no queremos abrir outra posio de


compra, ento, exibimos um alerta para nos informar e a retornar de forma que
o nosso CE ir agora esperar pela prxima variao. No entanto, se Buy_opened
FALSO, ento preparamos os nossos registros utilizando a varivel do tipo
MqlTradeRequest (mrequest) que declaramos anteriormente para enviar a
nossa ordem.
A ao aqui, que o tipo de operao de negociao,
TRADE_ACTION_DEAL porque ns estamos fazendo uma ordem de
negociao para uma execuo imediata. Se estamos modificando uma
ordem, ento utilizaremosTRADE_ACTION_MODIFY. Para deletar uma
ordem vamos utilizar TRADE_ACTION_REMOVE. Ns utilizamos o
nosso tipo MqlTick latest_price para conseguir o preo preo de venda
mais atual. O preo da ordem stop loss obtido ao subtrair nosso
StopLoss em pontos do Preo de Venda enquanto o preo da ordem
obter lucros obtido ao adicionar nosso TakeProfit em pontos ao Preo
de Venda. Voc tambm observar que utilizamos a funo
NormalizeDouble para os valores de preo de venda, valores de parar
perdas e obter lucros, uma boa prtica sempre normalizar esses preos
para o nmero de dgitos do par de moedas de cmbio antes de envi-los
para o servidor de comercializao.
O symbol o atual smbolo (_Symbol ou Symbol()). O tipo de ordem o
tipo de ordem que ns estamos colocando, aqui ns estamos colocando
uma ordem de compra ORDER_TYPE_BUY. Para uma ordem de venda,
ser ORDER_TYPE_SELL.
A ordem type_filling o tipo de execuo da ordem;
ORDER_FILLING_FOK significa que o acordo pode ser executado
exclusivamente com um volume especfico no preo igual ou melhor do
que o preo especificado pela ordem. Se no houver volume de ordens
suficiente no smbolo ordem, a ordem no ser executada.
A funo OrderSend() toma dois argumentos, a varivel tipo MqlTradeRequest e
a varivel tipo MqlTradeResult.
bool OrderSend(
MqlTradeRequest&

request

// query structure

08/12/2015 01:19

'Guia passo a passo para iniciantes para escrever um Expert Advisor n...

20 de 36

MqlTradeResult&
);

https://www.mql5.com/pt/articles/100

result

// structure of the answer

Como voc pode ver, ns utilizamos o nosso tipo varivel MqlTradeRequest e a


varivel tipo MqlTradeResult ao colocar a nossa ordem utilizando OrderSend.

// get the result code


if(mresult.retcode==10009 || mresult.retcode==10008) //Request
{
Alert("A Buy order has been successfully placed with Ticket
}
else
{
Alert("The Buy order request could not be completed -error:
ResetLastError();
return;
}

Tendo enviado a nossa ordem, utilizaremos a varivel tipo MqlTradeResult para


verificar o resultado da nossa ordem. Se a nossa ordem executada com
sucesso, queremos ser informados, se no, ns queremos saber tambm. Com
o tipo MqlTradeResult varivel mresult podemos acessar o cdigo de
retorno da operao e tambm o nmero do ticket da ordem se a ordem foi
colocada.
O cdigo de retorno 10009 mostra que a ordem OrderSend foi completada com
sucesso, enquanto que 10008 mostra que a nossa ordem foi colocada. por
isso que verificamos para qualquer um desses dois cdigos de retorno. Se
possumos qualquer um deles, temos certeza de que a nossa ordem foi
completa ou foi feita.
Para verificar se h uma oportunidade de venda, verificamos o oposto do que
fizemos para oportunidade de compra exceto o nosso ADX que deve ser maior
do que o valor minimo especificado.
/*
2. Check for a Short/Sell Setup : MA-8 decreasing downwards,
previous price close below it, ADX > 22, -DI > +DI
*/
//--- Declare bool type variables to hold our Sell Conditions
bool Sell_Condition_1 = (maVal[0]<maVal[1]) && (maVal[1]<maVal[
bool Sell_Condition_2 = (p_close <maVal[1]);
bool Sell_Condition_3 = (adxVal[0]>Adx_Min);
bool Sell_Condition_4 = (plsDI[0]<minDI[0]);
//--- Putting all together
if(Sell_Condition_1 && Sell_Condition_2)
{
if(Sell_Condition_3 && Sell_Condition_4)
{
// any opened Sell position?
if (Sell_opened)
{
Alert("We already have a Sell position!!!");
return;
// Don't open a new Sell Position
}
mrequest.action = TRADE_ACTION_DEAL;
mrequest.price = NormalizeDouble(latest_price.bid,_Digits
mrequest.sl = NormalizeDouble(latest_price.bid + STP*
mrequest.tp = NormalizeDouble(latest_price.bid - TKP*
mrequest.symbol = _Symbol;
mrequest.volume = Lot;
mrequest.magic = EA_Magic;
mrequest.type= ORDER_TYPE_SELL;
mrequest.type_filling = ORDER_FILLING_FOK;
mrequest.deviation=100;
//--- send order
OrderSend(mrequest,mresult);

Assim, como fizemos na seo de compra, estamos declarando uma varivel do

08/12/2015 01:19

'Guia passo a passo para iniciantes para escrever um Expert Advisor n...

21 de 36

https://www.mql5.com/pt/articles/100

tipo bool para cada uma de nossas condies que devem ser atendidas antes
que uma ordem possa ser colocada. Uma varivel do tipo boll pode apenas
conter VERDADEIRO ou FALSO. Ento a nossa estratgia de venda foi
quebrada em quatro condies. Se qualquer uma das condies for atendida ou
satisfeita, ento um valor de VERDADEIRO armazenado em nossa varivel
do tipo bool, de modo contrrio, um valor de FALSO ser armazenado. Vamos
olhar para elas uma a uma como ns fizemos para a seo de compra.
bool Sell_Condition_1 = (maVal[0]<maVal[1]) && (maVal[1]<maVal[

Aqui ns estamos olhando para os valores MA-8 nas barras 0, 1 e 2. Se o


valor de MA-8 na barra atual for menor do que seu valor na barra 1 anterior e
tambm o valor de MA-8 na barra 1 for menor do que seu valor na Barra 2,
significa que o MA-8 est decrescendo para baixo. Isso satisfaz uma das
nossas condies para uma configurao de venda.
bool Sell_Condition_2 = (p_close <maVal[1]);

Essa expresso est verificando para ver se o preo de fechamento da barra 1


menor do que o valor de MA-8 no mesmo perodo (perodo da barra 1). Se o
preo for menor, ento a nossa segunda condio tambm foi satisfeita, e
podemos verificar as outras condies. No entanto, se as duas condies que
acabamos de considerar no foram atendidas, ento no h necessidade de
verificar outras condies. por isso que decidimos incluir as prximas
expresses dentro dessas duas condies iniciais (expresses).
bool Sell_Condition_3 = (adxVal[0]>Adx_Min);

Agora queremos verificar se o valor atual de ADX (valor de ADX na barra 0)


maior do que o valor de ADX mximo declarado nos parmetros de entrada. Se
essa expresso for verdadeira, isto , o valor atual de ADX maior do que o
valor mnimo necessrio; tambm queremos nos certificar de que o valor
MinusDI maior do que o valor plusDI. Isso o que alcanamos na prxima
expresso.
bool Sell_Condition_4 = (plsDI[0]<minDI[0]);

Se todas essas condies forem atendidas, isto , se elas retornam verdadeiras,


ento ns queremos nos certificar de que no vamos abrir uma nova posio de
compra se ns j possumos uma. hora de verificar o valor da varivel
Buy_opened que declaramos anteriormente em nosso cdigo.
// any opened Sell position?
if (Sell_opened)
{
Alert("We already have a Sell position!!!");
return;
// Don't open a new Sell Position
}

Se Sell_opened for verdadeira, ns no queremos abrir outra posio de venda,


ento, exibimos um alerta para nos informar e a retornar de forma que o nosso
CE ir agora esperar pela prxima variao. No entanto, se Sell_opened for
FALSO, ento configuramos a nossa ordem de negociao de venda como
fizemos para a ordem de compra.
A maior diferena aqui a forma como calculamos o nosso preo stop loss e o
preo take profit. Tambm j que estamos vendendo, ns vendemos no preo
de cotao; por isso que utilizamos o nosso tipo MqlTick varivel
latest_price para conseguir o preo de cotao mais recente. O outro tipo
aqui, conforme explicado anteriormente, ORDER_TYPE_SELL.
Tambm aqui, utilizamos a funo NormalizeDouble para o preo de compra,
valor do stop loss (parar perdas) e take profit (obter lucros), boa prtica

08/12/2015 01:19

'Guia passo a passo para iniciantes para escrever um Expert Advisor n...

22 de 36

https://www.mql5.com/pt/articles/100

sempre normalizar estes preos ao nmero de dgitos do par de moedas antes


de enviar para o servidor de negociao.
Assim, como fizemos com a nossa ordem de compra, precisamos tambm
verificar se a nossa ordem de venda foi bem sucedida ou no. Ento utilizamos
a mesma expresso do que na nossa ordem de compra.

if(mresult.retcode==10009 || mresult.retcode==10008) //Request


{
Alert("A Sell order has been successfully placed with Ticke
}
else
{
Alert("The Sell order request could not be completed -error
ResetLastError();
return;
}
}

3. Depurando e testando o nosso consultor especialista


Nesse momento, precisamos testar o nosso CE pra sabermos se a nossa
estratgia funciona ou no. Tambm possvel que haja um ou dois erros no
cdigo do nosso CE. Isso ser descoberto no prximo passo.
3.1 Depurando
Depurar o nosso cdigo nos ajuda a ver como o nosso cdigo se desempenha
linha por linha (se ns configurarmos pontos de parada (breakpoints)) e l
podemos notar quaisquer erros ou bugs no nosso cdigo e rapidamente fazer as
correes necessrias antes de utilizar nosso cdigo em uma negociao real.
Aqui vamos passar pelo processo passo a passo de depurar o nosso consultor
especialista, primeiramente, configurando breakpoints e em segundo lugar, sem
breakpoints. Para fazer isso, certifique-se de que voc no fechou o editor.
Primeiramente, vamos selecionar o grfico que queremos utilizar para testar o
nosso CE. Na barra do menu do editor, clique em ferramentas e clique em
Opes como mostrado abaixo:

Figura 8. Configurando opes de depurao

Uma vez que a janela de opes aparece, selecione o par de moeda, e o


perodo/cronograma para utilizar e clique no boto OK:

08/12/2015 01:19

'Guia passo a passo para iniciantes para escrever um Expert Advisor n...

23 de 36

https://www.mql5.com/pt/articles/100

Antes de iniciarmos o depurador, vamos configurar os breakpoints.


Breakpoints nos permitem monitorar o comportamento/desempenho do nosso
cdigo em certas localizaes ou linhas selecionadas. Ao invs de percorrer todo
o cdigo de uma vez, o depurador para sempre que ver um breakpoint,
esperando a sua prxima ao. Com isso, seremos capazes de analisar o nosso
cdigo e monitorar seu comportamento conforme ele alcana cada conjunto de
breakpoints. Ns tambm seremos capazes de avaliar os valores de algumas
das nossas variveis para ver se as coisas de fato esto da forma como foram
visionadas.
Para inserir um breakpoint, v na linha em seu cdigo na qual voc quer inserir
o breakpoint. No lado da mo esquerda, no campo cinza perto da borda da linha
do cdigo, clique duas vezes e voc ver um pequeno boto azul redondo com
um quadrado branco dentro dele. Ou alternativamente, posicione o cursor do
seu mouse em qualquer lugar na linha do cdigo onde voc quer que o
breakpoint aparea e aperte F9. Para remover o breakpoint, pressione F9
novamente ou clique nele duas vezes.

Figura 10. Configurando um breakpoint

Para o nosso cdigo, ns vamos configurar breakpoints em cinco linhas


diferentes.

08/12/2015 01:19

'Guia passo a passo para iniciantes para escrever um Expert Advisor n...

24 de 36

https://www.mql5.com/pt/articles/100

Eu tambm identificarei eles de 1 a 5 para o bem da explicao.


Para continuar, configure o breakpoint nas sete linhas de cdigo como mostrado
na figura abaixo. O breakpoint 1 o que ns criamos acima.

Figura 11. Configurando breakpoints adicionais

Uma vez que tenhamos terminado de configurar os nossos breakpoints,


estamos agora prontos para comear a depurar o nosso cdigo.
Para iniciar o depurador, pressione F5 ou clique no boto verde na barra de
ferramentas do MetaEditor.

Figura 12. Iniciando o depurador

A primeira coisa que o editor faz compilar o cdigo, se houver qualquer erro
no ponto, ele ir exibi-lo e se no houver erro, ele ir lhe avisar que o cdigo foi
compilado com sucesso.

Figura 13. Relatrio de compilao

Por favor observe que o fato de que o cdigo compilou com sucesso no
significa que no existem erros no seu cdigo. Dependendo de como o cdigo
escrito, podem haver erros de execuo. Por exemplo, se qualquer uma das
nossas expresses no avalia corretamente devido a qualquer pequeno
descuido, o cdigo ir compilar corretamente porm pode no executar
corretamente. Muita conversa, vamos ver em ao...

08/12/2015 01:19

'Guia passo a passo para iniciantes para escrever um Expert Advisor n...

25 de 36

https://www.mql5.com/pt/articles/100

Uma vez que o depurador terminou de compilar o cdigo, ele leva voc para o
terminal de comercializao, e anexa o CE ao grfico que voc especificou nas
configuraes das opes do MetaEditor. Ao mesmo tempo, ele mostra para
voc a seo de parmetros de entrada do EA. J que no ainda no estamos
ajustando nada, apenas clique no boto OK.

Figura 14. Parmetros de entrada do consultor especialista para depurao

Voc vai agora ver o CE claramente no canto superior direito do grfico.


Uma vez que ele inicia o OnTick(), ele ir parar assim que ele chegar no nosso
breakpoint 1.

Figura 15. Depurador para no primeiro breakpoint

Voc notar uma seta verde na linha do cdigo. Isso lhe diz que a linha de
cdigo anterior foi executada; estamos agora prontos para executar a linha
atual.
Deixe-me fazer algumas explicaes antes de prosseguirmos. Se voc olhar a
barra de ferramentas do editor, voc observar que os trs botes com setas
curvas que estavam anteriormente em cinza agora esto ativados. Isso
porque estamos agora executando o depurador. Esses botes so utilizados

08/12/2015 01:19

'Guia passo a passo para iniciantes para escrever um Expert Advisor n...

26 de 36

https://www.mql5.com/pt/articles/100

para percorrer o nosso cdigo (entrar, passar ou cima ou sair)

Figura 16. Comando entrar

O entrar utilizado para ir de um passo na execuo do programa para o


prximo passo, entrando em qualquer funo chamada dentro daquela linha de
cdigo. Clique no boto ou pressione F11 para invocar o comando (utilizaremos
esse comando em nossa depurao passo a passo para o nosso cdigo).

Figura 17. Comando passar por cima

O passar por cima, por outro lado no entra na chamada funo dentro
daquela linha de cdigo. clique no boto ou pressione F10 para invocar o
comando

Figura 18. Comando sair

Par executar o passo do programa que um nvel acima, voc clica nesse boto
ou pressiona Shift+F11.
Tambm, na parte inferior do editor, voc ver a janela da caixa de
ferramentas. A aba de depurao nessa janela possui os seguintes
cabealhos:
Arquivo: Isso exibe o nome do arquivo chamado;
Funo: Isso exibe a funo presente do arquivo chamado;
Linha: Isso exibe o nmero da linha de cdigo no arquivo do qual a
funo chamada;
Expresso: Isso onde voc pode digitar o nome de qualquer
expresso/varivel que voc est interessado em monitorar do nosso
cdigo;
Valor: Isso ir exibir o valor da expresso/varivel que ns digitamos na
rea de expresso;
Tipo: Isso exibir o tipo de dados da expresso/varivel que foi
monitorada.
De volta ao processo de depurao...
A prxima coisa que queremos fazer agora inserir as variveis/expresses do
nosso cdigo que ns estamos interessados em monitorar. Certifique-se de
apenar monitorar variveis/expresses que realmente importam para o seu
cdigo. Por exemplo, monitoraremos as seguintes:
Old_Time (tempo antigo da barra);
New_Time[0] (tempo atual da barra);
IsNewBar (bandeira que indica a nova barra);
Mybars (total de barras no histrico) O nosso CE depende disso.
Voc pode adicionar outras como os valores ADX, os valores MA-8, etc.

08/12/2015 01:19

'Guia passo a passo para iniciantes para escrever um Expert Advisor n...

27 de 36

https://www.mql5.com/pt/articles/100

Para adicionar a expresso/varivel, clique duas vezes sob a rea de


expresses ou cliquei direito sob a rea de expresses e selecione Adicionar
como mostrado na figura acima.
Digite a expresso/varivel para monitorar ou observar.

Figura 19. A janela de observao das expresses

Digite todas as variveis/expresses necessrias...

Figura 20. Adicionando expresses ou variveis para observar

Se a varivel no foi declarada ainda, seu tipo "identificador desconhecido"


(exceto as variveis estticas).
Agora, vamos prosseguir...

Figura 21. Comando entrar em ao

Clique no boto entrar ou pressione F11 e observe o que acontece. Continue


pressionando esse boto ou F11 at que voc chegue no breakpoint no 2,
continue at que voc chegue no breakpoint no 4 como mostrado abaixo e

08/12/2015 01:19

'Guia passo a passo para iniciantes para escrever um Expert Advisor n...

28 de 36

https://www.mql5.com/pt/articles/100

observe a janela de observao de expresses.

Figura 22. Observando as expresses ou variveis

Figura 23. Observando as expresses ou variveis

08/12/2015 01:19

'Guia passo a passo para iniciantes para escrever um Expert Advisor n...

29 de 36

https://www.mql5.com/pt/articles/100

Figura 24. Observando as expresses ou variveis

Uma vez que h uma nova variao, ela retornar para a primeira linha do
cdigo na funo OnTick(). E todos os valores das nossas variveis/expresses
agora sero reiniciados porque essa uma nova varivel se qualquer um deles
for declarado como uma varivel esttica. Em nosso caso possumos uma
varivel esttica Old_Time.

Figura 25. Valores das variveis no evento NewTick

Para revisar o processo novamente, continue pressionando a tecla F11 e


continue monitorando as variveis na janela de observao de expresses. Voc
pode parar o depurador e ento remover todos os breakpoints.
Como podemos ver, em modo de depurao ele publica a mensagem "Ns

08/12/2015 01:19

'Guia passo a passo para iniciantes para escrever um Expert Advisor n...

30 de 36

https://www.mql5.com/pt/articles/100

temos uma nova barra aqui...".

Figura 26. Expert Advisor imprime a mensagem no modo de depurao

Iniciando o processo de depurao novamente; mas dessa vez sem breakpoints.


Fique observando a cada variao e se qualquer uma das nossas condies de
compra/venda for satisfeita, ele oferecer uma negociao e j que escrevemos
o nosso cdigo para nos dizer se uma ordem feita com sucesso ou no,
veremos um alerta.

Figura 27. Expert Advisor oferece uma negociao durante a depurao

Acho que voc pode deixar o CE (EA) trabalhando por mais alguns minutos
enquanto voc toma um caf. Quando voc estiver de volta e tiver ganhado
algum dinheiro (brincadeira), ento clique no boto PARAR (vermelho) no
MetaEditor para parar a depurao.

Figura 28. Parando o depurador

08/12/2015 01:19

'Guia passo a passo para iniciantes para escrever um Expert Advisor n...

31 de 36

https://www.mql5.com/pt/articles/100

O que ns fizemos de fato aqui ver que o nosso CE apenas procura uma
operao de comercializao na abertura de uma nova barra e que o nosso CE
funciona de fato. H muito espao para ajustes ao cdigo do nosso CE.
Preciso deixar claro, nesse ponto, que o terminal de comercializao deve ser
conectado internet, caso contrrio, a depurao no funcionar porque o
terminal no capaz de comercializar.
3.2 Testando a nossa estratgia de CE
Agora nesse momento queremos testar o nosso CE utilizando o verificador de
estratgia integrado no terminal de comercializao. Para iniciar o testador de
estratgia, pressione CONTROL+R ou clique no menu Visualizar na barra do
menu do terminal e clique em verificador de estratgia como mostrado abaixo.

Figura 26. Iniciando o teste da estratgia

O verificador (verificador de estrategia) mostrado na parte mais baixa do


terminal. Para voc ver todas as configuraes do verificador, preciso
expandir/redimensionar ele. Para fazer isso, mova o ponteiro do seu mouse
para a ponta mostrada pela seta vermelha (como mostrado abaixo):

Figura 27. Janela do verificador de estratgia

O ponteiro do mouse muda para uma seta com ponta dupla, segure o mouse e
arraste a linha para cima. Pare quando voc descobrir que voc pode ver tudo
na aba de configuraes.

08/12/2015 01:19

'Guia passo a passo para iniciantes para escrever um Expert Advisor n...

32 de 36

https://www.mql5.com/pt/articles/100

Figura 28. Aba de configuraes do verificador de estratgia

1. Selecione o CE que voc quer testar.


2. Selecione o par de moedas que voc quer utilizar para o teste.
3. Selecione um perodo/cronograma para utilizar para o teste.
4. Selecione o perodo personalizado e configure as datas em 5.
5. Configure as datas para o perodo personalizado a ser utilizado no teste.
6. Execuo normal.
7. Selecione a quantidade depositada em USD a ser utilizada para o teste.
8. Configure a otimizao para desabilitar (ns no estamos otimizando
agora, s queremos testar).
9. Clique nesse boto quando voc estiver pronto para comear.
Antes de clicarmos no boto iniciar, vamos olhar as outras abas no verificador.
Aba agentes
O processador utilizado pelo verificador para o teste. Dependendo do tipo de
processador do seu computador. O meu apenas um processador de um (1)
ncleo.

Figura 29. Aba agentes do verificador de estratgia

Uma vez no agente, voc ver algo similar a figura abaixo:

Figura 30. A aba agentes do verificador de estratgia durante um teste

Aba jornal
aonde todos os eventos ocorrendo durante o perodo de teste so exibidos

08/12/2015 01:19

'Guia passo a passo para iniciantes para escrever um Expert Advisor n...

33 de 36

https://www.mql5.com/pt/articles/100

Figura 31. Aba jornal do verificador de estratgia mostrando atividades de comercializao

Aba de entradas
Aqui onde voc pode especificar os parmetros de entrada para o CE.

Figura 32. Aba entradas do verificador de estratgia

Se ns estamos otimizando o nosso CE, ento ns precisaremos configurar os


valores na rea circulada.
O Start o valor que voc quer que comece com o verificador.
O Step a taxa de incremento para o valor que voc selecionou, e
O Stop o valor no qual o verificador ir parar de incrementar o valor
para aquele parmetro.
No entanto, em nosso caso, no estamos otimizando o nosso CE, ento no
precisaremos tocar nisso por enquanto.
Uma vez que tudo estiver pronto, podemos agora voltar a aba de
Configuraes e clicar no boto iniciar. Ento o verificador comea o seu
trabalho. Tudo que voc precisa fazer agora ir e tomar outra xcara de caf,
se quiser, ou, se voc for como eu, pode querer monitorar cada evento e,
ento, ir para a aba jornal.
Aba grfico
Uma vez que voc comear a ver mensagens sobre ordens sendo enviadas para
a aba jornal, voc pode querer voltar-se para uma nova aba chamada grfico
que acabou de ser criada. Uma vez que voc mude para a aba grfico, ver o
grfico aumentando ou diminuindo cada vez mais conforme o caso dependendo
do resultado das suas comercializaes.

Figura 33. O resultado do grfico para o teste do consultor especialista

Aba resultados

08/12/2015 01:19

'Guia passo a passo para iniciantes para escrever um Expert Advisor n...

34 de 36

https://www.mql5.com/pt/articles/100

Uma vez que o teste estiver completo, voc ver outra aba chamada
resultados. Mude para a aba resultados e voc ver o resumo do teste que
ns acabamos de fazer.

Figura 34. A aba dos resultados do verificador de estratgia mostrando o resumo dos resultados do teste

Voc pode ver o lucro bruto total, lucro lquido, comercializaes totais,
comercializaes de perda total e muito mais. muito interessante ver que
temos cerca de out USD 1,450.0 dentro do perodo que foi selecionado para o
nosso teste. Ao menos temos um poco de lucro.
Deixe-me tornar uma coisa muito clara para voc aqui. Voc descobrir que as
configuraes para os parmetros CE que voc v no verificador de estratgia
diferente das configuraes iniciais nos parmetros de entrada do CE. Eu acabei
de demonstrar para voc que possvel mudar qualquer um desses parmetros
de entrada para conseguir o melhor do seu CE. Ao invs de utilizar um perodo
de 8 cada para a mdia mvel e ADX, eu mudei para 10 para a mdia mvel e
14 para o ADX. Eu tambm mudei a stop loss de 30 para 35. Por ltimo, mas
no menos importante, decidi utilizar um cronograma de 2 horas. Lembre-se,
esse o verificador de estratgia.
Se voc quer visualizar um relatrio completo do teste, ento clique direito em
qualquer local da aba resultados, voc ver um menu. Desse menu, selecione
Salvar e relatar.

Figura 35. Salvando o resultado do teste

A janela de dilogo salvo aparecer, digite um nome para o seu relatrio (se
quiser, caso contrrio deixe o nome padro) e clique no boto salvar. Todo o
relatrio ser salvo no formato HTML para voc.
Para visualizar o grfico para o teste que foi realizado, clique em abrir grfico
e voc ver o grfico exibido.

08/12/2015 01:19

'Guia passo a passo para iniciantes para escrever um Expert Advisor n...

35 de 36

https://www.mql5.com/pt/articles/100

Figura 36. O grfico mostrando o teste

Pronto, escrevemos e testamos o nosso CE com sucesso e agora possumos um


resultado para trabalhar. Voc pode agora voltar para a aba de configuraes
de estratgia do verificador de estratgia e testar outros cronogramas/perodos.
Tarefa
Quero que voc conduza o teste utilizando diferentes pares de moedas,
diferentes cronogramas, diferentes stop loss, diferentes take profit e veja como
o CE se desempenha. Voc pode at tentar a nova mdia mvel e os valores
ADX. Como eu disse anteriormente, isso a essncia do verificador de
estratgia. Eu tambm gostaria que voc compartilhasse os seus resultados
comigo.

Concluso
Nesse guia passo a passo ns conseguimos visualizar as etapas bsicas
necessrias para escrever um consultor especialista simples baseado em uma
estratgia de comercializao desenvolvida. Ns tambm vimos como verificar o
nosso CE para erros utilizando o depurador. Tambm discutimos como testar o
desempenho do nosso CE utilizando o verificador de estratgia. Com isso,
conseguimos ver o poder e robustez da nova linguagem MQL5. O nosso CE
ainda no perfeito ou completo j que muitos outros ajustes precisam ainda
ser feitos de forma a utilizar ele para comercializaes reais.
Ainda h mais a aprender e eu quero que voc leia o artigo vrias vezes
juntamente com o manual do MQL5, e tente tudo que voc aprendeu nesse
artigo, eu posso lhe assegurar que voc ser um timo desenvolvedor de CE em
um futuro prximo.
Feliz programao.
Traduzido do Ingls por MetaQuotes Software Corp.
Artigo original: https://www.mql5.com/en/articles/100

Arquivos anexados |
Download ZIP
my_first_ea.mq5
(11.86 KB)
Aviso: Todos os direitos a estes materiais so reservados a MQL5 Ltd. A cpia ou reimpresso destes materiais, no todo

Junte-se a ns download MetaTrader 5!

08/12/2015 01:19

'Guia passo a passo para iniciantes para escrever um Expert Advisor n...

36 de 36

Windows

iPhone/iPad

Mac OS

https://www.mql5.com/pt/articles/100

Android

Linux

Estratgia para Linguagem MQL5 | Biblioteca de Cdigo Fonte | Como escrever um Expert Advisor ou um
indicador | Encomendar o Desenvolvimento de um Expert Advisor
Download MetaTrader 5 | Plataforma de Negociao MetaTrader 5 | Loja de Aplicativos | MQL5 Cloud Network
Sobre | Histria do Site | Termos e Condies | Poltica de Privacidade | Contatos
Copyright 2000-2015, MQL5 Ltd.

08/12/2015 01:19

Você também pode gostar