Функция для совы: поиск самой большой/маленькой цены среди открытых ордеров

 

Коллеги, задача:

Робот торгует в обе стороны, одновременно могут быть открыты несколько ордеров в каждую стороны. 

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

Подскажите, как написать эту функцию. Владимир в соседней ветке (https://www.mql5.com/ru/forum/168079) подсказал код для MQL5, а мне нужно под 4-ку: 

void UpDownPrices(ENUM_POSITION_TYPE pos_type,double &up_price,double &down_price)
  {
//--- обнулим цены - мало-ли какое там занчение пришло :)
   up_price=0.0;
   down_price=0.0;
   int count=0;
   for(int i=PositionsTotal()-1;i>=0;i--) // returns the number of open positions
      if(m_position.SelectByIndex(i))     // selects the position by index for further access to its properties
         if(m_position.Symbol()==m_symbol.Name() && m_position.Magic()==m_magic)
            if(m_position.PositionType()==pos_type) // gets the position type
              {
               double price_open=m_position.PriceOpen();
               if(count==0)
                 {
                  up_price=down_price=price_open;
                  continue;              
                 }
               if(price_open>up_price)
                  up_price=price_open;
               if(price_open<down_price)
                  down_price=price_open;
               count++;
              }
  }
Найти лучшую цену из открытых сделок и текущего Bid/Ask
Найти лучшую цену из открытых сделок и текущего Bid/Ask
  • www.mql5.com
Коллеги, подскажите: Есть 2-5 сделок Sell и 1 Buy...
 
Vitaliy Hudyakov:

Коллеги, задача:

Робот торгует в обе стороны, одновременно могут быть открыты несколько ордеров в каждую стороны. 

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

Подскажите, как написать эту функцию. Владимир в соседней ветке (https://www.mql5.com/ru/forum/168079) подсказал код для MQL5, а мне нужно под 4-ку: 

void UpDownPrices(ENUM_POSITION_TYPE pos_type,double &up_price,double &down_price)
  {
//--- обнулим цены - мало-ли какое там занчение пришло :)
   up_price=0.0;
   down_price=0.0;
   int count=0;
   for(int i=PositionsTotal()-1;i>=0;i--) // returns the number of open positions
      if(m_position.SelectByIndex(i))     // selects the position by index for further access to its properties
         if(m_position.Symbol()==m_symbol.Name() && m_position.Magic()==m_magic)
            if(m_position.PositionType()==pos_type) // gets the position type
              {
               double price_open=m_position.PriceOpen();
               if(count==0)
                 {
                  up_price=down_price=price_open;
                  continue;              
                 }
               if(price_open>up_price)
                  up_price=price_open;
               if(price_open<down_price)
                  down_price=price_open;
               count++;
              }
  }

вот функция возвращает цену открытия последнего ордера, может сообразишь как переделать под свои нужды

double price_order(int type)
  {
   double value=0;
   int total=OrdersTotal();
   for(int i=0; i<total; i++)
     {
      if(!OrderSelect(i,SELECT_BY_POS))continue;
      if(OrderSymbol()!=Symbol())continue;
      if(OrderMagicNumber()!=Magic)continue;
      if(OrderType()==type || type==-1)value=OrderOpenPrice();
     }
   return(value);
  }


 ..

 
Sergey Gritsay:

вот функция возвращает цену открытия последнего ордера, может сообразишь как переделать под свои нужды

double price_order(int type)
  {
   double value=0;
   int total=OrdersTotal();
   for(int i=0; i<total; i++)
     {
      if(!OrderSelect(i,SELECT_BY_POS))continue;
      if(OrderSymbol()!=Symbol())continue;
      if(OrderMagicNumber()!=Magic)continue;
      if(OrderType()==type || type==-1)value=OrderOpenPrice();
     }
   return(value);
  }


 ..

 

Вроде так получается:

double Best_Price(int ot=-1)
  {
   double orders_best_price = 0;
  
   for(int i=OrdersTotal()-1;i>=0;i--)
     {
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
        {
         if(OrderSymbol()==Symbol() && OrderMagicNumber()==Magic)
           {
            if(OrderType()==0 && ot==0)
              {
               if (orders_best_price == 0) orders_best_price = OrderOpenPrice();
               if (OrderOpenPrice() < orders_best_price) orders_best_price = OrderOpenPrice();
              }

            if(OrderType()==1 && ot==1)
              {
               if (orders_best_price == 0) orders_best_price = OrderOpenPrice();
               if (OrderOpenPrice() > orders_best_price) orders_best_price = OrderOpenPrice();
              }
           }
        }
     }
   return(orders_best_price);
  }
 
Vitaliy Hudyakov:

 

Вроде так получается:

double Best_Price(int ot=-1)
  {
   double orders_best_price = 0;
  
   for(int i=OrdersTotal()-1;i>=0;i--)
     {
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
        {
         if(OrderSymbol()==Symbol() && OrderMagicNumber()==Magic)
           {
            if(OrderType()==0 && ot==0)
              {
               if (orders_best_price == 0) orders_best_price = OrderOpenPrice();
               if (OrderOpenPrice() < orders_best_price) orders_best_price = OrderOpenPrice();
              }

            if(OrderType()==1 && ot==1)
              {
               if (orders_best_price == 0) orders_best_price = OrderOpenPrice();
               if (OrderOpenPrice() > orders_best_price) orders_best_price = OrderOpenPrice();
              }
           }
        }
     }
   return(orders_best_price);
  }
Можно ввести две переменные, bestMaxPrice и bestMinPrice и получать их по ссылке. Тогда за один проход в цикле можно будет получить и максимальную и минимальную цену открытых ордеров.

void Best_Price(double & bestMaxPrice, double & bestMinPrice)
  {
    for(int i = 0; i < OrdersTotal(); i++)
     {
      if(OrderSelect(i, SELECT_BY_POS) && OrderSymbol() == Symbol() && OrderMagicNumber() == Magic)
       {
        if(i == 0)
         {
          bestMaxPrice = OrderOpenPrice();
          bestMinPrice = OrderOpenPrice();
          continue;
         }
        bestMaxPrice = fmax(bestMaxPrice, OrderOpenPrice());
        bestMinPrice = fmin(bestMinPrice, OrderOpenPrice());
       }
     }
  }
 
Alexey Viktorov:
Можно ввести две переменные, bestMaxPrice и bestMinPrice и получать их по ссылке. Тогда за один проход в цикле можно будет получить и максимальную и минимальную цену открытых ордеров.

void Best_Price(double & bestMaxPrice, double & bestMinPrice)
  {
    for(int i = 0; i < OrdersTotal(); i++)
     {
      if(OrderSelect(i, SELECT_BY_POS) && OrderSymbol() == Symbol() && OrderMagicNumber() == Magic)
       {
        if(i == 0)
         {
          bestMaxPrice = OrderOpenPrice();
          bestMinPrice = OrderOpenPrice();
          continue;
         }
        bestMaxPrice = fmax(bestMaxPrice, OrderOpenPrice());
        bestMinPrice = fmin(bestMinPrice, OrderOpenPrice());
       }
     }
  }

Алексей, мне нужно самую низкую и самую высокую цену именно с привязкой к типу ордера - самая низкая из OP_BUY и самая высокая из OP_SELL, а не из общей массы всех ордеров. 

 
Vitaliy Hudyakov:

Алексей, мне нужно самую низкую и самую высокую цену именно с привязкой к типу ордера - самая низкая из OP_BUY и самая высокая из OP_SELL, а не из общей массы всех ордеров. 

В общем-то это пример как получить из функции больше 1 исходящего значения.

Дальше не сложно объединить с тем что ты уже сделал и получится оптимальный код.
 
//+----------------поиск мин цены ордера----------------------------------------+
double findminprise(int otype,int magik)
  {
   double oldopenprise=0;
   double prise=9999;
   for(int i=OrdersTotal()-1; i>=0; i--)
     {
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
        {
         if(OrderSymbol()==Symbol() && OrderMagicNumber()==magik && OrderType()==otype)
            oldopenprise=OrderOpenPrice();
         if(oldopenprise<prise)
            prise=OrderOpenPrice();

        }
     }
   return(prise);
  }
//+----------------поиск макс цены ордера----------------------------------------+
double findmaxprise(int otype,int magik)
  {
   double oldopenprise=0;
   double prise=0;
   for(int i=OrdersTotal()-1; i>=0; i--)
     {
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
        {
         if(OrderSymbol()==Symbol() && OrderMagicNumber()==magik && OrderType()==otype)
            oldopenprise=OrderOpenPrice();
         if(oldopenprise>prise)
            prise=OrderOpenPrice();

        }
     }
   return(prise);
  }
 
Aleksey Semenov:
Да ужжж... Для каждой операции свой цикл по всем ордерам это жесть...
 
Alexey Viktorov:
Да ужжж... Для каждой операции свой цикл по всем ордерам это жесть...
ой что вы, это очень древние функции, они стары как мир, но для начинающих - очень простые и понятные вещи, сейчас все норм программисты уже перешли на массивы, когда одна функция с одним циклом переборки ордеров выдаёт всё что тебе нужно - верхние, нижние, последние, первые, по баям или селам, средневзвешенные цены открытия/тейка/стопа, наличие/отсутствие этото тейка/стопа, + ещё и отложники тамже считаются и учтитываются
 

Сделал сам, благодарю всех за помощь!

Может кому будет нужно:

//+------------------------------------------------------------------+
//| Наибольшая/наименьшая цена среди открытых ордеров по типу        |
//+------------------------------------------------------------------+
double Best_Price(int ot=-1)
  {
   double orders_best_price = 0;
  
   for(int i=OrdersTotal()-1;i>=0;i--)
     {
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
        {
         if(OrderSymbol()==Symbol() && OrderMagicNumber()==Magic)
           {
            if(OrderType()==0 && ot==0)                  // можно добавить проверку среди отложек, которые еще не сработали и стоят на графике
              {
               if (orders_best_price == 0) orders_best_price = OrderOpenPrice();
               if (OrderOpenPrice() < orders_best_price) orders_best_price = OrderOpenPrice();
              }

            if(OrderType()==1 && ot==1)                  // можно добавить проверку среди отложек, которые еще не сработали и стоят на графике
              {
               if (orders_best_price == 0) orders_best_price = OrderOpenPrice();
               if (OrderOpenPrice() > orders_best_price) orders_best_price = OrderOpenPrice();
              }
           }
        }
     }
   return(orders_best_price);
  }


 вызываем стандартно:

   double best_buy_price = Best_Price(0);
   double best_sell_price = Best_Price(1);


 

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