Código não funciona

Aleksander Queiroz Da Silva  

Olá, estou praticando programação e tentei criar um EA simples, o código em si não apresenta erro, mas no backtest ele não funciona, seguramente algum erro de lógica, deixo o código aqui embaixo, se alguém puder verificar e me ajudar, fico muito grato.

 O que ele deveria fazer: calcular amplitude das velas(distância entre preço de abertura e de fechamento), e verificar se a última vela fechada, tem uma amplitude maior que a soma das últimas velas (definidas no imput velasBase), se for maior, enviar um sinal de compra ou de venda, depende da direção da última vela.

 Exemplo: input velasBase = 5

 última vela fechada tem uma amplitude de 300 pontos, a 2ª da ordem de mais recente tem 30, a 3ª = 50, 4º = 20 e a 5ª = 100 e a 6ª = 80.

 O EA tem que pegar então a última = 300 e comparar com a soma das 5 outras, que vai dar 30 + 50 + 20 + 100 + 80 = 280.

 300 > 280, então gera um sinal.

 Código: 

//-------------INCLUDES--------------------------------\

#include <Trade/Trade.mqh> //Biblioteca padrão CTrade

//-------------INCLUDES--------------------------------/

//---------------INPUTS--------------\     
                                      
input double lote = 0.01;
input int VelasBase = 10;
input bool compra = true;
input bool venda = true;

//---------------INPUTS--------------/

//----------------------------------GLOBAIS-----------------------------------\

int velasBaseHandle = INVALID_HANDLE;
double VelasBaseVetor[];

CTrade trade;

//----------EXPERT INITIALIZATION FUNCTION----------\

int OnInit()
{
   ArraySetAsSeries(VelasBaseVetor, true);
   
   velasBaseHandle = amplitudeVelasBase();

   return(INIT_SUCCEEDED);
}

//----------EXPERT INITIALIZATION FUNCTION----------/

//-------------------------------------EXPERT TICK FUNCTION ---------------------\
void OnTick()
{
   double Bid = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_BID),_Digits);
   if(isNewBar())
   {
      int copied1 = CopyBuffer(velasBaseHandle,0,0,2,VelasBaseVetor);
      
      bool sinalCompra = false;
      bool sinalVenda = false;
      
      if(copied1==2)
      {
          //--- sinal de compra
         if(compra == true && VelasBaseVetor[1] > somaVelasBase() && direcaoVela() == true)
         {
            sinalCompra = true;
         }
         //--- sinal de venda
         if(venda == true && VelasBaseVetor[1] > somaVelasBase() && direcaoVela() == false)
         {
            sinalVenda = true;
         }
      }
      
      //----------------------VERIFICAR SE ESTOU POSICIONADO-----------------------\
      
      bool comprado = false;
      bool vendido = false;
      if(PositionSelect(_Symbol))
      {
         //--- Se a posição for comprada
         if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY)
         {
            comprado = true;
         }
         //--- Se a posição for vendida
         if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL)
         {
            vendido = true;
         }
      }   
      //----------------------VERIFICAR SE ESTOU POSICIONADO--------------------/
      if(!comprado && !vendido && SymbolInfoInteger(_Symbol,SYMBOL_SPREAD) <= 600)
      {
         //--- sinal de compra
         if(sinalCompra)
         {
            trade.Buy(lote, _Symbol,0,Bid - VelasBaseVetor[1],Bid + VelasBaseVetor[1],"Compra a mercado");
         }
         //--- sinal de venda
         if(sinalVenda)
         {
            trade.Sell(lote, _Symbol,0,Bid + VelasBaseVetor[1],Bid - VelasBaseVetor[1],"Venda a mercado");
         }
      }
   } 
}

//-------------------------------------EXPERT TICK FUNCTION ------------------------/

//-------------------------------------------------------FUNÇÕES--------------------------------------------------------\

double amplitudeVelasBase()
{
   for(int i = 1; i < VelasBase; i++)
   {
      //Vela de alta
      if(CopyClose(_Symbol, _Period, i, 1, VelasBaseVetor) > CopyOpen(_Symbol,_Period, i, 1, VelasBaseVetor))
      {
         return CopyClose(_Symbol, _Period, i, 1, VelasBaseVetor) - CopyOpen(_Symbol,_Period, i, 1, VelasBaseVetor);
      }else 
      //Vela de baixa
      if(CopyClose(_Symbol, _Period, 1, 1, VelasBaseVetor) < CopyOpen(_Symbol,_Period, 1, 1, VelasBaseVetor))
      {
         return CopyOpen(_Symbol, _Period, 1, 1, VelasBaseVetor) - CopyClose(_Symbol,_Period, 1, 1, VelasBaseVetor);
      }
   }
   return 0;
}

double somaVelasBase()
{
   double soma = 0;
   for(int i = 1; i < VelasBase; i++)
   {
     soma = soma + VelasBaseVetor[i];
   }
   return soma;
}

bool isNewBar()
{
   //--- memorize the time of opening of the last bar in the static variable
   static datetime last_time = 0;
   //--- current time
   datetime lastbar_time = (datetime)SeriesInfoInteger(Symbol(), Period(),SERIES_LASTBAR_DATE);
      
   //--- if it is the first call of the function
   if(last_time==0)
   {
      //--- set the time and exit
      last_time = lastbar_time;
      return(false);
   }
   
   //--- if the time differs
   if(last_time != lastbar_time)
   {
      //--- memorize the time and return true
      last_time = lastbar_time;
      return(true);
   }
   //--- if we passed to this line, then the bar is not new; return false
   return(false);
}

bool direcaoVela()
{
   //Vela de alta
      if(CopyClose(_Symbol, _Period,1 , 1, VelasBaseVetor) > CopyOpen(_Symbol,_Period, 1, 1, VelasBaseVetor))
      {
         return true;
      }else 
      //Vela de baixa
      if(CopyClose(_Symbol, _Period, 1, 1, VelasBaseVetor) < CopyOpen(_Symbol,_Period, 1, 1, VelasBaseVetor))
      {
         return false;
      }
 return 0;
}

//-------------------------------------------------------FUNÇÕES--------------------------------------------------------/
Rogerio Giannetti Torres  
Aleksander Queiroz Da Silva:

Olá, estou praticando programação e tentei criar um EA simples, o código em si não apresenta erro, mas no backtest ele não funciona, seguramente algum erro de lógica, deixo o código aqui embaixo, se alguém puder verificar e me ajudar, fico muito grato.

 O que ele deveria fazer: calcular amplitude das velas(distância entre preço de abertura e de fechamento), e verificar se a última vela fechada, tem uma amplitude maior que a soma das últimas velas (definidas no imput velasBase), se for maior, enviar um sinal de compra ou de venda, depende da direção da última vela.

 Exemplo: input velasBase = 5

 última vela fechada tem uma amplitude de 300 pontos, a 2ª da ordem de mais recente tem 30, a 3ª = 50, 4º = 20 e a 5ª = 100 e a 6ª = 80.

 O EA tem que pegar então a última = 300 e comparar com a soma das 5 outras, que vai dar 30 + 50 + 20 + 100 + 80 = 280.

 300 > 280, então gera um sinal.

 Código: 

Olá

parei de ler depois disso aqui embaixo... sinto dizer que está erradíssimo e não é erro de lógica e falta de leitura (estudo)  leia o manual.

      if(CopyClose(_Symbol, _Period,1 , 1, VelasBaseVetor) > CopyOpen(_Symbol,_Period, 1, 1, VelasBaseVetor))
      {
         return true;
      }else 
      //Vela de baixa
      if(CopyClose(_Symbol, _Period, 1, 1, VelasBaseVetor) < CopyOpen(_Symbol,_Period, 1, 1, VelasBaseVetor))
      {
         return false;
      }

Aleksander Queiroz Da Silva  

Perdão, refiz o código com base no que você comentou, poderia me ajudar agr?


//-------------INCLUDES--------------------------------\

#include <Trade/Trade.mqh> //Biblioteca padrão CTrade

//-------------INCLUDES--------------------------------/

//---------------INPUTS--------------\     
                                      
input double lote = 0.01;
input int VelasBase = 10;
input bool compra = true;
input bool venda = true;

//---------------INPUTS--------------/

//----------------------------------GLOBAIS-----------------------------------\

MqlRates velas[];

CTrade trade;

//----------------------------------GLOBAIS-----------------------------------/

//----------EXPERT INITIALIZATION FUNCTION----------\

int OnInit()
{
   CopyRates(_Symbol, _Period, 0, VelasBase, velas);
   ArraySetAsSeries(velas, true);
}

//----------EXPERT INITIALIZATION FUNCTION----------/

//-------------------------------------EXPERT TICK FUNCTION ---------------------\
void OnTick()
{
double Bid = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_BID),_Digits);
   if(isNewBar())
   {  
      bool sinalCompra = false;
      bool sinalVenda = false;
      
         //--- sinal de compra
         if(compra == true && amplitudeVelasBase() > somaVelasBase() && isAlta(velas[1].open,velas[1].close) == true)
         {
            sinalCompra = true;
         }
         //--- sinal de venda
         if(venda == true && amplitudeVelasBase() > somaVelasBase() && isBaixa(velas[1].open,velas[1].close) == true)
         {
            sinalVenda = true;
         }
      
      //----------------------VERIFICAR SE ESTOU POSICIONADO-----------------------\
      
      bool comprado = false;
      bool vendido = false;
      if(PositionSelect(_Symbol))
      {
         //--- Se a posição for comprada
         if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY)
         {
            comprado = true;
         }
         //--- Se a posição for vendida
         if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL)
         {
            vendido = true;
         }
      }   
      //----------------------VERIFICAR SE ESTOU POSICIONADO--------------------/
      if(!comprado && !vendido && SymbolInfoInteger(_Symbol,SYMBOL_SPREAD) <= 600)
      {
         //--- sinal de compra
         if(sinalCompra)
         {
            trade.Buy(lote, _Symbol,0,Bid - amplitudeVelasBase(),Bid + amplitudeVelasBase(),"Compra a mercado");
         }
         //--- sinal de venda
         if(sinalVenda)
         {
            trade.Sell(lote, _Symbol,0,Bid +amplitudeVelasBase(),Bid - amplitudeVelasBase(),"Venda a mercado");
         }
      }
   } 
}

//-------------------------------------EXPERT TICK FUNCTION ------------------------/

//-------------------------------------------------------FUNÇÕES--------------------------------------------------------\

double amplitudeVelasBase()
{
   for(int i = 1; i < ArraySize(velas);i++)
   {
      //Vela de alta
      if(isAlta(velas[i].open,velas[i].close))
      {
         return velas[i].close - velas[i].open;
      }else 
      //Vela de baixa
      if(isBaixa(velas[i].open,velas[i].close))
      {
         return velas[i].open - velas[i].close;
      }
   }
   return 0;
}

double somaVelasBase()
{
   double soma = 0;
   for(int i = 1; i < ArraySize(velas); i++)
   {
     soma = soma + amplitudeVelasBase();
   }
   return soma;
}

bool isNewBar()
{
   //--- memorize the time of opening of the last bar in the static variable
   static datetime last_time = 0;
   //--- current time
   datetime lastbar_time = (datetime)SeriesInfoInteger(Symbol(), Period(),SERIES_LASTBAR_DATE);
      
   //--- if it is the first call of the function
   if(last_time==0)
   {
      //--- set the time and exit
      last_time = lastbar_time;
      return(false);
   }
   
   //--- if the time differs
   if(last_time != lastbar_time)
   {
      //--- memorize the time and return true
      last_time = lastbar_time;
      return(true);
   }
   //--- if we passed to this line, then the bar is not new; return false
   return(false);
}

bool isAlta(double O, double C)
{
   bool resp = false;
   
   if(O < C)
   {
      resp = true;
   }
   return resp;
}

bool isBaixa(double O, double C)
{
   bool resp = false;
   
   if(O > C)
   {
      resp = true;
   }
   return resp;
}

//-------------------------------------------------------FUNÇÕES--------------------------------------------------------/
Vinicius Pereira De Oliveira  
Aleksander Queiroz Da Silva:

Perdão, refiz o código com base no que você comentou, poderia me ajudar agr?


Boa noite Aleksander!


Fiz algumas correções, mas ainda tem bastante coisa pra implementar antes de pensar colocar em conta real. Mas vale o aprendizado! 👍


//-------------INCLUDES--------------------------------\

#include <Trade/Trade.mqh> //Biblioteca padrão CTrade

//-------------INCLUDES--------------------------------/

//---------------INPUTS--------------\     
                                      
input double lote = 0.01;
input int VelasBase = 10;
input bool compra = true;
input bool venda = true;

//---------------INPUTS--------------/

//----------------------------------GLOBAIS-----------------------------------\

MqlRates velas[];

CTrade trade;

//----------------------------------GLOBAIS-----------------------------------/

//----------EXPERT INITIALIZATION FUNCTION----------\

int OnInit()
{
   ArraySetAsSeries(velas, true);

   return(INIT_SUCCEEDED);
}

//----------EXPERT INITIALIZATION FUNCTION----------/

//-------------------------------------EXPERT TICK FUNCTION ---------------------\
void OnTick()
{
double Bid = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_BID),_Digits);
double Ask = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_ASK),_Digits);
   if(isNewBar())
   {  
      bool sinalCompra = false;
      bool sinalVenda = false;
      
      CopyRates(_Symbol, _Period, 0, VelasBase + 2, velas);
        

         //--- sinal de compra
         if(compra == true && amplitudeVelaBase() > somaVelasBase() && isAlta(velas[1].open,velas[1].close) == true)
         {
            sinalCompra = true;
         }
         //--- sinal de venda
         if(venda == true && amplitudeVelaBase() > somaVelasBase() && isBaixa(velas[1].open,velas[1].close) == true)
         {
            sinalVenda = true;
         }
      
      //----------------------VERIFICAR SE ESTOU POSICIONADO-----------------------\
      
      bool comprado = false;
      bool vendido = false;
      if(PositionSelect(_Symbol))
      {
         //--- Se a posição for comprada
         if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY)
         {
            comprado = true;
         }
         //--- Se a posição for vendida
         if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL)
         {
            vendido = true;
         }
      }   
      //----------------------VERIFICAR SE ESTOU POSICIONADO--------------------/
      if(!comprado && !vendido && SymbolInfoInteger(_Symbol,SYMBOL_SPREAD) <= 600)
      {
         //--- sinal de compra
         if(sinalCompra)
         {
            trade.Buy(lote, _Symbol,Ask,Ask - amplitudeVelaBase(),Ask + amplitudeVelaBase(),"Compra a mercado");
         }
         //--- sinal de venda
         if(sinalVenda)
         {
            trade.Sell(lote, _Symbol,Bid,Bid + amplitudeVelaBase(),Bid - amplitudeVelaBase(),"Venda a mercado");
         }
      }
   } 
}

//-------------------------------------EXPERT TICK FUNCTION ------------------------/

//-------------------------------------------------------FUNÇÕES--------------------------------------------------------\

double amplitudeVelaBase()
{
   return(velas[1].high - velas[1].low);
}

double somaVelasBase()
{
   double soma = 0;
   for(int i = 2; i <= VelasBase; i++)
   {
     soma += velas[i].high - velas[i].low;
   }
   return soma;
}

bool isNewBar()
{
   //--- memorize the time of opening of the last bar in the static variable
   static datetime last_time = 0;
   //--- current time
   datetime lastbar_time = (datetime)SeriesInfoInteger(Symbol(), Period(),SERIES_LASTBAR_DATE);
      
   //--- if it is the first call of the function
   if(last_time==0)
   {
      //--- set the time and exit
      last_time = lastbar_time;
      return(false);
   }
   
   //--- if the time differs
   if(last_time != lastbar_time)
   {
      //--- memorize the time and return true
      last_time = lastbar_time;
      return(true);
   }
   //--- if we passed to this line, then the bar is not new; return false
   return(false);
}

bool isAlta(double O, double C)
{
   bool resp = false;
   
   if(O < C)
   {
      resp = true;
   }
   return resp;
}

bool isBaixa(double O, double C)
{
   bool resp = false;
   
   if(O > C)
   {
      resp = true;
   }
   return resp;
}

//-------------------------------------------------------FUNÇÕES--------------------------------------------------------/
Aleksander Queiroz Da Silva  

Bom dia, obrigado pela ajuda.

Tenho uma pequena interface já programada e coloquei para que ela mostrasse 

amplitudeVelaBase()

//e

somaVelasBase()

 e percebi que esses dois valores não se atualizam, ficam fixos desde que começa a rodar o EA, acredito que seja esse o motivo de não funcionar "nunca abre uma posição", alguém consegue ver o que está errado?


Obrigado desde já.

Ricardo Rodrigues Lucca  
Aleksander Queiroz Da Silva:

Bom dia, obrigado pela ajuda.

Tenho uma pequena interface já programada e coloquei para que ela mostrasse 

 e percebi que esses dois valores não se atualizam, ficam fixos desde que começa a rodar o EA, acredito que seja esse o motivo de não funcionar "nunca abre uma posição", alguém consegue ver o que está errado?


Obrigado desde já.

Aparentemente deve ser erro nesse seu outro codigo. Ali pra cima nao abriu ordem nenhuma nao indica que ele nao tentou abrir a ordem e falhou. Verifique na aba diaria se houve essa tentativa. Na chamada a buy e sell nao esta sendo normalizado para o tick do ativo. Entao, o calculo pode estar tendo a abertura rejeitada por estar desnormalizado (exemplo em um ativo que tem um ticksize de 5, tu so consegue colocar ordens e stops em multiplos desse valor).
Rogerio Giannetti Torres  
Aleksander Queiroz Da Silva:

Bom dia, obrigado pela ajuda.

Tenho uma pequena interface já programada e coloquei para que ela mostrasse 

 e percebi que esses dois valores não se atualizam, ficam fixos desde que começa a rodar o EA, acredito que seja esse o motivo de não funcionar "nunca abre uma posição", alguém consegue ver o que está errado?


Obrigado desde já.

Exatamente, pois você copiou as cotações somente uma vez e no OnInit(),  coloque o CopyRates() dentro do OnTick().

Obs. O ArraySet só precisa ser executado uma vez!

Razão: