English Русский 中文 Español Deutsch 日本語
Modelo Universal do Expert Advisor

Modelo Universal do Expert Advisor

MetaTrader 4Sistemas de negociação | 22 fevereiro 2016, 14:05
1 528 1
Вадим Андреевич
Вадим Андреевич

Introdução

Muitos operadores enfrentam o problema de escrever seu próprio Expert Advisor. O que vem primeiro? Como definir um código do EA de take-profit, stop-loss ou trailing-stop? Como verificar a funcionabilidade de uma estratégia? Neste artigo, vamos tratar sobre as principais funções para criar Expert Advisors. Talvez alguém achará o código de rastreamento útil.

Variáveis do Expert Advisor

Quais são as variáveis necessárias em todos os Expert Advisors? O que deve ser feito para o verificador percorrer também os parâmetros definidos por variáveis booleanas? Primeiro, vou apresentar um código geral do EA, que funciona em todos os pares de moedas; para uma velocidade mais elevada, recomenda-se ajustá-los de acordo com seu próprio tipo de moeda. Em segundo lugar, 0-desativado, 1 habilitado (porque queremos que todos os parâmetros sejam verificados em um otimizador. Se um código final é raramente otimizado, recomenda-se alterar este parâmetro). Em terceiro lugar, as variáveis de níveis (stops) são inicializadas por números inteiros, em um código, se necessário, são transformadas em números fracionários. Na vida real negociamos com moedas diferentes, aqui é apenas um modelo. Em quarto lugar, se os parâmetros de paragem forem iguais a zero, a paragem não funciona.

Definição das variáveis

Agora vamos começar a definir variáveis. Vamos começar com aquelas, passíveis de otimização, as variáveis externas.

extern double MaxLot;
extern double TakeProfit;
extern double TrailingStop;
extern double StopLoss;
extern double MinProfit;
extern double ProfitPoints;
extern int    Slippage=0;
extern int Condition1=1;
extern double LotSpliter=1.0;
extern int CloseByOtherSideCondition;

Quando queremos limitar o lote máximo usado (o lote também é limitado por um servidor, mas isso será discutido mais tarde), a variável MaxLot define o lote máximo.
TakeProfit, StopLoss e TrailingStop funcionam no nosso código quando forem maiores que zero.
MinProfit e ProfitPoints funciona quando ProfitPoints forem maiores que zero, de acordo com o seguinte princípio: um preço alcança ProfitPoints e retorna até alcançar MinProfit.
ConditionX habilita as condições de entrada.
LotSpliter é um divisor de lotes. Ele usa apenas uma parte dos lotes disponíveis, por exemplo, 0,1 inclui apenas cargas, 10 vezes menor do que a taxa disponível para todo o depósito.
CloseByOtherSideCondition fecha uma ordem quando uma condição de lado oposto aparece.

Vamos ajustar as variáveis internas que serão discutidas juntamente com a descrição do EA.

double Lot;
double PP=0;
double slu,sld,a,b;
double tp,sl;

Código de inicialização

Agora veremos o que pode ser calculado apenas iniciando um Expert Advisor e utilizar ainda mais em um código.

int init()
  {
   tp=TakeProfit;
   sl=StopLoss;
   return(0);
  }

Tomamos os valores destas variáveis para caso haja alteração dos níveis de paragem. Podemos, também, calcular um lote se formos negociar todo o tempo com o mesmo volume e exibir o excesso (mais tarde neste artigo o cálculo do lote será analisado). Podemos também criar um comentário visível, contendo uma descrição do EA ou de direitos autorais. Isto é feito da seguinte forma:

Comment("cloud trade \n v2.0.11");

"\n" - significa mudar para a linha de exibição seguinte, "retorno da carreta".


Código de estrutura

Agora veremos um código de quando não há ordens:

   if(OrdersTotal()==0)
   {   
      preinit();
      if(U()==1)
      {
         OrderBuy();
         return(0);
      }
      if(U()==2)
      {
         OrderSell();
         return(0);
      }
      return(0);
   }

Parte destas funções serão analisadas posteriormente. Aqui está o princípio: inicializar os parâmetros, verificar se existem condições de entrada, entrar por uma condição.

Agora veremos um código de quando há uma ordem:


if(OrderType()==OP_BUY)
        {
         if((slu)>PP)
           {
            PP=slu;
           }
         if(((slu)>0.001) && (OrderStopLoss()<(b-TrailingStop))
          && (OrderOpenPrice()<(b-TrailingStop))
           && (OrderProfit()>MathAbs(OrderSwap())))
           {
            if(TrailingStop!=0)
              {
               OrderModify(OrderTicket(), 0, b-TrailingStop, 0, 0, 0);
              }
           }
        }
      if(OrderType()==OP_SELL)
        {
         if((sld)>PP)
           {
            PP=sld;
           }
         if(((sld)>0.001) && (OrderStopLoss()>(a+TrailingStop))
          && (OrderOpenPrice()>(a+TrailingStop)))
           {
            if(TrailingStop!=0)
              {
               OrderModify(OrderTicket(), 0, a+TrailingStop, 0, 0, 0);
              }
           }
        }
      if(ProfitPoints!=0)
        {
         if(OrderType()==OP_BUY && PP>=ProfitPoints && (slu)<=MinProfit)
           {
            CloseOnlyOrder(OrderTicket());
            return(0);
           }
         if(OrderType()==OP_SELL && PP>=ProfitPoints && (sld)<=MinProfit)
           {
            CloseOnlyOrder(OrderTicket());
            return(0);
           }
        }
      if(CloseByOtherSideCondition==1)
        {
         if(OrderType()==OP_BUY && U()==2)
           {
            CloseOnlyOrder(OrderTicket());
            return(0);
           }
         if(OrderType()==OP_SELL && U()==1)
           {
            CloseOnlyOrder(OrderTicket());
            return(0);
           }
        }

Primeiro, escolhemos a única ordem para ações futuras nela (este código será analisado em uma parte separada do artigo). Depois, atribuímos variáveis a preços, a fim de não alterar uma ordem, por exemplo, em um trailing-stop na direção errada ou em novos preços não rentáveis. Primeiro vamos verificar uma ordem para a probabilidade de uma trailing-stop, e ao mesmo uma coleta de dados de tempo para a próxima função - lucro mínimo, o uso foi descrito anteriormente. Em seguida, a função de fechar uma ordem ao aparecimento de uma condição de lado oposto e a abertura de uma ordem no sentido oposto.

Funções analisadas no artigo

Agora, veremos as funções destinados à encurtar um código e incorporar em blocos os comandos usados com maior frequência, de modo que os blocos completos possam ser chamados. Vamos tentar definir tais condições e verificá-las:

//+------------------------------------------------------------------+
//|  returns a signal to buy or to sell                              |
//+------------------------------------------------------------------+
int U()
  {
      if((U1()==2 && Condition1==1)
       || (U2()==2 && Condition2==1)){return(2);}
      if((U1()==1 && Condition1==1)
       || (U2()==1 && Condition2==1)){return(1);}
   return(0);
  }
//+------------------------------------------------------------------+
//|  returns a signal based on stochastic values                     |
//+------------------------------------------------------------------+
int U1()
  {
   if(iStochastic(Symbol(),Period(),Kperiod,Dperiod,Slowing, Method,PriceUsing,MODE_SIGNAL,1)>=80)
     {
      if(iStochastic(Symbol(),Period(),Kperiod,Dperiod,Slowing,Method,PriceUsing,MODE_SIGNAL,2)
           <=iStochastic(Symbol(),Period(),Kperiod,Dperiod,Slowing, Method,PriceUsing,MODE_MAIN,2))
        {
         if(iStochastic(Symbol(),Period(),Kperiod,Dperiod,Slowing,Method,PriceUsing,MODE_SIGNAL,1)
           >=iStochastic(Symbol(),Period(),
              Kperiod,Dperiod,Slowing,Method,PriceUsing,MODE_MAIN,1))
           {
            return(2);
           }
        }
     }
   if(iStochastic(Symbol(),Period(),Kperiod,Dperiod,Slowing,Method,PriceUsing,MODE_SIGNAL,1)<=20)
     {
      if(iStochastic(Symbol(),Period(),Kperiod,Dperiod,Slowing,Method,PriceUsing,MODE_SIGNAL,2)
           >=iStochastic(Symbol(),Period(),Kperiod,Dperiod,Slowing,Method,PriceUsing,MODE_MAIN,2))
        {
         if(iStochastic(Symbol(),Period(),Kperiod,Dperiod,Slowing, Method,PriceUsing,MODE_SIGNAL,1)
              <=iStochastic(Symbol(),Period(),Kperiod,Dperiod,Slowing,Method,PriceUsing,MODE_MAIN,1))
           {
            return(1);
           }
        }
     }
   return(0);
  }
//+------------------------------------------------------------------+
//| find trend direction using fractals                              |
//+------------------------------------------------------------------+
int U2()
  {
   double fu=0,fd=0;
   int f=0,shift=2;
   while(f<2)
     {
      if(iFractals(Symbol(),Period(),MODE_UPPER,shift)>0)
        {
         fu=fu+1;
         f=f+1;
        }
      if(iFractals(Symbol(),Period(),MODE_LOWER,shift)>0)
        {
         fd=fd+1;
         f=f+1;
        }
      shift=shift+1;
     }
   if(fu==2){return(2);}
   if(fd==2){return(1);}
   return(0);
  }

A primeira função verifica condições, as duas funções seguintes definem as condições.

Agora, veremos a função, calculando níveis de paragens, se ela está definida de forma errada e define um valor do lote:

//+------------------------------------------------------------------+
//| preliminary initialization of variables                          |
//+------------------------------------------------------------------+
int preinit()
  {
   Lot=NormalizeDouble(MathFloor(LotSpliter*AccountBalance()*AccountLeverage()
      /Ask/MathPow(10,Digits+1)*10)/10,1);
   if(MaxLot>0 && Lot>MaxLot){Lot=MaxLot;}
   if(Lot>MarketInfo(Symbol(),MODE_MAXLOT)){Lot=MarketInfo(Symbol(),MODE_MAXLOT);}
   PP=0;
   StopLoss=sl;
   TakeProfit=tp;
   if(TakeProfit!=0 && TakeProfit<(MarketInfo(Symbol(),MODE_STOPLEVEL)))
     {
      TakeProfit=MarketInfo(Symbol(),MODE_STOPLEVEL);
     }
   if(StopLoss!=0 && StopLoss<(MarketInfo(Symbol(),MODE_STOPLEVEL)))
     {
      StopLoss=MarketInfo(Symbol(),MODE_STOPLEVEL);
     }
   return(0);
  }

Agora defina funções abrindo ordens dependendo dos níveis de paragem predefinidos:

//+------------------------------------------------------------------+
//| returns true in case of a successful opening of Buy              |
//+------------------------------------------------------------------+
bool OrderBuy()
  {
   bool res=false;
   if(StopLoss!=0 && TakeProfit!=0)
     {
      res=OrderSend(Symbol(), 0, NormalizeDouble(Lot,1), Ask, Slippage,
       NormalizeDouble(Ask-StopLoss,4),
        NormalizeDouble(Ask+TakeProfit,4), 0, 0, 0, 0);
      return(res);
     }
   if(StopLoss==0 && TakeProfit!=0)
     {
      res=OrderSend(Symbol(), 0, NormalizeDouble(Lot,1), Ask, Slippage, 0,
       NormalizeDouble(Ask+TakeProfit,4), 0, 0, 0, 0);
      return(res);
     }
   if(StopLoss==0 && TakeProfit==0)
     {
      res=OrderSend(Symbol(), 0, NormalizeDouble(Lot,1), Ask,
       Slippage, 0, 0, 0, 0, 0, 0);
      return(res);
     }
   if(StopLoss!=0 && TakeProfit==0)
     {
      res=OrderSend(Symbol(), 0, NormalizeDouble(Lot,1), Ask, Slippage,
       NormalizeDouble(Ask-StopLoss,4), 0, 0, 0, 0, 0);
      return(res);
     }
   return(res);
  }
//+------------------------------------------------------------------+
//|   returns true in case of a successful opening of Sell           |
//+------------------------------------------------------------------+
bool OrderSell()
  {
   bool res=false;
   if(StopLoss!=0 && TakeProfit!=0)
     {
      res=OrderSend(Symbol(), OP_SELL, NormalizeDouble(Lot,1), Bid, Slippage,
       NormalizeDouble(Bid+StopLoss,4),
        NormalizeDouble(Bid-TakeProfit,4), 0, 0, 0, 0);
      return(res);
     }
   if(StopLoss==0 && TakeProfit!=0)
     {
      res=OrderSend(Symbol(), OP_SELL, NormalizeDouble(Lot,1), Bid, Slippage,
       NormalizeDouble(Bid+StopLoss,4),
        NormalizeDouble(Bid-TakeProfit,4), 0, 0, 0, 0);
      return(res);
     }
   if(StopLoss==0 && TakeProfit==0)
     {
      res=OrderSend(Symbol(), OP_SELL, NormalizeDouble(Lot,1), Bid, Slippage,
       NormalizeDouble(Bid+StopLoss,4),
        NormalizeDouble(Bid-TakeProfit,4), 0, 0, 0, 0);
      return(res);
     }
   if(StopLoss!=0 && TakeProfit==0)
     {
      res=OrderSend(Symbol(), OP_SELL, NormalizeDouble(Lot,1), Bid, Slippage,
       NormalizeDouble(Bid+StopLoss,4),
        NormalizeDouble(Bid-TakeProfit,4), 0, 0, 0, 0);
      return(res);
     }
   return(res);
  }

A próxima função fecha uma ordem com um bilhete indicado, volume e em um preço indicado:

//+-------------------------------------------------------------------------+
//|  returns true in case of a successful closing of an order with Ticket   |
//+-------------------------------------------------------------------------+
bool CloseOnlyOrder(int Ticket, double Lots ,double priceClose)
  {
   bool res=false;
   res=OrderClose(Ticket, Lots, priceClose, Slippage, 0);
   return(res);

Agora vamos ver a função de escolha de uma ordem sobre o número da posição para operação adicional sobre ele:

//+--------------------------------------------------------------------------------+
//| returns true in case of a successful choosing of an order in the position pos  |
//+--------------------------------------------------------------------------------+
bool SelectOnlyOrder(int pos)
  {
   bool res=false;
   res=OrderSelect(pos,SELECT_BY_POS,MODE_TRADES);
   return(res);
  }
//+------------------------------------------------------------------+

Algumas recomendações de codificação

Em primeiro lugar, defina opções como 0 e 1 em vez de verdadeiro e falso. Isso irá ajudá-lo a otimizar melhor o seu Expert Advisor. Em segundo lugar, não negligencie stop-loss para limitar eventuais perdas quando o mercado se mover na direção oposta, oposta às condições. Terceiro, não teste Expert advisors sem stop-loss - isto pode fazer com que aconteça uma perda rápida de depósito. Em quarto lugar, use funções e blocos que ajudam a compreender o código mais facilmente.

Conclusão

Criar Expert Advisors é fácil. E para tornar esta tarefa ainda mais fácil, o arquivo anexado contém o Expert Advisor analisado neste artigo.


Traduzido do russo pela MetaQuotes Ltd.
Artigo original: https://www.mql5.com/ru/articles/1495

Arquivos anexados |
template.mq4 (8.07 KB)
Últimos Comentários | Ir para discussão (1)
Mauricioadm
Mauricioadm | 10 nov 2020 em 20:50
o EA NÃO FUNCIONA.
Linguagem MQL4 para Iniciantes. Indicadores técnicos e funções integradas Linguagem MQL4 para Iniciantes. Indicadores técnicos e funções integradas
Este é o terceiro artigo da série "Linguagem MQL4 para Iniciantes". Agora, vamos aprender a utilizar funções integradas e funções para trabalhar com indicadores técnicos. Estes últimas serão essenciais para o desenvolvimento futuro de seus próprios Advisors e indicadores. Além disso, veremos em um exemplo simples, como rastrear sinais de trading para entrar no mercado, assim, você entenderá como usar indicadores corretamente. E no final do artigo você aprenderá algo novo e interessante sobre a própria linguagem.
Romper o limite do verificador de estratégia em testes de cobertura do EA Romper o limite do verificador de estratégia em testes de cobertura do EA
Uma ideia de teste de cobertura dos Expert Advisors utilizando o verificador de estratégia.
Como implementar seus próprios critérios de otimização Como implementar seus próprios critérios de otimização
Neste artigo um exemplo de otimização com critérios de lucro/levantamento de crédito com resultados retornados em um arquivo é desenvolvido para um Expert Advisor Padrão - Média Móvel.
Matemática na negociação: Como estimar resultados de trading Matemática na negociação: Como estimar resultados de trading
Nós todos sabemos que "Nenhum lucro obtido no passado garantirá algum sucesso no futuro". No entanto, ser capaz de estimar sistemas de negociação, ainda é muito atual. Este artigo trata sobre alguns métodos simples e convenientes que ajudarão a estimar resultados de trade.