fez um 2 EMA cross EA, precisa de aconselhamento

 

Olá!

Eu sou novo no mql 4 e fiz um simples 2 EMA cross advisor, que eu testei em uma conta demo, mas um pouco assustado para conseguir um de verdade

Testar com lotes pequenos em escala de 1h levaria muito tempo, e testá-lo em escalas de minutos é caro, porque o lote mínimo em meu corretor é de cerca de 7 usd.

Portanto, eu ficaria grato se você desse uma olhada e pudesse apontar alguns erros óbvios que eu poderia ter cometido.

Este consultor deve negociar no mercado de Bitcoin/USD que é extremamente volátil (o preço pode ir + - 30% por dia), portanto, parar as perdas e ter lucro não estão em pips, mas em porcentagens de uma oferta ou pedido.

As variáveis e outras coisas:

#property copyright "me"
#property link      "killnosock.net"
extern int SlowEma = 21;
extern int FastEma = 10;
extern int MaxRisk = 100;// % of Depo to be traded per order
extern int  TakeProfit=100;
extern int  StopLoss=100;
extern int Slippage = 10;

int LastBars = 0;

int init(){return(0);}
int deinit() {return(0);}

Esta função é determinar o tamanho do lote, de acordo com a % de depósito que é permitido usar por pedido (risco int)

double GetLot(int Risk)
{double Free    =AccountFreeMargin();
 double One_Lot =MarketInfo(Symbol(),MODE_MARGINREQUIRED);
 double Min_Lot =MarketInfo(Symbol(),MODE_MINLOT);
 double Max_Lot =MarketInfo(Symbol(),MODE_MAXLOT);
 double Step    =MarketInfo(Symbol(),MODE_LOTSTEP);
 double Lot     =MathFloor(Free*Risk/100/One_Lot/Step)*Step;
 if(Lot<Min_Lot) Lot=Min_Lot;
 if(Lot>Max_Lot) Lot=Max_Lot;
 if(Lot*One_Lot>Free) {
 Alert(" free= ", AccountFreeMargin()," for one lot= ", MarketInfo(Symbol(),MODE_MARGINREQUIRED)," lot= ", Lot);
 return(0.0);}
return(Lot);}

Esta é a função que abre novo pedido, Cmd é comprar ou vender

int NewOrder(int Cmd,double Lot)
{double TP=0; //takeprofit
 double SL=0; //stoploss
 double PR=0; //price
 color clr = CLR_NONE;
 while(!IsTradeAllowed()) Sleep(10);
 RefreshRates();
 if(Cmd==OP_BUY)
   {PR=Ask;
    if(TakeProfit>0) TP=Ask + Ask*TakeProfit/100;
    if(StopLoss>0) SL=Ask - Ask*StopLoss/100;
    if(SL<0) SL = 0;
    if(TP<0) TP = 0;
    clr = Green;}
 if(Cmd==OP_SELL)
   {PR=Bid;
    if(TakeProfit>0) TP=Bid - Bid*TakeProfit/100;
    if(StopLoss>0) SL=Bid + Bid*StopLoss/100;
    if(SL<0) SL = 0;
    if(TP<0) TP = 0;
    clr = Red;}
 int tic=OrderSend(Symbol(),Cmd,Lot,PR,Slippage,SL,TP,"",0,0,clr);
 if(tic<0) Print("Open order error: ",GetLastError());
return(tic);}

Aqui eu fecho 1 pedido ou fecho todos os pedidos:

//CloseOrder
void CloseOrder()
{double PR=0;
 while(!IsTradeAllowed()) Sleep(10);
 RefreshRates();
 if(OrderType()==OP_BUY)  PR=Bid;
 if(OrderType()==OP_SELL) PR=Ask;
 if(!OrderClose(OrderTicket(),OrderLots(),PR,Slippage,CLR_NONE))
   Print("Order close error: ",GetLastError());
return;}
//Close all Orders
void CloseAllOrders()
{
  for(int i=OrdersTotal()-1;i>=0;i--)
   if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
     {
      CloseOrder();
     }
return;}

Esta função é usada para calcular a diferença de EMA rápida e lenta (EMA rápida - EMA lenta):

double EmaDiff(int shift)
   {
      double difference;
      difference = iMA(Symbol(),0,FastEma,0,MODE_EMA,PRICE_CLOSE,shift)
                 - iMA(Symbol(),0,SlowEma,0,MODE_EMA,PRICE_CLOSE,shift);
      return(difference);
   }

E aqui vai o corpo principal:

int start()
  {
double Lot;
    // check if new bar opened
    if (LastBars == Bars) return(0);
    else LastBars = Bars;
      {         
         if ((EmaDiff(1) > 0) && (EmaDiff(2) < 0))
            {
               CloseAllOrders();
               Lot = GetLot(MaxRisk);
               NewOrder(OP_BUY,Lot);
            }
            
         if ((EmaDiff(2) > 0) && (EmaDiff(1) < 0))
            {
               CloseAllOrders();
               Lot = GetLot(MaxRisk);
               NewOrder(OP_SELL,Lot);
            }                    
      }
   return(0);
  }

Vou adicionar uma parada móvel, e considerar comparar o EmaDiff não a zero, mas a alguma pequena parede para não ser cortada quando o EMA lento e rápido se aproximam muito um do outro e se cruzam todas as barras.

 
 //CloseOrder
void CloseOrder()
{double PR=0;
 while(!IsTradeAllowed()) Sleep(10);
 RefreshRates();
 if(OrderType()==OP_BUY)  PR=Bid;
 if(OrderType()==OP_SELL) PR=Ask;
 if(!OrderClose(OrderTicket(),OrderLots(),PR,Slippage,CLR_NONE))
   Print("Order close error: ",GetLastError());
return;}



//Close all Orders
void CloseAllOrders()
{
  for(int i=OrdersTotal()-1;i>=0;i--)
   if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
     {
      CloseOrder();
     }
return;}

não verificar símbolo não verificar um número mágico....

então o que acontecerá ao usá-lo viver com diferentes EA's nele ???

 
deVries:

não verificar símbolo não verificar um número mágico....

então o que acontecerá ao usá-lo viver com diferentes EA's nele ???


Você quer dizer, executar dois EA's de uma conta?
 
prupru:

Você quer dizer, executar dois EA's de uma conta?
Dois EAs ou um EA e operações colocadas manualmente . . . ou apenas operações colocadas manualmente.
 
prupru:

Olá!

Eu sou novo no mql 4 e fiz um simples 2 EMA cross advisor, que eu testei em conta de demonstração, mas um pouco assustado para conseguir um de verdade

Testar com lotes pequenos em escala de 1h levaria muito tempo, e testá-lo em escalas de minutos é caro, porque o lote mínimo em meu corretor é de cerca de 7 usd.

Portanto, eu ficaria grato se você desse uma olhada e pudesse apontar alguns erros óbvios que eu poderia ter cometido.

É bom ver alguém verificando valores de retorno da função de negociação sem ser solicitado a fazê-lo. . . mas você precisa de mais informações se obtiver um erro para que possa diagnosticar o que causou o problema, você não pode voltar no tempo em situação viva para verificar o que era o Spread ou qual era o nível de Congelamento na época . .

if(tic < 0) Print("Open order error: ", GetLastError());

... isto é bom, mas você precisa de mais, que variáveis você precisará imprimir para que possa determinar a causa de qualquer erro que você receba... quando tiver determinado o que você pode precisar adicioná-las todas em sua chamada Print() certifique-se de usar o número correto de decimais (DoubeToStr(valor, dígitos)) para qualquer variável dupla, como Ask, Bid, etc.

 
RaptorUK:

É bom ver alguém verificando a função de troca retornar valores sem ser solicitado a fazê-lo. . .

Desculpe, mas eu não entendi essa parte. A única coisa que tenho é que preciso acrescentar o máximo de variáveis que puder para imprimir() chamar. Ponto tomado, obrigado.

deVries, obrigado por seus conselhos também, agora entendo o que você quer dizer.

Há mais alguma coisa a ser consertada?

 

de cursos que existe

    // check if new bar opened
    if (LastBars == Bars) return(0);
    else LastBars = Bars;

suponha que você já tenha barras máximas (há um limite).....

 
deVries:

de cursos que existe

suponha que você já tenha barras máximas (há um limite).....


ok, então, como posso melhor aproveitar o momento em que uma nova vela se abre?
 
prupru:

ok, então, como posso melhor aproveitar o momento em que uma nova vela se abre?


verificar a hora da última barra Tempo[0]

procure por NewBar e você encontra alguns exemplos

 
deVries:


verificar a hora da última barra Tempo[0]

procure por NewBar e você encontra alguns exemplos


obrigado, encontrei isto https://www.mql5.com/en/code/10370

 
 if(Cmd==OP_BUY)
   {PR=Ask;
    if(TakeProfit>0) TP=Ask + Ask*TakeProfit/100;
    if(StopLoss>0) SL=Ask - Ask*StopLoss/100;
    if(SL<0) SL = 0;
    if(TP<0) TP = 0;
    clr = Green;}

Eu não acho que isto é certo

como você consegue 100 pips takeprofit e 150 pips Stoploss ???

update veja " então pare de perder e tire lucro não estão em pips, mas em porcentagens de uma oferta ou pedido".

ainda assim você recebe um preço válido dessa forma ... se seu símbolo tem 5 dígitos o resultado será muitas vezes 2 dígitos a mais