Как сделать перебор открытых позиций?

 
//+------------------------------------------------------------------+
//|                                                        proba.mq5 |
//|                        Copyright 2018, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2018, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---

//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---

  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   int _PositionsTotal=PositionsTotal();
   datetime _time;
   for(int i=0; i<_PositionsTotal; i++)
     {
      if(PositionSelect(_Symbol)==true)
         {
          _time=PositionGetInteger(POSITION_TIME);//
          Print(_time);
         }
      
     }
  }
//+------------------------------------------------------------------+


Как сделать перебор открытых позиций? К примеру я хочу знать время открытия каждой открытой позиции

В справке указано по поводу PositionSlect - При независимом представлении позиций (ACCOUNT_MARGIN_MODE_RETAIL_HEDGING) по каждому символу одновременно может быть открыто несколько позиций. В этом случае,

PositionSelect выберет позицию с наименьшим тикетом.

Как быть? 

 

Ну а в чем проблема-то ?

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

У меня это в МТ5 организовано следующим образом.

Через PositionsTotal() получаю количество позиций.

Затем, с помощью PositionGetTicket() собираю все тикеты в массив. Одновременно контролирую, чтобы исследуемая позиция была нужного символа, нужного магика (можно контролировать и другие параметры).

В результате - ты имеешь массив тикетов нужных позиций.

Далее, когда нужно работать с позицией - через PositionSelectByTicket() выбираешь нужный тикет, и получаешь необходимые данные.

Если тебе нужна одна позиция - и того проще - не надо собирать тикеты, просто перебираешь все, находишь нужную позицию, и получаешь с нее данные.

 
Georgiy Merts:

Ну а в чем проблема-то ?

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

В примере у меня организован цикл, где позиция выбирается функцией PositionSelect, но она согласна справке будет выбирать только ордер с наименьшим тикетом. Что я делаю неправильно?

 
Все понял ! спасибо! неправильно выбрал функцию выбора ордера
 

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

int _PositionsTotal=PositionsTotal();
   datetime _time;
   
   MqlRates mrate[1];
   if(CopyRates(_Symbol,_Period,0,1,mrate)<0) return;

     
   for(int i=0; i<_PositionsTotal; i++)
     {
      PositionSelectByTicket(PositionGetTicket(i));
      _time=PositionGetInteger(POSITION_TIME);
      Print(_time,"    ",mrate[0].time); 
            
     }
 
Tango_X:
***

Правильный способ обхода цикла, это от PositionsTotal()-1 к нулю:

   for(int i=PositionsTotal()-1;i>=0;i--) // returns the number of current positions


Почему это Важно: например если нужно какую-то (или все) позицию закрыть, то только метод обхода от PositionsTotal()-1 к нулю гарантирует, что ни одна позиция не будет пропущена. 

 
Tango_X:

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

Тебе нужно сравнивать текущее время или время текущего бара ? Это ж разные времена-то !

Время сравнивается напрямую, простым больше-меньше (для переменных типа datetime).

Для исключения секунд (или часов, или еще каких-то преобразований) - удобно сперва преобразовать время в структуру, потом сделать изменение, и потом - опять вернуть в datetime.

 
Tango_X:

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

В качестве времени я предлагаю брать TimeCurrent() - последнее известное время торгового сервера. В таком случае обход позиций (по-умолчанию стоит магик "0" - позиции открытые вручную) покажет сколько секунд назад была открыта позиция:

//+------------------------------------------------------------------+
//|                                                       Test_1.mq5 |
//|                              Copyright © 2018, Vladimir Karputov |
//|                                           http://wmua.ru/slesar/ |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2018, Vladimir Karputov"
#property link      "http://wmua.ru/slesar/"
#property version   "1.000"
#property script_show_inputs
//---
#include <Trade\PositionInfo.mqh>
CPositionInfo  m_position;                   // trade position object
//--- input parameters
input ulong   m_magic=0;                     // magic number
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
//---
   for(int i=PositionsTotal()-1;i>=0;i--) // returns the number of current positions
      if(m_position.SelectByIndex(i))     // selects the position by index for further access to its properties
         if(m_position.Symbol()==Symbol() && m_position.Magic()==m_magic)
           {
            datetime time_current=TimeCurrent();
            Print("Position ",m_position.Ticket()," was opened ",(int)(time_current-m_position.Time())," seconds ago");
           }
  }
//+------------------------------------------------------------------+


Пример вывода:

2018.06.21 18:33:55.539 Test_1 (GBPUSD,M1)      Position 269725675 was opened 67 seconds ago
Файлы:
Test_1.mq5  3 kb
 
Всем спасибо! обьяснили очень популярно, даже с вариантами)
 
Tango_X:

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

В этой строке

PositionSelectByTicket(PositionGetTicket(i));

достаточно оставить только

int ticket = PositionGetTicket(i);
Согласно документации
Функция возвращает тикет позиции по индексу в списке открытых позиций и автоматически выбирает эту позицию для дальнейшей работы с ней при помощи функций
 
Vladimir Karputov:

Правильный способ обхода цикла, это от PositionsTotal()-1 к нулю:


Почему это Важно: например если нужно какую-то (или все) позицию закрыть, то только метод обхода от PositionsTotal()-1 к нулю гарантирует, что ни одна позиция не будет пропущена. 

А почему проход в обратном направлении не гарантирует?
Причина обращения: