Проверка открытости свечи

 

Привет, ребята,

Я довольно новичок в кодировании в mql4 и очень стараюсь заставить свой первый советник работать. Я был бы очень признателен за помощь в следующем. Это просто базовое пересечение, так сказать, но вместо пересечения скользящих средних, это просто цена пересекает скользящую среднюю.

Мне нужно, чтобы ордер срабатывал на открытии свечи, если: ( цена открытия текущей свечи > скользящей средней) и если (предыдущая свеча закрылась ниже скользящей средней).

На данный момент у меня есть следующий код в основной области:


//+------------------------------------------------------------------+

int start()

{

//---

double PreviousSlow = iMA(NULL,0,SlowMa,SlowMaShift, SlowMaMethod, SlowMaAppliedTo,1);

double CurrentSlow = iMA(NULL,0,SlowMa,SlowMaShift, SlowMaMethod, SlowMaAppliedTo,0);

double PreviousFast = iMA(NULL,0,FastMa,FastMaShift, FastMaMethod, FastMaAppliedTo,1);

double CurrentFast = iMA(NULL,0,FastMa,FastMaShift, FastMaMethod, FastMaAppliedTo,0);

double PreviousPriceClose= iClose(NULL, 0, 1);

double CurrentCandleOpen= iOpen(NULL,0,0);

//---------------------- Основной расчет начинается здесь


if(PreviousPriceClose<PreviousSlow && (CurrentCandleOpen>(CurrentSlow)))

if(OrdersTotal () == 0)

BuyTicket = OrderSend(Symbol(),OP_BUY, LotSize,CurrentCandleOpen, Slippage, Ask-(StopLoss*Pips), Ask+(TakeProfit*Pips), "Main Entry EA", 0,0,clrLimeGreen);

//--------------

return(0);

return(0);

}

//+------------------------------------------------------------------+

Что бы я ни делал, я просто не могу работать, и я не думаю, что я делаю что-то правильно. Еще раз, я буду очень признателен за помощь!

 
    

  double CurrentSlow = iMA(NULL,0,SlowMa,SlowMaShift, SlowMaMethod, SlowMaAppliedTo,0);   

Это значение изменяется, пока свеча находится под током

double CurrentCandleOpen= iOpen(NULL,0,0);

Это не так

BuyTicket = OrderSend(Symbol(),OP_BUY, LotSize,CurrentCandleOpen, Slippage, Ask-(StopLoss*Pips), Ask+(TakeProfit*Pips), "Main Entry EA", 0,0,clrLimeGreen);

CurrentCandleOpen вряд ли будет действительной ценой входа для многих тиков.

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

Проверьте возвращаемые значения, если OrderSend не сработал

 
GumRai:

Это значение изменяется, пока свеча находится под током

Это не так

CurrentCandleOpen вряд ли будет действительной ценой входа для многих тиков.

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

Проверьте возвращаемые значения, если OrderSend не сработает.


Спасибо за быстрый ответ! Позвольте мне проверить, правильно ли я понял:

  1. CurrentSlow на самом деле не будет работать, потому что он все еще формируется. Хорошо, это нормально, я могу использовать значение скользящей средней, которая сформировалась для предыдущей свечи. Это не должно быть проблемой.
  2. Поскольку CurrentCandleOpen не является скользящим значением... тогда я предполагаю, что эта часть кода верна?
  3. Как я могу заставить это работать, чтобы это было достаточно близко к CandleOpen? Вы упомянули, что нужно рассчитывать только один раз, когда открывается новый бар. Не могли бы вы рассказать об этом подробнее? Я не совсем понимаю, как это сделать.
Еще раз спасибо, GumRai.

 
   static datetime bar_time=0;
   if(bar_time!=Time[0])
     {
      bar_time=Time[0];
      //Code to process the signal
     }

   
Код в фигурных скобках будет выполняться только при первом тике нового бара
 
GumRai:
Код в фигурных скобках будет выполняться только при первом тике нового бара

Спасибо за код! Я обновил следующее, как обсуждалось ранее:

  1. Заменил текущую медленную MA на предыдущую медленную.
  2. Удалил CurrentCandleOpen с Ask. Всякий раз, когда я использовал CurrentCandleOpen вместо Ask, не происходило никаких сделок. Однако, когда я заменил его на Ask, он заработал, но, конечно, сделки происходили всякий раз, когда Ask пересекал МА, а не на открытии свечи.

Но после этого, когда я вставил его в ваш код следующим образом, он снова не совершает никаких сделок. Правильно ли я вставил это?

int start()
  {
//---
    
  double PreviousSlow = iMA(NULL,0,SlowMa,SlowMaShift, SlowMaMethod, SlowMaAppliedTo,1);     //1 at the end signifies that we want it on candle close
  double CurrentSlow = iMA(NULL,0,SlowMa,SlowMaShift, SlowMaMethod, SlowMaAppliedTo,0);     //1 at the end signifies that we want it on candle close

  double PreviousFast = iMA(NULL,0,FastMa,FastMaShift, FastMaMethod, FastMaAppliedTo,1);     //1 at the end signifies that we want it on candle close
  double CurrentFast = iMA(NULL,0,FastMa,FastMaShift, FastMaMethod, FastMaAppliedTo,0);     //1 at the end signifies that we want it on candle close
   
  double PreviousPriceClose= iClose(NULL, 0, 1);
  double CurrentPriceClose= iOpen(NULL, 0, 0);
  
//----------------------Main calculation starts here

 static datetime bar_time=0;
   if(bar_time!=Time[0])
     {
      bar_time=Time[0];
   if(PreviousPriceClose<PreviousSlow && Ask>PreviousSlow)
      if(OrdersTotal () == 0)
         BuyTicket = OrderSend(Symbol(),OP_BUY, LotSize,Ask, Slippage, Ask-(StopLoss*Pips), Ask+(TakeProfit*Pips), "Main Entry EA", 0,0,clrLimeGreen);
   }
//--------------
   return(0);
   return(0);
  }
 

Зачем размещать вызовы iMA за пределами нового штрих-кода? Это означает, что они вызываются каждый тик, когда они не нужны - неэффективно.

   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 PreviousPriceClose=iClose(NULL,0,1);   //You can just use Close[1]
      if(PreviousPriceClose<PreviousSlow && Bid>PreviousSlow)
         if(OrdersTotal()==0)
            {
            BuyTicket=OrderSend(Symbol(),OP_BUY,LotSize,Ask,Slippage,Ask-(StopLoss*Pips),Ask+(TakeProfit*Pips),"Main Entry EA",0,0,clrLimeGreen);
            if(BuyTicket==-1)
               {
               //Error checking code
               }
     }

Не используйте Ask для сравнения значений на графике MT4, они основаны на цене Bid.

Проверьте наличие ошибок при неудачной отправке OrderSend.

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

 

Большое спасибо GumRai. Я искренне благодарен за помощь.

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

***поглаживает себя по голове***

Я переделаю свой код. Ваша последняя строка указала на недостаток в том, что я хотел и что на самом деле я закодировал.

На самом деле мне нужно сделать следующее:

  • Шаг 1: свеча закрывается ниже MA,
  • шаг 2: свеча пересекает МА и закрывается выше МА.
  • Шаг 3: вход в сделку на открытии новой свечи.

Последний вопрос, и я думаю, что понял его...

для шага 1 выше, iMA, SlowMaShift будет 2, правильно? Так как это 2 бара позади? И iClose будет: iClose(NULL,0,2) для этого сравнения правильно?

 

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

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

 
GumRai:

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

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

Я смог заставить его работать! Спасибо GumRai.
Теперь я делаю то же самое, но использую противоположные правила для взятия шорта. Самостоятельно это работает хорошо, но я не знаю, как использовать функцию OrderCloseBy, чтобы если лонг открыт, а шорт срабатывает, он закрывал в первую очередь лонг, потому что я понятия не имею, как найти тикет ордера... Я попробовал обойти OrderCloseBy, сделав следующее:

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]
      double PreviousPriceClose2=iClose(NULL, 0,2);
      if(PreviousPriceClose2<PreviousSlow2 && 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",0,0,clrLimeGreen);
      if(PreviousPriceClose2>PreviousSlow2 && PreviousPriceClose<PreviousSlow)
         if(OrdersTotal()==1)
         {
            OrderClose(BuyTicket,LotSize,Ask,Slippage,clrPink) && OrderSend(Symbol(), OP_SELL, LotSize, Bid, Slippage, Bid+(StopLoss*Pips),Bid-(TakeProfit*Pips),"Main Sell EA",0,0,clrAliceBlue);
                  }
         if(OrdersTotal()==0)
         {
            OrderSend(Symbol(), OP_SELL, LotSize, Bid, Slippage, Bid+(StopLoss*Pips),Bid-(TakeProfit*Pips),"Main Sell EA",0,0,clrAliceBlue);
            }
     }
//--------------
   return(0);
   return(0);
  }
  return(0);
  }
 
      if(PreviousPriceClose2>PreviousSlow2 && PreviousPriceClose<PreviousSlow)
         if(OrdersTotal()==1)

не может быть удовлетворена, так как находится внутри блока условий

         if(OrdersTotal()==0)

   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]
      double PreviousPriceClose2=iClose(NULL,0,2);
      if(PreviousPriceClose2<PreviousSlow2 && 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",0,0,clrLimeGreen);
        }
      else
      if(PreviousPriceClose2>PreviousSlow2 && PreviousPriceClose<PreviousSlow)
        {
         if(OrdersTotal()==1)
           {
            OrderClose(BuyTicket,LotSize,Ask,Slippage,clrPink);
            OrderSend(Symbol(),OP_SELL,LotSize,Bid,Slippage,Bid+(StopLoss*Pips),Bid-(TakeProfit*Pips),"Main Sell EA",0,0,clrAliceBlue);
           }
         else
         if(OrdersTotal()==0)
           {
            OrderSend(Symbol(),OP_SELL,LotSize,Bid,Slippage,Bid+(StopLoss*Pips),Bid-(TakeProfit*Pips),"Main Sell EA",0,0,clrAliceBlue);
           }
        }
     }

Я думаю, что вышеприведенный вариант больше похож на то, что вы задумали.

Вы должны проверить коды возврата ошибок

 
GumRai:

Я думаю, что вышеописанное больше похоже на то, что вы хотели сказать.

Вы должны проверить коды возврата ошибок

Спасибо за код... к сожалению, он не сработал, так как теперь он входит в короткую позицию более одного раза. Вот что я попытался сделать вместо этого - я разбиваю его отдельно - длинный вход и выход, а затем я создам противоположное для короткого входа и выхода. Это будет более управляемым для меня, и немного легче настраивать. Я работаю над тем, чтобы сначала разобраться с длинным входом и выходом. Но почему-то не получается закрывать сделки, когда свеча закрывается ниже скользящей средней для коротких сделок. Есть идеи, что я делаю не так? Выдает ошибку: Return value of 'OrderClose' should be checked. Я все утро искал решение, но, похоже, оно не работает.

   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]
      double PreviousPriceClose2=iClose(NULL,0,2);
      if(PreviousPriceClose2<PreviousSlow2 && 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",0,0,clrLimeGreen);
        }
      else
      if(PreviousPriceClose2>PreviousSlow2 && PreviousPriceClose<PreviousSlow && Bid<PreviousSlow)
        {
          OrderClose(BuyTicket,LotSize,Ask,Slippage,clrPink);
          
        }
     

Обновление: Я избавился от кода ошибки, но закрытие заказа по-прежнему не работает. Все, что я хочу, это чтобы он закрыл покупку, как только свеча пересечет и закроется ниже MA.

Причина обращения: