Escolar Documentos
Profissional Documentos
Cultura Documentos
Nestas pginas, tentaremos esclarecer e entender o mstico e o confuso sobre o MQL4, mostrando-lhes as explicaes detalhadas e exemplos comentados. Nesta srie de captulos, mostrarei como voc pode utilizar a linguagem MQL4 para criar seus Consultores especialistas (Experts Advisors ou simplesmente EA), Indicadores e Scripts. Caso voc seja um programador, ou conhea, a linguagem C ou C++, indubitavelmente voc conhece uma grande parte de MQL4, antes mesmo de comearmos qualquer uma das lies deste curso. Caso voc nunca tenha escrito nenhum programa em nenhuma linguagem computacional, no se preocupe, pois, eu guiarei voc, a fim de entender os conceitos de linguagem de programao em geral.
- Scripts: so programas onde voc automatiza seqncias de trabalho que normalmente fariam manualmente no sistema. Diferentemente dos Customs Indicators e Expert Advisors os Scripts so executados somente uma vez (sob demanda) e no cada vez que uma cota mude. E, naturalmente, no pode acessar funes que trabalham com indicadores.
At agora nos vimos "O que o MQL4" e "Porque usar o MQL4" Agora vamos ver "Onde usar o MQL4". Para escrever seu cdigo em MQL4, como qualquer coisa no mundo, voc necessita escolher um destes dois caminhos : "Caminho Fcil" ou o "Caminho Difcil".
O caminho Difcil
Pelo caminho difcil, voc utiliza o seu editor de textos favorito e utiliza a linha de comandos (command prompt) para compilar seu programa. O NotePad no uma m escolha como editor de textos para sua programao, mas no esquea do seguinte: - Ao salvar seu texto (cdigo) voc deve usar o formato texto simples (sem formataes) - O arquivo deve preferencialmente ser salvo com a extenso .mq4 (isto torna mais fcil abri-lo no editor de textos do MetaTrader, o MetaEditor). Porem voc pode utilizar qualquer extenso que quiser. Depois de salvar o programa voc necessita seguir alguns passos extras para deixar seu programa pronto para ser utilizado. Estes so os passos de compilao. Compilar a ao de transformar o programa que voc escreveu, na linguagem que voc entende, para uma linguagem que o computador possa executar, ou a chamada linguagem de mquina. MetaTrader possui um programa que utilizado para compilar o programa que voc escreveu, este programa se chama MetaLang.Exe. MetaLang.exe um programa que possui 2 parametros de entrada, e que como sada grava um programa com a extenso .ex4 (arquivo este que o MetaTrader entende). - O primeiro parmetro so as opes, e a nica opo disponvel -q (quit). - O segundo parmetro o nome de seu arquivo fonte com o cdigo que voc programou, a este nome voc deve juntar ao caminho completo do diretrio onde ele se encontra (a localizao exata do arquivo em seu computador). Basicamente a sintaxe do compilador por linha de comando possui este modelo metalang | opes | NomeDoArquivo
Vamos a um exemplo para o melhor entendimento 1) busque onde se encontra o arquivo MetaLang,exe. Geralmente ele se encontra no diretorio no qual voce instalou o MetaTrader (No meu caso dm "C:\Archivos de programa\Forex\Interbank FX" 2) Crie um arquivo de lote (Bat) com o nome Compile.Bat (ou qualquer outro nome que voce quiser) 3) Dentro deste arquivo escreva as seguintes linhas (No esquea de modificar o caminho de acordo com sua localizao do MetaTrader
C: CD "C:\Archivos de programa\Forex\Interbank FX\Experts\Scripts" ..\..\MetaLang -q MeuPrimeiroScript.mq4
4) Execute o Arquivo bat a partir da linha e comando - Menu Iniciar -> Executar - Na caixa de texto da janela digite "cmd.exe" (sem as aspas) - Clique em executar - Na nova janela, digite o caminho + nome do arquivo bat, eu gravei ele no diretrio C:\SistemasMT e tecle enter - Voc deve obter uma tela parecida com a de abaixo IMAGEM - Apos isso voc obtm o arquivo MeuPrimeiroScript.mq4 - digite exit e tecle enter na janela de comandos para encerrar o trabalho
O caminho Fcil
Para facilitar nossa vida e evitar esta "perdas de tempo" o MetaTrader disponibilizou uma tima IDE (Integrated Development Editor ou Editor de desenvolvimento integrado) chamado MetaEditor, que possui estas qualidades - Editor de texto com identificao de palavras chaves e smbolos por diferentes cores que aparecem enquanto voc esta construindo ou digitando seu cdigo. Isto facilita muito a vida pois evita que voc use erroneamente palavras chaves durante o processo de desenvolvimento. - Sistema de desenvolvimento com tecnologia MDI (Multi Document Interface ou Interface de documentos mltiplos) isso significa que voc pode ter vrios arquivos abertos ao mesmo tempo em seu editor. - Seu programa facilmente compilado. Simplesmente tecle F5 quando o cdigo que voc quer compilar seja o documento atualmente ativo, isso far que o editor faa todo o trabalho do caminho difcil para voc e disponibilize em um s toque de tecla o arquivo .mq4 que estar pronto para uso (lgico, desde que o arquivo no contenha nenhum erro de semntica ou outro qualquer identificado pelo compilador), caso haja algum erro o mesmo ser indicado e apontado na janela de dialogo do
editor, o que possibilita um acesso mais rpido e fcil a linha onde ocorreu o referido erro - Acesso rpido ao sistema de ajuda, basta colocar o cursor em cima de alguma palavra no seu cdigo, caso esta palavra seja identificada pelo editor como parte integrante da base de MQL4 automaticamente o arquivo de ajuda trar o texto referente aquela palavra. - abaixo a aparncia que tem o MetaEditor, para que voc j v se familiarizando IMAGEM
Meta Editor
Acessando o MetaEditor
No basta voc ter um linguagem de programao a sua disposio, para fazer o que voc necessita para realizar sua anlise ou suas negociaes. Muito mais que isso, voc necessita facilidades e flexibilidades para utilizar sua linguagem. MQL4 no estaria completa se no fornecesse uma ferramenta capaz de dar a voc um mnimo de comodidade e legibilidade a seu trabalho. Para isso existe o MetaEditor. Ele nada mais que um editor de textos avanados, capaz de identificar para voc os vrios aspectos de MQL4, bem como, tornar o processo de compilao de um cdigo seu, muito mais fcil e cmodo. Para chamar o Meta Editor, voc pode acessar seu atalho no Menu Iniciar do Windows, na pasta onde o seu MetaTrader se encontrar. Porem uma maneira mais fcil cham-lo diretamente do MetaTrade, para isso voc possui trs caminhos distintos para chegar a este objetivo. Considere a figura
1) Menu "Ferramentas" e "Editor da Linguagem MetaQuotes" 2) Simplesmente teclando F4 quando estiver no MetaTrader 3) Acessando este cone na Barra de Ferramentas
1) rea destinada ao desenvolvimento de seu cdigo 2) Navegador, aqui voc pode localizar mais facilmente os cdigos disponveis em seu diretrio Experts dentro do seu MetaTrader. 3) Ferramentas, aqui voc ter uma interao direta, quando necessitar de alguma ajuda, ou quando compilar um programa ou ainda quando fizer uma busca em algum arquivo em disco. 4) Menu do MetaEditor 5) Barra de Ferramentas 6) Barra de Status 7) Menu da janela de ferramentas
Comea o projeto de um novo cdigo, chamando o assistente do MetaEditor Abre um arquivo existente Fecha o arquivo que atualmente tem o foco do
teclado, voc pode ter mais de um arquivo aberto, porem somente um deles ter a ateno (foco) do teclado.
Save Save As Save All Compilar Imprimir Setup Print Preview Print Lista dos ultimos abertos Editar Desfazer Refazer Cortar Copiar
Salva o arquivo que tem o foco atual do teclado Salva o arquivo que tem o foco atual do teclado, porem com um outro nome que voc poder especificar Salva todos os arquivos que esto abertos. Compila o cdigo do arquivo que esteja com o foco do teclado. Configura a impressora que ser utilizada para imprimir Visualiza como ficara a impresso do arquivo do cdigo atual Imprime o arquivo do cdigo atual Mantm uma lista dos n ltimos arquivos que foram acessados Desfaz a ultima digitao Recupera a ultima digitao desfeita Retira e transfere para a rea de transferncia do Windows um texto selecionado Copia para a rea de transferncia do Windows um texto selecionado Coloca, a partir da posio atual do cursor, no seu cdigo, o texto que estiver disponvel na rea de transferncia do Windows Apaga um texto selecionado Seleciona todo o cdigo do arquivo atual Busca uma ocorrncia de de texto no seu cdigo Busca prxima ocorrncia, baseado na ultima busca Busca a ocorrncia anterior, baseado na ultima busca Substitui um texto por outro em seu cdigo Executa busca de textos em Arquivos, esta opo tem interao com a janela de ferramentas.
Colar Delete Select All Find Find Next Find Previus Replace Buscar em Arquivos Toggle BreakPoint Clear All Break Point Book Mark
possa ter um acesso rpido a determinadas sees do seu cdigo. Toggle Prximo Anterior
Limpar
Coloca ou Tira uma marca de texto Vai para a prxima marca de texto configurada Vai para a marca de texto anterior a atual que foi configurada Elimina todas as marcas de texto em seu cdigo
List Names
Abre uma pequena janela, onde o cursor se encontra em seu texto, com todas as funes e palavras chaves disponveis na linguagem MQL4, muito til para voc verificar a sintaxe enquanto voc digita. Mas no se preocupe, O MetaEditor, amigvel suficiente para abrir automaticamente esta janela depois de voc digitar a terceira letra de uma palavra e ele conseguir identificar como uma palavra de sua lista Quando voc digita uma das funes padres de MQL4, e no se lembra quais so os parmetros que voc pode utilizar na mesma esta opo lhe oferece uma ajuda rpida lembrando voc de como utilizar a referida funo Aqui voc pode modificar o idioma na qual o MetaEditor conversa com voce. Mostra ou esconde a Barra de tarefas Mostra ou esconde a Barra de Status Mostra ou esconde a janela de Ferramentas Mostra ou esconde a janela do Navegador Deixa que voc modifique as barras de ferramentas do MetaEditor Chama o MetaTrader, onde voc faz suas negociaes. Configura o MetaEditor de acordo com suas atribuies. Abre uma nova janela texto, com o mesmo cdigo do arquivo que atualmente tem o foco do teclado Organiza suas janelas abertas em Cascata Organiza suas janelas Horizontalmente
Parameter Info
Languages Toolbar Exibir Status Bar Tool Box Navegator Customize Terminal de negocia es Opes Nova Janela Cascata Tile Horizontal
Tools
Windows
Tile Vertical Arrumar Icones Fechar Todos Lista de janelas abertas Ajuda Ajuda Tpicos Sobre
Organiza suas janelas Verticalmente Configura suas janelas minimizadas Fecha todas as janelas Abertas Mantm a lista de arquivos abertos do MetaEditor Ajuda especifica sobre o MetaEditor Caractersticas do MetaEditor
O Navegador do MetaEditor
Janela do Navegador
Aqui voc encontra todos os diretrio e subdiretrio que o MetaTrader utiliza diretamente, bem como aos arquivos neles encontrados
Aqui se encontra o Menu de ajuda da linguagem MQL4, onde voc pode tirar suas duvidas sobre as regras da mesma
Simplesmente para digitar um texto a ser buscado no arquivo de ajuda da linguagem MQL4
Configurando o MetaEditor
Agora, aprenderemos como modificar algumas caractersticas do MetaEditor para que nos parea mais amigvel, em nosso trabalho do dia a dia. Primeiramente as opes gerais. - Tab size : o tamanho em caracteres que tero nossas tabulaes, elas aparecero quando voc teclar a tecla TAB, na verdade nada mais o numero mximo de espaos em branco ate a prxima tabulao. - Inserir espaos : Ao passar para a prxima linha e se o sistema "Auto identificar" estiver ligado, o MetaEditor vai inserir espaos em branco em vez de tabulaes. - Auto identificar : quando voc teclar o <enter> para a prxima linha, o MetaEditor se posicionara exatamente embaixo do comeo da ultima linha - Auto parameter info : ao identifica uma funo e quando voc teclar o parnteses, aparece uma pequena janela de ajuda de como os parmetros de vem ser passados na chamada da referida funo, mas isto somente funciona com as funes padres do MQL4, para as funes que voc desenvolve no existe esta ajuda. - Auto Listar nomes : diz para o MetaEditor mostras as possveis funes ou palavras chaves que voc pode utilizar e que so padroes do MQL4, isso ajuda voc a no cometer erros de sintaxe.
- Listar nomes depois de : Mostra a janela de nomes do MQL4, depois de voc digitar o caractere da palavra, desde que o comeo tenha alguma ocorrncia na lista de nomes
Voc notara que a medida que voc digita as palavras no editor, elas assumem uma cor diferente. Isto se da ao fato de que o MetaEditor usa o esquema de identificao de palavras e identificadores baseado em cores. Isto torna se cdigo mais legvel e fcil de entender. Aqui simplesmente voc pode dar as cores que quiser aos diferentes grupos de palavras que o MetaEditor identifica.
Se voc no gosta da fonte utilizada pelo MetaEditor, ou se acha ela pequena demais ou muito grande, na prxima tabulao das opes voc pode modific-la e deix-la da maneira que voc quiser. Porem voc s pode utilizar fontes de tamanho fixo, esta fontes, no importa a letra, elas ocupam a mesma largura na tela, isto o "i" tem o mesmo espao reservado que o "m".
Bom por ultimo, se voc acessa sua internet com um servidor proxy, aqui que voc o configura, isto para utilizar a ajuda on-line ja janela de ferramentas.
Formato
Quando voc escreve seu cdigo, voc pode livremente usar espaos, tabulaes e de linhas que vazias. Se voc formata seu seu cdigo de maneira que fique mais agradvel aos olhos (Leitura e entendimento). Por exemplo estas 3 formas de definir variveis so vlidas em MQL4:
double MacdCurrent, MacdPrevious, SignalCurrent; double MacdCurrent, MacdPrevious, SignalCurrent; double MacdCurrent, MacdPrevious, SignalCurrent;
Mas, como voc v, a primeira linha mais legvel e fcil de compreender. E como tudo no mundo, h excees rgra: 1) voc no pode usar a linha nova no "controle da compilao" (Preprocessors) Voc saber mais sobre o "controle da compilao" numa das seguintes lies, mas recorde apenas que isto uma exceo. Para o exemplo a linha seguinte do cdigo invlida e o compilador MQL4 reclamar: #property copyright "Copyright 2004, MetaQuotes Software Corp." Esta seria a forma correta da sintaxe para o "controle da compilao":
#property copyright "Copyright 2004, MetaQuotes Software Corp."
2) voc no pode usar a linha ou o espao novo no meio de valores constantes, de identificadores ou de palavras-chaves. Para o exemplo esta linha vlida:
extern int MA_Period=13;
"extren" e "int" so aqui os palavras chaves, "MA_Period" um identificador e "13" so um valor constante. Voc saber mais nas lies seguintes sobre estas terminologias. Por exemplo as linhas seguintes so invalidas:
Comentrios
Para fazer o mundo de programao mais fcil, toda a lnguagem de programao tem seu estilo de comentrios da escrita. Voc usa comentrios para escrever linhas em seu cdigo (ou parte de uma linha) que o compilador ignorar, porem, elas faro seu cdigo mais compreensvel. Suponha que voc escreva um programa no vero e no inverno voc quer o ler. Sem comentrios, mesmo voc sendo o criador criador do cdigo, voc provavelmente no compreendera, em primeira instancia, todas estas linhas que voc escreveu. MQL4 (& C/C++) usam dois tipos de estilos dos comentrios 1) Comentrio de linha : uma nica linha para comentrios, a linha do comentrio comea com "//" e termina com a linha nova. Por exemplo:
//Este um comentrio de linha extern int MA_Period=13; //Este tambm um comentrio de linha
2) Comentrio de varias linhas: comea o comentrio com "/*" e termina com "*/". Em outras palavras tudo que estiver entre "/*" e "*/" inclusive novas linhas ser considerado comentrio (voc pode ter tambm comentrios de linha dentro dos comentrios, o que vale o comentrio de varias linhas). Com essa facilidade possvel voc eliminar uma parte do cdigo que no momento voc no deseja (mas no futuro pode ter que usar) simplesmente colocando ele entre os smbolos de comentrios de varias linhas.Por exemplo:
/* este um comentrio de varias linhas*/ /* este um comentrio de varias linhas*/
Identificadores
Um identificador o nome que voc escolhe a suas variveis, constantes e funes. Por o exemplo MA_Period aqui um identificador:
extern int MA_Period=13;
H poucas regras e limitaes para escolher nomes de identificadores: 1) O comprimento mximo (tamanho) do identificador no deve exceder 31 caracteres. 2) O identificador deve comear com uma letra (maiscula ou minscula) ou o smbolo sublinhando ( _ ). Assim, no se pode comeado o nome de um identificador com um nmero ou um outro smbolo (que no seja o smbolo sublinhando). 3) Voc no pode usar nenhumas palavras chave como um identificador. Voc ver a lista das palavras chaves mais adiante nesta mesma lio. 4) Os nomes dos identificadores so caso sensveis ao caso (diferenciam letras maisculas de minsculas). Assim, MA_PERIOD no o mesmo que o ma_period ou o MA_Period ou Ma_PeRioD (ou qualquer outra combinao de letras maisculas com minsculas no nome com as mesmas letras nas mesmas posies). Deixe-nos fazer exame de alguns exemplos:
nomes vlidos Nome1 N1o2m3e4 nomes invlidos Minha_Primeira_Variavel_Longa_1 mais de 31 caracteres ~Nome smbolo que no o sublinha comea com numero smbolo que no o sublinha palavra-chave (reservada)
Palavras-chaves
Para cada lngua (idioma) existem "palavras" que a ela usa para aes especficas ou determinar alguma coisa. Em linguagens computacionais a mesma coisa. Assim, so algumas palavras so reservados ao uso da linguagem e voc no pode us-los como um nome do identificador ou para nenhuma outra finalidade que no seja aquela que elas foram criadas. Esta a lista das palavras-chaves reservadas na linguagem MQL4:
Tipos de dados bool color datetime double int string void Classe de memria extern static Operadores break case continue default for else if return switch while false true outros
Como voc pode observar, so poucas as palavras chaves, porem elas representam todo o poder da linguagem MQL4. Quero ainda exemplificar, baseado em palavras chaves, alguma linhas de programao invalidas:
extern int datetime =13; int extern =20; double continue = 0; // datetime palavra reservada // extern palavra reservada // continue palavra reservada
Variveis
As variveis so os nomes que daremos partes da memria em que os dados podem ser armazenados. Para visualizar melhor, pensar que isso como um retrato, imagine que a memria uma srie de caixas diferentes do tamanho. O tamanho da caixa rea de armazenamento da memria requerida nos bytes (Um byte um dos tipos de dados integrais em computao. usado com freqncia para especificar o tamanho ou quantidade da memria ou da capacidade de armazenamento de um computador, independentemente do tipo de dados l armazenados). Agora imagine essas caixas e acompanhe os raciocnios abaixo: - A fim usar uma caixa para armazenar dados, a caixa deve ser dada um nome; este processo conhecido como a declarao. - No processo da declarao voc usa uma palavra que diz ao computador qual o tipo e o tamanho da caixa que voc quer se usar, esta palavra conhecida como o Palavra-Chave. - Ajuda muito se voc der a uma caixa um nome significativo que se relacione ao tipo de informao que voc colocar nela, e que torne mais fcil de encontrar os dados. - Os dados so colocados em uma caixa atravs da atribuio os dados esta caixa. - Quando ns atribumos o valor da caixa na mesma linha que voc declarou, este processo conhecido como como a iniciao. Quando ns criamos uma varivel que ns somos dizendo ao computador que ns queremos atribuir um comprimento especificado da memria (nos bytes) a nossa varivel, desde armazenar um nmero simples, a uma letra ou um nmero grande, com certeza, cada um destes processos no ocupara o mesmo espao na memria. Deste modo voc deve informar ao computador quais so o tipo dos dados e qual o comprimento dos dados. Para isto servem os tipos de dados.
Este o meio pelo qual ns estamos requisitando ao computador para ajustar um bloco de um comprimento de 4 bytes na memria com o nome de "MyVaraiable". No exemplo acima ns especificamos ao computador como se fosse a seguinte declarao :
int =-> representa uma palavra-chave int =-> representa um tipo de dados que especifica nmeros inteiros int =-> representa uma dilacerao MyVaraible =-> Nome da varivel =0; =-> Atribumos um valor inicial a varivel
Ns saberemos mais sobre variveis nas lies futuras. Bem, agora, continnuanto, em MQL4, estes so os tipos de dados: - Inteiro (int) - Lgico (bool) - Literais (char) - Cadeia de Literais (string) - Ponto Flutuante (double) - Cores (color) - Data e Hora (datatime)
Use a palavra-chave int para criar uma varivel para armazenar um nmero inteiro
int intInteger = 0; int intAnotherIntger = -100; int intHexIntger = 0x12;
Decimal: A notao decimal a escrita dos nmeros na base de 10, e usa os dgitos (0, 1, 2, 3, 4, 5, 6, 7, 8 e 9) para representar nmeros. Estes dgitos so usados freqentemente com um ponto decimal que indique o comeo de uma parte fracionria, e com um dos smbolos do sinal + (mais) ou (menos) para indicar o sinal. O hexadecimal um sistema numerao com uma base de 16 smbolos e que so escritos geralmente usando os smbolos 0-1-2-3-4-5-6-7-8-9 e A-B-C-D-E-F ou a-bc-d-e-f. Para entender melhor vamos converter um numero decimal para hexadecimal e vice-versa Converter o numero decimal 12345 para Hexadecimal. Basta fazermos divises sucessivas : comeamos com agora dividimos agora dividimos 12345 / 16 = 771 e sobra 9 771 / 16 = 48 e sobra 3 48 / 16 = 3 e sobra 0
para montar o numero hexadecimal utilizamos o resultado da ultima diviso com todos os restos de todas as divises, logo teremos que 12345 em decimal 3039 em hexadecimal. Agora converteremos o numero hexadecimal AB12 para decimal. Basta fazermos Potenciaes com o numero 16, multiplicaes e somas: 2 1 B A = 2 x = 1 x = 11 x = 10 x 16^0 16^1 16^2 16^3 = 2 x 1 = 1 x 16 = 11 x 256 = 10 x 4096 = 2 = 16 = 2816 = 40960 ------43794
Como vimos, para montar o numero decimal somamos todas as multiplicaes, logo teremos que AB12 em hexadecimal 43794 em decimal. Observao: no sistema hexadecimal A=10, B=11, C=12, D=13, E=14, F=15 Explicar porque usar nmeros hexadecimais esta fora do escopo deste curso. Porem se voc tiver interessado busque no google (favor utilizar nossa caixa de busca na pagina de entrada) para descobrir porque o sistema hexadecimal to importante na computao.
matemtico grande Boole George. Ns usamos a palavra chave bool criar uma varivel Lgica, de agora em diante chamada de booleana. Por exemplo:
bool I = true; bool bFlag = 1; bool bBool=FALSE;
Existem alguns caracteres chamados caracteres especiais e no podem apresentarse diretamente dentro das aspas simples porque tm mecanismos reservados na linguagem MQL4. Aqui ns usamos algo como uma seqncia de escape para mostrar estes caracteres especiais, E isso se faz prefixando o caractere especial junto com o caractere de barra invertida (\). Por exemplo:
int chrA = '\\'; int chrB = '\n'; // quando quiser usar a barra invertida // especifica nova linha em um texto
\r
nova linha
double quote
\"
aspas duplas
hexadecimal ASCII- cdigo hexadecimal onde xx o numero a ser code \xhh representado
MQL4 limita o tamanho da varivel da string a 255 caracteres e qualquer tentativa de armazenar mais de de 255 caracteres gerar este erro: (string muito longa (mximo de 255 caracteres)). Voc pode usar todo o carter especial - mencionado acima em sua string desde que usado com a barra invertida (\). Ns usamos a palavra-chave "string" para criar varivel. Por o exemplo: string str1 = "Hello world1, com a cortesia de DooMGuarD; string str2 = "Copyright 2005, \"Forex-tsd forum\"."; //Nota : usa as aspas duplas dentro da string string str3 = "1234567890";
.E seu valor pode estar entre 2.2e-308 at 1.8e308. Ns usamos a palavra-chave "double" para criar uma varivel de ponto flutuante. Por exemplo:
// Representao por nmero inteiro 0xFFFFFF // branco 16777215 // branco 0x008000 // verde 32768 // verde
Quadro de paletas de cores com seus respectivos nomes (respeitar minsculas e maisculas)
ao analizermos esta parte da linha "(y*z)/w", observamos: y, z e w so identificadores =, * e / so operadores Juntos nesta linha (poderiam se 2 linhas ou mais tambm) eles formam uma expresso. As combinaes de uma expresses fazem uma indicao. E quando as indicaes se juntam fazem uma funo e quando as funes se juntam fazem um programa. No restante desta lio ns estaremos falando sobre os operadores usados em MQL4. Assim, deixe-nos comear com os operadores aritmticos bsicos:
Operaes Aritmticas
Em MQL4 h 9 operaes aritmticas Esta a lista delas com o uso de cada uma:
Operador Nome + + * Operador da adio Operador da subtrao Exemplo A = B+C; A = B-C; Descrio Adicione A a B e atribua o resultado a C. Subtraia C de B e atribua o resultado a C. Mude o sinal de A de positivo ao negativo Multiplique B e C e atribua o resultado a A
A = B/C;
A o resto da diviso entre B e C. exemplos: A = B%C; 10%2 resultara em 0 10%3 resultara em 1 Aumente A em uma unidade 1. exemplo: se A = 1 entao A++ resultara em A = 2 Diminua A em uma unidade 1. exemplo: se A = 1 entao A-resultara em A = 0
++
Operador de incremento
A++;
--
Operador de decremento
A--;
Nota: voc pode combinar operadores de incremento e decremento com outras expresses:
A = (B++)*5;
Operaes de Atribuio
A finalidade de toda a expresso est produzindo um resultado e os operadores de atribuio que atribuem o resultado do lado esquerdo a varivel do lado direito. Por o exemplo:
A = B*C;
Aqui ns multiplicamos B e C e atribumos o resultado a A. (=) est aqui o para executar de atribuio. Em MQL4 h 11 operaes das atribuies Esta a lista deles com o uso de cada uma:
Operador Nome = Operador de atribuio Exemplo A = B; Descrio Atribua B a A. igual a: A = A + B; Adicione B a A e atribua o resultado a A. igual a: A = A - B; subtraia B a A e atribua o resultado a A. igual a:
+=
-=
*=
A = A * B; multiplique B por A e atribua o resultado a A. igual a: A = A / B; divida A por B e atribua o resultado a A. igual a: A = A % B; divida A por B e atribua o resto da diviso a A.
/=
%=
>>=
igual a: Operadores de A = A >> B; atribuio com A >>= B; desloque A em B bits a direita deslocamento e atribua o resultado a A. igual a: Operadores de A = A << B; atribuio com A <<= B; desloque A em B bits a esquerda deslocamento e atribua o resultado a A. Operadores de atribuio com A &= B; Lgica E (AND) igual a: A = A & B; compare se A e B so verdadeiros atribua resultado a A. igual a: A = A | B; compare se A ou B so verdadeiros atribua resultado a A. igual a: A = A ^ B; compare se exclusivamente se A ou B so verdadeiros atribua resultado a A.
<<=
&=
|=
Operadores de atribuio com A |= B; Lgica OU (OR) Operadores de atribuio com Lgica OU A ^= B; Exclusivo (XOR)
^=
Nota: voc aprendera mais sobre operadoras lgicos mais adiante nesta mesma lio
Operaes Relacionais
Os operadores relacionais comparam dois valores (operandos) e resultam em um valor falso (False ou Zero) ou verdadeiro (True ou diferente de Zero). Seria como obter a resposta a seguinte a pergunta " Joo mais alto do que Alfredo? Sim ou No.?". Responsta sim seria True (sim, Joo mais alto que Alfredo) e No seria False (no, Joo no mais alto que Alfredo). Por exemplo
4 == 4; //true 4 < 4; //false 4 <= 4; //true;
Em MQL4 h 6 operaes relacionais Esta a lista deles com o uso de cada um:
Operador Nome == igual a Exemplo a == B Descrio Verdadeiro se A for igual a B. Falso se A for diferente de B. Verdadeiro se A for diferente de B. Falso se A for igual a B. Verdadeiro se A for maior que B. Falso se A for menor ou igual a B. Verdadeiro se A for menor que B. Falso se A for maior ou igual a B. Verdadeiro se A for maior ou igual q B. Falso se A for menor que B. Verdadeiro se A for menor ou igual a B. Falso se A for maior que B.
!=
diferente de a != B
>
maior que
a > B
<
menor que
a < B
>=
maior ou igual a
a >= B
<=
menor ou igual a
a <= B
Operaes Lgicos
Na cincia da computao, as lgebras booleanas so estruturas algbricas que "capturam a essncia" das operaes lgicas E, OU e NO, bem como das operaes da teoria de conjuntos soma, produto e complemento. Receberam o nome de George Boole, matemtico ingls, que foi o primeiro a defini-las como parte de um sistema de lgica em meados do sculo XIX. Mais especificamente, a lgebra booleana foi uma tentativa de utilizar tcnicas algbricas para lidar com expresses no clculo proposicional. Hoje, as lgebras booleanas tm muitas aplicaes na eletrnica. Foram pela primeira vez aplicadas a interruptores por Claude Shannon, no sculo XX. Os operadores da lgebra booleana podem ser representados de vrias formas. freqente serem simplesmente escritos como E, OU ou NO (so mais comuns os seus equivalentes em ingls: AND, OR e NOT). Na descrio de circuitos tambm podem ser utilizados NAND (NOT AND), NOR (NOT OR) e XOR (OR exclusivo). Os matemticos usam com freqncia + para OU e . para E (visto que sob alguns aspectos estas operaes so anlogas adio e multiplicao noutras estruturas algbricas) e representam NO com uma linha traada sobre a expresso que est a ser negada. MQL4 usa os 3 operadores lgicos os mais importantes. Esta a lista deles com o uso de cada um:
Operador Nome Exemplo Descrio
&&
A && B
Verdadeira se A e B forem Verdadeiro Falso para qualquer outra combinao Verdadeira se A ou B forem Verdadeiro se A e B forem Verdadeiros Falso se A e B forem Falsos Verdadeiro se A for Falso Falso se A for Verdadeiro
||
ou
A || B
negado
!A
AND : O operador binrio AND, ou conjuno binria devolve um bit 1 sempre que ambos operandos sejam '1', conforme podemos confirmar pela tabela de verdade:
& 0 1 0 0 0 1 0 1
OR : o operador binrio OR, ou disjuno binria devolve um bit 1 sempre que pelo menos um dos operandos seja '1', conforme podemos confirmar pela tabela de verdade:
| 0 1 0 0 1 1 1 1
XOR : O operador binrio XOR, ou disjuno binria exclusiva devolve um bit 1 sempre que apenas um dos operandos '1', conforme podemos confirmar pela tabela de verdade:
^ 0 1
0 0 1
1 1 0
Shift : O operador unrio de bit shifting, ou deslocamento bit-a-bit, equivale multiplicao ou diviso por 2 do operando que, ao contrrio dos casos anteriores, um grupo de bits, e consiste no deslocamento para a esquerda ou para a direita do grupo de bits. O bit inserido sempre 0, e o bit eliminado pode ser opcionalmente utilizado (flag CF dos registros do processador).
( 101011(43) >> 1 ) = 010101[1] (21) ( 101011(43) << 1 ) = [1]010110 (22)
MQL4 usa os 3 operadores lgicos os mais importantes. Esta a lista deles com o uso de cada um:
Operador Nome Exemplo Descrio Compara duas resultado de partes forem 0. A = 00000100 B = 00000111 & = 00000100 partes e gera um 1 se ambos as 1; se no, retorna ( ( ( 4) 7) 4)
&
A & B
ou
A | B
Compara dois bocados e gera um resultado de 1 se os bocados forem complementares; se no, retorna 0 A = 00000100 ( 4) B = 00000111 ( 7) | = 00000111 ( 7) Compara duas partes e gera um resultado de 1 se um ou outro ou ambas as partes forem 1; se no, retorna 0. A = 00000100 ( 4) ^ = 00000011 ( 3) Usado para inverter todos as partes do operandor. A = 00000100 ( 4) ~ = 11111011 (251) Move as partes para a direita, rejeita o as partes a direita, e atribui a parte esquerda um valor de 0. Cada movimento direita divide eficazmente o valor ao meio. A = 00000100 ( 4) B = 00000111 ( 7) >> = 00000011 ( 3) Move as partes para a esquerda, rejeita as partes a esquerda, e atribui a parte direita o valor de 0. Cada movimento esquerda
ou exclusivo
A ^ B
complemento
~A
>>
A >> B
<<
A << B
multiplica eficazmente por 2. A = 00000100 ( 4) B = 00000111 ( 7) >> = 00001110 ( 14) Nota : todos os operandos associados com bits (bitwise) devem utilizados com ser inteiros.
Ao escrever expresses compostas, voc deve ser explcito e indicar com os parnteses () que os operadores devem ser avaliados primeiramente. Voc especifica a ordem de avaliao usando parnteses, sendo que os parnteses mais internos so avaliados primeiro. Esta prtica far seu cdigo mais fcil de ler e manter. A seguinte tabela mostra a precedncia atribuda aos operadores no MQL4. Os operadores nesta tabela so listados na ordem da precedncia: Quanto mais acima na tabela um operador aparece, o mais elevado sua precedncia ou prioridade. Os operadores com prioridade mais elevada so avaliados antes dos operadores com uma prioridade relativamente mais baixa. Os operadores no mesmo grupo tm a prioridade igual. Quando os operadores da precedncia igual aparecem na mesma expresso, uma rgua deve governar que seja avaliada primeiramente. Todos os operadores binrios exceo dos operadores de atribuio so avaliados da esquerda para a direita. Os operadores de atribuio so avaliados para a direita esquerda
Operador Nome () [] ! ~ * / % + << >> < <= > >= == != & ^ || = += -= *= /= Parnteses Colchetes negao complemento sinal multiplicao diviso resto da diviso soma subtrao
Descrio chamadas de funes seleo de elementos numa matriz negao lgica bit a bit Mudana de sinal (positivo/negativo de um numero) da esquerda para a direita
deslocamento a da esquerda para a direita esquerda deslocamento a da esquerda para a direita direita menor que menor ou igual a maior que maior ou igual a igual diferente e ou exclusivo ou assinao assinao com soma assinao com subtrao assinao com multiplicao assinao com diviso assinao com resto da diviso assinao com deslocamento a bit a bit direita assinao com deslocamento a bit a bit esquerda
%=
>>=
<<=
&= |= ^= ,
Algoritmos
Antes de prosseguir com nosso estudo, faz-se necessrio algumas consideraes, sobre como os programas computacionais trabalham, por este motivo, abri espao para falar sobre algoritmos. Algoritmos pode ser descrito como o sequenciamento lgico do pensamento a ser seguido para a resoluo de um problema. Meu Objetivo, com esta lio mostrar o voc o mundo dos algoritmos, lgico que somente lendo este capitulo voc no se tornara um experto no assunto, mas poder entender algumas coisas.
Definio de Algoritmo
Um algoritmo uma seqncia no ambgua de instrues que executada at que determinada condio se verifique. Mais especificamente, em matemtica, constitui o conjunto de processos (e smbolos que os representam) para efetuar um clculo. O conceito de algoritmo freqentemente ilustrado pelo exemplo de uma receita, embora muitos algoritmos sejam mais complexos. Eles podem repetir passos (fazer iteraes) ou necessitar de decises (tais como comparaes ou lgica) at que a tarefa seja completada. Um algoritmo corretamente executado no ir resolver um problema se estiver implementado incorretamente ou se no for apropriado ao problema. Um algoritmo no representa, necessariamente, um programa de computador, e sim os passos necessrios para realizar uma tarefa. Sua implementao pode ser feita por um computador, por outro tipo de autmato ou mesmo por um ser humano. Diferentes algoritmos podem realizar a mesma tarefa usando um conjunto diferenciado de instrues em mais ou menos tempo, espao ou esforo do que outros. Tal diferena pode ser reflexo da complexidade computacional aplicada, que depende de estruturas de dados adequadas ao algoritmo. Por exemplo, um algoritmo para se vestir pode especificar que voc vista primeiro as meias e os sapatos antes de vestir a cala enquanto outro algoritmo especifica que voc deve primeiro vestir a cala e depois as meias e os sapatos. Fica claro que o primeiro algoritmo mais difcil de executar que o segundo apesar de ambos levarem ao mesmo resultado.
Etimologia
A palavra algoritmo tem origem no sobrenome, Al-Khwarizmi, do matemtico persa do sculo IX Mohamed ben Musa, cujas obras foram traduzidas no ocidente cristo no sculo XII, tendo uma delas recebido o nome "Algorithmi de numero indorum", sobre os algoritmos usando o sistema de numerao decimal (indiano). Outros autores, contudo, defendem a origem da palavra em Al-goreten (raiz conceito que se pode aplicar aos clculos).
Formalismo
Um programa de computador essencialmente um algoritmo que diz ao computador os passos especficos e em que ordem eles devem ser executados, como por exemplo, os passos a serem tomados para calcular as notas que sero impressas nos boletins dos alunos de uma escola. Logo, o algoritmo pode ser considerado uma seqncia de operaes que podem ser simuladas por uma mquina de Turing completa ( um dispositivo terico, conhecido como mquina universal). Quando os procedimentos de um algoritmo envolvem o processamento de dados, a informao lida de uma fonte de entrada, processada e retornada sob novo valor aps processamento, o que geralmente realizado com o auxlio de uma ou mais estruturas de dados (Dados organizados de forma coerente). Para qualquer processo computacional, o algoritmo precisa estar rigorosamente definido, especificando a maneira que ele se comportar em todas as circunstncias. O algoritmo pode ser provado matematicamente, bem como a quantidade de tempo e espao (complexidade) necessrios para a sua execuo. Estes aspectos dos algoritmos so alvo da anlise de algoritmos. A maneira mais simples de se pensar um algoritmo por uma lista de procedimentos bem definida, no qual as instrues so executadas passo a passo a partir do comeo da lista, uma idia que pode ser facilmente visualizada atravs de um fluxograma. Tal formalizao adota as premissas da programao imperativa, que uma forma mecnica para visualizar e desenvolver um algoritmo. Concepes alternativas para algoritmos variam em programao funcional e programao lgica.
Fluxogram a, um exemplo de algoritmo imperativo. O estado em vermelho indica a entrada do algoritmo enquanto os estados em verde indicam as possveis sadas
Trmino do algoritmo
Alguns autores restringem a definio de algoritmo para procedimentos que eventualmente terminam. Minksy constatou que se o tamanho de um procedimento no conhecido de antemo, tentar descobri-lo problema, j que o procedimento pode ser executado infinitamente, de forma que nunca se ter a resposta. Alan Turing provou em 1936 que no existe mquina de Turing para realizar tal anlise para todos os casos, logo no h algoritmo para realizar tal tarefa para todos os casos. Tal condio conhecida atualmente como problema da parada. Para algoritmos interminveis o sucesso no pode ser determinado pela interpretao da resposta e sim por condies impostas pelo prprio desenvolvedor do algoritmo durante sua execuo.
Implementao
A maioria dos algoritmos desenvolvida para ser implementada em um programa de computador. Apesar disso eles tambm podem ser implementados por outros modos tais como uma rede neural biolgica (tal como no crebro quando efetuamos operaes aritmticas) em circuitos eltricos ou at mesmo em dispositivos mecnicos. Para programas de computador existem uma grande variedade de linguagens de programao, cada uma com caractersticas especficas que podem
Analise de Algoritmos
A anlise de algoritmos um ramo da cincia da computao que estuda as tcnicas de projeto de algoritmos e os algoritmos de forma abstrata, sem estarem implementados em uma linguagem de programao em particular ou implementadas de algum outro modo. Ela preocupa-se com os recursos necessrios para a execuo do algoritmo tais como o tempo de execuo e o espao de armazenamento de dados. Deve-se perceber que para um dado algoritmo pode-se ter diferentes quantidades de recursos alocados de acordo com os parmetros passados na entrada. Por exemplo, se definirmos que o fatorial de um nmero natural igual ao fatorial de seu antecessor multiplicado pelo prprio nmero, fica claro que a execuo de fatorial(10) consome mais tempo que a execuo de fatorial(5). Um meio de exibir um algoritmo afim de analis-lo atravs da implementao por pseudocdigo em portugus estruturado. O exemplo a seguir um algoritmo em portugus estruturado que retorna (valor de sada) a soma de dois valores (tambm conhecidos como parmetros ou argumentos, valores de entrada) que so introduzidos na chamada da funo:
funo SomaDeDoisValores (A numrico, B numrico) inicio declare SOMA numrico SOMA <-- A + B retorne (SOMA) fim
C) Serial ou paralelo - algoritmos so geralmente assumidos por serem executados instruo instruo individualmente, como uma lista de execuo, o que constitui um algoritmo serial. Tal conceito base para a programao imperativa. Por outro lado existem algoritmos executados paralelamente, que levam em conta arquiteturas de computadores com mais de um processador para executar mais de uma instruo ao mesmo tempo. Tais algoritmos dividem os problemas em sub-problemas e o delegam a quantos processadores estiverem disponveis, agrupando no final o resultado dos subproblemas em um resultado final ao algoritmo. Tal conceito base para a programao paralela. De forma geral, algoritmos iterativos so paralisveis; por outro lado existem algoritmos que no so paralisveis, chamados ento problemas inerentemente seriais. D) Determinstico ou no-determinstico - algoritmos determinsticos resolvem o problema com uma deciso exata a cada passo enquanto algoritmos nodeterminsticos resolvem o problema ao deduzir os melhores passos atravs de estimativas sob forma de heursticas. E) Exato ou aproximado - enquanto alguns algoritmos encontram uma resposta exata, algoritmos de aproximao procuram uma resposta prxima a verdadeira soluo, seja atravs de estratgia determinstica ou aleatria. Possuem aplicaes prticas sobretudo para problemas muito complexos, do qual uma resposta correta invivel devido sua complexidade computacional.
E) Reduo - a reduo resolve o problema ao transform-lo em outro problema. chamado tambm transformao e conquista. F) Busca e enumerao - vrios problemas podem ser modelados atravs de grafos. Um algoritmo de explorao de grafo pode ser usado para caminhar pela estrutura e retornam informaes teis para a resoluo do problema. Esta categoria inclui algoritmos de busca e backtracking. G) Paradigma heurstico e probabilstico - algoritmos probabilsticos realizam escolhas aleatoriamente. Algoritmos genticos tentar encontrar a soluo atravs de ciclos de mutaes evolucionrias entre geraes de passos, tendendo para a soluo exata do problema. Algoritmos heursticos encontram uma soluo aproximada para o problema.
Um ponto e virgula no fim da instruo uma parte crucial da sintaxe mas geralmente fcil de esquecer, e isso que geralmente representa cerca de 90% dos erros. Mas a execuo coma para baixo no o nico caso e ela tem duas excees. Essas excees so os laos e as decises (condies). Nos programas que voc escreve como um ser humano, voc decide o que fazer de acordo com determinada circunstncia. Nestes casos os fluxos do controle possibilitam salta de uma parte do programa a outra. As palavras chaves que possibilitam tais saltos so chamadas de indicaes de controle. Tais controles consistem em laos e em decises.
Laos for
O lao for considerado o lao o mais fcil porque todos seus elementos do controle so encontrados em um s lugar. O lao for executa uma parte do cdigo um nmero fixo das vezes. Para o exemplo:
int j; for(j=0; j<15; j++) Print(j);
Bem ele consiste em uma palavra-chave, o for, seguido por trs instrues separadas por virgula que se encontram entre chaves: "for(j=0; j<15; j++)". Estas trs expresses so :
j=0 - expresso da iniciao j<15 - expresso do teste j++ - expresso do increment
O corpo do lao o cdigo a ser executado o nmero fixo de vezes (15 neste caso, de 0 ate 14, lembre-se que ele faz o lao enquanto j for menor que 15) e neste caso seria "Print(j);" Nota: entre o a instruo for e o passo dentro do lao no se usa ponto e virgula. Isso porque o for e a intruo do corpo do lao so considerados como sendo uma s instruo no programa. A expresso da iniciao est executada somente uma vez, quando o lao comea. E sua finalidade dar varivel do lao um valor inicial (0 em nosso exemplo). Voc pode declarar o varivel fora do lao(como vimos antes) ou voc pode fazer a declarao dentro dos parnteses do lao, assim:
int j; for(int j=0; j<15; j++) Print(j);
As duas linhas precedentes do cdigo so iguais, a no ser pela validade de cada um varivel (voc saber mais sobre a declarao e validade de variveis na lio das variveis). O mtodo de declarao exterior da varivel faz cada linha no bloco do cdigo faz com que cada linha saiba sobre esta varivel, enquanto que a declarao interna faz com que somente o lao saiba da existncia da varivel. Voc pode usar mais que uma expresso da iniciao no lao for, separando cada uma com vrgula, assim:
int j; int i; for(j=0, i=0; j<15; j++) Print(j," ",i);
A expresso do teste: testa sempre uma expresso relacional na qual se use operadores relacionais (consulte por favor aos operadores relacionais na lio correspondente). Avaliado pelo lao cada vez que o lao executado para determinar se o lao continua ou para. Continuar se o resultado da expresso for verdadeiro e parar se ele falso. Em nosso exemplo o lao do corpo continuar imprimindo "Print(j," ",i);" enquanto J<15, ou seja caso j seja igual a 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 ou 15. E quando j seja 15, o lao para e o controle passa prxima instruo que seguir apos o lao. A expresso do incremento: A expresso do incremento muda o valor da varivel do lao (j em nosso exemplo) aumentando seu valor em uma (1) unidade a cada vez que o computador termina o lao.
Como a expresso da iniciao, na expresso do incremento voc pode usar mais de uma expresso do incremento no para o lao separando o com vrgula, assim
int j; int i; for(int j=0; j<15; j++, j++) Print(j," ",i);
Porm voc pode somente usar uma expresso do teste. Fluxograma de funcionamento do lao for
Uma outra observao sobre a expresso do incremento, no somente pode aumentar a varivel do lao, mas pode executar e operao de decrscimos, assim:
for(int j=15; j>0; j--) Print(j);
No nosso exemplo usamos somente um passo no corpo do lao: "Print(j);". Quando voc for usar mais de um passo dentro do lao, voc deve colocar todos os passos entre chaves. Para fixar bem, tudo que estiver entre chaves considerado um bloco agrupado no programa.
for(int j=15; j>0; j--) { Print(j); PlaySound("alert.wav"); }
No cdigo que acima o corpo do lao contem duas intrues, o programa executar a primeira instruo e depois a segunda a cada excusso do lao. No se esquea de pr um ponto e virgula no fim de cada intruo. A instruo break: a palabra chave break quando o presentes em qualquer parte do lao far com que a execuo do lao termine e o controle seja passado a prxima insruo aps o lao. Por Exemplo
for(int j=15; j>0; j--) { if(i==10) break; Print(j); }
O exemplo acima executar o lao at que j alcance 10, pois quando atingir este valor a palavra chave break causara um ruptura e terminar o lao. O cdigo produzir estes valores: 0.1.2.3.4.5.6.7.8.9. e sair do lao sem passar pelos demais valores. A instruo continue: faz com que o controle do lao salte para o incremento da varivel e inicie o lao novamente. Por exemplo:
for(int j=15; j>0; j--) { if(i==10) continue; Print(j); }
O exemplo acima executar o lao completo, porem somente imprimira estes valores: 0.1.2.3.4.5.6.7.8.9.11.12.13.14 Uma ultima observao sobre o lao for: Voc pode deixar uma ou todas as expresses dentro para o lao sem serem preenchidas "for(;;) ", porem, neste caso, o lao ser executado eternamente.
Laos while
O lao for geralmente usado no caso voc sabe quantas vezes o lao ser executado. O que acontecem se voc no souber quantas vezes voc quer executar o lao? Quando o lao devera parar de ser executado?. Para esta ocasies voc usar o lao ehile com uma condio de teste. Mas no tem expresses da iniciao ou do incremento. Este um exemplo:
No exemplo acima voc observar os passos: 1) A varivel do lao tem declarado e inicializao antes do lao, e voc no pode declar-la ou idealiz-la dentro dos parnteses do lao (como permitido fazer no lao for). 2) A indicao de i++ aqui no a expresso do incremento como voc pode pensar, mas o corpo do lao deve conter alguma indicao que muda a varivel do lao, se no o lao nunca terminaria. Como o exemplo acima trabalha? A instruo while contem somente a expresso do teste, e ao examin-la em cada lao, se for verdadeiro o lao continuara e se for falsa o lao terminara e a passagem do controle do programa ira para a prxima intruo aps o lao. No exemplo o lao executar at que i alcance o valor 16. Fluxograma de funcionamento do lao while
Tudo que eu disse antes para o lao for, aqui no no lao while, tem aspectos similares 1) Voc pode usar a instruo break e continue com o mesmo efeito. 2) Voc pode colocar vrios passos dentro do lao, desde que todas as instrues estejam entre chaves. 3) "while(true)" tem o mesmo efeito de "for(;;)"
Instruo if ...
A instruo if a a mais simples instruo de deciso, eis um exemplo:
if( x < 100 ) Print(j);
Aqui se a palavra chave seguida por parnteses, dentro dos parnteses a expresso do teste (x 100), quando o resultado da expresso do teste for verdadeiro o corpo do if ser executado: "Print(j);" , e se for falso, a passagem do controle ira para a prxima instruo apos o bloco do if . Fluxograma do da deciso if
Varios intrues (passos) no corpo do if : Como nos laos, o corpo do if puder ter em mais do que uma instruo, a unica condio que esteja entre chaves. Por exemplo:
Observe o smbolo "==" na expresso do teste; um dos operadores que relacionais voc estudou na lio de operaes e de expresses. Esta uma fonte dos muitos dos erros que voc pode cometer quando escreve seu cdigo fonte, quando voc se esquece e se usa do operador de atribuio "=" no lugar do de comparao "==" . Os laos e as estruturas da deciso podem ser o bloco interior um outro bloco; voc pode aninhar o if dentro dos laos, laos dentro de if, if dentro do if , e assim por diante. Est aqui um exemplo:
for(int i=2; i<10; i--) if(i%2==0) { Print("Este um nmero par"); PlaySound("warning.wav"); }
No exemplo acima, temos uma estrutura de aninhamento, um bloco if no interior de um bloco for (lao). Voc observar que no h nenhuma chave no do corpo do lao, isto porque se a instruo for e as instruo if formam um s corpo, como se fossem consideradas ser uma nica instruo, isso porque a nica instruo do lao for o bloco if .
Se expresso na instruo if for verdadeira, a mensagem ("Este preo maior, esquea...") ser mostrada, se no for verdadeiro, ento a outra mensagem ("Este preo maior, esquea...") que aparecera. Fluxograma do da deciso if ... else ...
Novamente aqui, voce pode aninhar blocos. H um problema potencial no aninhado if ... mais as indicaes, voc puderem inadvertidamente combinar um outro com o erro se. Para resolver este caso voc pode fazer uma de duas coisas: 1 que voc pode limitou se... se emparelhasse mais com as cintas como isto:
for(int i=2; i<10; i--) if(i%2==0) { Print("Este um nmero par"); PlaySound("Par.wav"); } else { Print("Este um nmero impar"); PlaySound("Impar.wav"); }
Existem alguns erros que podem passar inadvertidos e podem dar muita dor de cabea a um programador, veja os 2 codigos abaixo
if(A>B) Print("A maior que B."); if(A==B) Print("A igual a B."); else Print("A diferente de B"); if(A>B) { Print("A maior que B."); if(A==B) Print("A igual a B."); else Print("A diferente de B"); }
veja que no segundo caso, temos um bloco para o primeiro if, com mais de uma instruo, e a comparao de igualdade entre A e B nunca ser verdadeiro, pois o bloco s ser executado se a primeira condio if for verdadeira, s seja se A>B ento A nunca ser igual a B. Portanto, muita ateno quando escrever seus programas.
Instruo switch
Se voc tiver uma rvore grande de decises, e todas as decises dependerem do valor da mesma varivel, voc pode usar uma indicao switch. Est aqui um exemplo:
switch(x) { case 'A': Print("x igual a A"); break; case 'B': case 'C': Print("x igual a B ou C"); break; default: Print("x no igual nem a A, nem a B e nem a C"); break; }
No exemplo acima a palavra chave switch seguido por parnteses, dentro dos parnteses que voc encontrar a constante a ser avaliada pelo switch, esta constante pode ser um inteiro, um carter ou uma expresso constante. A expresso constante no deve incluir uma varivel. por exemplo: case X+Y: a constante invlida para
switch.
Como o exemplo acima funciona? A instruo switch combina o x com uma das constantes dos casos (case). Seria como se imaginasse vrios ifs um apos ao outro. O raciocnio seria assim : - No case x=='A' o programa imprimir a "x igual a A" e a instruo break fara com que o programa passe o controle para a prxima instruo aps o bloco switch. - No case x=='B' dos case x=='C', o programa imprimir a "x igual a B ou C" e a instruo break fara com que o programa passe o controle para a prxima instruo aps o bloco switch. - No caso de x!= "algumas das constantes dos casos" o programa imprimir a "x no igual nem a A, nem a B e nem a C" e a instruo break fara com que o programa passe o controle para a prxima instruo aps o bloco switch.
int C=0; // retorna um valor inteiro int CalculaFatoria(int Numero) { if (Numero>0) { Print("Erro no Fatorial argumento negativo"); return(0); } if (Numero>1) return (CalculaFatoria(Numero-1)); else return(1); } // no retorna nenhum valor void InformaValorDeC() { Print("Valor de C=",C); // embora no retorne valor // nada impede voc de declarar // um valor de retorno return(0); // no necessrio em funes tipo void porem usar no causa erro nenhum }
A fim de tornar mais amplo o uso de uma funo, a linguagem MQL4 permite o uso de parmetros. Este parmetros possibilitam que se definida sobre quais dados a funo deve operar. A funo CalculaFatoria(int Numero), por exemplo, recebe como parmetro um Numero para calcular o fatorial, permitindo que se defina seu comportamento a partir deste valor. Para definir os parmetros de uma funo o programador deve explicit-los como se estive declarando uma varivel, entre os parnteses do cabealho da funo. Caso precise declarar mais de um parmetro, basta separ-los por vrgulas, assim
int C=0; // retorna um valor inteiro int Soma(int A, int B, int C) { return(A+B+C); }
Note que no caso das funes, cada parmetro declarado deve conter sua palavra chave de identificao de tipo, seno o compilador ira reclamar. Os parmetros da funo na sua declarao so chamados parmetros formais. Na chamada da funo os parmetros so chamados parmetros atuais. Os parmetros so passados para uma funo de acordo com a sua posio. Ou seja, o primeiro parmetro atual(da chamada) define o valor o primeiro parmetro formal (na definio da funo, o segundo parmetro atual define o valor do segundo parmetro formal e assim por diante. Os nomes dos parmetros na chamada no tem relao com os nomes dos parmetros na definio da funo
// // // //
a a a a
do de do de
Recursividade
Na linguagem MQL4, assim como em muitas outras linguagens de programao, uma funo pode chamar a si prpria. Uma funo assim chamada funo recursiva. Todo cuidado pouco ao se fazer funes recursivas. A primeira coisa a
se providenciar um critrio de parada. Este vai determinar quando a funo dever parar de chamar a si mesma. Isto impede que a funo se chame infinitas vezes o que poder ocasionar um erro em tempo de excusso, chamado, estouro de pilha, ou seja no existe mais memoria para trabalhar com a funo. H certos algoritmos que so mais eficientes quando feitos de maneira recursiva, mas a recursividade algo a ser evitado sempre que possvel, pois, se usada incorretamente, tende a consumir muita memria e ser lenta. Lembre-se que memria consumida cada vez que o computador faz uma chamada a uma funo. Com funes recursivas a memria do computador pode se esgotar rapidamente. Um exemplo desta funo o calculo do fatorial.
int CalculaFatoria(int Numero) { if (Numero>0) { Print("Erro no Fatorial argumento negativo"); return(0); } if (Numero>1) return (CalculaFatoria(Numero-1)); else return(1); }
// sem edentao int CalculaFatoria(int Numero) { if (Numero>0) { Print("Erro no Fatorial argumento negativo"); return(0); } if (Numero>1) return (CalculaFatoria(Numero-1)); else return(1); } // sem edentao int CalculaFatoria(int Numero){ if (Numero>0) { Print("Erro no Fatorial argumento negativo"); return(0); } if (Numero>1) return (CalculaFatoria(Numero-1)); else return(1); }
Para o compilador o mesmo cdigo, mas visualmente falando voc consegue identificar no primeiro cdigo o que faz parte da funo e da cada if ou if else. Em todos os casos s diferena visual mostra como voc organiza seu cdigo.
Analisaremos agora a primeira linha do nosso exemplo. Atravs desta linha estamos dizendo ao compilador que necessitamos um bloco de memria com o comprimento de 4 bytes, especificamos tambm que temos a inteno de armazenar um numero inteiro (isto sem a parte decimal, em outras palavra numero naturais) e como se no fosse o bastante pedimos para o compilador colocar como valor inicial de nossa varivel o numero zero (0). Assim o compilador entenderia esta linha :
int int int NumeroDaConta =0
: uma palavra chave : tipo de dados da varivel : uma declarao : nome de uma varivel : inicializao da varivel
No MQL4 temos os seguintes tipos de dados (como ja vimos) e suas respectivas declaraes
Inteiro (int) Lgico (bool) Literais ou caractere (int) Cadeia de Literais (string) Ponto Flutuante (double) Cores (color) Data e Hora (datatime)
Declarao
Declarar uma varivel significa introduzi-la ao mundo do seu programa e especificar seu tipo de dados. Usando as palavras chaves que aprendemos em TIPOS de DADOS e descritos acima (int, bool, char, string, string, double, color e datatime) com o nome que voc escolheu varivel. Por exemplo:
int MinhaVariavel; int A, B, C, D; int H=1, Z=2, X=3, Y=4;
Aqui voc declarou uma varivel nomeada MinhaVariavel que um tipo do inteiro (int). Antes de declarar esta varivel voc no pude utiliz-la em seu cdigo. Se voc a usar sem declarar o compilador MQL4 ira reclamar e lhe apresentara uma mensagem de erro dizendo que a varivel no foi definida, parecia com esta mensagem: 'MinhaVariavel ' - variable not defined. 1 error(s), 0 warning(s). Na segunda linha declaramos varias variveis com uma nica palavra chave de declarao. Nas linhas 3 e 4 declaramos e inicializamos as variveis, veja a flexibilidade, declarando uma varivel em cada linha voc pode colocar o descritor para que ela serve no lado, aumentando o grau de documentao do seu cdigo fonte, Exemplo:
int LE=2, PM=4; // lucro esperado em pips // Perda Mxima em pips
Outra informao importante, MQL4 sensvel ao caso, ouse seja, diferencia maisculas de minsculasem suas declaraes ento todas as variveis no exemplo abaixo so diferentes nomes de variveis
int par=2, Par=4, PAr=6, paR=8, PaR=10, pAR=12, PAR=14;
Este um fato que cria muitos erros na programao: Declarar uma varivel de uma jeito e usar de outro, combinando maisculas com minsculas.
Inicializao
Inicializar a varivel significa atribuir-lhe um valor inicial; Voc pode inicializar a varivel na mesma linha da declarao, assim
Ou se voce preferir pode declarar a varivel em um lugar e idealiz-la em um outro lugar do seu codigo, assim
int MinhaVariavel; ... ... ... ... MinhaVariavel = 10;
Porm uma regra nunca deve ser esquecida : a declarao de uma varivel deve vir antes de sua inicializao.
double MinhaFuncao(double a) { int d=2; // valida somente em MinhaFuncao return (a*d*c); } double OutraFuncao(double a) { return (a*d*c); // vai resultar um erro, embora // c seja valida nesta funo // d no varivel valida aqui } double OutraFuncaoDeNoco(double a) { return (a*c); // Sem erro pois c valido aqui tambm }
Como voc v, "C" uma varivel global pois foi declarada no bloco principal do programa. Tanto "d" quanto "a" so variveis locais, ou seja somente so validas nos blocos onde elas foram declaradas. Outro fato importante a lembra que todas as variveis globais so automaticamente inicializadas com zero se voc no inicializar. Isso significa que estes seriam os valores para estas variveis ao serem declaradas globais se voc no idealiz-las
Inteiro (int)...............: Lgico (bool)...............: Literais ou caractere(int)..: Cadeia de Literais (string).: Ponto Flutuante (double)....: Cores (color)...............: Data e Hora (datatime)......: 0 False NULL "" (vazia) 0.0 Black 01/01/1970 00:00:00
Variveis externas
A palavra chave "extern" utilizada para declarar um tipo especial das varivel, todos aqueles tipos de variveis que devem ser usados para definir entrada de dados ao seu programa, essas variveis so utilizadas na janela de propriedades do seu Consultor Especialista (Expert Advisor) ou indicador, para que voc permita ao usurio especificar alguma configurao especial para que seu sistema utilize. Porexemplo
extern color CorDoIndicador=C'0x00,0x00,0xFF'; // blue int init() { return (0); } CorDoIndicador aparecera na janela de propriedades do Consultor ou do indicador, permitindo que o usurio mude seu valor antes de iniciar a excusso do seu cdigo. Mas ateno esse tipo de varivel, embora possa ser definida em um script, tem o mesmo efeito de uma varivel global, pois no script no se apresenta tela de propriedades quando se inicia sua excusso.
Abaixo a imagem da janela de propriedades onde aparece o local de interao com o usurio e seu programa:
Matrizes
Matriz uma srie de elementos (variveis) do mesmo tipo alocadas consecutivamente na memria que podem ser referenciados individualmente adicionando-se um ndice a um nome nico. Isso significa que, por exemplo, podemos guardar 5 valores do tipo int sem ter que declarar 5 variveis diferentes cada uma com um identificado diferente. Ao invs disso, usando uma matriz, podemos guardar cinco valores diferentes do mesmo tipo, int, por exemplo, com um identificador nico. Por exemplo, uma matriz que contm 5 valores inteiros do tipo int chamada billy poderia ser representada dessa maneira:
0 billy int int in int int 1 2 3 4
Onde cada painel em branco representa um elemento da matriz, que nessa caso so valores inteiros do tipo int. Esses so numerados de 0 at 4, pois em matrizes o primeiro ndice sempre 0, independentemente de seu tamanho. Como qualquer outra varivel, uma matriz precisa ser declarada antes de ser usada. Uma declarao tpica de uma matriz em MQL4 :
tipo nome[elementos];
onde tipo um tipo de objeto vlido (int, double, ...), nome um identificador de varivel vlido e o campo elementos, que est entre colchetes [], especifica quantos desses elementos a matriz contm. Ao declarar uma matriz de escopo local (dentro de uma funo), se no especificarmos nada, no ser inicializada, ento seu contedo ser indeterminado
at que guardemos alguns valores nela. Se declararmos uma matriz global (fora de qualquer funo) seu contedo ser inicializado com todos seus elementos preenchidos com zeros. Assim, se declararmos em um escopo global:
int billy[5];
Todos os elementos de billy sero preenchidos inicialmente com 0. Mas, alm disso, quando declaramos uma matriz, temos a possibilidade de atribuir valores iniciais para cada um de seus elementos usando chaves { }. Por exemplo:
int billy[5] = {16, 2, 77, 40, 12071};
Essa declarao teria criado (na memria) uma matriz como a seguinte
0 billy 16 int 1 2 int 2 77 in 3 40 int 4 12071 int
O nmero de elementos em uma matriz que inicializamos dentro das chaves { } precisa estar de acordo com o tamanho de elementos que declaramos para a matriz dentro dos colchetes [ ]. Por exemplo, no exemplo da matriz billy, ns declaramos que tinha 5 elementos e na lista de valores iniciais dentro das chaves { } ns preenchemos com 5 valores diferentes, um para cada elemento. Devido ao fato disso ser considerado uma repetio intil, o MQL4 inclui a possibilidade de deixar os colchetes vazios [ ] e o tamanho da matriz ser definido pelo nmero de valores inclusos entre chaves { }:
int billy[] = {16, 2, 77, 40, 12071};
De acordo com os exemplos anteriores no qual billy tinha 5 elementos e cada um desses elementos eram do tipo int, os nomes que podemos usar para nos referenciar a cada elemento so os seguintes:
Billy[0] billy 16 int Billy[1] 2 int Billy[2] 77 in Billy[3] 40 int Billy[4] 12071 int
Por exemplo, para guardar o valor 75 no terceiro elemento de billy, um comando aceitvel seria esse:
billy[2] = 75;
E, por exemplo, para passar o valor do terceiro elemento de billy para uma varivel a, poderamos digitar:
a = billy[2];
Sendo assim, para todos os propsitos, a expresso billy[2] como qualquer outra varivel de tipo int. Note que o terceiro elemento de billy especificado como billy[2], pois o primeiro elemento billy[0], o segundo billy[1], e sendo assim, o terceiro billy[2]. Pela mesma razo, seu ltimo elemento billy[4]. Pois se escrevssemos billy[5], estaramos nos referenciando ao sexto elemento de billy e ento excedendo o tamanho da matriz. Em MQL4 perfeitamente vlido exceder o limite vlido de ndices para uma matriz, o que pode causar problemas pois eles no causam erros de compilao, mas podem causar resultados inesperados ou erros srios durante a execuo. A razo pela qual isso permitido ser vista mais a frente quando comearmos a usar ponteiros.
jimmy representa uma matriz bidimensional de 3 por 5 valores do tipo int. O maneira de se declarar essa matriz seria:
int jimmy[3][5];
e, por exemplo, a maneira de referenciar o segundo elemento verticalmente e o quarto horizontalmente em uma expresso seria:
billy[1][3] = 75; jimmy 0 0 1 2 3 4
1 2
75
Matrizes multidimensionais no so limitadas a dois ndices (duas dimenses). Elas podem conter quantos ndices forem necessrios, embora seja raro ter que representar mais que 3 dimenses. Apenas considere a quantidade de memria que uma matriz com muitos ndices pode precisar. Por exemplo:
int century[100][365][24][60][60];
atribui um int para cada segundo contido em um sculo, que mais que 3 bilhes de ints! Isso consumiria algo em torno de 12000 megabytes de memria RAM se pudssemos declarar. Matrizes multidimensionais no so nada mais que uma abstrao, pois que podemos obter os mesmo resultados com uma matriz simples simplesmente colocando um fator entre os ndices:
int jimmy[3][5]; // isso int jimmy[15]; // equivalente a isso //com a nica diferena que o compilador nos //lembra a profundidade de cada dimenso imaginria
Nota Final : Matrizes, tanto simples quanto multidimensionais, passadas como parmetro de funes so uma fonte de erros comum para programadores com pouca experincia.
A diretiva Define
Define a diretriz orientadora usada gerar uma constante. A constante muito como a varivel com a somente uma diferente, voc ajusta seu valor somente uma vez e voc no pode mudar seu valor em seu cdigo como a varivel
#define Minha_Constante 100
Como voc pode observar no exemplo acima no h nenhum smbolo da atribuio (=) mas somente espao entre o nome constante (Minha_Constante) e seu valor (100). E voc pode observar demasiado que a linha no terminou com ponto e virgula, mas terminou com um caractere do carriage-return (linha nova). O nome da constante obedece as mesmas rguas que voc tinha aprendido sobre escolher os nomes do identificador (SINTAXE da lio 2), porque o exemplo voc no pode comear o nome constante com um nmero nem no excede 31 caracteres. O valor do ndice pode ser qualquer tipo que voc quiser. O compilador substituir cada ocorrncia do nome constante em seu cdigo de fonte com o valor correspondente.
Assim voc pode usar a constante acima em seu cdigo como aquela:
Soma = Minha_Constante * 10;
A diretiva property
Existem algumas constantes predefinidas chamadas "controle de compilao" includa na lngua MQL4, que voc pode os ajustar em parmetros em seu programa, algumas so especificas para indicadores. Abaixo as propriedades que voc pode ajustar em seu programa
descrio de uso o link da pagina web da companhia ou pagina pessoa de quem desenvolveu o cdigo companhia ou nome pessoa de quem desenvolveu o codigo tamanho da pilha, o tamanho de uma determinada reagio de memria que o seu programa pode usar para trabalhos com as funes como por exemplo criar variveis locais define que o cdigo que esta sendo escrito faz parte de uma biblioteca diz ao compilador que o traado grfico que o indicador far devera fazer parte da mesma janela onde esto sendo plotadas as cotaes diz ao compilador que o traado grfico que o indicador far devera fazer parte de uma janela separada da janela onde esto sendo plotadas as cotaes numero de penas de traados grficos no indicador, um indicador pode ter no mximo 8 buffers de dados, ou seja 8 matrizes onde ele colocara seus clculos, estas matrizes contem os dados que daro origem as curvas e smbolos traados pelo indicador no grfico
stacksize
int
library
void
indicator_chart_window
void
indicator_separate_window void
indicator_buffers
int
indicator_minimum
valor mnimo que ser mostrado no grfico double para o indicador, numero abaixo deste no sero plotados pois ficam fora do grfico valor mximo que ser mostrado no grfico double para o indicador, numero acima deste no sero plotados pois ficam fora do grfico color define a cor da pena de desenho de cada um dos 8 buffers utilizados pelo indicador define a espessura da linha da pena de desenho de cada um dos 8 buffers utilizados pelo indicador define a estilo da linha as ser plotada pela pena de desenho de cada um dos 8 buffers
indicator_maximum
indicator_colorN
indicator_widthN
int
indicator_styleN
int
utilizados pelo indicador indicator_levelN int define a linha de nvel do indicador, essas linha aparecem na horizontal na janela onde o indicador plotado, com se fosse uma linha separadora de valores no grfico define a cor da linha de nvel do indicador, essas linha aparecem na horizontal na janela onde o indicador plotado, com se fosse uma linha separadora de valores no grfico define a espessura da linha de nvel do indicador, essas linha aparecem na horizontal na janela onde o indicador plotado, com se fosse uma linha separadora de valores no grfico define o estilo da linha de nvel do indicador, essas linha aparecem na horizontal na janela onde o indicador plotado, com se fosse uma linha separadora de valores no grfico define que deve aparecer a janela de confirmao de excusso do cdigo quando ele comear a ser executado mostra na janela terminal, tabulao experts, as configuraes das variveis externas que o cdigo esta usando
indicator_levelcolor
color
indicator_levelwidth
int
indicator_levelstyle
int
show_confirm
void
show_inputs
void
A diretiva include
Para programas escritos emMQL4, antes da compilao propriamente dita, h um processo que chamamos de pr-compilao. O papel desta diretiva instruir o prprocessador (parte do compilador responsvel pelo pr-processamento) para incluir, na hora da compilao, um arquivo especificado. Sua forma geral :
#include "win32.h"
No exemplo acima voc que diz ao compilador para abrir o arquivo "win32.h" e ler todo seu contedo e copil-lo no mesmo lugar em que encontrou a diretiva include. No exemplo que acima voc incluiu o nome do arquivo entre aspas duplas, esse o meio de voc especificar ao compilador para usar o diretrio padro para buscar o arquivo (geralmente, <diretrio do MetaTrader>\experts\include). Voc pode incluir arquivos localismos em outros diretrios, porem a pesquisa sempre comea no diretrio padro de trabalho desta diretiva no MetaTrader. cosidere os seguintes diretorios no MetaTrader
de de de de de de de de
\\ na proxima linha voce diz que o arquivo esta em \\C:\Arquivos de programas\MetaTrader 4\experts\include #include "win32.h" \\ na proxima linha voce diz que o arquivo esta em \\C:\Arquivos de programas\MetaTrader 4\experts #include "..\win32.h" \\ na proxima linha voce diz que o arquivo esta em \\C:\Arquivos de programas\MetaTrader 4\experts\files #include "..\files\win32.h"
A diretiva import
Algumas vezes, voc necessita rotinas criadas em outros aplicativos que no seja o MetaTrader (por exemplo, alguma funo especifica do Windows) ou em outros programas compilados do prprio MetaTrader. Para isto voc usa a diretiva import, com ela voc diz ao compilador que com as definies que esto dentro do import, voc quer chagar funes em outros aplicativos. Por exemplo:
#import "user32.dll" int MessageBoxA(int hWnd, string lpText, string lpCaption, int uType); int MessageBoxExA(int hWnd, string lpText, string lpCaption, int uType, int wLanguageId); #import "stdlib.ex4"
Na verdade, voc simplesmente esta dizendo ao computador para chamar as funes que voc define apos a diretiva em outro cdigo executvel. No primeiro caso voc quer chamar as funes MessageBoxA e MessageBoxExA na biblioteca do windows. Em arquivos DLL voce tem de definir como as funes sero chamadas pelo MT
No segundo caso voc quer chamar as funes em executvel do prprio MetaTrader chamado stdlib.ex4. Em arquivos ex4 que so os arquivos executveis dos cdigos digitados no MetaEditor e compilados, as funes j esto prontas para uso, nada impede voce de defini-las assim: #import "stdlib.ex4" string int bool string string ErrorDescription(int error_code); RGB(int red_value,int green_value,int blue_value); CompareDoubles(double number1,double number2); DoubleToStrMorePrecision(double number,int precision); IntegerToHexString(int integer_number);
experts
files
include
indicators
fica dentro do diretrio experts libraries Diretrio base para a diretiva property library. Todo cdigo que voce definir como uma biblioteca ser colocado neste diretorio. (*) fica dentro do diretrio experts aqui gravado pelo MetaTrade, para cada dia, todas as mensagens geradas pelos consultores, indicadores e scripts, os quais voc pode acessar para estudar algum erro que ocorreu no seu cdigo, vale a pena salientar que a saida da funo print vai para este log tambm. O nome do arquivo no seguinte formato AAAAMMDD.LOG onte AAAA - Ano que o arquivo corresponde MM - Mes que o arquivo corresponde DD - dia que o arquivo corresponde .LOG - a extenso do arquivo fica dentro do diretrio experts. Diretorio onde sero gravados seus scripts. (**)
logs
scripts
fica dentro do diretrio experts Quando voc cria um consultor, indicador, script ou outro cdigo, voc templates pode especificar ele como uma base para novos cdigos, neste diretrio voc deve colocar as instrues. logs Aqui voc encontra os logs do MetaTrader, no que diz respeito a erros e aberturas e fechamentos de ordens. O nome do arquivo no seguinte
formato AAAAMMDD.LOG (*) voc pode especificar outro diretrio sendo que a base tem de ser este diretrio (**) voc pode colocar o cdigo e o executvel em outro diretrio que no seja este, porem o mesmo no ficara disponvel para ser utilizado pelo MetaTrade
Bom Agora separaremos os tipos de cdigos que voc mais comumente ira criar : - Scripts - Indicadores Peronalizados - Consultores Especialistas
Indicadores Personalizados
Nada mais que um indicador tcnico escrito independentemente, ou seja, ele no vem junto com o MetaTrade integrado ao terminal, voc necessita compil-lo para poder utilizar. Como indicadores internos, no podem negociar automaticamente e so apenas utilizado com funes de analise. Embora no possam realizar as negociaes, os indicadores podem enviar sinais sonoros e alertas sobre o melhor perodo para uma negociao, cabendo ao usurio executar a ordem de negociao. Como citado acima os Consultores so gravador no diretrio terminal_directory\experts\indicators.
Consultores Especialistas
Um Consultor Especialista (Tambem chamado de Expert, Expert Advisor ou simplesmente EA) nada mais que um Trade System Automtico (Automated Trading System - ATS) escrito na linguagem especfica do MetaTrader, o MetaQuotes Language (MQL), alm de notificar o investidor sobre pontos de compra e venda, de acordo com o mtodo especificado, capaz de executar automaticamente os trades, enviando as ordens diretamente corretora. Automatizar os trades, voc elimina a sua obrigao de acompanhar o mercado o tempo todo. tambem pode testar seu sistema sobre dados histricos, facilitando o desenvolvimento de estratgias de trading. Escrever um Expert Advisor relativamente fcil, sendo apenas necessrio que o investidor tenha conceitos bsicos de programao (Neste portal eu lhe ensino a programar para MetaTrader). A linguagem MQL inclui um grande nmero de variveis usadas para controlar dados correntes e passados, operaes aritmticas e lgicas, e comandos internos usados para controle das posies (abertura, cancelamento, fechamento de ordens etc). MQL possui uma linguagem similar ao EasyLanguage, desenvolvida pela TradeStation Technologies.
Dentre as vantagens dos Trade Systems Automticos, podemos citar as principais: O investidor no precisa acompanhar o mercado o tempo todo, podendo realizar diversas operaes intraday sem perder as boas oportunidades do mercado. Como o FOREX opera 24 horas, o investidor pode deixar o seu Trade System executando e ir dormir, almoar ou sair com os amigos; executa as ordens o computador, no tendo o risco de qualquer emoo do investidor interferir nos trades. O computador realiza lucro e prejuzo (aciona STOP) sem dor e arrependimento, fazendo exatamente o que o Trade System determina. Vale lembrar que qualquer emoo que venha a influenciar os trades pode causar perdas significativas. Um Consultor Especialista comea a funcionar a cada mudana na cota do smbolo ao qual esta ligado. Cada nova cota gera uma execuo da funo principal do Consultor (start()), logicamente, se ocorrer uma nova cota no par e o Consultor ainda no terminou de executar a funo principal, o chamado para esta nova cota ser perdido. O Consultor serva para informar sobre uma possibilidade para negociar e executar a referida negociao em um cliente, o que o faz emitir automaticamente ordens diretamente ao servidor sem a interveno do usurio. Como a maioria de sistemas negociando. importante salientar que voc tem a possibilidade de testar seu histrico no Testador de Estratgias, utilizando dados histricos para avaliar seu consultor, porem, eu, particularmente no confio muito no testador de estratgia, j vi muitas divergncias ocorrerem entre os testes e a conta demo ou real. Como citado acima os Consultores so gravador no diretrio terminal_directory\experts.
Quem
Scripts
na verdade uma seqncia de comandos pr determinados, o qual criado para ser executado uma nica vez. Uma vez terminada a excusso os mesmos so retirados da memria, caso haja a necessidade de seu trabalho o mesmo devera ser executado novamente pelo usurio. Vo pode considerar um script como sendo um Consultor especialista que executado somente uma vez.Alguns trabalhos comuns para scripts - Colocar ordens de negociao com parametros padronizados (Volume, SP, TP, etc) - Fechar todas as ordens abertas - Modificar ordens abertas - etc Como citado acima os Consultores so gravador no diretrio terminal_directory\experts\scripts.
B) No MetaTrade, abra o grfico em que voc deseja que seu cdigo seja seja executado C) Abra a janela de navegao, e localize o tipo de executvel que voc quer utilizar
D) Simplesmente clique no nome do cdigo que voc deseja executar, sem soltar o boto do mouse arraste e solte em cima do grfico ao qual este cdigo deva ser ligado, caso seja um indicador ou consultor o mesmo apresentar a janela de propriedades onde voc informa a configurao na qual o cdigo deve ser executado (lembre-se aqui voc configura todas as variveis externas do seu cdigo). No caso dos scripts, a janela de propriedades no ser mostrada, pois o mesmo no possui esta facilidade. E) Agora uma explicao resumida para conferir se seu consultor vai ser executado corretamente
1 - Expert que vou usar (note que o cone esta mais colorido, indica que j esta compilado, os outros dois no) 2 - depois de clicar com o boto direito do mouse sobre o nome do experts aparece o menu e peo a opo para adicion-lo ao chart 3 - Ai esta o nome do chart, se aparecer um "x" indica que o expert no esta sendo executado 4 - para ativar a excusso procure na barra de ferramentas este cone e clique nele 5 - Carinha indica que o expert esta sendo executado, porem a carinha triste indica que ele no pode abrir posies 6 - para liberar o expert para abrir posies pea propriedades e selecione a marca "alow live trading" (note que a minha no esta selecionada, voc tem de selecionar) 7 - apareceu a carinha feliz o expert ta funcionando...
Bem vindo ao mundo prtico de que voc ira comear neste momento em MQL4; bem vindo a seu primeiro indicador em MQL4. Eu recomendo-o reler com muito com cuidado as lies precedentes, antes de continuar com estas sries do cursos, o motivo que ns os usaremos tudo que vimos ate agora nossas explanaes e estudos dos indicadores e consultores especialistas feitos sob encomenda, os quais ns criaremos nesta srie das lies. Hoje ns criaremos um indicador simples, que no signifique demasiado para nosso mundo, mas significa muito para nossa compreenso da programao em MQL4. Simplesmente realizaremos a subtrao dos preos high e low; porem no se apresse, voc saber como tudo funciona mais adiante. Ento mos a obra
O assistente do MetaEditor
Simplesmente, abra o MetaEditor e inicie um novo arquivo fonte. Aparecer a janela do assistente do MetaEditor. Escolheremos que queremos montar o cdigo de um indicador.
O Prximo passo clicar no boto seguinte, e aparece a tela onde identificaremos o nome do nosso indicador, o autor ou nome do proprietrio do cdigo, bem como o link da pgina ou do e-mail do mesmo. Aqui tambm definiremos quais so as variveis que o usurio pode modificar para configura o indicador (no nosso caso no temos nenhuma neste primeira verso)
Clicamos no boto seguinte e finalmente aparece a ultima pagina do assistente, onde identificaremos as caractersticas de plotagem do nosso indicador, entre elas : - Onde o indicador ser desenhado - A janela de desenho possui um limite mnimo ou Maximo - Quantos indicadores e suas caractersticas teremos (mximo de 8 itens)
Feito isto, clicamos em finalizar e o assistente ira gerar o cdigo inicial de nosso indicador, poupando-nos algum trabalho de digitao.
int init() { //---- indicators SetIndexStyle(0,DRAW_LINE); SetIndexBuffer(0,ExtMapBuffer1); //---return(0); } //+-----------------------------------------------------------------+ //| Custom indicator deinitialization function | //+-----------------------------------------------------------------+ int deinit() { //---//---return(0); } //+-----------------------------------------------------------------+ //| Custom indicator iteration function | //+-----------------------------------------------------------------+ int start() { int counted_bars=IndicatorCounted(); //---//---return(0); } //+-----------------------------------------------------------------+
No sei quanto a voc, mas quem inventou o assistente, merece um premio, pois em poucos passos geramos cdigo suficiente para compilar um programa completo de indicador em MQL4 sem que o compilador retorne nenhum erros. Claro que o indicador compilado com este cdigo no ira desenhar nada no grfico ao qual for anexado (somente criar a janela onde ele dever trabalhar), porem, voc tem de concordar, nos poupou um grande trabalho na digitao. Agora vamos explicar as partes de do cdigo, antes e comearmos a programar o nosso indicador.
Aqui no temos muito segredos, o que o assistente montou n cdigo, nada mais que as definies e comentrios sobre quem escreveu o cdigo. Note que o que o assessor nada mas fez que copiar as informaes que voc colocou na segunda janela do assistente (Autor e Link) como uma propriedade para o compilador. Aqui ressaltamos uma particularidade da linguagem MQL4 : os comentrios. Comentrios so segmentos ou partes do seu cdigo que no interessam ao compilador, portanto voc pode escrever o que quiser neles que o compilador no ira se importar. Em MQL4 existem dois tipos de comentrios - Comentrios de Linha : sempre que voc encontrar duas barras juntas "//" significa que deste ponto em diante at o fim da linha ser um comentrio
//+-----------------------------------------------------------------+ //| MeuPrimeiroIndicador.mq4 | //| Copyright 2007, DooMGuarD Sistemas Especialistas... | //| http://dgforex.50webs.com | //+-----------------------------------------------------------------+
- Comentrios de vrias linhas : sempre que voc encontrar uma barra e um asterisco "/*", significa que a partir deste ponto esta iniciando um comentrio, este comentrio somente ter um fim ao encontrar a seqncia de um asterisco e uma barra "*/". Em outras palavras, tudo que estiver entre /* e */ ser considerado comentrio
Bem nesta parte do cdigo, foi criado, pelo assistente, a identificao que estamos criando um indicador. Isto se da pelas definies das propriedades #property. Qual a funo de cada uma? o que veremos em seguida diz ao compilador para criar um indicador, onde as retas plotadas no grfico, no faro parte da rea do grfico utilizada para colocar as cotaes. O sistema vai criar uma janela separada para plotar seus valores. Se os valores do seu indicador, acompanhar oa valores das cotaes, voce pode plotar ele no mesma rea das cotaes, para isso esta propriedade tem de ser #property indicator_chart_window. Na figura abaixo identificamos as 2 reas no grfico
#property indicator_separate_window:
Nota: voc pode colocar vrios indicadores com seus valores plotados na janela principal do grfico, mas no pode juntar 2 indicadores uma janela separada, ou seja cada vez que voc usar , o sistema criar uma nova rea de plotagem separada no grfico.
#property indicator_buffers: aqui dizemos ao compilador quantos buffer (rea de armazenamento de memria) que utilizaremos no nosso indicador, voc pode considerar cada buffer como um conjunto de valores que ira gerar uma curva em um grfico, para entender mais facilmente, porem o objetivo dos buffers vai alem disso (mais adiante veremos o seu funcionamento). No nosso caso usaremos somente um buffer de memria. Voc pode ter no mximo 8 buffers para cada indicador.
para cada buffer do indicador podemos atribuir caractersticas que so assumidas como padres, ou caractersticas iniciais. Uma destas caractersticas a cor que usaremos para plotar o indicar. Aqui esta definido que no utilizaremos nenhuma cor como padro, o usurio ter que escolher uma na janela de propriedades do indicador. Por fim, mas no menos importante, definimos uma varivel, na qual colocaremos os valores calculados do nosso indicador, para que os mesmos sejam plotados no grfico. Como a quantidade de itens de um indicador vai aumentando a medida que novas cotaes, em relao ao tempo, vo aparecendo, esta matriz criada sem nenhuma dimenso, o compilador acrescenta um cdigo que a medida que necessitamos mais um item na matriz ao usar este item ele ser automaticamente criado na memria se no existir.
#property indicator_color1:
Esta funo a primeira parte do nosso cdigo executada quando voc acrescentar seu indicador no grfico. Ela ser executada a cada vez que voc mudar as propriedades do seu indicador. Aqui declaramos todas as caractersticas do indicador que desejarmos. No cdigo criado pelo assistente indicamos que o estilo do indicador ser uma linha e que a varivel ExtMapBuffer1 ser utilizada como buffer do operador No sei se voc observou, mas quando declaramos as propriedade do indicador o ndice que ele recebeu foi 1 (um)
#property indicator_color1 C'None'
Isto se deve ao fato de que todas as variveis de memria que so matrizes comeam com o ndice 0 (zero). Como a propriedade do indicador no uma matriz mas sim definies separadas onde a diferena se da no numero ao final da propriedade os criadores da linguagem acharam por bem definir as propriedade do indicador comeando em 1
Nesta funo voc simplesmente elimina qualquer lixo que seu indicador possa ter deixado no grfico, tipo, se voce desenhou algum smbolo que no foi criado como buffer, ou limpa um comentrio, ou simplesmente grava alguma coisa em algum arquivo. Sua necessidade girara voc nesta tarefa.
Bem, nesta funo onde colocaremos o cdigo real de calculo do indicador para cada intervalo de tempo no grfico. Ela ser chamada sempre que mudar alguma cotao do par que esta sendo representado no grfico bem como em cada vez que uma barra necessitar do seu clculo. O simplesmente criou uma varivel (counted_bars) com o nmero de barras que no necessitam o calculo do valor do indicador. Em outra palavras ela contem o numero de barras onde o indicador j foi calculado e, em teoria, no necessitam ser recalculadas novamente
Nosso indicador, nada mais faz que determinar a extenso de um candle. Um indicador deste tipo, pode revelar a voc como os candles se comportam quanto ao tamanho, fato este que pode orientar voc em seus stops. O Seu funcionamento simples : Indicacador = (Preo_High - Preo_Low) / Variao_Minima_do_Par Por variao mnima do por se ente como sendo o valor da menor variao de preo que um par pode ter, por exemplo
EURUSR = 0.0001 USDJPY = 0.01
indicator_width1 3
para a espessura 0 //trao contnuo. //tracejado. //pontilhado. //alternado pontos e traos. //alternado traos e dois pontos.
Funo de inicializao
Aqui definiremos os demais parmetros do indicador, como dizer o tipo de linha, qual buffer utilizar, dar um nome que aparecer no grafico, etc, etc. Vamos ao cdigo
//+-----------------------------------------------------------------+ //| Custom indicator initialization function | //+-----------------------------------------------------------------+ int init() { //---- indicators SetIndexStyle(0,DRAW_HISTOGRAM); //queremos que seja um histograma SetIndexBuffer(0,ExtMapBuffer1); IndicatorShortName("Meu Primeiro: "); indicador //---return(0); } //damos um nome ao
Funo de termino
No possumos nenhuma espcie de trabalho para quando o indicador retirado do grfico, quando voc fecha a janela do grfico ou quando o MetaTrader desligado. Logo essa parte do cdigo continua a mesma.
Funo de trabalho
Primeiramente retiraremos a declarao de counted_bars pois, no usarei este nome de varivel. Criaremos duas novas variveis, uma para controlar o lao (loop) e outra para limit-lo. No lao simplesmente calcularemos o valor de cada barra que foi requisitada.
//+-----------------------------------------------------------------+ //| Custom indicator iteration function | //+-----------------------------------------------------------------+ int start() { int Itens = Bars - IndicatorCounted(), // total de velas a calcular Item; // controle do lao //---- Calculo dos valores requisitados for(Item=Itens;Item>=0;Item--) { ExtMapBuffer1[Item] = (High[Item] - Low[Item])/Point; } //---return(0); } //+-----------------------------------------------------------------+ Itens : simplesmente contem a quantidade de candles que necessitam de recalculo. Aqui vale a pena lembrar algumas variveis no MQL4 :
- Bars: o nmero total de candles ou barras no grfico - IndicatorCounted(): o numero total de candles ou barras que no se modificaram desde a ultima chamada da funo trabalho do indicador, logo a conta nos da a quantidade de itens a serem recalculados. Vale a pena salientar que o ndice 0 (zero) o candle atual, ou o que ainda no se completou no tempo, ou ainda o candle mais a direita do grfico. - High[Item]: Valor do preo mximo da cotao do para para o referido candle - Low[Item]: Valor do preo mnimo da cotao do para para o referido candle - Point: o valor da variao mnima da cotao do par, muito usado para transformar diferenas entre cotaes para pips Ento (High[Item] - Low[Item])/Point nos da a diferena em pips entre o valor mximo e o valor mnimo do candle o qual ser armazenado no buffer do indicador () e que ser utilizado pelo MetaTrade para gerar nosso grfico de histograma.
Note que o nome que voc deu ao indicador aparecer no grfico, junto com o valor atual do mesmo.
// definiremos linhas de niveis no grfico // Nota pode-se definir no maximo 8 valores #property indicator_levelcolor Yellow #property indicator_levelstyle STYLE_DOT #property indicator_levelwidth 0 #property indicator_level1 25 #property indicator_level2 50 #property indicator_level3 75 #property indicator_level4 100
Se voc compilar esta simples mudana e colocar no grfico ter esta seguinte sada:
Note que s apareceram 2 linhas pontilhadas, apesar de termos definido 4 linhas, que as outras ficam fora do limite superior, se voc quiser pode definir o valor mnimo e mximo para um indicador utilizando o seguinte cdigo (o codigo a seguir no faz parte de nosso indicador, somente ilustrativo).
#property indicator_minimun 0 #property indicator_maximum 150
Se voc acrescentar estas definies no seu cdigo ter uma sada como a de abaixo (note os limites verticais do grafico):
Agora sim apareceram as 4 linhas de nveis definidas, mas este cdigo no far parte do nosso indicador.
buffer #property indicator_color1 Green //mudamos a cor para verde #property indicator_style1 STYLE_SOLID //queremos uma linha slida #property indicator_width1 3 //espessura da linha = 3 //segundo buffer #property indicator_color2 Red //mudamos a cor para vermelho #property indicator_style2 STYLE_SOLID //queremos uma linha slida #property indicator_width2 0 //espessura da linha = 0
indicator_levelcolor Yellow indicator_levelstyle STYLE_DOT indicator_levelwidth 0 indicator_level1 25 indicator_level2 50 indicator_level3 75 indicator_level4 100
//---- input parameters extern int PeriodoMA = 25; // Nmero de perodos da mdia extern int TipoMA = 1; // tipo de mdia a ser utilizada extern string TipoMASos = "SMA=0, EMA=1, SMMA=2, LWMA=3"; // tipos de mdia //---- buffers double ExtMapBuffer1[]; double ExtMapBuffer2[]; // buffer para a nova pena do indicador double ValoresParaMedia[500]; // Maior periodo para Media de 500 valores
Os parmetros de entrada "input parameters" geralmente so definidos no assistente o qual ficaria como na figura abaixo
Para acrescentar uma parmetro, simplesmente clique no boto "add" que aparece uma nova linha, com um duplo clique em cada uma das configuraes voc pode mudar o que ali aparecer escrito. Lgico que para eliminar um parmetro voc simplesmente seleciona o mesmo com um clique do mouse sobre o parmetro e depois clica no boto "Deletar"
S duas observaes, 1) para utilizarmos o sistema de calculo de mdias mveis, usaremos as mesmas definies do MQL4 para designar o tipo, a saber
// Tipos de linhas para a espessura 0 MODE_SMA 0 //Mdia simples MODE_EMA 1 //Mdia exponencial MODE_SMMA 2 //Amortizada. MODE_LWMA 3 //Linear com atribuio de pesos.
2) TipoMASos na verdade no tem propsito real em nossos clculos, s foi adicionado para mostrar ao usurio o que ele pode informar para a varivel TipoMA. Ira produzir a seguinte tela de parmetros (note que a terceira linha uma ajuda importante ao usurio)
Com isso o usurio que utilizar o indicador vai saber que o TipoMA=1 para utilizar uma mdia tipo EMA.
IndicatorShortName("Meu Primeiro Poderoso: "); //damos um nome ao indicador // Testa se periodo valido if (PeriodoMA<1) PeriodoMA = 1; if (PeriodoMA>500) PeriodoMA = 500; // Testa se periodo valido if ((TipoMA<0)||(TipoMA<3)) TipoMA = 1; // Padro EMA //---return(0); }
Somente uma observao, como temos um certo numero de perodos para calcular a mdia, se estivermos calculando sobre menos barras que o perodo necessrio, ento no teremos valores corretos da media e consequentemente do indicador, ento diremos ao sistema de plotagem de indicadores que no queremos plotar essas barras iniciais do grfico. Para voc entender a funo SetIndexDrawBegin veja a figura abaixo, pois uma imagem vale mais que mil palavras....
Funo de termino
No possumos nenhuma espcie de trabalho para quando o indicador retirado do grfico, quando voc fecha a janela do grfico ou quando o MetaTrader desligado. Logo essa parte do cdigo continua a mesma.
Funo de trabalho
Agora vamos acrescentar o calculo da mdia para que a mesma possa ser plotada no sistema
//+-----------------------------------------------------------------+ //| Custom indicator iteration function | //+-----------------------------------------------------------------+ int start() { int Itens = Bars - IndicatorCounted(), // total de velas a calcular Item; // controle do lao //---- Calculo dos valores requisitados for(Item=Itens;Item>=0;Item--) { // calcula o tamanho do candle em pips ExtMapBuffer1[Item] = (High[Item] - Low[Item])/Point; // Monta a matriz para calcular a mdia for(int i=0;i<PeriodoMA;i++) ValoresParaMedia[i] = (High[Item + i] - Low[Item + i])/Point; // calcula a mdia e joga no buffer do indicador ExtMapBuffer2[Item] = iMAOnArray(ValoresParaMedia,PeriodoMA,PeriodoMA,0,TipoMA,0); } //---return(0); } //+-----------------------------------------------------------------+
Bom, para calcular este segundo buffer do indicador, necessitamos criar uma matriz com os dados para o calculo da mdia. Voc deve estar se perguntando, porque no usar uma matriz aberta, sem dimenses, a passagem de parmetro para uma funo em MQL4 deve ser uma regio definida de memria, e uma matriz aberta no satisfaz esta condio. Outra pergunta que voc deve estar fazendo, porque no pego simplesmente o valor de ExtMapBuffer1 assim ValoresParaMedia[i] = ExtMapBuffer1[Item], simples estamos caculando o valro de ExtMapBuffer1 porem, os valores apos o valor atual que a matriz necessita ainda no foram calculados, por este motivo que utilizamos a funo SetIndexDrawBegin na funo de inicializao, exatamente para evitar os valores do comeo do grfico.
Nota : Junto com o nome do indicador sempre aparece o valor atual dos buffers do indicador, ou seja, referente a ltima cota recebida do servidor.
Aqui temos uma limitao de no mximo 8 penas, e voc no pode usar mais. O que voc usou na definio acima, diz ao compilador quantas penas voc quer utilizar, porem voc pode utilizar buffers sem a necessidade de desenhar valores no grfico. Qual a vantagem de utilizar um buffer e no plotar nada, simples, quando
voc traa um buffer voc trabalha com uma matriz aberta, logo, quando comear um novo candle, o buffer de ndice 0 foi colocado no ndice 1 para que o ndice 0 fique disponvel para esse novo candle, ou seja, a cada nova vela os valores so manipulados na memria para que o ndice zero do buffer seja sempre o da ultima vela. Logo se voc deseja ter valores auxiliares, referentes a clculos anteriores, voc coloca em um buffer que no vai ser desenhado, assim voc no necessita criar um cdigo para mover estes valores na memria para deixar tudo conforme voc necessita, e tambm no necessitara executar o calculo para todos os candles a cada vez que for calcular o indicador usando estes dados auxiliares. Para ter mais buffers que os definidos veja o cdigo abaixo
property indicator_buffers 1 // onde n pode variar de 1 a 8 ... double ExtMapBuffer1[]; double ExtMapBuffer2[]; ... int init() { //---- indicators IndicatorBuffers(2); buffers SetIndexStyle(0,DRAW_HISTOGRAM); SetIndexBuffer(0,ExtMapBuffer1); SetIndexBuffer(1,ExtMapBuffer2); return(0); }
//aumento o numero de
// definies dos buffers 2 a 7 //oitavo e ultimo buffer #property indicator_color8 Red //mudamos a cor para vermelho #property indicator_style8 STYLE_SOLID //queremos uma linha slida #property indicator_width8 0 //espessura da linha = 0
Linhas de nveis
Se voc tem em seu indicador valores que so mais ajustados a determinadas situaes, como por exemplo, entre dois valores calculados, indicam um nervosismo no mercado ou algo assim, ento melhor mostrar essa regio ao usuario.
#property indicator_levelcolor Yellow #property indicator_levelstyle STYLE_DOT #property indicator_levelwidth 0 #property indicator_level1 25 // definies dos niveis de 2 a 7 #property indicator_level8 100
Sobe) { ObjectDelete(Nome); ObjectCreate(Nome,OBJ_ARROW,0,Tempo,Valor); if (Sobe) ObjectSet(Nome,OBJPROP_ARROWCODE,241); else ObjectSet(Nome,OBJPROP_ARROWCODE,242); ObjectSet(Nome,OBJPROP_COLOR,Blue); return (0); } // usando int start() { int Itens = Bars - IndicatorCounted(), // total de velas a calcular Item; // controle do lao bool SinalBuy = False; // Sinal para comprar bool SinalSell = False; // Sinal para vender string NomeSinal; // nome do objeto //---- Calculo dos valores requisitados for(Item=Itens;Item>=0;Item--) { // calcula a curva a plotar e se tem sinal //... //Cria um nome para o objeto NomeSinal = StringConcatenate("Sinal",Time[Item]); // se tem sinal buy coloca a seta 1 pip abaixo do preo mnimo if (SinalBuy) MostraSeta(NomeSinal ,Time[Item],Low[Item]-Point,True); // se tem sinal buy coloca a seta 1 pip acima do preo Maximo if (SinalSell) MostraSeta(NomeSinal ,Time[Item],High[Item]-Point,False); } //---return(0); }
//+-----------------------------------------------------------------+ //| MeuPrimeiroIndicadorPoderoso.mq4 | //| Copyright 2007, DooMGuarD Sistemas Especialistas... | //| http://dgforex.50webs.com | //+-----------------------------------------------------------------+ #property copyright "Copyright 2007, MetaQuotes Software Corp." #property link "http://www.metaquotes.net" #property indicator_chart_window #property indicator_buffers 2 #property indicator_color1 Red //mudamos a cor para verde #property indicator_style1 STYLE_SOLID //queremos uma linha slida #property indicator_width1 3 //espessura da linha = 3
#property indicator_color2 Green //mudamos a cor para verde #property indicator_style3 STYLE_SOLID //queremos uma linha slida double ExtMapBuffer1[]; double ExtMapBuffer2[]; int init() { SetIndexStyle(0,DRAW_HISTOGRAM); SetIndexBuffer(0,ExtMapBuffer1); SetIndexStyle(1,DRAW_HISTOGRAM); SetIndexBuffer(1,ExtMapBuffer2); return(0); } int deinit() { return(0); } int start() { int Itens = Bars - IndicatorCounted(), Item; for(Item=Itens;Item>=0;Item--) { ExtMapBuffer2[Item] = Low[Item]; ExtMapBuffer1[Item] = High[Item]; } return(0); }
Note que as cotaes coloquei como grfico de linhas (roxa), ento as barras verdes so plotadas pelo indicador. Se trocar a linha que identifica onde o indicador ser desenhado, voc ter a seguinte sada:
#property indicator_separate_window
Compile, retire o indicador antigo e anexe o novo no grfico e voc ira obter:
Neste primeiro momento, com a informao apresentada conseguiremos dar inicio aos nossos trabalhos. Lembre-se, nosso objetivo no produzir a verso mais sofisticada do indicador, mas sim a mais simples, e ir incrementando o mesmo, para entendermos o processo de desenvolvimento de um Consultor Especialista.
O assistente do MetaEditor
Simplesmente, abra o MetaEditor e inicie um novo arquivo fonte. Aparecer a janela do assistente do MetaEditor. Escolheremos que queremos montar o cdigo de um Expert Advisor (Consultor Especialista).
O Prximo passo clicar no boto Seguinte, e aparece a tela onde identificaremos o nome do nosso indicador, o autor ou nome do proprietrio do cdigo, bem como o link da pgina ou do e-mail do mesmo. Aqui tambm definiremos quais so as variveis que o usurio pode modificar para configura o Consultor. Como j explicado termos 2 variveis : - MALPerido (Media Mvel Lenta Perodo): o nosso perodo Lento uma varivel inteira, pois o indicador de mdias mveis que utilizaremos no consegue mensurar meio perodo ou partes de um perodo (quando falo perodo estou falando no tempo que utilizado para montar cada barra). Usaremos como mdia lentao valor 21 perodos, ou as ultimas 21 barras do grfico no qual o consultor ser anexado. - MACPerido (Mdia Mvel Curta Perodo): o nosso perodo Rpido tambm uma varivel inteira. Usaremos como mdia curta o valor de 10 perodos, ou as ultimas 10 barras do grfico no qual o consultor ser anexado. Nota: estes valores sero os valores padres para o nosso consultor, ou seja, quando o usurio anexar o consultor ao grfico estes valores aparecem, sendo que se o usurio desejar, poder modific-lo.
Feito isto, clicamos em finalizar e o assistente ira gerar o cdigo inicial de nosso consultor, poupando-nos algum trabalho de digitao.
int init() { //---//---return(0); } //+-----------------------------------------------------------------+ //| expert deinitialization function | //+-----------------------------------------------------------------+ int deinit() { //---//---return(0); } //+-----------------------------------------------------------------+ //| expert start function | //+-----------------------------------------------------------------+ int start() { //---//---return(0); } //+-----------------------------------------------------------------+
Aqui, novamente, no temos muito segredos, o que o assistente montou no cdigo, nada mais que as definies e comentrios sobre quem escreveu o cdigo.
Note que o que o assessor nada mas fez que copiar uma parte das informaes que voc colocou na segunda janela do assistente (Autor e Link) como uma propriedade para o compilador, e tambm montou o cdigo com as funes principais do nosso Consultor Especialista.
O assistente criou as variveis que informamos na segunda janela. A principio isso no parece ser grande coisa mas ele evitou alguma digitao. Como esta variveis j esto inicializadas com valores, estes valores sero assumidos como padres ao se anexar o Consultor Especialista ao grfico.
Bem, o assistente, no tem a mnima idia de como deve funcionar nosso consultor, ento, logicamente ele no pode fazer mais nada que criar este corpo de funo de inicializao, pois como ele no conhece o mtodo ele no pode prever o que tem de ajustar antes de rodar a primeira vez o cdigo da funo principal.
Se o assistente no sabe o que vamos fazer, saber muito menos o que tem que tirar ou encerrar quando o consultor retirado da memria. Portanto ele somente cria o corpo da funo. Mais uma vez aqui o assistente no pode montar um cdigo maior que esse, pois no sabe o que tem a fazer ao encerrar o Consultor Especialista.
Sem maiores comentrios, ns dominamos a idia do Consultor Especialista e no o assistente, logicamente ele no pode mais montar o cdigo de entrada e sada da funo principal. Bom agora oficial, sinto que voc esta desapontado com o assistente do Consultor Especialista. Sim, porque voc deve estar pensando: Um consultor realiza um trabalho mais complicado e mais importante que um indicador, e o assistente sabe menos sobre ele que sobre o indicador.... Lembre-se o assistente foi concebido para seguir passos de montagem inicial de um cdigo e no para pensar no que voc pode querer fazer.... Para isso, usaremos a prxima lio
Aproveito o desenho para identificar a numerao das barras na matriz de dados do MetaTrader, para os valores de indicadores e cotaes. Onde a numero zero (0),
a barra mais a direita, e a numerao das barras cresce no sentido da direita para a esquerda do grfico.
Nossa funo de inicializao vai prever qualquer falha nos valores do perodo a ser utilizado, ento deve ficar assim
int init() { //Testa se limites esto invertidos if (MMLPeriodo<MMCPeriodo) { // Periodo do mdia Longa menor que a Curta ento inverte os valores int Auxiliar = MMLPeriodo; // Guarda valor original de Perodo Longo MMLPeriodo = MMCPeriodo; // novo valor para Perodo Longo MMCPeriodo = Auxiliar; // novo valor para Perodo Curto } // se perodos iguais ento assume o padro // pois se as mdias forem iguais no existira cruzamento if (MMLPeriodo==MMCPeriodo){ MMLPeriodo = MediaLonga; // novo valor para Perodo Rpido MMCPeriodo = MediaCurta; // novo valor para Perodo Rpido }
return(0); }
int Total = OrdersTotal(), no MetaTrader NumOrdensBuy = 0, neste consultor NumOrdensSell = 0, neste consultor i;
// Numero Total de ordens // Numero de ordens buy // Numero de ordens sell // utilizado nos loops
// Calculo das medias para o perodo lento double MML1 = iMA(NULL,0,MMLPeriodo,0,MODE_EMA,PRICE_CLOSE,1); // barra 1 double MML2 = iMA(NULL,0,MMLPeriodo,0,MODE_EMA,PRICE_CLOSE,2); // barra 2 // Calculo das medias para o perodo Curto double MMC1 = iMA(NULL,0,MMCPeriodo,0,MODE_EMA,PRICE_CLOSE,1); // barra 1 double MMC2 = iMA(NULL,0,MMCPeriodo,0,MODE_EMA,PRICE_CLOSE,2); // barra 2 // Determina se tem algum cruzamento // se Curta abaixo da lenta na barra 2 e // Curta acima da lenta na barra 1 entao sinal buy bool SinalBuy = (MMC2<MML2) && (MMC1>MML1); // Cruzou para cima? // se Curta acima da lenta na barra 2 e // Curta abaixo da lenta na barra 1 entao sinal sell bool SinalSell = (MMC2>MML2) && (MMC1<MML1); // Cruzou para baixo?
onde necessito comentar algumas desta variveis - MML1 : media Longa calculada na barra 1 (linha laranjada no grfico) - MML2 : media Longa calculada na barra 2 (linha laranjada no grfico) - MMC1 : media Curta calculada na barra 1 (linha amarela no grfico) - MMC2 : media Curta calculada na barra 2 (linha amarela no grfico) Note, que nesta verso do Consultor, no deixamos o usurio mudar o tipo de mdia e nem o preo a ser utilizado para o clculo da mdia, simplesmente queremos usar Mdia Exponencial e o preo de fechamento de cada barra. Para existir um sinal Buy a linha amarela (MMC) tem de estar abaixo da linha laranja (MML) na barra 2 e acima na barra 1. Com isso determinamos o cruzamento de cima para cima da linha amarela pela linha laranja. Para existir um sinal Sell a linha amarela (MMC) tem de estar acima da linha laranja (MML) na barra 2 e abaixo na barra 1. Com isso determinamos o cruzamento de cima para baixo da linha amarela pela linha laranja. Agora contaremos quantas ordens de cada tipo que nos interessam temos abertas, isso porque, se ja temos uma ordem aberta dependendo do sinal temos de fech-la ou impedir que abra outra ordem igual. Para isso lanaremos mo de um lao for que percorre todas as ordens abertas no MetaTrader, e logicamente algumas funes auxiliares para determinar se a ordem que estamos trabalhando no momento foi criada pelo nosso Consultor Especialista e se faz parte do Par de moedas do Grfico onde o Consultor Especialista esta sendo executado.
Dentro do lao, a primeira providencia selecionar a ordem que estaremos trabalhando, ao requisitarmos uma ordem no MetaTrader, no necessariamente pode ser a ordem que queremos, por exemplo, a ordem pode ter sido aberta manualmente ou por outro Consultor Especialista, e neste caso no nos interessa esta ordem em particular. Para isso verificamos algumas informaes sobre a ordem para saber se ela se enquadra na ordem que nosso Consultor Especialista quer utilizar. Aqui lanaremos mo de dois artifcios, uma perguntamos se a ordem do par cujo o grfico o nosso Consultor especialista esta anexado e a outra que se o nmero mgico da ordem o mesmo que o nosso Consultor Especialista definiu como o dele. Note bem, nada garante que 2 consultores especialistas tenham um numero mgico diferente, porem, isso difcil de acontecer. Bem, vamos contar ento
// Conta as ordens abertas por este sistema for(i=0;i<Total;i++) { // passa por todas as ordens abertas // seleciono a ordem da lista de ordens // pela localizao da mesma na lista OrderSelect(i,SELECT_BY_POS,MODE_TRADES); // se a ordem pertence a este par e tem este nmero mgico if ((OrderSymbol()==Symbol()) && // deste par de moedas (OrderMagicNumber()==NumeroMagico)) { // e deste Consultor if (OrderType()==OP_BUY) NumOrdensBuy++; if (OrderType()==OP_SELL) NumOrdensSell++; } }
Agora que determinamos a existncia dos sinais e j sabemos se temos ou no ordens abertas e quais os seus tipos, somente nos resta fazer cumprir as demais regras do nosso Consultor Especialista, e a primeira delas determinar se existe alguma ordem do tipo diferente ao sinal e fechar a posio aberta (se existir), pois segundo nossa regra numero 4 devemos ter somente uma ordem aberta e se existe um sinal para abrir uma ordem diferente da j aberta no podemos deix-la continuar aberta, independente se tenha ou no lucro. Um dos cdigos possveis e mais indicado para isso esse:
// verifica se tem de fechar alguma ordem e a fecha for(i=0;i<Total;i++) { // passa por todas as ordens abertas // seleciono a ordem da lista de ordens // pela localizao da mesma na lista OrderSelect(i,SELECT_BY_POS,MODE_TRADES); // se a ordem pertence a este par e tem este nmero mgico if ((OrderSymbol()==Symbol()) && // deste par de moedas (OrderMagicNumber()==NumeroMagico)) { // e deste Consultor // se tem ordem aberta e for contraria ao sinal obtido ento fecha if ((SinalBuy &&(NumOrdensSell>0)) || // Sina Buy com Ordem Sell Aberta (SinalSell&&(NumOrdensBuy>0 ))) // ou Sina Sell com Ordem Buy Aberta // entao fechar essa ordem OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 0, Red); } }
Com certeza voc me perguntar, no podamos fechar j quando contamos as ordens, ou seja, antes de incrementar determina os o tipo e se ela deve ser fechada, pois assim economizaramos um lao e seguramente o programa seria executado mais rapidamente. Sim, existe essa possibilidade, mas agora queremos separar bem as etapas para fixar as partes de trabalho do nosso consultor. Isso voc poder fazer como tarefa de casa, se assim o desejar, depois de terminarmos esta primeira verso do nosso consultor. Bom s nos resta agora determinar, se devemos abrir alguma ordem. Para isso perguntamos se existe um sinal e se no existe alguma ordem aberta na direo que o sinal esta indicando. Caso exista o sinal e no exista ordem nesta direo colocamos uma ordem como pede o sinal. Note que aqui identificaremos nossa ordem com o numero mgico do nosso consultor. Para isso usamos a funo:
// verifica se abre uma posio longa // deve ter sinal buy e nenhuma ordem buy aberta if ((SinalBuy) && (NumOrdensBuy==0)) OrderSend(Symbol(), OP_BUY, 1, Ask, 0, 0, 0, ComentarioDoConsultor,NumeroMagico, 0, Green); // verifica se abre uma posio Curta // deve ter sinal sell e nenhuma ordem sell aberta if (SinalSell && (NumOrdensSell==0)) OrderSend(Symbol(), OP_SELL, 1, Bid, 0, 0, 0, ComentarioDoConsultor, NumeroMagico, 0, Green);
Com isso terminamos nossa primeira verso do nosso Consultor Especialista, Abaixo a evoluo obtida no strategy tester no grfico GBPJPY no TimeFrame de 1 hora e no perodo de Janeiro a Maro de 2007, com um saldo inicial de USD 10.000,00.
Nada mau para nosso primeiro teste. Porem, com algumas coisas que acrescentaremos no nosso EA, no prximo capitulo, voc ver que o rendimento dele, vai cair, pois as vezes ao tentar nos proteger perdemos oportunidades de maiores lucros, esta claro, estou falando do Take Profit, Stop Loss e Trailing Stop. Quero abrir mais um parntese neste nosso mundo de testes de Consultores Especialistas, existem alguma coisas que no se pode ter muita confiana, e em minha opinio o Strategy Tester uma destas coisas. Pois com o tempo voc notara que dependendo o mtodo usar o vai ter um resultado diferente e esse resultado diferente de uma conta real ou conta demo.
ocorre como esperado, o MQL4 tem uma funo especial, a GetLastError, Esta funo retorna o numero do ultimo erro ocorrido no processamento, o qual foi detectado pelo MetaTrader. Bem ele retorna um nmero (cujas definies esto no arquivo de incluso stderror.mqh), mas, e ai, o que significa este nmero. Bem, para auxiliar melhor voc, existe um arquivo de incluso (stdlib.mqh) onde uma funo (ErrorDescription) retorna a descrio do erro para voc poder mostrar ao usurio. Para lanar mo destes recursos prontos, iremos incluir em nosso cdigo estes arquivos
//+-----------------------------------------------------------------+ //| MeuPrimeiroConsultor.mq4 | //| Copyright 2006, DooMGuarD Sistemas Especialistas... | //| http://dgforex.50webs.com | //+-----------------------------------------------------------------+ #property copyright "Copyright 2006, DooMGuarD Sistemas Especialistas..." #property link "http://dgforex.50webs.com" #include "include\stderror.mqh" #include "include\stdlib.mqh" // cdigos dos erros // descritor dos erros
Agora poderemos utiliz-los em nosso sistema. Primeiramente quando tentamos fechar uma ordem
// verifica se tem de fechar alguma ordem e a fecha for(i=0;i<Total;i++) { // passa por todas as ordens abertas // se a ordem pertence a este par e tem este nmero mgico OrderSelect(i,SELECT_BY_POS,MODE_TRADES); if ((OrderSymbol()==Symbol()) && (OrderMagicNumber()==NumeroMagico)) { // se tem ordem aberta e for contraria ao sinal obtido ento fecha if ((SinalBuy&&(NumOrdensSell>0)) ||(SinalSell&&(NumOrdensBuy>0))) if (!OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 0, Red)) // verifica se houve algum erro na requisio de modificao Print(" Erro nmero : ",ErrorDescription(GetLastError())); } } }
Agora quando, tentamos abrir uma ordem. Aqui quero abrir uma observao, como somente enviamos uma ordem de cada vez para o servidor, no existe a necessidade de colocar em dois lugares a mensagem de erro, por isso resolvi colocar no fim do cdigo de requisio das ordens. Bem, a funo OrderSend retorna -1 se a no conseguir completar a requisio da ordem para o servidor, utilizaremos esta
informao para ver quando existe alguma ordem que no se completou. Para tanto criaremos uma nova varivel dentro da funo Start(). Vejamos o cdigo
int Total = OrdersTotal(), no MetaTrader NumOrdensBuy = 0, neste consultor NumOrdensSell = 0, neste consultor Ticket = 0, requisitada ao servidor i; // Numero Total de ordens // Numero de ordens buy // Numero de ordens sell // Numero de ordem // utilizado nos loops
// verifica se abre uma posio longo // deve ter sinal buy e nenhuma ordem buy aberta if ((SinalBuy) && (NumOrdensBuy==0)) Ticket = OrderSend(Symbol(), OP_BUY, 1, Ask, 0, 0, 0,"Primeiro Consultor", NumeroMagico, 0, Green); // verifica se abre uma posio curta // deve ter sinal sell e nenhuma ordem sell aberta if (SinalSell && (NumOrdensSell==0)) Ticket = OrderSend(Symbol(), OP_SELL, 1, Bid, 0, 0, 0,"Primeiro Consultor", NumeroMagico, 0, Green); // verifica se houve algum erro na requisio da ordem para o servidor if (Ticket<0) Print(" Erro nmero : ",ErrorDescription(GetLastError()));
Nota, as funes de compra e venda sero modificadas mais adiante, para a incluso de outra protees, no cdigo acima apenas ilustrei as modificaes para acrescenta a mensagem de erro, caso ela ocorra.
#define MediaLonga 21 #define MediaRapida 10 //---- input parameters extern int TakeProfit = 300; // objetivo de 300 pips (zero desabilita) extern int StopLoss = 75; // perda mxima de 75 pips (zero desabilita) extern int MMLPeriodo = MediaLonga; // Muda para usar a constante Lenta extern int MMRPeriodo = MediaRapida; // Muda para usar a constante Rpida int NumeroMagico = 543621; // Nosso nmero mgico
Agora vamos testar estas duas novas variveis. Cada corretora tem um valor mnimo para colocar stops, ento, simplesmente vamos ver se o valor for menor ou igual ao stop mnimo da corretora desabilitaremos esta facilidade no consultor. Para descobrir o stop mnimo da corretora, faremos uso da funo MarketInfo na funo
init() int StopMinimo = MarketInfo(Symbol(),MODE_STOPLEVEL); //Verifica se o Take Profit valido if (TakeProfit <= StopMinimo ) TakeProfit = 0; //Verifica se o Stop Loss valido if (StopLoss <= StopMinimo ) StopLoss = 0;
Agora que j temos certeza que os valores vo ser aceitos pelo servidor ento programaremos estes stops, Como observao, programamos estes valores de SL e TP em pips, para transform-los em valores monetrios da moeda devemos multiplic-los pelo valor do ponto naquele par, isso se faz mediante o uso da varivel pr-definida Point, por exemplo : Point no EURUSD vale 0.0001, j no GBPJPY vale 0.01. Point a menor variao que um par pode ter, em outras palavras o valor de um pip para uma unidade de troca do par.
// verifica se abre uma posio longa // deve ter sinal buy e nenhuma ordem buy aberta if ((SinalBuy) && (NumOrdensBuy==0)) { TipoOrd = OP_BUY; // Tipo da ordem a abrir Preco = Ask; // preo a utilizar na abertura // Calcula lucro Mximo esperado if (TakeProfit>0) LocalTP = Preco + (TakeProfit * Point); // Calcula perda Mxima aceita if (StopLoss>0) LocalSL = Preco - (StopLoss * Point); } // verifica se abre uma posio Curta // deve ter sinal sell e nenhuma ordem sell aberta if (SinalSell && (NumOrdensSell==0)) { TipoOrd = OP_SELL; Preco = Bid; // Calcula lucro Mximo esperado if (TakeProfit>0) LocalTP = Preco - (TakeProfit * Point); // Calcula perda Mxima aceita if (StopLoss>0) LocalSL = Preco + (StopLoss * Point); } if (TipoOrd!=-1) { // Abre a ordem de acordo com as especificaes Ticket = OrderSend(Symbol(), TipoOrd, 1, Preco, 0, LocalSL, // Programa perda maxima LocalTP, // Programa lucro mximo ComentarioDoConsultor, NumeroMagico, 0, Green); // verifica se houve algum erro na requisio da ordem para o servidor if (Ticket<0) Print(" Erro nmero : ",ErrorDescription(GetLastError())); }
Bem, agora que nos certificamos que a varivel contem um valor aceito pelo servidor de nossa corretora, vamos proteger nosso lucro. Bem, para isso acrescentaremos o cdigo de proteo onde contamos as ordens controladas pelo nosso consultor. Nele, verificaremos se o lucro o que queremos para proteger nossa ordem. Necessitamos mais algumas variveis de trabalho
int Total = OrdersTotal(), // Numero Total de ordens no MetaTrader NumOrdensBuy = 0, // Numero de ordens buy neste consultor NumOrdensSell = 0, // Numero de ordens sell neste consultor Ticket = 0, // Numero de ordem requisitada ao servidor Lucro = 0, // Lucro da ordem atual Atual = 0, // Diferenta atual entre SL e o preo TipoOrd = -1, // Tipo de ordem a a abri 1 = nenhuma i; // utilizado nos loops double NovoSL = 0, // Novo valor para o SL LocalTP = 0, // TP calculado para a ordem LocalSL = 0, // SL calculado para a ordem Preco; // preo para abrir a ordem // Conta as ordens abertas por este sistema for(i=0;i<Total;i++) { // passa por todas as ordens abertas // seleciono a ordem da lista de ordens // pela localizao da mesma na lista OrderSelect(i,SELECT_BY_POS,MODE_TRADES); // se a ordem pertence a este par e tem este nmero mgico if ((OrderSymbol()==Symbol()) && (OrderMagicNumber()==NumeroMagico)) { // Cacula o lucro da ordem em pips Lucro = OrderProfit() / Point; // Zera variavel para novo SL NovoSL = 0; if (OrderType()==OP_BUY) { NumOrdensBuy++; // Conta se for Buy //se tem trailing entao calculoa novo SL if (TrailingStop>0) { // Calcula quantos pips do preo atual esta o SL // lembre-se na ordem buy o SL esta sempre abaixo do preo Atual = (OrderClosePrice()-OrderStopLoss())/Point; // so usa o trailing se estiver com lucro maior que o proprio trailing // e se o SL esta abaixo do Trailing esperado if ((Lucro>TrailingStop) && (Atual>TrailingStop)) NovoSL = OrderClosePrice() - (TrailingStop*Point); } } if (OrderType()==OP_SELL) { NumOrdensSell++; // Conta se for Sell //se tem trailing entao calculoa novo SL
if (TrailingStop>0) { // Calcula quantos pips do preo atual esta o SL // lembre-se na ordem sell o SL esta sempre acima do preo Atual = (OrderStopLoss()-OrderClosePrice())/Point; // so usa o trailing se estiver com lucro maior que o proprio trailing // e se o SL esta abaixo do Trailing esperado if ((Lucro>TrailingStop) && (Atual>TrailingStop)) NovoSL = OrderClosePrice() + (TrailingStop*Point); } } // Se tiver um novo SL entao programa ele na ordem if (NovoSL>0) { // tenta modificar a ordem bool Ok = OrderModify(OrderTicket(), OrderOpenPrice(), NovoSL, OrderTakeProfit(), 0,Red); // verifica se houve algum erro na requisio de modificao if (!Ok) Print(" Erro nmero : ",ErrorDescription(GetLastError())); } } }
Com isso terminamos nossa segunda verso do nosso Consultor Especialista, Abaixo a evoluo obtida no strategy tester no grfico GBPJPY no TimeFrame de 1 hora e no perodo de Janeiro a Maro de 2007, com um saldo inicial de USD 10.000,00.
Bem, voc lembra que falei no fim da lio passada, as protees podem nos fazer perder algumas chances de lucros maiores, bem, acabamos de comprovar, no mudamos nada no mtodo, apenas colocamos as protees, e nosso lucro diminuiu consideravelmente. Claro que voc deve realizar mais testes e ver qual a configurao ideal para trabalhar com as protees que colocamos. Em todos os
casos minha dica, melhor garantir um lucro menor, que apostar numa perda maior... Se quer comprovar isso, simplesmente informe zero para as variveis de proteo e rode o teste, Vera que o resultado obtido ser mo mesmo da verso 1 do nosso Consultor Especialista. Agora cabe a voc determinar os melhores valores de proteo, ou se voc quer utiliz-los realmente...
A terceira mdia um media de muitos perodos (muito mais longa que a longa), onde sempre tenta mostrar a definio de uma tendncia a longo prazo, ora, se resolvermos confiar nesta tendncia, podemos dizer ao nosso sistema para somente considerar sinais que esto a favor da tendncia. No grfico acima veja que houve dois sinais um de compra (sinalizado) e algum tempo depois outro de venda. Note que os sinais esto acima da terceira media, como a terceira media da uma clara viso de tendncia altista, ento todos os sinais de venda acima desta media podem ser desconsiderados, pois o mercado baixou, mas pela terceira mdia ele tende a subir novamente. Com isso queremos eliminar falsos sinais (ou pelo menos a maioria deles). Como a compra que estava aberta no foi fechada, o sistema tambm ignora o prximo sinal (que seria uma compra) pois ele foi desenhado para ter somente uma ordem aberta por vez, e como j uma ordem de compra, um sinal de compra no muda nada...
Note que agora deixamos mais controle do nosso Consultor Especialista ao usurio. Note tambm, algumas variveis externas em forma de string, as quais nada mais so para uma separao dos parmetros de entrada e os valores possveis em
algumas vaiveis, tais como o tipo de media e o preo a utilizar. Agora vamos determinar se o usurio entrou com estes novos valores corretamente, as linhas abaixo devem estar na funo init()
// Verificaes para a mdia base, tem de ser mairo que a longa // se for menor ou igual desabilita o uso da terceira mdia // Lembre-se que zero desabilita essa verificao if (MMBPeriodo<=MMLPeriodo) MMBPeriodo = 0; // // if if if Verificando os tipos de media em cada periodo se estiver fora dos limites assume metodo EMA ((MMBMetodo<0) || (MMBMetodo>3)) MMBMetodo = MODE_EMA; ((MMLMetodo<0) || (MMLMetodo>3)) MMLMetodo = MODE_EMA; ((MMCMetodo<0) || (MMCMetodo>3)) MMCMetodo = MODE_EMA;
// Verificando os preos utilizados em cada cada periodo so validos // se estiver fora dos limites assume Preo Close if ((MMBPreco<0) || (MMBPreco>6)) MMBPreco = PRICE_CLOSE; if ((MMLPreco<0) || (MMLPreco>6)) MMLPreco = PRICE_CLOSE; if ((MMCPreco<0) || (MMCPreco>6)) MMCPreco = PRICE_CLOSE;
Pronto, nada mais nos resta que verificar se temos que utilizar a terceira media para a determinao de nossos sinais, isto se faz na funo start() com o seguinte cdigo
// se informou media base diferente de zero entao usa a terceira media if (MMBPeriodo>0) { // Verifica Mdia Base para validar entrada na barra atual double MMB0 = iMA(NULL,0,MMBPeriodo,0,MMBMetodo,MMBPreco,1); // barra 0 // verifica se a terceira mdia autoriza os sinais SinalBuy = SinalBuy && (Close[0]>MMB0); SinalSell = SinalBuy && (Close[0]<MMB0); }
Abaixo a evoluo obtida no strategy tester no grfico GBPJPY no TimeFrame de 1 hora e no perodo de Janeiro a Maro de 2007, com um saldo inicial de USD 10.000,00.
aqui vemos o que a adio de uma simples mdia de controle de tendncia a longo prazo faz com nosso Consultor Especialista. Aumentamos o lucro tentando evitar sinais falsos no sistema. Diminumos o numero de negociaes porm aumentamos o lucro. Bem, qualquer melhoria que voc queira fazer no mtodo do Consultor Especialista, agora de sua responsabilidade e risco. O que faremos no prximo passo falar um pouco de gerenciamento de dinheiro.
Gerenciamento de dinheiro
Programaremos dois tipos de gerenciamento de dinheiro no nosso sistema, um no qual utilizaremos uma quantidade fixa no volume da ordem e outra que usa um percentual do dinheiro disponvel, de maneira que ser aumentamos nosso saldo nosso volume aplicado numa ordem aumenta e se perdemos em alguma ordem na prxima aplicamos menos. O tipo de genreciamento que voc quer utilizar depende de sua imaginao... Primeiro criaremos as variveis nas quais o usurrio escolhe o tipo e o valor do gerenciamento a ser utilizado
extern string MMRisco = "--- Calculo do Volume"; // zero uma das variveis abaixo desabilita a mesma // porem se as duas estiverem zeradas usa o mnimo // se as duas tiverem ativa usa Lotes extern double Percentual = 4; // usa 10% da Margem Livre no calculo do volume extern double Lotes = 0; // usa lotes fixos no volume
Depois acrescentaremos esse calculo do volume e o ajuste do valor do lote de acordo com o tamanho do lote, a variao mnima que o lote pode ter bem como os mximos e mnimos lotes possveis de serem utilizados
// Calculo o volume da ordem, de acordo com a Margem livre double LMax = MarketInfo(Symbol(),MODE_MAXLOT), // Lote Maximo LMin = MarketInfo(Symbol(),MODE_MINLOT), // Lote Minimo Lote = LMin, // Valor do Lote MinL = MarketInfo(Symbol(),MODE_LOTSTEP); // Variao do Lote // usa percentual da margem if (Percentual>0) { Lote = AccountFreeMargin(); // dinheiro disponivel Lote = Lote * (Percentual/100); // aplico o percentual Lote = Lote * AccountLeverage(); // aplica a alavancagem // tranforma em lotes Lote = Lote ; MarketInfo(Symbol(),MODE_LOTSIZE); } // usa lotes if (Lotes>0) Lote = Lotes; // verifico quantas variaes vabem neste lote Lote = NormalizeDouble(Lote / MinL,0)*MinL; // verifica limites da corretora if (Lote<LMin) Lote = LMin; if (Lote>LMax) Lote = LMax; // Abre a ordem de acordo com as especificaes Ticket = OrderSend(Symbol(), TipoOrd, Lote, Preco, 0, LocalSL, // Programa perda maxima LocalTP, // Programa lucro mximo ComentarioDoConsultor, NumeroMagico, 0, Green);
Como voc pode ver no grfico abaixo, simplesmente, mudando a estratgia do calculo do volume a ser aplicado aumentamos nosso rendimento no perodo, pois ao utilizar um percentual do dinheiro disponvel se ganhamos mais arriscamos mais se perdemos arriscamos menos...
Informamos os demais dados e pronto nosso script esta com o corpo criado
//+-----------------------------------------------------------------+ //| MeuPrimeiroScriptVersao1.mq4 | //| Copyright 2006, DooMGuarD Sistemas Especialistas... | //| http://dgforex.50webs.com | //+-----------------------------------------------------------------+ #property copyright "Copyright 2006, DooMGuarD Sistemas Especialistas..." #property link "http://dgforex.50webs.com" //+-----------------------------------------------------------------+ //| script program start function | //+-----------------------------------------------------------------+ int start() { //---//---return(0); } //+-----------------------------------------------------------------+
Como voc notou, no temos funo de inicializao e nem de finalizao, isso porque o script ser executado somente uma vez, no momento em que for anexado ao grfico, e ao terminar seu trabalho ele ser encerrado.
= = = =
// // // //
onde colocar a ordem Lucro esperado perda mxima lotes das ordens
agora o cdigo da funo principal, mas lembre-se, no estou adicionando nenhuma proteo ou verificao ao sistmema, deixarei isso como lio de casa para voc.
int start() { // Parametros para double PrecoBuy = double TPBuy = double SLBuy = // Parametros para double PrecoSell = double TPSell = double SLSell =
BuyStop Ask + (Distancia * Point); PrecoBuy + (TakeProfit * Point); PrecoBuy - (StopLoss * Point); SellStop Bid - (Distancia * Point); PrecoSell - (TakeProfit * Point); PrecoSell + (StopLoss * Point);
// Coloca Ordem BuyStop OrderSend(Symbol(), OP_BUYSTOP, Lotes, PrecoBuy, 3, SLBuy, // Programa perda mxima TPBuy, // Programa lucro mximo ComentarioDoScript, NumeroMagico, 0, Green); // Coloca Ordem SellStop // Coloca Ordem BuyStop OrderSend(Symbol(), OP_SELLSTOP, Lotes, PrecoSell, 3, SLSell, // Programa perda mxima TPSell, // Programa lucro mximo ComentarioDoScript, NumeroMagico, 0, Green); return(0); }
Simples, porem, facilita muito a vida de quem opera com noticias. Ao adicionar este script no grfico voc Vera que ele pega o preo atual, e coloca 2 ordens stops, de acordo com as regras - Uma ordem BuyStop 20 pips acima do preo - Uma ordem SellStop 20 pips abaixo do preo Lgico cada uma com seus respectivos volumes e stops de proteo. Sempre que voc desejar modificar os valores ter de compilar o script novamente, visto que o script no possui janela de propriedades como os Indicadores e Consultores especialistas
agora vamos simplesmente programar para ele rodar e esperar o horrio especificado para o trabalho
int start() { // Loop para o controle do horario de trabalho int Horario bool sair = False; while (!Sair) { Horario = (TimeHour(TimeLocal()) * 10000) + // Hora HH0000 (TimeMinute(TimeLocal()) * 100) + // Minuto MM00 TimeSeconds(TimeLocal()); // seguntos SS // verifica se pode sair do loop e continuar o trabalho Sair = Horario >= AbrimEm; // adormece o programa por 5 segundos para nao sobrecarregar o // processador if (!Sair) sleep(5000); } // verifica se ja passou o limite final para abrir a ordem if (Horario>LimitaAbrir) return(0); // se sim entao cai fora sem fazer nada // Parametros para double PrecoBuy = double TPBuy = double SLBuy = // Parametros para double PrecoSell = double TPSell = double SLSell = BuyStop Ask + (Distancia * Point); PrecoBuy + (TakeProfit * Point); PrecoBuy - (StopLoss * Point); SellStop Bid - (Distancia * Point); PrecoSell - (TakeProfit * Point); PrecoSell + (StopLoss * Point);
// Coloca Ordem BuyStop OrderSend(Symbol(), OP_BUYSTOP, Lotes, PrecoBuy, 3, SLBuy, // Programa perda mxima TPBuy, // Programa lucro mximo ComentarioDoScript, NumeroMagico, 0, Green); // Coloca Ordem SellStop // Coloca Ordem BuyStop OrderSend(Symbol(), OP_SELLSTOP, Lotes, PrecoSell, 3, SLSell, // Programa perda mxima TPSell, // Programa lucro mximo ComentarioDoScript, NumeroMagico, 0, Green); return(0); }
so chamo ateno para a funo sleep(5000) ela faz com que o nosso programa fique inativo por 5 segundos, com isso nao ficamos ocupando o processo e liberamos o MetaTrader para outros scripts e indicadores. Qualquer melhoria que voc tenha, fica como tarefa de casa para melhorar suas aptides de programao de scripts.
- Diretorio_Do_MetaTrader/TESTER/FILES : para ser utilizado no strategy tester - Diretorio_Do_MetaTrader/EXPERTS/FILES : para os demais casos Qualquer outro diretrio esta terminantemente proibido de trabalhar, e o mesmo no seja acessado pelo programa que voce montar
int FileOpen( string filename, int mode, int delimiter=';') onde - filename : Nome do arquivo a ser aberto - Modo : modo de abertura do arquivo, aqui devemos especificar uma combinao que diz o tipo de arquivo que queremos abrir e tambm como iremos trabalhar com o arquivo. FILE_BIN : define que o tipo de arquivo ser binrio FILE_CSV : define que o tipo de arquivo ser Texto sem formato FILE_WRITE : define o arquivo ser somente para ser escrito, se o arquivo existir ele sera zerado e se no existir ser criado. FILE_READ : define que o arquivo ser somente leitura, se no existir no poder ser aberto - delimiter: quando voc grava varias informaes em uma linha, este parmetro especifica como sero separadas as informaes, o padro o ponto e vrgula, sinceramente, eu nunca mudei esta informao Regras bsicas - FILE_BIN e FILE_CSV no podem ser utilizados juntos, ou usa um ou usa outro, porem um deles deve ser utilizado - FILE_WRITE e FILE_READ no podem ser utilizados juntos, ou usa um ou usa outro, porem um deles deve ser utilizado a funo retorna um numero que o Handle de manipulao do arquivo, sempre que voc quiser se referenciar a este arquivo use esse numero
FileClose
somente um parmetro
void FileClose( int handle) onde - Handle : o numero do arquivo devolvido pela funo FileOpen.
Agora, o nmero mximo de arquivos que poder estar abertos ao mesmo tempo 32. Se por algum motivo a funo FileOpen no conseguir abrir o arquivo ele retornara -1 e o erro poder ser verificado com a funo GetLastError(). Os handles de um arquivo aberto em um mdulo no podem ser passados a outros mdulos, por modulo entende-se como um arquivo compilado tipo ex4 ou uma library. Quando voc abrir um arquivo no strategy tester (back test) lembre-se que ele ser aberto no Diretorio_Do_MetaTrader/TESTER/FILES e quando abrir anexado em uma conta demo ou conta real ele estar sendo aberto no
Diretorio_Do_MetaTrader/EXPERTS/FILES
exemplo
FileWriteArray: int FileWriteArray( int handle, object array[], int start, int count)
exemplo
exemplo
exemplo
exemplo