Ejecutar más de un EA a la vez - página 3

 
#property copyright "Copyright 2014, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict

extern bool CheckOncePerBar=true;
extern double FixedLotSize=1;
extern double SystemStopLoss=150;
extern double TakeProfit=0;
extern int Slippage=5;
extern int MagicNumber=3574;

//Global Variables
int BuyTicket=0;
int SellTicket=0;
double InternalStopLoss=0;
double CalcDigits=0;
double CalcPoint=0;
bool MABuyFanning=false;
bool MASellFanning=false;
int SelectedOrder=0;
bool Closed=false;
int ErrorCode=0;
string ErrLog="a";
double BuyStopLoss=0;
double SellStopLoss=0;
bool NewBar=false;
double ThisBarOpen=0;
double SmallMA=0;
double MediumMA=0;
double LargeMA=0;
int Counter=0;



//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
CalcDigits = MarketInfo(Symbol(),MODE_DIGITS);//MODE_DIGITS is count of digits after decimal point
if(CalcDigits==0) CalcPoint=1;//Dow      
if(CalcDigits==1) CalcPoint=0.1;   
if(CalcDigits==2) CalcPoint=0.01;//Gold & Nymex
if(CalcDigits==3) CalcPoint=0.01;//Yen
if(CalcDigits==4) CalcPoint=0.0001;//Not used
if(CalcDigits==5) CalcPoint=0.0001;//Non-Yen forex
InternalStopLoss=SystemStopLoss*CalcPoint;
   
   return(INIT_SUCCEEDED);
  }
//-----------------------------------------------

void OnTick()
{

   if(CheckOncePerBar)
      {
      if(ThisBarOpen!=Open[0])
         {
         ThisBarOpen=Open[0];
         NewBar=true;
         }
      else NewBar=false;
      }
    else NewBar=true;

if(NewBar)
{


//Reset Moving Averages
SmallMA=iMA(NULL,0,8,0,1,0,0);
MediumMA=iMA(NULL,0,10,0,1,0,0);
LargeMA=iMA(NULL,0,50,0,1,0,0);


   if(SmallMA>MediumMA&&MediumMA>LargeMA) MABuyFanning=true;
   else MABuyFanning=false;
      
   if(SmallMA<MediumMA&&MediumMA<LargeMA) MASellFanning=true; 
   else MASellFanning=false;   



if(BuyTicket==0&&MABuyFanning)
 {
      RefreshRates();
      BuyStopLoss= Bid-InternalStopLoss;
   //   while(IsTradeContextBusy()) Sleep(10);
      BuyTicket=OrderSend(Symbol(),OP_BUY,FixedLotSize,Ask,Slippage,BuyStopLoss,0,"Buy Order",MagicNumber,0,Green);
          if(BuyTicket==-1)
            {
            ErrorCode=GetLastError();
            Alert("Symbol: ",Symbol(),"Error in buy routine: ",ErrorCode);
            ErrLog=StringConcatenate("Bid: ",MarketInfo(Symbol(),MODE_BID)," Ask: ",MarketInfo(Symbol(),MODE_ASK)," Lots: ",FixedLotSize," Stop Loss: ",BuyStopLoss);
            Print(ErrLog);
            //Buy ticket revert to 0 so it can try again in case of slow connection/timeout etc.
            BuyTicket=0;
            } 
 }   


if(SellTicket==0&&MASellFanning)
 {
      RefreshRates();
      SellStopLoss=Ask+InternalStopLoss;
    //  while(IsTradeContextBusy()) Sleep(10);
      SellTicket=OrderSend(Symbol(),OP_SELL,FixedLotSize,Bid,Slippage,SellStopLoss,0,"Sell Order",MagicNumber,0,Red);
          if(SellTicket==-1)
            {
            ErrorCode=GetLastError();
            Alert("Symbol: ",Symbol(),"Error in sell routine: ",ErrorCode);
            ErrLog=StringConcatenate("Bid: ",MarketInfo(Symbol(),MODE_BID)," Ask: ",MarketInfo(Symbol(),MODE_ASK)," Lots: ",FixedLotSize," Stop Loss: ",SellStopLoss);
            Print(ErrLog);
            SellTicket=0;
            } 
  }  

//Exits

         if(BuyTicket!=0)
            {
            if(SmallMA<MediumMA)
            {
            for(Counter=0; Counter<=OrdersTotal()-1;Counter++)
               {
               SelectedOrder=OrderSelect(Counter,SELECT_BY_POS);
               if(OrderMagicNumber()==MagicNumber&&OrderSymbol()==Symbol()&&OrderType()==OP_BUY)
                  {
                 // while(IsTradeContextBusy()) Sleep(10);
                  Closed=OrderClose(OrderTicket(),OrderLots(),MarketInfo(Symbol(),MODE_BID),Slippage,Red);
                  if(Closed) BuyTicket=0;
                  else Alert("Symbol: ",Symbol()," Ticket: ",BuyTicket," unable to close buy order(s): buy ma convergence close routine");                  
                  }
            Counter--;               
                }
            }
            }

         if(SellTicket!=0)
            {
            if(SmallMA>MediumMA)
            {
            for(Counter=0;Counter<=OrdersTotal()-1;Counter++)
               {
               SelectedOrder = OrderSelect(Counter,SELECT_BY_POS);
               if(OrderMagicNumber()==MagicNumber&&OrderSymbol()==Symbol()&&OrderType()==OP_SELL)
                  {
               //   while(IsTradeContextBusy()) Sleep(10);
                  Closed=OrderClose(OrderTicket(),OrderLots(),MarketInfo(Symbol(),MODE_ASK),Slippage,Red);
                  if(Closed) SellTicket=0;
                  else Alert("Symbol: ",Symbol()," Ticket: ",SellTicket," unable to close sell order(s): sell ma convergence close routine");                  
                  }
            Counter--;               
                }
            }
            }
}            
return;   
}
 

Todavía tienes a Counter...

Ver el comentario de GumRai https://www.mql5.com/en/forum/151167/page2#954622

 
¿Cree que dos barras consecutivas pueden tener el mismo precio de apertura exacto?
   if(CheckOncePerBar){
      if(ThisBarOpen!=Open[0]){
         ThisBarOpen=Open[0];
         NewBar=true;
         }
      else NewBar=false;
      }
    else NewBar=true;

if(NewBar)
{
   : // doit
Utilice siempre el tiempo
static datetime ThisBarTime = 0;
if(ThisBarTime != Time[0] || !CheckOncePerBar)
{
   ThisBarTime = Time[0];
   : // doit
Esto no maneja los ciclos deinit/init. variable estática externa - Foro MQL4
 

Gracias por tus comentarios.

Utilicé Open en lugar de Time porque una vez que se produce la Open de una barra es fija para siempre y nunca cambiará. No está buscando dos barras consecutivas - es la misma barra y está preguntando si la apertura de la barra actual durante la cual se acaba de producir el tick es la misma que el valor de Open almacenado en ThisBarOpen. Además, habría pensado que Open sería más sencillo que Time porque es una simple búsqueda de datos mientras que Time podría tener que referenciar algo más y posiblemente hacer algún tipo de cálculo.

Re--; No cambié eso porque otro EA no sería capaz de cerrar una orden porque el código comprueba que tanto el MagicNumber y Symbol() son los mismos primero.

Ciertamente tomo el punto acerca de un corte de energía borrando el contenido de BuyTicket pero eso no ha sucedido durante mis pruebas y mi código sigue funcionando muy lentamente. Por lo tanto, tampoco puedo ver cómo podría ser la causa.

Mi pregunta principal en este momento es por qué tomó tanto tiempo para eliminar los EAs de las ventanas en la terminal que tenían posiciones abiertas y ningún tiempo para eliminarlos de la terminal que no tenía posiciones abiertas. Puede que sea una coincidencia, pero ¿las cuatro ventanas?

 
La última vez tuve el mismo problema y en realidad es la forma de codificar el ea. Tal vez es hora de que su ea necesita ser escrito desde cero de nuevo. v2 por ejemplo.
 

No sé si esto es realmente relevante para su problema, pero usted limita su comercio a 1 compra, 1 venta por EA así que ¿por qué hacer todo esto?

  if(SellTicket!=0)
  {if(SmallMA>MediumMA)
   {for(Counter=0;Counter<=OrdersTotal()-1;Counter++)
    {SelectedOrder = OrderSelect(Counter,SELECT_BY_POS);
     if(OrderMagicNumber()==MagicNumber&&OrderSymbol()==Symbol()&&OrderType()==OP_SELL)
     {Closed=OrderClose(OrderTicket(),OrderLots(),MarketInfo(Symbol(),MODE_ASK),Slippage,Red);
      if(Closed) SellTicket=0;
      else Alert("Symbol: ",Symbol()," Ticket: ",SellTicket," unable to close sell order(s): sell ma convergence close routine");                  
     }
    Counter--;               
}}}} 

Usted ya tiene su número de ticket aquí:

SellTicket=OrderSend(Symbol(),OP_SELL,FixedLotSize,Bid,Slippage,SellStopLoss,0,"Sell Order",MagicNumber,0,Red);

si lo convierte en un int estático puede cerrar su orden explícitamente por ese número de ticket sin tener que buscarlo en el conjunto de órdenes.

Closed=OrderClose(SellTicket,OrderLots(),MarketInfo(Symbol(),MODE_ASK),Slippage,Red);
 
Sneck55:

Gracias por vuestros posts.


Re--; No cambié eso porque otro EA no podría cerrar una orden porque el código comprueba que tanto el MagicNumber como el Symbol() son iguales primero.


Mi principal duda en este momento es por qué tardó tanto tiempo en eliminar los EAs de las ventanas del terminal que tenían posiciones abiertas y nada de tiempo en eliminarlos del terminal que no tenía posiciones abiertas. Coincidencia tal vez - pero ¿las cuatro ventanas?


¿Entiendes cómo funcionan los bucles?

if(BuyTicket!=0)
            {
            if(SmallMA<MediumMA)
            {
            for(Counter=0; Counter<=OrdersTotal()-1;Counter++)
               {
               SelectedOrder=OrderSelect(Counter,SELECT_BY_POS);
               if(OrderMagicNumber()==MagicNumber&&OrderSymbol()==Symbol()&&OrderType()==OP_BUY)
                  {
                 // while(IsTradeContextBusy()) Sleep(10);
                  Closed=OrderClose(OrderTicket(),OrderLots(),MarketInfo(Symbol(),MODE_BID),Slippage,Red);
                  if(Closed) BuyTicket=0;
                  else Alert("Symbol: ",Symbol()," Ticket: ",BuyTicket," unable to close buy order(s): buy ma convergence close routine");                  
                  }
            Counter--;               
                }
            }
            }

Digamos que tienes 3 órdenes abiertas

En la primera ejecución, el contador==0, por lo que la orden con el índice 0 será seleccionada

Al final del bucle disminuyes el contador en 1, por lo que contador== -1.

Antes de que el bucle se ejecute de nuevo, el contador se incrementa en 1 como parte de la función for. Así que contador ==0

Así que en la siguiente ejecución del bucle el contador vuelve a ser =0, y así sucesivamente.

Estás atrapado en un bucle sin fin que sigue comprobando el índice de orden 0

La única manera de que se detenga es si no hay órdenes abiertas porque entonces OrdersTotal - 1 será -1 y 0 no es <= -1

 
Muchas gracias GumRaj - ¡¡¡Has resuelto mi problema!!! Ahora funciona bien. Esta es la primera vez que escribo código en MQL4 así que es un proceso de aprendizaje para mí. Yo estaba confundido acerca de cómo el bucle for trabajado.
 
Sneck55: GumRaj - ¡¡Has resuelto mi problema!! Ahora funciona bien.
¿Y cómo lo has resuelto? Si no está contando hacia abajo todavía tiene un problema (# 3) - sólo oculta hasta que tenga varias órdenes o múltiples EAs.
 
Tiene que decrementar si cierra una orden para que coincida con lo que ocurre en el pool pero no si no cierra una orden. Si se decrementa sin cerrar una orden se entra en un bucle sin fin.