Подскажите, пожалуйста, как решить проблему с открытием последовательности ордеров.

 

Доброго времени суток, уважаемые форумчане :)

Решил разобраться в языке mql и написать своего первого советника. Возникла проблема с решением логической задачки, которая позволяла бы открывать ордера при правильном сигнале советника.

Итак, что я хочу получить от приведенного ниже кода: при сигнале советника открывается ОДИН новый ордер, затем снова идет поиск сигнала далее по графику и положительном результате открываться следующий ордер. Всего максимальное количество открытых открыто не более пяти.

int start()
  {
      //расчет лота к покупке в зависимости от риска(%)
      double Lot=GetLot(MaxRisk); 
      if(Lot==0) {Alert("Недостаточно средств!");return(0);}
      RefreshRates();

      // считаем количество открытых ордеров
      int Count=0;
      for(int i=OrdersTotal()-1; i>=0; i--)
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)) Count++;
      
      // определение новой свечи
      datetime PreviousBar;
      bool NewBar = false;
      if(PreviousBar<Time[0])
      {NewBar=true; PreviousBar = Time[0];}
      else {NewBar=false;}
      
      // проверяем условие на совершение сделок      
      if (Count <= 4)
      {
         if(NewBar == true)
         {
         
            if(Signal1()==S1_SELL && Signal2()==S2_SELL)
               { 
                   NewOrder(OP_SELL,Lot);
               }
      
            if(Signal1()==S1_BUY && S2ignal()==S2_BUY)
               { 
                   NewOrder(OP_BUY,Lot);
               }
          }
      }      
             
      return(0);
  }

Теперь, что получается в реале:

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

 

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


Как решить эту проблему? Не умещается пока в моей голове эта логическая задачка :)

Я пробовал использовать сравнение с реальным временем при проверке на новую свечу, но тогда совершается всего одна сделка, после которой советник не торгует, так висит NewBar = false.

 
antoshka.vbg:

Доброго времени суток, уважаемые форумчане :)

Решил разобраться в языке mql и написать своего первого советника. Возникла проблема с решением логической задачки, которая позволяла бы открывать ордера при правильном сигнале советника.

Итак, что я хочу получить от приведенного ниже кода: при сигнале советника открывается ОДИН новый ордер, затем снова идет поиск сигнала далее по графику и положительном результате открываться следующий ордер. Всего максимальное количество открытых открыто не более пяти.

Теперь, что получается в реале:

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

 

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


Как решить эту проблему? Не умещается пока в моей голове эта логическая задачка :)

Я пробовал использовать сравнение с реальным временем при проверке на новую свечу, но тогда совершается всего одна сделка, после которой советник не торгует, так висит NewBar = false.


Попробуйте использовать статичные переменные
 

Вам знакомо выражение "бесполезные вычисления"?

Попробуйте осознать его и сразу научиться с этим бороться.

Например:

void start()
{
    // считаем количество открытых ордеров
    int Count = 0;
    for (int i = OrdersTotal() - 1; i >= 0; i--)
    if (OrderSelect (i, SELECT_BY_POS)) Count++;
      
    if (Count > 4) return;
    // определение новой свечи
    static datetime PreviousBar = 0;
    if (PreviousBar == Time[0]) return;
    PreviousBar = Time[0];

    // расчет лота к покупке в зависимости от риска(%)
    double Lot = GetLot(MaxRisk); 
    if (Lot == 0.) {Alert ("Недостаточно средств!"); return;}
    RefreshRates();
    // проверяем условие на совершение сделок      
    if (Signal1() == S1_SELL) if (Signal2() == S2_SELL)
    {NewOrder (OP_SELL, Lot); return;}
    if(Signal1() == S1_BUY) if (S2ignal() == S2_BUY)
    {NewOrder (OP_BUY, Lot);}
}
 
TarasBY:

Вам знакомо выражение "бесполезные вычисления"?

Попробуйте осознать его и сразу научиться с этим бороться.

Например:


Благодарю за правку кода и спасибо за замечание! Буду стараться :)

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

Подскажите, пожалуйста, что значит данная конструкция:

if (Count > 4) return; 

Если не выполнилось условие, сразу же прерываем исполнение? 

 

Чем такая конструкция

if (Signal1() == S1_SELL) if (Signal2() == S2_SELL) 

в принципе отличается от такой

  if(Signal1()==S1_SELL && Signal2()==S2_SELL)

 

И что значит точка после нуля?

if (Lot == 0.) 

 
antoshka.vbg:


Благодарю за правку кода и спасибо за замечание! Буду стараться :)

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

Подскажите, пожалуйста, что значит данная конструкция:

if (Count > 4) return; 

Если не выполнилось условие, сразу же прерываем исполнение? 

Да. Не имеет смысла делать дальнейшие расчёты, что очень существенно для тестера.

antoshka.vbg:

Чем такая конструкция

if (Signal1() == S1_SELL) if (Signal2() == S2_SELL) 

в принципе отличается от такой

  if(Signal1()==S1_SELL && Signal2()==S2_SELL)

быстродействием. Если первое условие не выполняется, то второе уже не проверяется.

antoshka.vbg:

И что значит точка после нуля?

if (Lot == 0.) 

упрощённое написание. Идентично: if (Lot == 0.0)

 
antoshka.vbg:


Чем такая конструкция

if (Signal1() == S1_SELL) if (Signal2() == S2_SELL) 

в принципе отличается от такой

  if(Signal1()==S1_SELL && Signal2()==S2_SELL)

 


Ничем. Если первое не выполняется, второе не проверяется в любом случае.
 
Roger:

Ничем. Если первое не выполняется, второе не проверяется в любом случае.

Поправлю. Во втором случае продолжается проверка второго условия
 
Спасибо всем за помощь! Сейчас попробую поправить код.
 

Доброго времени суток!

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

// считаем количество открытых ордеров
    int Count = 0;
    for (int i = OrdersTotal() - 1; i >= 0; i--)
    if (OrderSelect (i, SELECT_BY_POS)) Count++;
      
    if (Count > 4) return;
    // определение новой свечи
    static datetime PreviousBar = 0;
    if (PreviousBar == Time[0]) return;
    PreviousBar = Time[0];

Думаю, проблема все-таки в проверке на новую свечу. Видно, останавливается работа после  if (PreviousBar == Time[0]) return;

Не могу понять, вроде же все логично, почему не работает? Может как-то по другому обыграть? 

 
antoshka.vbg:

Доброго времени суток!

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

Думаю, проблема все-таки в проверке на новую свечу. Видно, останавливается работа после  if (PreviousBar == Time[0]) return;

Не могу понять, вроде же все логично, почему не работает? Может как-то по другому обыграть? 

Другой подход. Запрет открытия второго ордера на текущей свече.

   // считаем количество открытых ордеров
    int Count = 0;
    bool ban = false; // переменная для запрета открытия ордера на свече
    for (int i = OrdersTotal() - 1; i >= 0; i--)
    	if (OrderSelect (i, SELECT_BY_POS))
    	{
       	   Count++;
	   // если на свече уже есть открытый ордер, ставим запрет
       	   if ( OrderOpenTime() >= Time[ 0 ] ) ban = true;
    	}
    if ( ban || Count > 4 ) return;
 
antoshka.vbg:

Доброго времени суток!

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

Думаю, проблема все-таки в проверке на новую свечу. Видно, останавливается работа после  if (PreviousBar == Time[0]) return;

Не могу понять, вроде же все логично, почему не работает? Может как-то по другому обыграть? 


Может проблема в другом месте
Причина обращения: