hizo una cruz de 2 EMA EA, necesita asesoramiento

 

¡Hola!

Soy nuevo en mql 4 y he hecho un simple 2 EMA cross advisor, que he probado en la cuenta demo, pero un poco de miedo de conseguirlo en una real

Probarlo con lotes pequeños en escala de 1h me llevaría demasiado tiempo, y probarlo en escalas de minutos es caro, porque el lote mínimo en mi broker es de unos 7 usd.

Así que les agradecería que le echaran un vistazo y que me indicaran algunos errores obvios que podría haber cometido.

Este asesor se supone que el comercio en el mercado de Bitcoin / USD que es extremadamente volátil (el precio puede ir + - 30% al día), por lo que la pérdida de la parada y tomar ganancias no están en pips, pero en porcentajes de una oferta o demanda.

Las variables y demás:

#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 función es para determinar el tamaño del lote, de acuerdo al % de depo que se permite utilizar por orden (int Risk)

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 es la función que abre una nueva orden, Cmd es comprar o 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);}

Aquí cierro 1 orden o cierro todas las órdenes:

//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 función sirve para calcular la diferencia de EMA rápida y 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);
   }

Y aquí va el cuerpo 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);
  }

Voy a añadir un trailing stop, y considerar la comparación de EmaDiff no a cero, sino a algún walue pequeño para no ser picado uo cuando EMA lenta y rápida se acercan mucho entre sí y se cruzan cada barra.

 
 //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;}

no comprobar el símbolo no comprobar un magicnumber....

entonces, ¿qué va a pasar usando en vivo con diferentes EA en él?

 
deVries:

no comprobar el símbolo no comprobar un magicnumber....

entonces, ¿qué va a pasar usando en vivo con diferentes EA en él?


¿Te refieres a la ejecución de dos EA de 1 cuenta?
 
prupru:

¿Te refieres a la ejecución de dos EA de 1 cuenta?
Dos EAs o un EA y operaciones colocadas manualmente... o sólo operaciones colocadas manualmente.
 
prupru:

¡Hola!

Soy nuevo en mql 4 y he hecho un simple 2 EMA cross advisor, que he probado en la cuenta demo, pero un poco de miedo de conseguirlo en una real

Probarlo con lotes pequeños en escala de 1h me llevaría demasiado tiempo, y probarlo en escalas de minutos es caro, porque el lote mínimo en mi broker es de unos 7 usd.

Así que te agradecería que le echaras un vistazo y que me indicaras algunos errores obvios que podría haber cometido.

Es bueno ver que alguien comprueba los valores de retorno de las funciones de comercio sin que se le pida que lo haga... pero se necesita más información si se obtiene un error para poder diagnosticar qué causó el problema, no se puede retroceder en el tiempo en situación de vida para comprobar cuál era el Spread o cuál era el nivel de Freeze en ese momento....

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

... esto es bueno pero necesitas más, ¿qué variables necesitarás imprimir para poder determinar la causa de cualquier error que obtengas? cuando hayas determinado lo que podrías necesitar añádelas todas en tu llamada a Print() asegurándote de usar el número correcto de decimales (DoubeToStr(value, digits)) para cualquier variable doble como Ask, Bid, etc

 
RaptorUK:

Es bueno ver que alguien comprueba los valores de retorno de las funciones comerciales sin que se le pida que lo haga....

Lo siento, pero no entendí esa parte. Lo único que entendí es que tengo que añadir todas las variables que pueda a la llamada de Print(). Entendido, gracias.

deVries, gracias también por tu consejo, ahora entiendo lo que quieres decir.

¿Hay que arreglar algo más?

 

por supuesto que sí

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

suponga que ya tiene el máximo de barras (hay un límite).....

 
deVries:

por supuesto que sí

suponga que ya tiene el máximo de barras (hay un límite).....


ok, ¿entonces cómo puedo captar mejor el momento en que se abre una nueva vela?
 
prupru:

ok, entonces, ¿cómo puedo captar mejor el momento en que se abre una nueva vela?


comprueba la hora de la última barra Time[0]

busque NewBar y encontrará algunos ejemplos

 
deVries:


comprobar la hora de la última barra Time[0]

busque NewBar y encontrará algunos ejemplos


gracias, he encontrado esto 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;}

No creo que esto sea correcto

¿como se consiguen 100 pips de take profit y 150 pips de Stoploss?

actualización ver " por lo que la pérdida de la parada y tomar ganancias no están en pips, pero en porcentajes de una oferta o demanda ".

aun asi se obtiene un precio valido de esa manera ... si su simbolo tiene 5 digitos el resultado sera a menudo 2 digitos mas