Eseguire più di un EA alla volta - pagina 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;   
}
 

Hai ancora Counter--

Vedi il commento di GumRai https://www.mql5.com/en/forum/151167/page2#954622

 
Pensi che due barre consecutive possano avere lo stesso identico prezzo di apertura?
   if(CheckOncePerBar){
      if(ThisBarOpen!=Open[0]){
         ThisBarOpen=Open[0];
         NewBar=true;
         }
      else NewBar=false;
      }
    else NewBar=true;

if(NewBar)
{
   : // doit
Usa sempre il tempo
static datetime ThisBarTime = 0;
if(ThisBarTime != Time[0] || !CheckOncePerBar)
{
   ThisBarTime = Time[0];
   : // doit
Questo non gestisce i cicli di deinit/init. variabile statica esterna - MQL4 forum
 

Grazie per i vostri post.

Ho usato Open invece di Time perché una volta che l'Open di una barra si verifica è fisso per sempre e non cambierà mai. Non sta cercando due barre consecutive - è la stessa barra e sta chiedendo se l'apertura della barra corrente durante la quale il tick ha appena avuto luogo è lo stesso del valore di Open memorizzato in ThisBarOpen. Inoltre, avrei pensato che Open sarebbe stato più diretto di Time perché è una semplice ricerca di dati mentre Time potrebbe dover fare riferimento a qualcos'altro e forse fare una sorta di calcolo.

Re Counter--; Non l'ho cambiato perché un altro EA non sarebbe in grado di chiudere un ordine perché il codice controlla che sia il MagicNumber che il Symbol() siano uguali.

Certamente prendo il punto sul fatto che un'interruzione di corrente cancelli il contenuto di BuyTicket, ma questo non è successo durante i miei test e il mio codice funziona ancora molto lentamente. Quindi non riesco a vedere come questo possa essere la causa.

La mia domanda principale al momento è perché ci sia voluto così tanto tempo per rimuovere gli EA dalle finestre del terminale che avevano posizioni aperte e nessun tempo per rimuoverli dal terminale che non aveva posizioni aperte. Coincidenza forse - ma tutte e quattro le finestre?

 
L'ultima volta ho avuto lo stesso problema e in realtà è come si codifica l'ea. Forse è il momento che il tuo ea deve essere scritto di nuovo da zero. v2 per esempio.
 

Non so se questo è davvero rilevante per il tuo problema, ma tu limiti il tuo trading a 1 acquisto, 1 vendita per EA quindi perché fare tutto questo?

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

Hai già il tuo numero di ticket qui:

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

se lo rendi un int statico puoi chiudere il tuo ordine esplicitamente con quel numero di ticket senza doverlo cercare nel pool di ordini.

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

Grazie per i vostri post.


Re Counter--; non l'ho cambiato perché un altro EA non sarebbe in grado di chiudere un ordine perché il codice controlla che entrambi i MagicNumber e Symbol() siano gli stessi prima.


La mia domanda principale al momento è perché ci sia voluto così tanto tempo per rimuovere gli EA dalle finestre del terminale che avevano posizioni aperte e nessun tempo per rimuoverli dal terminale che non aveva posizioni aperte. Coincidenza forse - ma tutte e quattro le finestre?


Hai capito come funzionano i loop?

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

Diciamo che hai 3 ordini aperti

Al primo giro, il contatore==0, quindi l'ordine con l'indice 0 sarà selezionato

Alla fine del ciclo diminuisci il contatore di 1, quindi contatore== -1.

Prima che il ciclo venga eseguito di nuovo, il contatore viene aumentato di 1 come parte della funzione for. Quindi contatore ==0

Quindi alla prossima esecuzione del ciclo il contatore==0 di nuovo!! e così via e così via.

Sei bloccato in un ciclo infinito che continua a controllare l'indice d'ordine 0

L'unico modo in cui si fermerà è se non ci sono ordini aperti perché allora OrdersTotal - 1 sarà -1 e 0 non è <= -1

 
Grazie mille davvero GumRaj - hai risolto il mio problema! Ora funziona bene. Questa è la prima volta che scrivo codice in MQL4 quindi è un processo di apprendimento per me. Ero confuso su come funzionava il ciclo for.
 
Sneck55: GumRaj - hai risolto il mio problema! Ora funziona bene.
E come l'hai risolto? Se non stai facendo il conto alla rovescia hai ancora un problema (#3) - appena nascosto fino a quando hai più ordini o più EAs.
 
Ha bisogno di diminuire se chiude un ordine per corrispondere a ciò che accade nel pool, ma non se non chiude un ordine. Se diminuisce senza chiudere un ordine va in un ciclo infinito.
Motivazione: