hizo una cruz de 2 EMA EA, necesita asesoramiento - página 3

 
deVries:


no si pruebas con el spread actual esto es muy loco moviéndose así que el spread puede llegar a ser muy grande

¿como hiciste la prueba?

¿se trata de un spread fijo o de un spread actual?


ok, este es el momento en que voy a googlear "spread"

Te agradezco que respondas a mis estúpidas preguntas))

Volveré en un rato

 
prupru:


ok, ahora es cuando voy a buscar en google "spread"

Te agradezco que respondas a mis estúpidas preguntas))

Volveré en un rato

Spread = Ask - Bid
 

y cada tick este valor puede cambiar

la razón por la que he preguntado por el método de hacer la prueba

 
deVries:

y cada tick este valor puede cambiar

la razón por la que he preguntado el método de cómo hacer la prueba

¡exactamente!

¡Yo la diferencia fue debido a la prueba de spread actual, cuando realicé las pruebas con spread fijo fueron exactamente las mismas!

¡Muchas gracias chicos!

Realmente he mejorado mis conocimientos.

Y por favor, háganme saber si queda algo por mejorar en el código.

 
prupru:

¡exactamente!

¡Yo la diferencia se debió a la prueba de spread actual, cuando realicé las pruebas con spread fijo eran exactamente las mismas!

¡Muchas gracias chicos!

Realmente he mejorado mis conocimientos.

Y por favor, háganme saber si queda algo por mejorar en el código.


si muestra en qué se ha convertido su código ahora

Me gustaría ver también un nuevo errorhandling, ver el comentario RaptorUK https://www.mql5.com/en/forum/148529

 
deVries:


si muestra lo que su código se ha convertido ahora

como para ver también un nuevo errorhandling, ver el comentario RaptorUK https://www.mql5.com/en/forum/148529

Ok, aquí vamos:

#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=0;
extern int  StopLoss=0;
extern int TrailingStop=0;
extern int Slippage = 10;

extern double MinDiff = 0.002;

int LastBars = 0;
//0 - undefined, 1 - bullish cross (fast MA above slow MA), -1 - bearish cross (fast MA below slow MA)
int PrevCross = 0;

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

normalización de precios:

double NormPrice(double g_price)
{
   return (NormalizeDouble(g_price,MarketInfo(Symbol(),MODE_DIGITS)));
}

Función GetLot, supongo que no ha cambiado

//function GetLot, get size of the lot according to MaxRisk
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);}

Nueva función Order, ahora utiliza los precios normalizados:

//function NewOrder, place new order
int NewOrder(int Cmd,double Lot)
{double TP=0; //тейкпрофит
 double SL=0; //стоплосс
 double PR=0; //Цена
 color clr = CLR_NONE;
 while(!IsTradeAllowed()) Sleep(10);
 RefreshRates();
 if(Cmd==OP_BUY)
   {PR=Ask;
    if(TakeProfit>0) TP=NormPrice(Ask + Ask*TakeProfit/100);
    if(StopLoss>0) SL=NormPrice(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=NormPrice(Bid - Bid*TakeProfit/100);
    if(StopLoss>0) SL=NormPrice(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());
   Print("cmd ", Cmd, " Lot ", Lot, " PR ", PR, " Slip ", Slippage, " SL ", SL, " TP ", TP, " Ask ", Ask, " Bid ", Bid);
  }
return(tic);}

Cerrar 1 o todas las órdenes

No he cambiado la función de cierre de órdenes para comprobar el símbolo y los números mágicos, porque voy a operar en un solo símbolo y con un solo EA por cuenta. Pero lo haré después de ocuparme de otros temas más importantes y de la puesta a punto.

//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("Close order error: ",GetLastError());
   Print("Type ", OrderType()," PR ",PR, " Ask ", Ask, " Bid ", Bid, " OrderTicket ", OrderTicket(), " OrderLots ", OrderLots());
  }
return;}
//--------------------------- end of close order

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

He cambiado la detección de cruces de EMA de comparar EmaDiff[2] a EmaDiff[1] a comparar EmaDiff[0] a cero y usar una bandera adicional (todo esto viene de algún ejemplo que encontré)

En una cuenta Demo a escala de minutos hace falsos disparos cuando el spread es tan alto que una operación de compra hace que las EMAs se crucen y luego una operación de venta que viene después dentro de la misma barra de minutos hace que se separen de nuevo.

[url=http://postimg.org/image/udq4ufmqf/][img]http://s15.postimg.org/udq4ufmqf/mess.jpg[/img][/url]

Ahora mismo estoy pensando en cómo solucionar esto

// check cross
void CheckCross()
{
   double FMA_Current = iMA(Symbol(),0,FastEma,0,MODE_EMA,PRICE_CLOSE,0);
   double SMA_Current = iMA(Symbol(),0,SlowEma,0,MODE_EMA,PRICE_CLOSE,0);
   double Poin = (FMA_Current + SMA_Current)/2;
   double Lot;
   if (PrevCross == 0) //Was undefined
   {
      if ((FMA_Current - SMA_Current) >= MinDiff * Poin) PrevCross = 1; //Bullish state
      else if ((SMA_Current - FMA_Current) >= MinDiff * Poin) PrevCross = -1; //Bearish state
      return;
   }
   else if (PrevCross == 1) //Was bullish
   {
      if ((SMA_Current - FMA_Current) >= MinDiff * Poin) //Became bearish
      {
         CloseAllOrders();
         Lot = GetLot(MaxRisk);
         NewOrder(OP_SELL,Lot);
         PrevCross = -1;
      }
   }
   else if (PrevCross == -1) //Was bearish
   {
      if ((FMA_Current - SMA_Current) >= MinDiff * Poin) //Became bullish
      {
         CloseAllOrders();
         Lot = GetLot(MaxRisk);
         NewOrder(OP_BUY,Lot);
         PrevCross = 1;
      }
   }
}

la función de trailing stop:

// trailing stop
void DoTrailing()
{
   int total = OrdersTotal();
   for (int pos = 0; pos < total; pos++)
   {
      if (OrderSelect(pos, SELECT_BY_POS) == false) continue;
      if (OrderSymbol() == Symbol())
      {
         if (OrderType() == OP_BUY)
         {
            RefreshRates();
            if (Bid - OrderOpenPrice() >= TrailingStop * Bid/100) //If profit is greater or equal to the desired Trailing Stop value
            {
               if (OrderStopLoss() < (Bid - TrailingStop * Bid/100)) //If the current stop-loss is below the desired trailing stop level
                  OrderModify(OrderTicket(), OrderOpenPrice(), NormPrice(Bid - TrailingStop * Bid/100), OrderTakeProfit(), 0);
            }
         }
         else if (OrderType() == OP_SELL)
         {
            RefreshRates();
            if (OrderOpenPrice() - Ask >= TrailingStop * Ask/100) //If profit is greater or equal to the desired Trailing Stop value
            {
                      if ((OrderStopLoss() > (Ask + TrailingStop * Ask/100)) || (OrderStopLoss() == 0)) //If the current stop-loss is below the desired trailing stop level
                  OrderModify(OrderTicket(), OrderOpenPrice(), NormPrice(Ask + TrailingStop * Ask/100), OrderTakeProfit(), 0);
            }
         }
      }
   }   
}

y el propio cuerpo:

//main program
int start()
  {

   if (TrailingStop > 0) DoTrailing();
          
        static datetime Time0;
        if (Time0 == Time[0]) return;
        Time0 = Time[0];
      {
       CheckCross();     
              
      }

   return(0);
  }

¡Gracias por tu interés!



 
prupru:


No he cambiado la función de cierre de órdenes para comprobar el símbolo y los números mágicos, porque voy a operar en un solo símbolo y con un solo EA por cuenta. Pero lo haré después de ocuparme de otros temas más importantes y de la puesta a punto.


¡¡¡¡no seas perezoso, hazlo directamente !!!!

es una cosa importante que siempre tienes que incluir

si quieres arreglar tu programa y te aconsejamos lo que hay que hacer

entonces si no quieres trabajar para arreglarlo entonces ¿que hacemos ayudándote?

 
deVries:


¡¡¡¡no seas perezoso, hazlo directamente !!!!

es una cosa importante que siempre tienes que incluir

si quieres arreglar tu programa y te aconsejamos lo que hay que hacer

entonces si no quieres trabajar para arreglarlo entonces ¿que hacemos ayudándote?


ok, ok, solo tómalo con calma)

aqui esta, creo que deberia servir.

abrir función de orden :

OrderSend(Symbol(),Cmd,Lot,PR,Slippage,SL,TP,"",Expert_ID,0,clr);

cerrar toda la función de orden:

//Close all Orders
void CloseAllOrders()
{
  for(int i=OrdersTotal()-1;i>=0;i--)
   {
    if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
     {
      if ((OrderSymbol() == Symbol()) && (OrderMagicNumber() == Expert_ID))  CloseOrder();
     }
    else
     {
      Print("Error selecting order: ",GetLastError());
      Print(" i= ", i, " Symbol= ", OrderSymbol());
     }
   }
return;}
 

Ahora tengo un problema mayor, mi broker tiende a ejecutar parcialmente las órdenes.

Estimado cliente,

Le informamos que su operación se ha abierto parcialmente (2,32 lotes de 15,84) al precio 587,318.

Si tiene alguna pregunta adicional sobre este tema, no dude en ponerse en contacto con nosotros.

Saludos cordiales,

Corredor.

esto es lo que dice el soporte:

Por favor, tenga en cuenta que durante los períodos de alta volatilidad o baja liquidez, las órdenes de límite pueden ser ejecutadas parcialmente. Esto significa que la posición se ejecutará inmediatamente de forma total o parcial si se cumple el precio. En su caso su orden fue ejecutada parcialmente, por eso ha recibido la carta de notificación.

Entiendo cómo cerrar todas las órdenes a pesar de que se hayan cerrado parcialmente, sólo tengo que hacer Close all Orders while OrdersTotal() > 0, pero no sé qué hacer todavía cuando las órdenes se abren parcialmente.

editar:

Acabo de darme cuenta de que tengo que comprobar las órdenes propias de Symbol y magicnumber, es un poco más difícil

edit: aquí está la función close all orders que debería cerrar las órdenes incluso con cierre parcial

//Close all my Orders
void CloseAllOrders()
{
int notMyOrders = 0;

for(int j=OrdersTotal()-1;j>=0;j--)
{
    if(OrderSelect(j,SELECT_BY_POS,MODE_TRADES))
      {
       if ((OrderSymbol() != Symbol()) || (OrderMagicNumber() != Expert_ID)) notMyOrders++;
      }
    else
      {
       Print("Error selecting order: ",GetLastError());
       Print(" j= ", j, " Symbol= ", OrderSymbol());
      }    
}

 while (OrdersTotal()>notMyOrders)
 {
  for(int i=OrdersTotal()-1;i>=0;i--)
   {
    if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
     {
      if ((OrderSymbol() == Symbol()) && (OrderMagicNumber() == Expert_ID))  CloseOrder();
     }
    else
     {
      Print("Error selecting order: ",GetLastError());
      Print(" i= ", i, " Symbol= ", OrderSymbol());
     }
   }
 }


return;}
 

Así es como voy a luchar con la ejecución parcial de las órdenes abiertas,

La apertura de la orden ya no se realizará con una función NewOrder, sino que se hará con ésta:

//OpenOrders in case of partial execution
int OpenPartOrders(int Cmd, double Lot)
{
 int NumOrders = 0;
 int LastTic = -1;
 double Step = MarketInfo(Symbol(),MODE_LOTSTEP);
 double LotRemains = Lot;
 
 //MathFloor( /Step)*Step;;
while (LotRemains>0)
 {
  LastTic = NewOrder(Cmd, LotRemains);
  NumOrders++;
  if(OrderSelect(LastTic, SELECT_BY_TICKET)==true)
     {
      LotRemains = LotRemains - OrderLots();
      Print("NumberOfOrders ", NumOrders, " Ticket ", LastTic, " LotRemains ", LotRemains, " initial Lot ", Lot);          
     }
  else
   {
    Print("OrderSelect returned the error of ",GetLastError());
    LotRemains = 0;//not to create an endless loop opening new orders again and again
   }
 } 
return(NumOrders);}