Função TrailingStop com erro de cálculo

 
#property version   "1.00"
#property strict
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+

extern int MAGICMA = 1;
extern int periodo_menor = 9;
extern int periodo_maior = 21;
extern double loteentrada = 0.01;
 
extern double fator_exp_lote = 1.4;
extern bool operaSELL = true;  
extern bool operaBUY = true;   
extern bool parartrade = false;  
extern int tp = 1000;
extern int sl = 500;
extern int trailing = 100;
extern int Slippage=3;
 

int OnInit()
{

      
return (INIT_SUCCEEDED);

}
//**********************************************************************
void OnDeinit ( const int reason )
{

}
//**********************************************************************
void OnTick()  // funçao que chama as outras a cada mudança de 1 tick 
{
      checkForOpen (MAGICMA, Symbol()) ; 
    
      TrailingStop( trailing ) ;
}


//+------------------------------------------------------------------+
//| Verifica o sinal onde tem os cruzamentos                                   |
//+------------------------------------------------------------------+

bool sinal_media_moveis( int buy )  //  cria um sinal 
{


   bool retorno = false;  // variavel criada fora e dps dentro dos "ifs" para nao dar erro
   double media_menor = iMA(NULL,0,periodo_menor,0,MODE_EMA,PRICE_CLOSE,1);  // penultima vela
   double media_menor_ant = iMA(NULL,0,periodo_menor,0,MODE_EMA,PRICE_CLOSE,2);  // antepenultima vela
   
   double media_maior = iMA(NULL,0,periodo_maior,0,MODE_EMA,PRICE_CLOSE,1);
   double media_maior_ant = iMA(NULL,0,periodo_maior,0,MODE_EMA,PRICE_CLOSE,2);
   
   
       
    if (buy == OP_BUY) //  opera compra
    {
      
      if((media_menor_ant < media_maior_ant) && (media_menor > media_maior)  )
         retorno = true;
      else
         retorno = false;
     }   
     
   return(retorno); 
    
   
}//**********************************************************************
//+------------------------------------------------------------------+
//| Verifica todas se há ordens em aberto, pra poder executar uma por vez                                   |
//+------------------------------------------------------------------+

double total_ordem_aberta(int magicma_n, int buy)
{
   int totalordens = OrdersTotal();  // busca total de ordens em aberto no terminal. Se fosse fechada seria HISTORY
   int contador = 0;  //  precisa criar uma variavel pra contar
   
      for(int i=0; i<totalordens; i++)  //  precisa de um loop pra saber so as que esse robo é responsavel
// ex. se a variavel contador tiver total de 100 ordens, ele vai começar de zero (i=0) e ver se zero < totalordens,
// se sim ele incrementa      , fazendo isso a cada loop
      {
         if(OrderSelect(  i, SELECT_BY_POS, MODE_TRADES)==false )
         
         break;
         
         if ((OrderMagicNumber() == magicma_n) && (OrderType() == buy))   
         
         contador++;
      }
      
   return(contador);
      
 }
//**********************************************************************
//+------------------------------------------------------------------+
//| Função que abre as ordens                                   |
//+------------------------------------------------------------------+

void checkForOpen (int Magicma_n, string symb)
{
   
   int res;  //  recebe valor da ordemSend...qd abri uma operação
   
   double total_ordem_venda = total_ordem_aberta( Magicma_n, OP_SELL ); // chama a funçao totalordemaberta
   double total_ordem_compra = total_ordem_aberta( Magicma_n, OP_BUY ); // chama a funçao totalordemaberta
   double lote_ent = 0;
   
   
   if (parartrade == true)
      {   
      
            if (total_ordem_compra == 0) 
         
            return;
      }
   
   
   if(Volume[0] >3) return;  // abri na abertura da vela e uma condiçao q so abre se volume acima de 3
   
   if ( IsTradeContextBusy() == true)// verifica se tem alguma ordem na fila
      return;
      
      
      RefreshRates();  // atualiza valores de preço bid e preço ask
      
      // ate aqui cod ok, sem err0
      
     
         
      if(operaBUY == true)
      {
         if ((sinal_media_moveis(OP_BUY) == true) && (total_ordem_compra==0) && (total_ordem_venda==0) ) //&& (total_ordem_venda==0) ) 
         {
            lote_ent = get_lotes(loteentrada, Magicma_n, fator_exp_lote); 
            
            res=OrderSend(Symbol(),OP_BUY,loteentrada,Ask,3,Ask-(sl * Point), Ask + (tp*Point),""  ,Magicma_n,0,clrBlue);
             
                      
          }  
              
      }
     
}
//+------------------------------------------------------------------+
//| Função TRAILING STOP             |
//+------------------------------------------------------------------+


void TrailingStop(double tstop)
  {

 
   for(int i=0; i<OrdersTotal(); i++)
         
        {
         if(OrderType()==OP_BUY) //  
           {
              if( OrderStopLoss() < OrderOpenPrice())  //  se o o stop los for menor q o preço de abertura
              // e se a diferença entre preço atual e o preço de abertura da posiçao for maior q T/S
              {
                  if(Bid - OrderOpenPrice()> tstop*Point)
                  // se o stoploss for menor q diferença entre preço atual e T/S
                  {
                        if(OrderStopLoss() < Bid - tstop*Point)  // calcule o valor do novo take profit
                        { 
                         //  
                          {
                           OrderModify (OrderTicket(), OrderOpenPrice(), Bid-tstop*Point ,OrderTakeProfit() ,0,clrPink);
                           
                           return; 
                          }
                         }
                   } 
              }  //                                
           }
            
        }// for
           
           
  }          

//+------------------------------------------------------------------+
//| Função que otimiza os lotes, incrementa a cada perda             |
//+------------------------------------------------------------------+
 
 double get_lotes( double lote_inicial, int Magicma, double fator_incremento=1)
{
   double tamanho_lote = 0; // 0.01
   int    maior_ticket = 0;     // history orders total
   double lote = 0; 
   double maior_lote=0;
   double profit=0;
   
      for(int i=0; i< OrdersHistoryTotal(); i++)// nao pode ser OrdersTotal pq precisa saber as ordens fechadas no historico
     {
            if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY)==false)
             break;
         
               if( (OrderSymbol()==Symbol()) && (OrderMagicNumber()== Magicma))//verifica a moeda, qual robô e
               {
                     if(OrderTicket() > maior_ticket)//  pega o maior tiket
                     {
                       maior_ticket = OrderTicket();
                       maior_lote = NormalizeDouble(OrderLots(),2);
                       profit = OrderProfit();
                     }
              }
     }
 
   if (OrderSelect(maior_ticket,SELECT_BY_TICKET,MODE_HISTORY)==false)
   return (lote_inicial);
   
      if (maior_lote ==0 ) // significa que nao ha nenhuma ordem em aberto
      tamanho_lote = lote_inicial;
         else
         {
          if(profit>0)// se a ultima ordem aberta foi positivo, nao faz nada, senão irá incrementar
          tamanho_lote = lote_inicial;
            else
            
             tamanho_lote = maior_lote * fator_incremento;
         }
         
    lote = NormalizeDouble(tamanho_lote,2);
    return(lote);
     
}


Olá a todos!

Não sou programador, entendo pouco do assunto.

Quero pedir humildemente aos senhores para me ajudar com  o problema da minha função do trailing.

Meu objetivo é mover o stoploss  "x" pts. a cada mesmos "x" pts. a favor da operação. 

Como veem pela imagem anexada isso não acontece, pois ao alcançar 25 pts o stop sobre totalmente e pára no ponto de abertura da ordem.

Eu não sei o que devo alterar no código para ter sucesso no meu objetivo.

Fico grato se puderem me ajudar.

Arquivos anexados:
Buy.jpg  2466 kb
 
vcarneiro2:

Olá a todos!

Não sou programador, entendo pouco do assunto.

Quero pedir humildemente aos senhores para me ajudar com  o problema da minha função do trailing.

Meu objetivo é mover o stoploss  100 pts. a cada 100 pts. a favor da operação. 

Como veem pela imagem anexada isso não acontece, pois ao alcançar 25 pts o stop sobre totalmente e pára no ponto de abertura da ordem.

Eu não sei o que devo alterar no código para ter sucesso no meu objetivo.

Fico grato se puderem me ajudar.

vcarneiro, boa tarde,

Se você não é programador está no local errado. Aqui é um fórum de dúvidas técnicas, onde o povo ajuda em alguma dúvida técnica mas a programação quem faz é o programador.

No seu caso como não é programador o local correto será em Freelancer aqui mesmo no site do MQL5, onde você contratará uma pessoa para criar ou modificar seu código/robô.

 
#property  version    "1.00"
#property  strict
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+

extern int MAGICMA = 1 ;
extern int periodo_menor = 9 ;
extern int periodo_maior = 21 ;
extern double loteentrada = 0.01 ;
 
extern double fator_exp_lote = 1.4 ;
extern bool operaSELL = true ;  
extern bool operaBUY = true ;   
extern bool parartrade = false ;  
extern int tp = 1000 ;
extern int sl = 500 ;
extern int trailing = 100 ;
extern int Slippage= 3 ;
 

int OnInit ()
{

      
return ( INIT_SUCCEEDED );

}
//**********************************************************************
void OnDeinit ( const int reason )
{

}
//**********************************************************************
void OnTick ()   // funçao que chama as outras a cada mudança de 1 tick 
{
      checkForOpen (MAGICMA, Symbol ()) ; 
    
      TrailingStop( trailing ) ;
}


//+------------------------------------------------------------------+
//| Verifica o sinal onde tem os cruzamentos                                   |
//+------------------------------------------------------------------+

bool sinal_media_moveis( int buy )   //  cria um sinal 
{


   bool retorno = false ;   // variavel criada fora e dps dentro dos "ifs" para nao dar erro
   double media_menor = iMA ( NULL , 0 ,periodo_menor, 0 , MODE_EMA , PRICE_CLOSE , 1 );   // penultima vela
   double media_menor_ant = iMA ( NULL , 0 ,periodo_menor, 0 , MODE_EMA , PRICE_CLOSE , 2 );   // antepenultima vela
   
   double media_maior = iMA ( NULL , 0 ,periodo_maior, 0 , MODE_EMA , PRICE_CLOSE , 1 );
   double media_maior_ant = iMA ( NULL , 0 ,periodo_maior, 0 , MODE_EMA , PRICE_CLOSE , 2 );
   
   
       
     if (buy == OP_BUY) //  opera compra
    {
      
       if ((media_menor_ant < media_maior_ant) && (media_menor > media_maior)  )
         retorno = true ;
       else
         retorno = false ;
     }   
     
   return (retorno); 
    
   
} //**********************************************************************
//+------------------------------------------------------------------+
//| Verifica todas se há ordens em aberto, pra poder executar uma por vez                                   |
//+------------------------------------------------------------------+

double total_ordem_aberta( int magicma_n, int buy)
{
   int totalordens = OrdersTotal ();   // busca total de ordens em aberto no terminal. Se fosse fechada seria HISTORY
   int contador = 0 ;   //  precisa criar uma variavel pra contar
   
       for ( int i= 0 ; i<totalordens; i++)   //  precisa de um loop pra saber so as que esse robo é responsavel
// ex. se a variavel contador tiver total de 100 ordens, ele vai começar de zero (i=0) e ver se zero < totalordens,
// se sim ele incrementa      , fazendo isso a cada loop
      {
         if ( OrderSelect (  i, SELECT_BY_POS, MODE_TRADES)== false )
         
         break ;
         
         if ((OrderMagicNumber() == magicma_n) && (OrderType() == buy))   
         
         contador++;
      }
      
   return (contador);
      
 }
//**********************************************************************
//+------------------------------------------------------------------+
//| Função que abre as ordens                                   |
//+------------------------------------------------------------------+

void checkForOpen ( int Magicma_n, string symb)
{
   
   int res;   //  recebe valor da ordemSend...qd abri uma operação
   
   double total_ordem_venda = total_ordem_aberta( Magicma_n, OP_SELL ); // chama a funçao totalordemaberta
   double total_ordem_compra = total_ordem_aberta( Magicma_n, OP_BUY ); // chama a funçao totalordemaberta
   double lote_ent = 0 ;
   
   
   if (parartrade == true )
      {   
      
             if (total_ordem_compra == 0 ) 
         
             return ;
      }
   
   
   if (Volume[ 0 ] > 3 ) return ;   // abri na abertura da vela e uma condiçao q so abre se volume acima de 3
   
   if ( IsTradeContextBusy() == true ) // verifica se tem alguma ordem na fila
       return ;
      
      
      RefreshRates();   // atualiza valores de preço bid e preço ask
      
       // ate aqui cod ok, sem err0
      
     
         
       if (operaBUY == true )
      {
         if ((sinal_media_moveis(OP_BUY) == true ) && (total_ordem_compra== 0 ) && (total_ordem_venda== 0 ) ) //&& (total_ordem_venda==0) ) 
         {
            lote_ent = get_lotes(loteentrada, Magicma_n, fator_exp_lote); 
            
            res= OrderSend ( Symbol (),OP_BUY,loteentrada,Ask,
             3 ,Ask-(sl * Point ), Ask + (tp* Point ), ""   ,Magicma_n, 0 , clrBlue );
             
                      
          }  
              
      }
     
}
//+------------------------------------------------------------------+
//| Função TRAILING STOP             |
//+------------------------------------------------------------------+


void TrailingStop( double tstop)
  {

 int total=OrdersTotal();
      for(int k=1; k<=total; k++){
         if (OrderSelect(k-1,SELECT_BY_POS)==true){
            if (//(OrderMagicNumber()==Magicma_n)
            OrderSymbol()==Symbol()
            ){
               if(OrderType()==OP_BUY
               &&SymbolInfoDouble(Symbol(),SYMBOL_ASK)-OrderOpenPrice()>=tstop*Point()
               &&(OrderStopLoss()<OrderOpenPrice()||OrderStopLoss()==0)
               ){
                  if(OrderModify(OrderTicket(),OrderOpenPrice(),
                  SymbolInfoDouble(Symbol(),SYMBOL_ASK)-tstop*Point(),
                  0,0,clrAliceBlue)){}
               }
               if(OrderType()==OP_BUY
               &&SymbolInfoDouble(Symbol(),SYMBOL_ASK)-OrderStopLoss()>=tstop*Point()
               &&(OrderStopLoss()>OrderOpenPrice())
               ){
                  if(OrderModify(OrderTicket(),OrderOpenPrice(),
                  SymbolInfoDouble(Symbol(),SYMBOL_ASK)-tstop*Point(),
                  0,0,clrAliceBlue)){}
               }
               if(OrderType()==OP_SELL
               &&OrderOpenPrice()-SymbolInfoDouble(Symbol(),SYMBOL_BID)>=tstop*Point()
               &&(OrderStopLoss()>OrderOpenPrice()||OrderStopLoss()==0)
               ){
                  if(OrderModify(OrderTicket(),OrderOpenPrice(),
                  SymbolInfoDouble(Symbol(),SYMBOL_BID)+tstop*Point(),
                  0,0,clrAliceBlue)){}
               }
               if(OrderType()==OP_SELL
               &&OrderStopLoss()-SymbolInfoDouble(Symbol(),SYMBOL_BID)>=tstop*Point()
               &&(OrderStopLoss()<OrderOpenPrice())
               ){
                  if(OrderModify(OrderTicket(),OrderOpenPrice(),
                  SymbolInfoDouble(Symbol(),SYMBOL_BID)+tstop*Point(),
                  0,0,clrAliceBlue)){}
               }
            }
         }  
      }
           
           
  }          

//+------------------------------------------------------------------+
//| Função que otimiza os lotes, incrementa a cada perda             |
//+------------------------------------------------------------------+
 
 double get_lotes( double lote_inicial, int Magicma, double fator_incremento= 1 )
{
   double tamanho_lote = 0 ; // 0.01
   int     maior_ticket = 0 ;     // history orders total
   double lote = 0 ; 
   double maior_lote= 0 ;
   double profit= 0 ;
   
       for ( int i= 0 ; i< OrdersHistoryTotal(); i++) // nao pode ser OrdersTotal pq precisa saber as ordens fechadas no historico
     {
             if ( OrderSelect (i,SELECT_BY_POS,MODE_HISTORY)== false )
             break ;
         
               if ( (OrderSymbol()== Symbol ()) && (OrderMagicNumber()== Magicma)) //verifica a moeda, qual robô e
               {
                     if (OrderTicket() > maior_ticket) //  pega o maior tiket
                     {
                       maior_ticket = OrderTicket();
                       maior_lote = NormalizeDouble (OrderLots(), 2 );
                       profit = OrderProfit();
                     }
              }
     }
 
   if ( OrderSelect (maior_ticket,SELECT_BY_TICKET,MODE_HISTORY)== false )
   return (lote_inicial);
   
       if (maior_lote == 0 ) // significa que nao ha nenhuma ordem em aberto
      tamanho_lote = lote_inicial;
         else
         {
           if (profit> 0 ) // se a ultima ordem aberta foi positivo, nao faz nada, senão irá incrementar
          tamanho_lote = lote_inicial;
             else
            
             tamanho_lote = maior_lote * fator_incremento;
         }
         
    lote = NormalizeDouble (tamanho_lote, 2 );
     return (lote);
     
}
 

Denis Nikolaev ,  muito grato  mais muito grato mesmo pela ajuda, não pude terminar a faculdade de TI,sem $, por isso nao sei programar. Valeu.


Enfim, compilei mas a função ainda permanece "puxando" o stop para o ponto de entrada da ordem aos primeiros 25 pontos a favor, ou seja, pela proximidade o preço se movimenta pouquissimos pontos e finaliza a ordem.  

Imagem em anexo.

De forma leiga, tentei novamente mexer no código, alterei conforme pode conferir, mas também não deu certo.

Se não entendi errado, se a diferença entre o Ask e a Abertura da ordem forem >= tstop(100 pts) E Stop < Abertura da ordem entao modifique o Stop

if(OrderType()==OP_BUY
               &&SymbolInfoDouble(Symbol(),SYMBOL_ASK)-OrderOpenPrice() >= tstop
               &&(OrderStopLoss()<OrderOpenPrice()||OrderStopLoss()==0)
               ){
                  if(OrderModify(OrderTicket(),OrderOpenPrice(),OrderStopLoss()+tstop,
                  0,0,clrAliceBlue)){}


Não consigo ver onde esta o erro de mover o stop 100 pontos a cada 100 pontos alcançados a favor da ordem.

 
vcarneiro2:

Denis Nikolaev ,  muito grato  mais muito grato mesmo pela ajuda, não pude terminar a faculdade de TI,sem $, por isso nao sei programar. Valeu.


Enfim, compilei mas a função ainda permanece "puxando" o stop para o ponto de entrada da ordem aos primeiros 25 pontos a favor, ou seja, pela proximidade o preço se movimenta pouquissimos pontos e finaliza a ordem.  

Imagem em anexo.

De forma leiga, tentei novamente mexer no código, alterei conforme pode conferir, mas também não deu certo.

Se não entendi errado, se a diferença entre o Ask e a Abertura da ordem forem >= tstop(100 pts) E Stop < Abertura da ordem entao modifique o Stop


Não consigo ver onde esta o erro de mover o stop 100 pontos a cada 100 pontos alcançados a favor da ordem.

De novo, este Fórum é para quem quer programar, sabe programar, deseja programar, ou quer aprender a programar...

Isto quer dizer que você tem que ter as bases da programação MQL5 em suas veias, do contrário será mais um "Fução"... e você não terá ajuda aqui...

Falta de dinheiro para aprender não é mais desculpa... Temos excelentes traders e programadores que bastaram uma conexão com a internet e já se transformaram ...