Проверка открытости свечи - страница 3

 
  1. Код был написан до сборки 600. С февраля 2014 года нельзя использовать точки в именах переменных. Просто замените их подчеркиванием.
  2. Вот пример независимого от направления кода
    double DIR, OOP, OCP, ISL;  int OP;
    
    if(     Bid > High[1]){
       DIR = +1; OOP = Ask; OCP = Bid; OP = OP_BUY;
    }
    else if(Bid <  Low[1]){
       DIR = -1; OOP = Bid; OCP = Ask; OP = OP_BUY;
    }
    else return;
    
    ISL = OCP -DIR* pips_to_change( extISL_Pips );
    ... OrderSend(...);
    Вы просто меняете Ask/Bid на цены открытия/закрытия и пишете все остальное, как если бы это была покупка: ISL ниже OCP (OCP - ISL) и -DIR* меняет знак на продажу.
    Если вам нужно сравнение (A > B) , используйте (A - B) *DIR> 0, чтобы изменить знак сравнения для продажи.
 
GumRai:

Похоже, у вас есть идея.

Измените и опубликуйте свой код, а я или кто-то другой прокомментирует его.

Привет, GumRai,

Прошло много времени с тех пор, как я размещал здесь обновления, но я работал над кодом и наконец-то закончил его... Больно, когда работаешь по 10 часов в день. Однако у меня есть две основные проблемы. 1) Независимо от того, что я делаю, он генерирует код ошибки: "Unknown ticket XYZ for OrderCloseFunction" и 2) Я сделал сохранение файла (вызвал один USDCAD, другой EURUSD), с разными magicnumbers и т.д., но он все равно берет только одну сделку за раз - и не обрабатывает пары независимо. Фактически, он также создает ошибку "invalid ticket for OrderCloseFunction".

Я попытался погуглить, но безрезультатно. Буду очень признателен, если вы сможете направить меня в правильном направлении. Что я делаю неправильно?

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

//part with the extern int stating the terms of the MA removed to reduce space.

int MagicNumber = 1234;
int MagicNumber2 = 2345;
double Pips;
int BuyTicket;
int SellTicket;
int CloseTicket;
int CloseSellTicket;

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   double Ticksize = MarketInfo(Symbol(), MODE_TICKSIZE);
   if (Ticksize == 0.00001 || Ticksize == 0.001)
   Pips = Ticksize*10;
   else Pips = Ticksize;
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
int start()
  {
//---

   static datetime bar_time=0;
  if(bar_time!=Time[0])
     {
      bar_time=Time[0];
      double PreviousSlow=iMA(NULL,0,SlowMa,SlowMaShift,SlowMaMethod,SlowMaAppliedTo,1);
      double PreviousSlow2=iMA(NULL,0,SlowMa,SlowMaShift,SlowMaMethod,SlowMaAppliedTo,2);
      double PreviousPriceClose=iClose(NULL,0,1);
      double PreviousPriceClose2=iClose(NULL,0,2);
      if((iOpen(NULL,0,1)<PreviousSlow && PreviousPriceClose>=PreviousSlow && Bid>=(PreviousSlow+PipsBeforeEntry*Pips)))
        {
         if(OrdersTotal()==0)
            BuyTicket=OrderSend(Symbol(),OP_BUY,LotSize,Ask,Slippage,Ask-(StopLoss*Pips),Ask+(TakeProfit*Pips),"Main Entry EA",MagicNumber,0,clrLimeGreen);
        }
        
      else
      for(int i = OrdersTotal()-1; i >= 0; i--) 
         {
         if(!OrderSelect(i,SELECT_BY_POS,MODE_TRADES)) continue;
      if(iClose(NULL, 0,0)<PreviousSlow)
        {
          CloseTicket=OrderClose(BuyTicket,LotSize,Bid,Slippage,clrPink);
         }
         }
      if((iOpen(NULL,0,1)>PreviousSlow && PreviousPriceClose<PreviousSlow && Bid<=(PreviousSlow-PipsBeforeEntry*Pips)))
        {
         if(OrdersTotal()==0)
            SellTicket=OrderSend(Symbol(),OP_SELL,LotSize,Bid,Slippage,Bid+(StopLoss*Pips),Bid-(TakeProfit*Pips),"Main Entry EA",MagicNumber2,0,clrLimeGreen);
        }
      else
      for(i = OrdersTotal()-1; i >= 0; i--) 
         {
         if(!OrderSelect(i,SELECT_BY_POS,MODE_TRADES)) continue;
          if(iClose(NULL, 0,1)>PreviousSlow)
        {
          CloseSellTicket=OrderClose(SellTicket,LotSize,Ask,Slippage,clrPink);
              }
     }
     }
    return(0);
    return(0); 
    }
//--------------

  

Заранее большое спасибо!

 

Никогда не используйте OrdersTotal()==0 в качестве условия для входа в сделки

Это означает, что если сделка была открыта вручную, другим советником или тем же советником, прикрепленным к другому графическому символу, может быть открыта только 1 сделка.

У вас есть глобальная переменная BuyTicket, инициализируйте ее в -1

int BuyTicket=-1;

      if((iOpen(NULL,0,1)<PreviousSlow && PreviousPriceClose>=PreviousSlow && Bid>=(PreviousSlow+PipsBeforeEntry*Pips)))
        {
         if(BuyTicket==-1)
            BuyTicket=OrderSend(Symbol(),OP_BUY,LotSize,Ask,Slippage,Ask-(StopLoss*Pips),Ask+(TakeProfit*Pips),
                                "Main Entry EA",MagicNumber,0,clrLimeGreen);
        }

Не перебирайте ордера перед закрытием, в этом нет необходимости.

else
if(OrderSelect(BuyTicket,SELECT_BY_TICKET))
  {
   if(OrderCloseTime()==0)
     {
      if(Close[0]<PreviousSlow)
        {
         bool  CloseTicket=OrderClose(BuyTicket,LotSize,Bid,Slippage,clrPink);
         if(CloseTicket)
            BuyTicket=-1;
        }
     }
   else
      BuyTicket=-1;  //Order has closed so reset variable
  }

Теперь, при использовании глобально объявленных переменных для номеров билетов могут возникнуть проблемы, если терминал по какой-то причине будет выключен и перезапущен.

Поэтому объявите новую переменную в глобальной области видимости

 bool Recovery=true;

  
  if(Recovery)
     {
     //loop through open orders and check for magic number, symbol and type
     //if you find a buy order with the magic number and symbol
     BuyTicket=OrderTicket();
     //if you find a sell order with the magic number and symbol
     SellTicket=OrderTicket();
     Recovery=false;
     }

Я набирал это быстро, поэтому мог допустить ошибки, но этого достаточно, чтобы дать вам представление.

 
GumRai:


Спасибо большое за это! Причина, по которой я поместил туда цикл, заключается в том, что я заметил, что когда он закрывает продажу, он не запускает покупку по какой-то причине.

Я сделал необходимые изменения... но что-то все еще кажется неправильным. Теперь он не принимает никаких длинных сделок и выдает код ошибки invalid ticket, а также ошибку OrderClose 4051. Есть ли какие-нибудь предположения о том, что здесь не так?

Странно то, что и в предыдущем коде, и в текущем (только для продажи), он принимал сделки достаточно нормально (если я реализовал его только на одном графике).

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


if((iOpen(NULL,0,1)<PreviousSlow && PreviousPriceClose>=PreviousSlow && Bid>=(PreviousSlow+PipsBeforeEntry*Pips)))
        {
         if(BuyTicket==-1)
            BuyTicket=OrderSend(Symbol(),OP_BUY,LotSize,Ask,Slippage,Ask-(StopLoss*Pips),Ask+(TakeProfit*Pips),"Main Entry EA",MagicNumber,0,clrLimeGreen);
        }
        
      else
      if(OrderSelect(SELECT_BY_POS,MODE_TRADES))
      {
      if(OrderCloseTime()==0)
      {
       if(Close[0]<PreviousSlow)
        {
          bool CloseTicket=OrderClose(BuyTicket,LotSize,Bid,Slippage,clrPink);
          if(CloseTicket)
            BuyTicket=-1;
            }
         }
         else
            BuyTicket= -1;
            }
            
      if((iOpen(NULL,0,1)>PreviousSlow && PreviousPriceClose<PreviousSlow && Bid<=(PreviousSlow-PipsBeforeEntry*Pips)))
        {
         if(SellTicket==-1)
            SellTicket=OrderSend(Symbol(),OP_SELL,LotSize,Bid,Slippage,Bid+(StopLoss*Pips),Bid-(TakeProfit*Pips),"Main Entry EA",MagicNumber2,0,clrLimeGreen);
        }
      else
       if(OrderSelect(SELECT_BY_POS,MODE_TRADES))
       {
         if(Close[0]>PreviousSlow)
        {
        bool  CloseSellTicket=OrderClose(SellTicket,LotSize,Ask,Slippage,clrPink);
              if(CloseSellTicket)
                  SellTicket=-1;
                     }
         }
         else
            SellTicket= -1;
            }
            
    return(0);
    return(0); 
    }
 

Извините, но я действительно не знаю, что вы пытаетесь сделать.

if(OrderSelect(SELECT_BY_POS,MODE_TRADES))

Не выбирается никакой порядок. Код вообще компилируется?

      if(OrderCloseTime()==0)
      {
       if(Close[0]<PreviousSlow)
        {
          bool CloseTicket=OrderClose(BuyTicket,LotSize,Bid,Slippage,clrPink);
          if(CloseTicket)
            BuyTicket=-1;
            }
         }
         else
            BuyTicket= -1;

Здесь else применяется, если if(OrderCloseTime()==0) false

       if(OrderSelect(SELECT_BY_POS,MODE_TRADES))
       {
         if(Close[0]>PreviousSlow)
        {
        bool  CloseSellTicket=OrderClose(SellTicket,LotSize,Ask,Slippage,clrPink);
              if(CloseSellTicket)
                  SellTicket=-1;
                     }
         }
         else
            SellTicket= -1;

Здесь else применяется, если OrderSelect не работает, что, безусловно, происходит.

 
GumRai:

Извините, но я действительно не знаю, что вы пытаетесь сделать.

Не выбирается никакой порядок. Код вообще компилируется?

Здесь else применяется, если if(OrderCloseTime()==0) false

Здесь else применяется, если OrderSelect не работает, что, безусловно, происходит.

Извините, это полностью моя ошибка. Я не правильно прочитал/применил ваши предложения; большое спасибо, что указали на них. Здесь я все сделал правильно. Никаких ошибок в отчете не возникает. Единственное, теперь он вводит несколько ордеров на продажу и покупку, что мешает ему закрывать сделки в нужное время.

Edit: Если быть точным, он выходит только на SL и TP, а не когда цена пересекает другую сторону MA. Это как-то связано с bool?

int start()
  {
   static datetime bar_time=0;
  if(bar_time!=Time[0])
     {
      bar_time=Time[0];
      double PreviousSlow=iMA(NULL,0,SlowMa,SlowMaShift,SlowMaMethod,SlowMaAppliedTo,1);
      double PreviousSlow2=iMA(NULL,0,SlowMa,SlowMaShift,SlowMaMethod,SlowMaAppliedTo,2);
      double PreviousPriceClose=iClose(NULL,0,1);   //You can just use Close[1]
      if((iOpen(NULL,0,1)<PreviousSlow && PreviousPriceClose>=PreviousSlow && Bid>=(PreviousSlow+PipsBeforeEntry*Pips)))
        {
         if(BuyTicket==-1)
            BuyTicket=OrderSend(Symbol(),OP_BUY,LotSize,Ask,Slippage,Ask-(StopLoss*Pips),Ask+(TakeProfit*Pips),"Main Entry EA",MagicNumber,0,clrLimeGreen);
        }
      else
      if(OrderSelect(BuyTicket,MODE_TRADES))
      {
         if(OrderCloseTime()==0)
         {
          if(Close[0]<PreviousSlow)
           {
             bool CloseTicket=OrderClose(BuyTicket,LotSize,Bid,Slippage,clrPink);
             if(CloseTicket)
               BuyTicket=-1;
               }
            }
            else
               BuyTicket= -1; //Order has closed so reset variable
               }
            
      if((iOpen(NULL,0,1)>PreviousSlow && PreviousPriceClose<PreviousSlow && Bid<=(PreviousSlow-PipsBeforeEntry*Pips)))
        {
         if(SellTicket==-1)
            SellTicket=OrderSend(Symbol(),OP_SELL,LotSize,Bid,Slippage,Bid+(StopLoss*Pips),Bid-(TakeProfit*Pips),"Main Entry EA",MagicNumber2,0,clrLimeGreen);
        }
      else
       if(OrderSelect(SellTicket,MODE_TRADES))
       {
         if(Close[0]>PreviousSlow)
        {
        bool CloseSellTicket=OrderClose(SellTicket,LotSize,Ask,Slippage,clrPink);
              if(CloseSellTicket)
                  SellTicket=-1;
                     }
         }
         else 
            SellTicket= -1; //Order has closed so reset variable
            }
    return(0);
    return(0); 
    }
 
if(OrderSelect(BuyTicket,MODE_TRADES))
Это не выбирает торговлю, пожалуйста, следуйте примеру, который я вам дал, и делайте все правильно.
 
GumRai:
Это не выбирает торговлю, пожалуйста, следуйте примеру, который я вам дал, и делайте все правильно.

Я чувствую себя... очень глупо. lol. Спасибо за находку!!!

1) Осталось две вещи... теперь он создает код ошибки OrderClose 4108. Мне снова выложить код? Он такой же, как и выше, с исправлениями, которые вы указали. Он входит и выходит в соответствии с правилами.

2) И он не входит в короткую позицию сразу после закрытия длинной позиции, как показано на рисунке. Зеленая стрелка вниз показывает, где он должен был войти в короткую позицию. Он взял покупку и закрыл ее с убытком, как только она закрылась ниже желтой МА. Здесь она должна была стать короткой. Как я могу зациклить это?

Большое спасибо GumRai. Честно говоря, без вашей помощи я бы не дошел так близко.

надо было укоротиться.

 
int start()
  {
   static datetime bar_time=0;
   if(bar_time!=Time[0])
     {
      bar_time=Time[0];
      double PreviousSlow=iMA(NULL,0,SlowMa,SlowMaShift,SlowMaMethod,SlowMaAppliedTo,1);
      double PreviousSlow2=iMA(NULL,0,SlowMa,SlowMaShift,SlowMaMethod,SlowMaAppliedTo,2);
      double PreviousPriceClose=iClose(NULL,0,1);   //You can just use Close[1]
      if(BuyTicket==-1)
        {
         if((iOpen(NULL,0,1)<PreviousSlow && PreviousPriceClose>=PreviousSlow && Bid>=(PreviousSlow+PipsBeforeEntry*Pips)))
           {
            BuyTicket=OrderSend(Symbol(),OP_BUY,LotSize,Ask,Slippage,Ask-(StopLoss*Pips),Ask+(TakeProfit*Pips),"Main Entry EA",MagicNumber,0,clrLimeGreen);
           }
        }
      else
      if(OrderSelect(BuyTicket,SELECT_BY_TICKET))
        {
         if(OrderCloseTime()==0)
           {
            if(Close[0]<PreviousSlow)
              {
               bool CloseTicket=OrderClose(BuyTicket,LotSize,Bid,Slippage,clrPink);
               if(CloseTicket)
                  BuyTicket=-1;
              }
           }
         else
            BuyTicket=-1; //Order has closed so reset variable
        }

      if(SellTicket==-1)
        {
         if((iOpen(NULL,0,1)>PreviousSlow && PreviousPriceClose<PreviousSlow && Bid<=(PreviousSlow-PipsBeforeEntry*Pips)))
           {
            SellTicket=OrderSend(Symbol(),OP_SELL,LotSize,Bid,Slippage,Bid+(StopLoss*Pips),Bid-(TakeProfit*Pips),"Main Entry EA",MagicNumber2,0,clrLimeGreen);
           }
        }
      else
      if(OrderSelect(SellTicket,SELECT_BY_TICKET))
        {
         if(OrderCloseTime()==0)
           {
            if(Close[0]>PreviousSlow)
              {
               bool CloseSellTicket=OrderClose(SellTicket,LotSize,Ask,Slippage,clrPink);
               if(CloseSellTicket)
                  SellTicket=-1;
              }
           }
         else
            SellTicket=-1; //Order has closed so reset variable
        }
     }
   return(0);
  }

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

Согласно коду, нет причин для открытия продажи сразу после закрытия покупки.

Условия для выхода из покупки не совпадают с условиями для открытия продажи.

Помните, что поскольку вы проверяете только открытие свечи, Close[0] будет значением заявки первого тика, полученного для свечи.

 
GumRai:

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

Согласно коду, нет причин для открытия продажи сразу после закрытия покупки.

Условия для выхода из покупки не совпадают с условиями для открытия продажи.

Помните, что поскольку вы проверяете только открытие свечи, Close[0] будет значением заявки первого тика, полученного для свечи.

Святой! Вы сделали это! Спасибо еще и еще раз GumRai. Ты лучший.

Не могу сейчас проверить, но как только рынки откроются, я думаю, я смогу использовать это тогда, с другими парами, пока у меня разные magic# на демо.