Одновременный запуск более одного эксперта - страница 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;   
}
 

У вас все еще есть Контр...

См. комментарий GumRai https://www.mql5.com/en/forum/151167/page2#954622

 
Как вы думаете, могут ли два последовательных бара иметь одинаковую цену открытия?
   if(CheckOncePerBar){
      if(ThisBarOpen!=Open[0]){
         ThisBarOpen=Open[0];
         NewBar=true;
         }
      else NewBar=false;
      }
    else NewBar=true;

if(NewBar)
{
   : // doit
Всегда используйте время
static datetime ThisBarTime = 0;
if(ThisBarTime != Time[0] || !CheckOncePerBar)
{
   ThisBarTime = Time[0];
   : // doit
Это не обрабатывает циклы deinit/init. внешняя статическая переменная - Форум MQL4
 

Спасибо за ваши сообщения.

Я использовал Open вместо Time, потому что как только происходит открытие бара, оно фиксируется навсегда и никогда не изменится. Он не ищет два последовательных бара - это один и тот же бар и спрашивает, совпадает ли открытие текущего бара, на котором только что произошел тик, со значением Open, хранящимся в ThisBarOpen. Кроме того, я бы подумал, что Open будет более простым, чем Time, потому что это простой поиск данных, в то время как Time, возможно, придется ссылаться на что-то еще и, возможно, выполнять какие-то вычисления.

Re Counter--; я не изменил это, потому что другой советник не смог бы закрыть ордер, так как код сначала проверяет, что MagicNumber и Symbol() одинаковы.

Я, конечно, понимаю, что отключение электричества может стереть содержимое BuyTicket, но этого не произошло во время моих тестов, и мой код все еще работает очень медленно. Поэтому я не могу понять, как это может быть причиной.

Мой главный вопрос на данный момент - почему потребовалось так много времени, чтобы удалить советников из окон терминала, в которых были открытые позиции, и совсем немного времени, чтобы удалить их из терминала, в котором не было открытых позиций. Возможно, совпадение - но все четыре окна?

 
В прошлый раз у меня была такая же проблема, и на самом деле все дело в том, как вы кодируете ea. Возможно, пришло время написать вашу программу с нуля. Например, v2.
 

Я не знаю, что это действительно относится к вашему вопросу, но вы ограничиваете свою торговлю 1 покупкой, 1 продажей на советника, так зачем все это делать?

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

У вас уже есть номер вашего тикета:

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

если вы сделаете его статическим int, вы сможете закрыть свой ордер явно по этому номеру тикета, не копаясь в пуле ордеров в поисках его.

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

Спасибо за ваши сообщения.


Re Counter--; Я не изменил это, потому что другой советник не смог бы закрыть ордер, потому что код сначала проверяет, что MagicNumber и Symbol() одинаковы.


Мой главный вопрос на данный момент - почему потребовалось так много времени, чтобы удалить советников из окон на терминале, где были открытые позиции, и совсем немного времени, чтобы удалить их из терминала, где не было открытых позиций. Совпадение возможно - но все четыре окна?


Вы понимаете, как работают циклы?

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

Допустим, у вас открыто 3 ордера.

При первом проходе счетчик==0, поэтому будет выбран ордер с индексом 0.

В конце цикла вы уменьшаете счетчик на 1, так что counter== -1.

Перед повторным выполнением цикла счетчик увеличивается на 1 в рамках функции for. Таким образом, счетчик ==0

При следующем выполнении цикла счетчик снова = 0!!! и так далее, и так далее.

Вы застряли в бесконечном цикле, который просто продолжает проверять индекс порядка 0.

Единственный способ, которым он остановится, это если нет открытых ордеров, потому что тогда OrdersTotal - 1 будет -1, а 0 не <= -1.

 
Большое спасибо GumRaj - вы решили мою проблему!!! Теперь все работает нормально. Это первый раз, когда я пишу код на MQL4, так что это процесс обучения для меня. Я запутался в том, как работает цикл for.
 
Sneck55: GumRaj - вы решили мою проблему!!! Теперь все работает нормально.
А как вы ее решили? Если у вас нет обратного отсчета, у вас все еще есть проблема (#3) - просто скрытая, пока у вас нет нескольких ордеров или нескольких советников.
 
Он должен уменьшаться, если закрывает ордер, чтобы соответствовать тому, что происходит в пуле, но не уменьшаться, если ордер не закрыт. Если он уменьшается без закрытия ордера, то он попадает в бесконечный цикл.
Причина обращения: