Учет ордеров

 
Привет всем! Столкнулся я с такой задачей где нужно считать данные последних, например пяти, открытых ордеров... Что-то я не соображу как правильно провести такой подсчет, подскажите кто-нибудь, будьте добры!
 
Maksim Neimerik:
Привет всем! Столкнулся я с такой задачей где нужно считать данные последних, например пяти, открытых ордеров... Что-то я не соображу как правильно провести такой подсчет, подскажите кто-нибудь, будьте добры!

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

#property strict

#define     ORDERS_ARRAY_SIZE          5

struct OrderInfo
{
   int         nTicket;
   datetime    dtTime;
   
   OrderInfo()
      : nTicket(-1)
      , dtTime(0)
   {
   }
   
   void Set(const int _nTicket, const datetime _dtTime)
   {
      nTicket = _nTicket;
      dtTime = _dtTime;
   }
};

void OnStart()
{
   OrderInfo arrstOrderInfo[ORDERS_ARRAY_SIZE];
   for (int i = OrdersTotal() - 1; i >= 0; --i)
   {  
      if (!OrderSelect(i, SELECT_BY_POS))
         continue;
         
      SaveOrder(arrstOrderInfo, OrderTicket(), OrderOpenTime());
   }
   
   Print(ORDERS_ARRAY_SIZE, " последних ордеров в порядке убывания времени открытия:");
   for (int i = 0; i < ORDERS_ARRAY_SIZE; ++i)
      Print("Ордер #", arrstOrderInfo[i].nTicket, ", время открытия: ", TimeToString(arrstOrderInfo[i].dtTime));
}

void SaveOrder(OrderInfo &arrstOrderInfo[], const int nTicket, const datetime dtTime)
{
   for (int i = 0; i < ORDERS_ARRAY_SIZE; ++i)
   {
      if (dtTime < arrstOrderInfo[i].dtTime)
         continue;
         
      for (int j = ORDERS_ARRAY_SIZE - 1; j > i; --j)
         arrstOrderInfo[j] = arrstOrderInfo[j - 1];
         
      arrstOrderInfo[i].Set(nTicket, dtTime);
      return;
   }
}
Документация по MQL5: Константы, перечисления и структуры / Торговые константы / Свойства позиций
Документация по MQL5: Константы, перечисления и структуры / Торговые константы / Свойства позиций
  • www.mql5.com
Тикет позиции. Уникальное число, которое присваивается каждой вновь открытой позиции. Как правило, соответствует тикету ордера, в результате которого она была открыта, за исключением случаев изменения тикета в результате служебных операций на сервере. Например, начисления свопов переоткрытием позиции. Для нахождения ордера, которым была открыта...
 
Maksim Neimerik:
Привет всем! Столкнулся я с такой задачей где нужно считать данные последних, например пяти, открытых ордеров... Что-то я не соображу как правильно провести такой подсчет, подскажите кто-нибудь, будьте добры!

очередная задачка на сортировку структур

универсальное решение от @fxsaber https://www.mql5.com/ru/forum/170952/page134#comment_11532251

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

 

берем понравившийся способ сортировки из статьи https://www.mql5.com/ru/articles/3118

и правим под свои нужды - объявим имя поля в структуре, которую будем сортировать по этому полю как SortedValue

код:

template<typename T>
void BubbleSortForStruct(T &a[])
{
   for (int flag_swapped = -1, sz = ArraySize(a)-1, i = 0; i < sz; i++, flag_swapped = -1)
   {
      for (int j = 0; j < sz - i; j++)
      {
         if (a[j].SortedValue > a[j + 1].SortedValue)
         {
            T tmp = a[j];
            a[j] = a[j + 1];
            a[j + 1] = tmp;
            flag_swapped = 1;
         }
      }
      if (flag_swapped < 0) break;
   }
}

struct SDataSorted
{
   int SortedValue;  // datetime SortedValue;
   int ticket;
   double open_price;
};
//+------------------------------------------------------------------+
void OnStart()
{
   SDataSorted orders[5];
// инициализация
   for(int i = ArraySize(orders) - 1; i >= 0; i--)
   {
      orders[i].open_price = orders[i].SortedValue = orders[i].ticket = rand();
   }

   Print("Not sorted array :");
   ArrayPrint(orders);
   BubbleSortForStruct(orders);
   Print("Sorted :");
   ArrayPrint(orders);
}

результат:

2020.12.09 21:11:59.340 tst1 (EURUSD,H1) Not sorted array :

2020.12.09 21:11:59.340 tst1 (EURUSD,H1)     [SortedValue] [ticket] [open_price]

2020.12.09 21:11:59.340 tst1 (EURUSD,H1) [0]         25084    25084  25084.00000

2020.12.09 21:11:59.340 tst1 (EURUSD,H1) [1]          7315     7315   7315.00000

2020.12.09 21:11:59.340 tst1 (EURUSD,H1) [2]         30312    30312  30312.00000

2020.12.09 21:11:59.340 tst1 (EURUSD,H1) [3]         17049    17049  17049.00000

2020.12.09 21:11:59.340 tst1 (EURUSD,H1) [4]          4493     4493   4493.00000

2020.12.09 21:11:59.340 tst1 (EURUSD,H1) Sorted :

2020.12.09 21:11:59.340 tst1 (EURUSD,H1)     [SortedValue] [ticket] [open_price]

2020.12.09 21:11:59.340 tst1 (EURUSD,H1) [0]          4493     4493   4493.00000

2020.12.09 21:11:59.340 tst1 (EURUSD,H1) [1]          7315     7315   7315.00000

2020.12.09 21:11:59.340 tst1 (EURUSD,H1) [2]         17049    17049  17049.00000

2020.12.09 21:11:59.340 tst1 (EURUSD,H1) [3]         25084    25084  25084.00000

2020.12.09 21:11:59.340 tst1 (EURUSD,H1) [4]         30312    30312  30312.00000


все работает, для таких задач как у ТС - достаточно объявить одно поле в любой структуре с именем SortedValue - любого типа и применить к массиву таких структур функцию BubbleSortForStruct()

 
Igor Makanu:

берем понравившийся способ сортировки из статьи https://www.mql5.com/ru/articles/3118

и правим под свои нужды - объявим имя поля в структуре, которую будем сортировать по этому полю как SortedValue

код:

результат:



все работает, для таких задач как у ТС - достаточно объявить одно поле в любой структуре с именем SortedValue - любого типа и применить к массиву таких структур функцию BubbleSortForStruct()

Чем в 4ке  можно заменить) Сходу не соображу)

ArrayPrint
 
Valeriy Yastremskiy:

Чем в 4ке  можно заменить) Сходу не соображу)

ArrayPrint

увы, ничем - только самому распринтовать массив, как обычно в цикле

 
Igor Makanu:

увы, ничем - только самому распринтовать массив, как обычно в цикле

спс, это могу)

 

Я со структурами как-то не дружу. Надо конечно заняться этим вопросом, но пока написал вот так:

double LastOrders(int number,int numberorders)
{
   if(number>numberorders)
   {
      Print("Запрашиваемый ордер не входит в диапазон ордеров!");
      return(-1);
   }
   double res[];
   datetime t1[];
   for(int z=0;z<numberorders;z++)
   {
      ArrayResize(t1,z+1,1000);
      double OOP=0;
      datetime t=0;
      for(int i=OrdersTotal()-1;i>=0;i--)
      {
         if(OrderSelect(i,SELECT_BY_POS))
         {
            if(OrderSymbol()==Symbol())
            {
               if(OrderMagicNumber()==Magic)
               {
                  ArraySort(t1,WHOLE_ARRAY,0,MODE_DESCEND);
                  int t2=ArrayBsearch(t1,OrderOpenTime(),WHOLE_ARRAY,0,MODE_DESCEND);
                  if(OrderOpenTime()==t1[t2])continue;
                  if(OrderOpenTime()>t)
                  {
                     t=OrderOpenTime();
                     t1[z]=t;
                     OOP=OrderOpenPrice();
                  }
               }
            }
         }
      }
      ArrayResize(res,z+1,1000);
      res[z]=OOP;
   }
   return(res[number-1]);
}

Прокомментируйте пожалуйста...

 
Maksim Neimerik:

Я со структурами как-то не дружу. Надо конечно заняться этим вопросом, но пока написал вот так:

Прокомментируйте пожалуйста...

ну, как обычно, накидали портянок на элементарный вопрос....

а так чо?

      calcOR=5;

      maxOR=OrdersTotal()-1;

      minOR=maxOR-calcOR;

      for(i=maxOR; i>=minOR; i--)
      {
         if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))

         {

         .....

         }

     }
 
Renat Akhtyamov:

а так чо?

Мне нужно именно 5 последних ордеров... На сколько я знаю такой код не гарантирует выбор именно последних ордеров, иначе зачем при простом выборе одного последнего ордера ордера используют переменную типа datetime?

Вот к примеру выбор цены последнего ордера:

double LastPrice(int mode,int magic)
{
   double res=0;
   datetime t=0;
   for(int i=OrdersTotal()-1;i>=0;i--)
   {
      if(OrderSelect(i,SELECT_BY_POS))
      {
         if(OrderSymbol()==Symbol()&&OrderMagicNumber()==magic&&OrderOpenTime()>t)
         {
            if(OrderType()==mode||mode==-1)
            {
               res=OrderOpenPrice();
               t=OrderOpenTime();
            }
         }
      }
   }
   return(res);
}


 

Документация по MQL5: Основы языка / Типы данных / Целые типы / Тип datetime
Документация по MQL5: Основы языка / Типы данных / Целые типы / Тип datetime
  • www.mql5.com
Константы даты и времени могут быть представлены в виде литеральной строки, которая состоит из 6 частей, представляющих числовое значение года, месяца, числа (либо числа, месяца, года), часа, минуты и секунды. Константа обрамляется...
 
Maksim Neimerik:

Мне нужно именно 5 последних ордеров... На сколько я знаю такой код не гарантирует выбор именно последних ордеров, иначе зачем при простом выборе одного последнего ордера ордера используют переменную типа datetime?

Вот к примеру выбор цены последнего ордера:
 

а если проверить?