//+------------------------------------------------------------------+
//|                                                         4x14.mq4 |
//|                      Copyright © 2009, MetaQuotes Software Corp. |
//|                                        http://www.metaquotes.net |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2009, MetaQuotes Software Corp."
#property link      "http://www.metaquotes.net"

#define ComentarioDoConsultor "Meu EA V1"
#define MediaLonga 14 // Período padrão para a média longa
#define MediaCurta 4 // Período padrão para a média Curta

//---- input parameters
extern int       MMLPeriodo=MediaLonga; // Período da media Longa;
extern int       MMCPeriodo=MediaCurta; // Período da media Curta;
extern string MMRisco = "--- Calculo do Volume";
// zero uma das variáveis abaixo desabilita a mesma
// porem se as duas estiverem zeradas usa o mínimo
// 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 volum e

int NumeroMagico = 1001; // Nosso número mágico da versão 1
//+------------------------------------------------------------------+
//| expert initialization function                                   |
//+------------------------------------------------------------------+
int init()
{
//Testa se limites estão invertidos
if (MMLPeriodo<MMCPeriodo) {
// Periodo do média Longa é menor que a Curta então inverte os valores
int Auxiliar = MMLPeriodo; // Guarda valor original de Período Longo
MMLPeriodo = MMCPeriodo; // novo valor para Período Longo
MMCPeriodo = Auxiliar; // novo valor para Período Curto
}
// se períodos iguais então assume o padrão
// pois se as médias forem iguais não existira cruzamento
if (MMLPeriodo==MMCPeriodo){
MMLPeriodo = MediaLonga; // novo valor para Período Rápido
MMCPeriodo = MediaCurta; // novo valor para Período Rápido
}
return(0);
}
//+------------------------------------------------------------------+
//| expert deinitialization function                                 |
//+------------------------------------------------------------------+
int deinit()
  {
//----
   
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+
int start()
  {
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
i; // utilizado nos loops
// Calculo das medias para o período 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 período 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 ?
// 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 localização da mesma na lista
OrderSelect(i,SELECT_BY_POS,MODE_TRADES);
// se a ordem pertence a este par e tem este número mágico
if ((OrderSymbol()==Symbol()) && // é deste par de moedas
(OrderMagicNumber()==NumeroMagico)) { // e é deste Consultor
if (OrderType()==OP_BUY) NumOrdensBuy++;
if (OrderType()==OP_SELL) NumOrdensSell++;
}
}
// 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 localização da mesma na lista
OrderSelect(i,SELECT_BY_POS,MODE_TRADES);
// se a ordem pertence a este par e tem este número mágico
if ((OrderSymbol()==Symbol()) && // é deste par de moedas
(OrderMagicNumber()==NumeroMagico)) { // e é deste Consultor
// se tem ordem aberta e for contraria ao sinal obtido então 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);
}
}
// verifica se abre uma posição 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 posição 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);
// verifica se o número de barras é maior que o mínimo necessário if (Bars<=MediaLonga) {
Print("O número de barras no gráfico não pode ser menor que ",MediaLonga," Barras");
// 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); // Variação 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 variações vabem neste lote
Lote = NormalizeDouble(Lote / MinL,0)*MinL;
// verifica limites da corretora
if (Lote<LMin) Lote = LMin;
if (Lote>LMax) Lote = LMax;


   return(0);
}
  
//+------------------------------------------------------------------+