Tudo sobre Programação, com código fonte exemplo

 
Decidi criar esse tópico para concentrar tudo (perguntas, respostas, cases, informações, etc.) sobre Programação em geral — mas com código fonte exemplo — com questões relevantes para o desenvolvimento de tecnologias ou produtos utilizando o MT4/MT5.

Algumas regras básicas:

1. Por favor não faça perguntas sobre outros assuntos aqui.

2. Por favor não faça perguntas se não postar seu código fonte exemplo relacionado à dúvida.
3. Por favor utilize Alt+S para editar e apresentar seu código fonte nesse tópico.
4. Não publique nenhum código fonte nesse tópico se não for de sua autoria ou público, como por exemplo os existentes no CodeBase.
4. Se você já criou ou vai criar um tópico especificamente com sua pergunta coloque aqui apenas uma referência para ele para evitar redundância.
5. Por favor siga as regras do fórum (https://www.mql5.com/pt/about/rules)


Obrigado e boa discussão sobre Programação, com código fonte exemplo, a todos!

Rogério Figurelli
Regras
Regras
  • www.mql5.com
Por favor, seja educado na participação deste fórum. Quaisquer mensagens que possam ofender outros visitantes do fórum são proibidas. As discussões negativas sobre qualquer banco, corretoras, de outras empresas ou instituições financeiras estão proibidas. Estas postagens estão sujeitas à remoção. Todas as discussões sobre as relações pessoais...
 

Fórum de negociação, sistemas de negociação automatizados e testes de estratégias de negociação

ERRO AO MODIFICAR STOP E TAKE

northedan, 2019.02.20 18:32

Fala galera, eu de novo. Seguinte, o código do jeito que está aqui em baixo modifica normalmente a ordem na conta demo, mas quando vou pra conta real fica dando erro ao modificar o stoploss e takeprofit da ordem


//CONFIGURANDO O REQUEST,RESULT E ULTIMO PRECO
      MqlTradeRequest request;
      MqlTradeResult result;
      MqlTick latest_price;
      
      SymbolInfoTick(_Symbol,latest_price);
      
      ZeroMemory(request);
      SymbolInfoTick(Symbol(),latest_price);
      
      //AJUSTANDO OS DADOS PARA TICK DO SIMBOLO
      double ticksize= SymbolInfoDouble(_Symbol,SYMBOL_TRADE_TICK_SIZE); 
      
      double lastTick = (MathRound(latest_price.last/ticksize)*ticksize);
      
      double envUpTick = (MathRound(EnvelopesUpper[0]/ticksize)*ticksize);
      double envDownTick = (MathRound(EnvelopesLower[0]/ticksize)*ticksize);
      double ATRTick = (MathRound(ATR[0]/ticksize)*ticksize);
            
      //COMPRA E VENDA
      if(lastTick == envUpTick && isNewBar() && PositionSelect(_Symbol) == false
         && trade_time == true && trade_money == true && ATR[0] < 100)
      {
         Trade.Sell(Contrato,_Symbol,lastTick,(lastTick+ATRTick),(lastTick-ATRTick),"OneShotEA");
         Trade.SetExpertMagicNumber(MagicNumber);
         if(myposition.Select(_Symbol))
         {
            do Sleep(100); while(PositionSelect(_Symbol) == false);
            Trade.PositionModify(_Symbol,(lastTick+ATRTick),(lastTick-ATRTick));
         }
      }
      else if(lastTick == envDownTick  && isNewBar() && PositionSelect(_Symbol) == false
               && trade_time == true && trade_money == true && ATR[0] < 100)
      {
         Trade.Buy(Contrato,_Symbol,lastTick,(lastTick-ATRTick),(lastTick+ATRTick),"OneShotEA");
         Trade.SetExpertMagicNumber(MagicNumber);
         if(myposition.Select(_Symbol))
         {
            do Sleep(100); while(PositionSelect(_Symbol) == false);
            Trade.PositionModify(_Symbol,(lastTick-ATRTick),(lastTick+ATRTick));
         }
      }////COMPRA E VENDA




 

Fórum de negociação, sistemas de negociação automatizados e testes de estratégias de negociação

ERRO AO MODIFICAR STOP E TAKE

northedan, 2019.02.21 18:18

Modifiquei essa linha do código. Na modal está normal, mas na XP só vai a ordem e não tá dando erro no Diário.


do Sleep(100); while(PositionSelect(_Symbol) == false);
            double positionOpenPrice = myposition.PriceOpen();
            Trade.PositionModify(_Symbol,(positionOpenPrice+ATRTick),(positionOpenPrice-ATRTick+offset_takeprofit));
do Sleep(100); while(PositionSelect(_Symbol) == false);
            double positionOpenPrice = myposition.PriceOpen();
            Trade.PositionModify(_Symbol,(positionOpenPrice-ATRTick),(positionOpenPrice+ATRTick-offset_takeprofit));

 

Fórum de negociação, sistemas de negociação automatizados e testes de estratégias de negociação

Stoploss não funciona

Fabiano Possato, 2019.02.07 16:37

Obrigado pela ajuda Rogerio. O TP tamabém não está funcionando.
essa á a função de compra:

void Compra()
{
   double precocompra = simbolo.Ask();
   double stopcompra = simbolo.NormalizePrice((precocompra * (100-stop) / 100));
   double takecompra = simbolo.NormalizePrice((precocompra * (100+take) / 100));

   Print("Preço de compra: ", precocompra,"    Stop Loss: ", stopcompra,"    Take Profit: ", takecompra);

//se houver ordem pendente, cancela antes de enviar nova ordem
   int ordemcancelada = CancelaOrdem(); 
   Print ("quantidade de ordens canceladas: ", ordemcancelada);

// verifica se existe posição, se existe posição de compra, não executa nova compra
   double posicaoatual = Posicao();
   if (posicaoatual > 0) 
   {
      Print("Posição de compra: ", posicaoatual,". Nova compra não enviada");
      return;
   }
   
// se existe posicao de venda, dobra o lote para compra, assim inverte a posição  
// se não existe posição nenhuma, envia compra com o lote parametrizado
   double lotenegociacao = 0;
/*   if(posicaoatual < 0)
   {
      lotenegociacao = -posicaoatual + lote;
   }
   else
   {
      lotenegociacao = lote;
   }

   negocio.Buy(lote, NULL, precocompra, stopcompra, takecompra,"compra com preco, sl e tp");
//   negocio.Buy(lotenegociacao,NULL,0,0,0,"compra a mercado sem sl e tp");
*/ 

//--- se a posição for fechada, aguardo 10 minutos para fazer nova operação
   if (posicaoatual < 0)
   {
      negocio.Buy(lote, NULL, 0, 0, 0,"compra para fechar posição");
   }
   else
   {
      negocio.Buy(lote, NULL, precocompra, stopcompra, takecompra,"compra com preco, sl e tp");
//      negocio.BuyStop(lote, precocompra, NULL, stopcompra, takecompra,0,0,"compra stop");
   }
   hrultimaoper = TimeCurrent(); 
}

 

Fórum de negociação, sistemas de negociação automatizados e testes de estratégias de negociação

Limitar robô por horário e/ou numero de operções.

Willian De Caldas Leite, 2018.12.27 00:33

Se te ajudar eu uso esse padrao nos meus EA.


input string inicio="10:30"; //Horario de inicio(entradas);
input string termino="17:30"; //Horario de termino(entradas);
input string fechamento="17:45"; //Horario de fechamento(entradas);

MqlDateTime horario_inicio,horario_termino,horario_fechamento,horario_atual; 

int OnInit()
  {
//---
   TimeToStruct(StringToTime(inicio),horario_inicio);         //+-------------------------------------+
   TimeToStruct(StringToTime(termino),horario_termino);       //| Conversão das variaveis para mql    |
   TimeToStruct(StringToTime(fechamento),horario_fechamento); //+-------------------------------------+
   
//verificação de erros nas entradas de horario
   if(horario_inicio.hour>horario_termino.hour || (horario_inicio.hour==horario_termino.hour && horario_inicio.min>horario_termino.min))
     {
      printf ( "Parametos de horarios invalidos!" );
      return INIT_FAILED;
     }
     
    if(horario_termino.hour>horario_fechamento.hour || (horario_termino.hour==horario_fechamento.hour && horario_termino.min>horario_fechamento.min))
     {
      printf("Parametos de horarios invalidos!");
      return INIT_FAILED;
      }



bool HorarioEntrada()
      {
       TimeToStruct(TimeCurrent(),horario_atual);

      if(horario_atual.hour >= horario_inicio.hour && horario_atual.hour <= horario_termino.hour)
   {
      // Hora atual igual a de início
      if(horario_atual.hour == horario_inicio.hour)
         // Se minuto atual maior ou igual ao de início => está no horário de entradas
         if(horario_atual.min >= horario_inicio.min)
            return true;
         // Do contrário não está no horário de entradas
         else
            return false;
      
      // Hora atual igual a de término
      if(horario_atual.hour == horario_termino.hour)
         // Se minuto atual menor ou igual ao de término => está no horário de entradas
         if(horario_atual.min <= horario_termino.min)
            return true;
         // Do contrário não está no horário de entradas
         else
            return false;
      
      // Hora atual maior que a de início e menor que a de término
      return true;
   }
   
   // Hora fora do horário de entradas
   return false;
}


bool HorarioFechamento()
     {
      TimeToStruct(TimeCurrent(),horario_atual);
      
     
     // Hora dentro do horário de fechamento
   if(horario_atual.hour >= horario_fechamento.hour)
   {
      // Hora atual igual a de fechamento
      if(horario_atual.hour == horario_fechamento.hour)
         // Se minuto atual maior ou igual ao de fechamento => está no horário de fechamento
         if(horario_atual.min >= horario_fechamento.min)
            return true;
         // Do contrário não está no horário de fechamento
         else
            return false;
      
      // Hora atual maior que a de fechamento
      return true;
   }
   
   // Hora fora do horário de fechamento
   return false;
}



 

Fórum de negociação, sistemas de negociação automatizados e testes de estratégias de negociação

Você tem alguma questão sobre Metatrader 5! Pergunte Aqui!

ABettega, 2019.04.09 15:23

Acredito sim que pode ser algo no código. Estou fazendo o seguinte para colocar a ordem de venda:

      MqlTradeRequest request = {0};
      MqlTradeResult result = {0};
      request.action = TRADE_ACTION_PENDING;
      request.symbol = _Symbol;
      request.volume = contractAmount;
      request.deviation = 5;
      request.magic = 12345;
      request.type = ORDER_TYPE_SELL_STOP;
      request.price = entradaCompra;
      request.sl = entradaCompra + slTarget;
      request.tp = entradaCompra - tpTarget;
      request.type_filling = SYMBOL_FILLING_IOC;
      request.type_time = ORDER_TIME_DAY;
      bool ticket = OrderSend(request, result);
      Alert("Ticket: ", ticket);
      Alert("Result: ", result.retcode);


      trade.SellStop(contractAmount, normalizePrice(bid-entrada*_Point), _Symbol, normalizePrice(bid+(slTarget-entrada)*_Point), normalizePrice(bid-(tpTarget+entrada)*_Point), ORDER_TIME_GTC, 0, 0);

São duas vendas diferentes, não executo as duas ao mesmo tempo, sempre que vou fazer um teste eu comento a outra para não ter conflito. Com o MqlTradeRequest eu acredito que seja o meio correto, minha suposição é que seja um erro com o request.type, tipo eu deveria usar ORDER_TYPE_SELL_STOP_LIMIT talvez, mas não consegui chegar a uma resolução quanto a isso. O request.type_filling não altera nada, todos os testes resultam nesse problema.

O trade.SellStop é o CTrade básico.


 
Boa tarde, pessoal.

Estou desenvolvendo um robô, mas emperrei em uma parte do código. Sou novo nessa área, mas estou me esforçando aqui. Essa é a única coisa que falta para eu terminar, mas não consigo desenvolver, apesar de parecer ser algo bastante simples. É o seguinte: o robô calcula a meta diária de lucro ou prejuízo em dinheiro pré-definidos pelo operador. Quando bater a meta diária, o robô deve parar de operar naquele dia e voltar a operar normalmente apenas no dia seguinte. Essa parte de "parar de operar no dia e voltar a operar normalmente apenas no dia seguinte" que não estou conseguindo desenvolver. Estou mandando a função que desenvolvi, mas, caso seja necessário, posso enviar o código todo. Está tudo funcionando, só falta isso.


Eu devo desenvolver esse código dentro dos seguintes fragmentos: 

if(equity >= ((saldoCapital-profit-loss)+meta_diaria_lucro))
     {   
       zerar();     
       //Aqui eu devo desenvolver o código que para de operar hoje e volte a operar normalmente só no dia seguinte
       return(true);
     } 
     
     
     if(equity <= ((saldoCapital-profit-loss) meta_diaria_prejuizo))
     {       
       zerar();
       //Aqui eu devo desenvolver o código que para de operar hoje e volte a operar normalmente só no dia seguinte
       return(true);  
     }


Função completa:

bool funcao_verifica_meta_ou_perda_atingida()  
{

   double capital_liquido = AccountInfoDouble(ACCOUNT_EQUITY);
   double equity = DoubleToString(NormalizeDouble(capital_liquido, 2),2);
   
   double saldo = AccountInfoDouble(ACCOUNT_BALANCE);
   double saldoCapital = DoubleToString(NormalizeDouble(saldo, 2),2);
   
  
// --- determine the time intervals of the required trading history
   datetime end=TimeCurrent();                 // current server time
   datetime start=end-PeriodSeconds(PERIOD_D1);// set the beginning time to 24 hours ago

//--- request in the cache of the program the needed interval of the trading history
   HistorySelect(start,end);
//--- obtain the number of deals in the history
   int deals=HistoryDealsTotal();

   int returns=0;
   double profit=0;
   double loss=0;
   
//--- scan through all of the deals in the history
   for(int i=0;i<deals;i++)
     {
      //--- obtain the ticket of the deals by its index in the list
      ulong deal_ticket=HistoryDealGetTicket(i);
      if(deal_ticket>0) // obtain into the cache the deal, and work with it
        {
         string symbol             =HistoryDealGetString(deal_ticket,DEAL_SYMBOL);
         datetime time             =HistoryDealGetInteger(deal_ticket,DEAL_TIME);
         ulong order               =HistoryDealGetInteger(deal_ticket,DEAL_ORDER);
         long order_magic          =HistoryDealGetInteger(deal_ticket,DEAL_MAGIC);
         long pos_ID               =HistoryDealGetInteger(deal_ticket,DEAL_POSITION_ID);
         ENUM_DEAL_ENTRY entry_type=(ENUM_DEAL_ENTRY)HistoryDealGetInteger(deal_ticket,DEAL_ENTRY);

         //--- process the deals with the indicated DEAL_MAGIC
         if(order_magic==m_magic)
           {
            //... necessary actions
           }

         //--- calculate the losses and profits with a fixed results
         if(entry_type==DEAL_ENTRY_OUT)
          {
            //--- increase the number of deals 
            returns++;
            //--- result of fixation
            double result=HistoryDealGetDouble(deal_ticket, DEAL_PROFIT);
             
            //--- input the positive results into the summarized profit
            if(result>0) profit+=result;
            
            //--- input the negative results into the summarized losses
            if(result<0) loss+=result;
           
           }
           
        }
      else // unsuccessful attempt to obtain a deal
        {
         PrintFormat("We couldn't select a deal, with the index %d. Error %d",
                     i,GetLastError());
        }
            
     }
   
     if(equity >= ((saldoCapital-profit-loss)+meta_diaria_lucro))
     {   
       zerar();     
       //Aqui eu devo desenvolver o código que para de operar hoje e volte a operar normalmente só no dia seguinte
       return(true);
     } 
     
     
     if(equity <= ((saldoCapital-profit-loss)-meta_diaria_prejuizo))
     {
       
       zerar();
       //Aqui eu devo desenvolver o código que para de operar hoje e volte a operar normalmente só no dia seguinte
       return(true);  
     }
     
    return (false); 
 
 }
 

Fórum de negociação, sistemas de negociação automatizados e testes de estratégias de negociação

O robô deve voltar a operar somente no dia seguinte

evandrofg, 2019.04.09 20:50

Boa tarde, pessoal.

Sou novo aqui e peço desculpas por quaisquer erros. Estou desenvolvendo um robô, mas emperrei em uma parte do código. Sou novo nessa área, mas estou me esforçando aqui. Essa é a única coisa que falta para eu terminar, mas não consigo desenvolver, apesar de parecer ser algo bastante simples. É o seguinte: o robô calcula a meta diária de lucro ou prejuízo em dinheiro pré-definidos pelo operador. Quando bater a meta diária, o robô deve parar de operar naquele dia e voltar a operar normalmente apenas no dia seguinte. Essa parte de "parar de operar no dia e voltar a operar normalmente apenas no dia seguinte" que não estou conseguindo desenvolver. Estou mandando a função que desenvolvi, mas, caso seja necessário, posso enviar o código todo. Está tudo funcionando, só falta isso.


Eu devo desenvolver esse código dentro dos seguintes fragmentos: 

if(equity >= ((saldoCapital-profit-loss)+meta_diaria_lucro))
     {   
       zerar();     
       //Aqui eu devo desenvolver o código que para de operar hoje e volte a operar normalmente só no dia seguinte
       return(true);
     } 
     
     
     if(equity <= ((saldoCapital-profit-loss) meta_diaria_prejuizo))
     {       
       zerar();
       //Aqui eu devo desenvolver o código que para de operar hoje e volte a operar normalmente só no dia seguinte
       return(true);  
     }


Função completa:

bool funcao_verifica_meta_ou_perda_atingida()  
{

   double capital_liquido = AccountInfoDouble(ACCOUNT_EQUITY);
   double equity = DoubleToString(NormalizeDouble(capital_liquido, 2),2);
   
   double saldo = AccountInfoDouble(ACCOUNT_BALANCE);
   double saldoCapital = DoubleToString(NormalizeDouble(saldo, 2),2);
   
  
// --- determine the time intervals of the required trading history
   datetime end=TimeCurrent();                 // current server time
   datetime start=end-PeriodSeconds(PERIOD_D1);// set the beginning time to 24 hours ago

//--- request in the cache of the program the needed interval of the trading history
   HistorySelect(start,end);
//--- obtain the number of deals in the history
   int deals=HistoryDealsTotal();

   int returns=0;
   double profit=0;
   double loss=0;
   
//--- scan through all of the deals in the history
   for(int i=0;i<deals;i++)
     {
      //--- obtain the ticket of the deals by its index in the list
      ulong deal_ticket=HistoryDealGetTicket(i);
      if(deal_ticket>0) // obtain into the cache the deal, and work with it
        {
         string symbol             =HistoryDealGetString(deal_ticket,DEAL_SYMBOL);
         datetime time             =HistoryDealGetInteger(deal_ticket,DEAL_TIME);
         ulong order               =HistoryDealGetInteger(deal_ticket,DEAL_ORDER);
         long order_magic          =HistoryDealGetInteger(deal_ticket,DEAL_MAGIC);
         long pos_ID               =HistoryDealGetInteger(deal_ticket,DEAL_POSITION_ID);
         ENUM_DEAL_ENTRY entry_type=(ENUM_DEAL_ENTRY)HistoryDealGetInteger(deal_ticket,DEAL_ENTRY);

         //--- process the deals with the indicated DEAL_MAGIC
         if(order_magic==m_magic)
           {
            //... necessary actions
           }

         //--- calculate the losses and profits with a fixed results
         if(entry_type==DEAL_ENTRY_OUT)
          {
            //--- increase the number of deals 
            returns++;
            //--- result of fixation
            double result=HistoryDealGetDouble(deal_ticket, DEAL_PROFIT);
             
            //--- input the positive results into the summarized profit
            if(result>0) profit+=result;
            
            //--- input the negative results into the summarized losses
            if(result<0) loss+=result;
           
           }
           
        }
      else // unsuccessful attempt to obtain a deal
        {
         PrintFormat("We couldn't select a deal, with the index %d. Error %d",
                     i,GetLastError());
        }
            
     }
   
     if(equity >= ((saldoCapital-profit-loss)+meta_diaria_lucro))
     {   
       zerar();     
       //Aqui eu devo desenvolver o código que para de operar hoje e volte a operar normalmente só no dia seguinte
       return(true);
     } 
     
     
     if(equity <= ((saldoCapital-profit-loss)-meta_diaria_prejuizo))
     {
       
       zerar();
       //Aqui eu devo desenvolver o código que para de operar hoje e volte a operar normalmente só no dia seguinte
       return(true);  
     }
     
    return (false); 
 
 }

 

Fórum de negociação, sistemas de negociação automatizados e testes de estratégias de negociação

Interpretação de Código

Lucas Tavares, 2019.04.09 16:16

Estou com um código complicado vindo de um pedido no freelance.
O código funciona, mas gostaria de entender mais ele pra saber se há alguma possível falha escondido.
Gostaria de ajuda para entender alguns trechos, como este por exemplo :
double rs[]; int count = 0; int lastIndex = -1;
    while (true)
    {
      if (iBars(NULL, 0)<(count+1)*10) break;
      if (CopyBuffer(hrsi, 0, count*10+1, 10, tr)<10) return (-2);
      ArrayResize(rs, ArraySize(rs)+10);
      for (int i = 0; i < 10; i ++)
      {
        rs[i+count*10] = tr[10-i-1];
        if (rs[i+count*10]>=RsiSellResetLevel) { lastIndex = i+count*10; break; }
      }
      count ++;
      if (lastIndex!=-1) break;
    }

hrsi é o buffer de RSI.

tr é declarado um pouco mais acima. Double tr[].


 

Quais abordagens vocês utilizam para tratar problemas de sincronização dos dados de um ativo selecionado no terminal com os dados no servidor de negociação?

1. Excluem o EA do gráfico (radical)?

2. Acionam a função Sleep por um determinado tempo?

3. Usam outra abordagem?

 
Joscelino Celso de Oliveira:

Quais abordagens vocês utilizam para tratar problemas de sincronização ?

1. Excluem o EA do gráfico?

2. Acionam a função Sleep por um determinado tempo?

3. Usam outra abordagem?

Olá Juscelino, para mim depende do que você chama exatamente de problema de sincronização, pois isso é muito genérico. Por exemplo, pelas opções que você apresenta pode estar perguntando sobre sincronização de sinais, sincronização de timeframes de indicadores, etc.. 
Seja como for, minha resposta genérica, válida para qualquer problema de sincronização,  é começar pelo diagnóstico da causa e formulação do problema, para aí sim projetar uma solução.
Sds.,
Rogério Figurelli
Razão: