Uma pequena ajuda?

 

Portanto, estou aprendendo mql4 depois de alguns outros idiomas, e eu (ou assim pensei) acabei de terminar a primeira versão do meu primeiro EA, um simples comerciante médio móvel. Deixei-o para correr durante todo o dia de ontem sem preocupações, a entrada e a saída foram como esperado, e pensei que estava pronto para ir. Esta manhã entrei em todos os tipos de problemas, primeiro, o código quando eu o redirecionava, ele só venderia independentemente da posição, e agora, depois de um pouco de mexer, ele comprará e venderá nas posições corretas MAS quando comprar o negócio fechará no próximo tick, independentemente. Isto não está acontecendo quando estou vendendo apesar de manter o mesmo formato - alguém pode me apontar na direção de por quê?

(Como nota lateral, meu computador foi capaz de rodar o código todo o dia de ontem sem muito mais um zumbido (a média da CPU era de 12%) hoje está indo como o inferno para rodar o código (~60-90%))

Código:

int total;
//+------------------------------------------------------------------+
//| expert init function                                            |
//+------------------------------------------------------------------+
int init()
  {
//---- 
   int i;
   total=0;
   if (OrdersTotal()==0)
      {
      total=OrdersTotal();
   }
   else 
      {
      for (i=1; i<=OrdersTotal(); i++)                                                       //--- counter for any trades open on the pair
         {
         if (OrderSelect(i-1,SELECT_BY_POS)==true)
            {
            if (OrderSymbol()==Symbol())
               {
               if ((OrderType()==OP_BUY)&&(iMA(Symbol(),0,6,0,MODE_SMA,PRICE_CLOSE,0)<iMA(Symbol(),0,21,0,MODE_SMA,PRICE_CLOSE,0)))
                  { 
                  OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),0,Green);                   //--- with an open buy if the conditions have reversed close on initiation
               }
               if ((OrderType()==OP_SELL)&&(iMA(Symbol(),0,6,0,MODE_SMA,PRICE_CLOSE,0)>iMA(Symbol(),0,21,0,MODE_SMA,PRICE_CLOSE,0)))
                  {
                  OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),0,Green);                   //--- same with sell
               }
               else 
                  {
                  total++;                                                                   //--- if there are open trades yet to be completed add to tally (*)
               }
           }
       }
   }
}
//----
   return;
}
//+------------------------------------------------------------------+
//| expert deinitialization function                                 |
//+------------------------------------------------------------------+
int deinit()
  {
//----
//----
   return(0);
}
//+------------------------------------------------------------------+
//| expert start function                                   |
//+------------------------------------------------------------------+
int start()
  {
//----
   int p,q,z,i,L;
   while (AccountBalance()>50)                                                                                    //---- ensures an infinite loop for 1 trade a run 
   {                                                                                                              //---- (no infibuying!) (*) but always run
//---- 
RefreshRates();
//----
if ((iRSI(Symbol(),PERIOD_D1,14,PRICE_CLOSE,0)<70)&&(iMA(Symbol(),0,6,0,MODE_SMA,PRICE_CLOSE,0)>iMA(Symbol(),0,21,0,MODE_SMA,PRICE_CLOSE,0))&&(total==0))
      {                                                                                                                             //---------- ^ conditions to buy
      p=OrderSend(Symbol(),OP_BUY,0.1,Bid,0,0,0,"",z,0,Red);                                                                        //---------- Buy Order
      OrderSelect(p,SELECT_BY_TICKET);
         while (iMA(Symbol(),0,6,0,MODE_SMA,PRICE_CLOSE,0)>iMA(Symbol(),0,21,0,MODE_SMA,PRICE_CLOSE,0))                             //- whilst the above remains true
            {
            RefreshRates();                                                                                                         //- refresh then do nothing
            Sleep(1000);
         }
      OrderClose(OrderTicket(),0.1,OrderClosePrice(),0,Green);                                                                      //---when above is broken, close
         while (TimeSeconds(TimeCurrent())!=0)                                                                                      //---wait until a new minute
            {
            Sleep(1000);
         }
         continue;
      }
//-----         
if ((iRSI(Symbol(),PERIOD_D1,14,PRICE_CLOSE,0)>30)&&(iMA(Symbol(),0,6,0,MODE_SMA,PRICE_CLOSE,0)<iMA(Symbol(),0,21,0,MODE_SMA,PRICE_CLOSE,0))&&(total==0))
       {                                                                                                                            //---Same steps as above for sell
       q=OrderSend(Symbol(),OP_SELL,0.1,Ask,0,0,0,"",z,0,Blue);
       OrderSelect(q,SELECT_BY_TICKET);
         while (iMA(Symbol(),0,6,0,MODE_SMA,PRICE_CLOSE,0)<iMA(Symbol(),0,21,0,MODE_SMA,PRICE_CLOSE,0))
            {
            RefreshRates();
            Sleep(1000);
         }
      OrderClose(OrderTicket(),0.1,OrderClosePrice(),0,Green);
         while (TimeSeconds(TimeCurrent())!=0)
            {
            Sleep(1000);
         }      
         continue;
      }
if (total!=0)
   {
   L=0;
   for (i=1; i<=OrdersTotal(); i++)                                                       //--- if trades were open which werent initially closed
         {
         if (OrderSelect(i-1,SELECT_BY_POS)==true)
            {
            if (OrderSymbol()==Symbol())
               {
               if ((OrderType()==OP_BUY)&&(iMA(Symbol(),0,6,0,MODE_SMA,PRICE_CLOSE,0)<iMA(Symbol(),0,21,0,MODE_SMA,PRICE_CLOSE,0)))
                  { 
                  OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),0,Green);                   //--- close them if now the position has change
               }
               if ((OrderType()==OP_SELL)&&(iMA(Symbol(),0,6,0,MODE_SMA,PRICE_CLOSE,0)>iMA(Symbol(),0,21,0,MODE_SMA,PRICE_CLOSE,0)))
                  {
                  OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),0,Green);                   //--- same with sell
               }
               else 
                  {
                  L++;
               }
            }
            total=L;
         }
      }
   }
else 
   {
   Sleep(1000);
} 
}
//----
return;
}
//--------------------------------------------------------------+
 

Não fui muito fundo em seu código

Por que atualizar e depois dormir por 1 segundo, quando o mercado está se movendo rapidamente, os dados estarão desatualizados!?

Você está calculando em carrapatos, não em barras, então 1 carrapato pode acionar uma ordem por um MA movendo-se acima/abaixo do outro por uma quantidade mínima. Se o tique seguinte (após o sono) inverter, os MA se cruzam novamente e a ordem será fechada.

 

A idéia é simplesmente manter o ciclo enquanto as condições esperam até que as condições próximas ocorram (também conhecida como a troca da sma) - reconhecidamente não a melhor maneira de fazê-lo, mas uma das mais baratas computacionalmente.

A rápida movimentação do SMA acima/abaixo um do outro é uma das questões do código - mas não vejo nenhuma razão pela qual, quando há atualmente de 10 a 15 pips entre os dois em que estou correndo, levaria ao fechamento? as condições estão definitivamente se mantendo para que o loop permaneça no controle, ao invés de saltar instantaneamente para o fechamento (minha suposição é que o loop está sendo ignorado para a compra, mas não para a venda - e não sei por quê)

 
j.w.msb:

A idéia é simplesmente manter o ciclo enquanto as condições esperam até que as condições próximas ocorram (também conhecida como a troca da sma) - reconhecidamente não a melhor maneira de fazê-lo, mas uma das mais baratas computacionalmente.

A rápida movimentação do SMA acima/abaixo um do outro é uma das questões do código - mas não vejo nenhuma razão pela qual, quando há atualmente de 10 a 15 pips entre os dois em que estou correndo, levaria ao fechamento? as condições estão definitivamente se mantendo para que o loop permaneça no controle, ao invés de saltar instantaneamente para o fechamento (minha suposição é que o loop está sendo ignorado para a compra, mas não para a venda - e não sei por quê)


Se você estiver verificando apenas se um MA está acima/abaixo do outro, duvido que seja normalmente 10 a 15 pips de diferença, pode ser 0,1 pips e assim o próximo tick pode facilmente reverter o resultado.

É apenas minha opinião, mas ao trabalhar com crossovers, acredito que é melhor calcular apenas em barras fechadas para evitar muitos sinais opostos.

 

Também em seu init

 int i;
   total=0;
   if (OrdersTotal()==0)
      {
      total=OrdersTotal();
   }
   else 
      {
      for (i=1; i<=OrdersTotal(); i++)                                                       //--- counter for any trades open on the pair
         {
         if (OrderSelect(i-1,SELECT_BY_POS)==true)
            {
            if (OrderSymbol()==Symbol())
               {
               if ((OrderType()==OP_BUY)&&(iMA(Symbol(),0,6,0,MODE_SMA,PRICE_CLOSE,0)<iMA(Symbol(),0,21,0,MODE_SMA,PRICE_CLOSE,0)))
                  { 
                  OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),0,Green);                   //--- with an open buy if the conditions have reversed close on initiation
               }
               if ((OrderType()==OP_SELL)&&(iMA(Symbol(),0,6,0,MODE_SMA,PRICE_CLOSE,0)>iMA(Symbol(),0,21,0,MODE_SMA,PRICE_CLOSE,0)))
                  {
                  OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),0,Green);                   //--- same with sell
               }
               else 
                  {
                  total++;                                                                   //--- if there are open trades yet to be completed add to tally (*)
               }
           }
       }
   }
}

seu outro só se aplica ao último se, portanto, se a EA não fechar uma ordem de venda aberta, o total será aumentado em 1. Por que você quer isto?

 
GumRai:


Se você estiver apenas verificando se um MA está acima/abaixo do outro, duvido que seja normalmente 10 a 15 pips de diferença, pode ser 0,1 pips e assim o próximo tick pode facilmente reverter.

É apenas minha opinião, mas ao trabalhar com crossovers, acredito que é melhor calcular apenas em barras fechadas para evitar muitos sinais opostos.


foi um erro de cálculo da minha parte em termos de pips! meu erro! Mas a questão é que certamente há espaço de respiração entre os dois para que o sinal não seja cruzado para forçar a venda. Substituir o Sleep(1000) por while (TimeSecond(TimeCurrent)!=59) {Sleep(1000)} garantiria o teste do crossover somente no fechamento da vela?


Eu retirei o OrderClose na seção de compra e o pedido ainda está sendo aberto ao correr e depois fechado no próximo pip :s


Em seguida troquei OP_BUY e OP_SELL e a venda está se mantendo como esperado quando o 6SMA está acima do 21SMA - estou esperando a próxima cruzada para ver o que acontece (obviamente estou testando isto no minuto de tempo por enquanto)

 

Há muito a mudar..... uma coisa em que se pode trabalhar

Que número mágico o seu EA está criando...

por que você não o faz como uma variável de entrada externa para que você possa torná-lo um número único e não está fechando negócios outros EA's

int init()
  {

//---- 
   int i;
   total=0;
   if (OrdersTotal()==0)
      {
      total=OrdersTotal();
   }

o que acontece aqui...

      for (i=1; i<=OrdersTotal(); i++)                                                       //--- counter for any trades open on the pair

         {
         if (OrderSelect(i-1,SELECT_BY_POS)==true)
            {
            if (OrderSymbol()==Symbol())
               {
               if ((OrderType()==OP_BUY)&&(iMA(Symbol(),0,6,0,MODE_SMA,PRICE_CLOSE,0)<iMA(Symbol(),0,21,0,MODE_SMA,PRICE_CLOSE,0)))
                  { 
                  OrderClose( OrderTicket(),OrderLots(),OrderClosePrice(),0,Green);                   //--- with an open buy if the conditions have reversed close on initiation
               }
               if ((OrderType()==OP_SELL)&&(iMA(Symbol(),0,6,0,MODE_SMA,PRICE_CLOSE,0)>iMA(Symbol(),0,21,0,MODE_SMA,PRICE_CLOSE,0)))
                  {
                  OrderClose(O rderTicket(),OrderLots(),OrderClosePrice(),0,Green);                   //--- same with sell
               }
               else 
                  {
                  total++;                                                                   //--- if there are open trades yet to be completed add to tally (*)
               }
           }
       }

não conte com a verificação de negócios que falhará se você fechar negócios dentro do loop como você faz agora

Dê uma olhada aqui para ver porque você tem que trabalhar e como fazer a contagem regressiva

https://www.mql5.com/en/forum/139654

(iMA(Symbol(),0,6,0,MODE_SMA,PRICE_CLOSE,0)<iMA(Symbol(),0,21,0,MODE_SMA,PRICE_CLOSE,0)

esta condição pode mudar várias vezes em poucos momentos, quando um novo tick está chegando em cada comércio que você paga espalhado

a condição nem sempre muda uma vez .... em uma única barra

   while (AccountBalance()>50)                                                                                    //---- ensures an infinite loop for 1 trade a run 
   {                                                                                                              //---- (no infibuying!) (*) but always run
//---- 

o que sempre corre você deixa dormir

e de maneira normal quando o tick é feito e o novo tick começa() é chamado novamente

    while (TimeSeconds(TimeCurrent())!=0)                                                                                      //---wait until a new minute
            {
            Sleep(1000);
         }
         continue;
      }

desta forma executar o código apenas quando o segundo é 0 falhará com freqüência

porque pode acontecer frequentemente que, num segundo, não haja nenhum novo tique a entrar

se o primeiro tique do minuto chega a 1 segundo você tem que esperar por um novo minuto e esperar que o novo tique chegue no segundo 0 minuto seguinte

Verifique a função RefreshRates()

há mais coisas como fazê-la funcionar assim como corretor de 4 como de 5 dígitos

verificando os códigos de retorno....

Deslize seu valor 0 por que é necessário ???? para tê-lo maior

 
deVries:

Há muito a mudar..... uma coisa em que se pode trabalhar

Que número mágico o seu EA está criando...

por que você não o faz como uma variável de entrada externa para que você possa torná-lo um número único e não está fechando negócios outros EA's

o que acontece aqui...

não conte para a verificação de negócios que falhará se você fechar negócios dentro do loop como você faz agora

Dê uma olhada aqui para ver porque você tem que trabalhar e como fazer a contagem regressiva

https://www.mql5.com/en/forum/139654

esta condição pode mudar várias vezes em poucos momentos, quando um novo tick está chegando em cada comércio que você paga espalhado

a condição nem sempre muda uma vez .... em uma única barra

o que sempre corre você deixa dormir

e de maneira normal quando o tick é feito e o novo tick começa() é chamado novamente

desta forma executar o código apenas quando o segundo é 0 falhará com freqüência

porque pode acontecer frequentemente que, num segundo, não haja nenhum novo tique a entrar

se o primeiro tique do minuto chega a 1 segundo você tem que esperar por um novo minuto e esperar que o novo tique chegue no segundo 0 minuto seguinte

Verifique a função RefreshRates()

há mais coisas como fazê-la funcionar assim como corretor de 4 como de 5 dígitos

verificando os códigos de retorno....

Deslize seu valor 0 por que é necessário ???? para tê-lo maior

obrigado por sua ajuda, estou fazendo mudanças agora e verei como vai ser! Erros bobos compostos por erros estúpidos em meu nome! É quase uma maravilha por que correu em primeiro lugar!
 

Então, eu retirei o código para correr na mais simples das capacidades (ou seja, crossover = posições invertidas) - isso causa muitas ordens de compra/venda quando os dois SMAs estão próximos, mas não estou preocupado com isso (por enquanto) e funciona bem em uma conta demo. O que agora me preocupa é que se eu executar meu código no Testador de Estratégia, ele abre a primeira posição corretamente, mas depois falha em avançar no tempo, de modo que o SMA nunca cruza. O que eu estou fazendo de errado? Minha lista de impressão está:

2013.10.22 23:41:26 2013.09.18 00:41 Testador: o pedido nº 1 está fechado

2013.10.22 23:41:26 2013.09.18 00:41 SMACode3 GBPJPY,M1: 0

...

2013.10.22 23:40:53 2013.09.18 00:41 SMACode3 GBPJPY,M1: 0

2013.10.22 23:40:52 2013.09.18 00:41 SMACode3 GBPJPY,M1: 0

2013.10.22 23:40:51 2013.09.18 00:41 SMACode3 GBPJPY,M1: 0

2013.10.22 23:56:18 SMACode3 GBPJPY,M1: carregado com sucesso

Código:



//+------------------------------------------------------------------+
//|                                                   SMA scripy.mq4 |
//|                        Copyright 2013, MetaQuotes Software Corp. |
//|                                        http://www.metaquotes.net |
//+------------------------------------------------------------------+
#property copyright "Copyright 2013, MetaQuotes Software Corp."
#property link      "http://www.metaquotes.net"
extern int z=1234;
int total;
//----

//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+
int init()
  {
//---- 
   int i;
   total=0;
   if (OrdersTotal()!=0)
      {
      for (i=OrdersTotal()-1; i>=0; i--)                                                     
         {
         if (OrderSelect(i,SELECT_BY_POS))
            {
            if (OrderSymbol()==Symbol())
               {
               if (OrderMagicNumber()==z) 
                  {
                  if ((OrderType()==OP_BUY)&&(iMA(Symbol(),0,6,0,MODE_SMA,PRICE_CLOSE,0)<iMA(Symbol(),0,21,0,MODE_SMA,PRICE_CLOSE,0)))
                     { 
                     OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),0,Green);                  
                  }
                  if ((OrderType()==OP_SELL)&&(iMA(Symbol(),0,6,0,MODE_SMA,PRICE_CLOSE,0)>iMA(Symbol(),0,21,0,MODE_SMA,PRICE_CLOSE,0)))
                     {
                     OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),0,Green);                  
                  }
                  else 
                     {
                     total++;                                                                 
                  }
               }
           }
       }
   }
}
//----
   return;
}
//+------------------------------------------------------------------+
//| expert deinitialization function                                 |
//+------------------------------------------------------------------+
int deinit()
  {
//----
//----
   return(0);
}
//+------------------------------------------------------------------+
//| expert initialization function                                   |
//+------------------------------------------------------------------+
int start()
   {
//----
   int i,L;
   while (AccountBalance()>50)                                                                                     
   {
   RefreshRates();
//-----
double SMA6=iMA(Symbol(),0,6,0,MODE_SMA,PRICE_CLOSE,0);
double SMA21=iMA(Symbol(),0,21,0,MODE_SMA,PRICE_CLOSE,0);
double RSI70=iRSI(Symbol(),PERIOD_D1,14,PRICE_CLOSE,0)<70;
double RSI30=iRSI(Symbol(),PERIOD_D1,14,PRICE_CLOSE,0)>30;                                                                                                            
//-----   
if (IsTesting()==true)
{
Sleep(60000);
Print(GetLastError());
}
//----
   if (total==0)
      {
      if ((RSI70)&&(SMA6>SMA21))
         {                                                                                                                       
         OrderSend(Symbol(),OP_BUY,0.1,Ask,0,0,0,"",z,0,Red); 
         total+=1;                                                       
         continue;
      }
      if ((RSI30)&&(SMA6<SMA21))
         {
         OrderSend(Symbol(),OP_SELL,0.1,Bid,0,0,0,"",z,0,Blue);
         total+=1;
         continue;
      }  
   }
//---
if (total!=0)
   {
   L=0;
   for (i=OrdersTotal()-1; i>=0; i--)                                                    
      {
      if (OrderSelect(i,SELECT_BY_POS))
         {
         if (OrderSymbol()==Symbol())
            {
            if (OrderMagicNumber()==z) 
               {
               if ((OrderType()==OP_BUY)&&(SMA6<SMA21))
                  { 
                  OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),0,Green);
                     total+=-1;
                 return;
               }
               if ((OrderType()==OP_SELL)&&(SMA6>SMA21))
                  {
                  OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),0,Green);                 
                     total+=-1;
                  return;
               }
               else 
                  {
                  L++;                                                                  
               }
            }
            total=L;
         }
      }
   }
}
//----
}
//----
return;
}
//--------------------------------------------------------------+
 
j.w.msb: O que agora me preocupa é que se eu executar meu código no Testador de Estratégia, ele abre a primeira posição corretamente, mas depois falha em avançar no tempo,
  1. int start(){
       while (AccountBalance()>50){
          :
    É claro que não. RTFM. Você só recebe um novo tique quando volta do início.
  2. if (IsTesting()==true){
        Sleep(60000);
        Print(GetLastError());
    }
    RTFM & Tester limitações você NÃO pode dormir no testador
  3.         OrderSend(Symbol(),OP_SELL,0.1,Bid,0,0,0,"",z,0,Blue);
                      OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),0,Green);
    
    O que são valores de retorno de função ? Como posso utilizá-los ? - Fórum MQL4
 
RefreshRates não muda nenhum valor no testador, então você está preso em um loop de tempo porque ele não tem nenhum valor novo para trabalhar.