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

 

Вопрос возник из  просторы алгоритма. 2 отложенных ордера по разные стороны от цены с параметром срок истечения ордера. Если один стал рыночным, другой удаляется. При открытии ордеров тикеты запоминаются в глобальные переменные. Всего по типам ордеров получается 6 переменных. Каждый раз в цикле искать нужный ордер показалось не лучшим и дорогим решением.

Прочитал на форуме, что тикеты существующих ордеров могут теряться или не находится.

Вопрос могут тикеты (SELECT_BY_TICKET) ордеров в МТ4 и тикеты сделок и позиций в МТ5 после выбора ордера / сделки / позиции ОрдерСелект  смениться со временем (измениться в терминале выбранный тикет). Например на следующий день. Советник не отключается.

Если отложенный ордер стал рыночным можно посмотреть по типу ордера. Если рыночный закрылся, то смотрим время закрытия ордера, не равно нулю OrderCloseTime()!=0

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

Не нашел запроса Время, когда отложенный ордер стал рыночным. Запрос Время открытия ордера OrderOpenTime возвращает время открытия отложенного ордера. На каждом тике смотреть тип ордера по тикету (так и делаю) и запоминать время как то костыли.

Есть другие решения?

int ticket=OrderSend(Symbol(),OP_BUY,1,price,3,stoploss,takeprofit,"My order",16384,0,clrGreen);

Вопрос, время срок истечения ордера есть и в рыночных ордерах(МТ4), работает, если там реальное время указать? 

 

Есть внутренняя статик структура ордера, доступ к полям которой делается через OrderOpenTime, OrderTakeProfit и т.д. функциии (статик-методы).

OrderSelect - заполнение этой структуры.

Соответственно, если OrderSelect не делать, то в ней никогда не поменяется информация.

 
fxsaber:

Есть внутренняя статик структура ордера, доступ к полям которой делается через OrderOpenTime, OrderTakeProfit и т.д. функциии (статик-методы).

OrderSelect - заполнение этой структуры.

Соответственно, если OrderSelect не делать, то в ней никогда не поменяется информация.

Спасибо, с этих позиций и хочу отказаться от цикла поиска.

Каким запросом из структуры ордера узнать произошло ли удаление отложенного ордера по сроку истечения?

На каждом тике смотрю по тикету тип ордера выбранного OrderSelect, если стал 0 или 1 значит стал рыночным. Что можно запросить из структуры ордера, что бы узнать что ордер стал историческим, не выполняя поиск по историческим ордерам? 

правка. Правильно ли понял. Делать OrderSelect по тикету среди Исторических ордеров?

Но только вопрос, можно ли с флагом выбора по тикету?

if(OrderSelect(Tickets, SELECT_BY_TICKET, MODE_HISTORY )==true) 
 

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

Для Оптимизатора скорость нужна. Так там все четко, как с кувалдой.

 
Valeriy Yastremskiy:

На каждом тике смотрю по тикету тип ордера выбранного OrderSelect, если стал 0 или 1 значит стал рыночным. 

Нет, имея тикет, ордер нельзя разделять по пулам. Он будет всегда выбран, если имеется среди рабочих или в истории счета. Чтобы понять, какому пулу принадлежит ордер, нужно запросить время закрытия. У рабочих оно равно нулю. Соответственно у закрытых/удаленных - больше нуля.

 
Valeriy Yastremskiy:

Спасибо, с этих позиций и хочу отказаться от цикла поиска.

Каким запросом из структуры ордера узнать произошло ли удаление отложенного ордера по сроку истечения?

На каждом тике смотрю по тикету тип ордера выбранного OrderSelect, если стал 0 или 1 значит стал рыночным. Что можно запросить из структуры ордера, что бы узнать что ордер стал историческим, не выполняя поиск по историческим ордерам? 

правка. Правильно ли понял. Делать OrderSelect по тикету среди Исторических ордеров?

Но только вопрос, можно ли с флагом выбора по тикету?

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

 
Artyom Trishkin:

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

не достаточно

месяц закончился история ордеров изменилась

брокер на новостях обрубил связь

..... даже не хочу придумывать ситуации

скорость OrderSelect() очень большая, что хранить структуры с ордерами (или массивы с тикетами), что использовать OrderSelect()  -разницы нет, даже в тестере МТ4, если и есть то очень незначительная , по крайне мере в ТС где число ордеров 1-5 , больше не делал в МТ4


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

 
Igor Makanu:

не достаточно

месяц закончился история ордеров изменилась

брокер на новостях обрубил связь

..... даже не хочу придумывать ситуации

скорость OrderSelect() очень большая, что хранить структуры с ордерами (или массивы с тикетами), что использовать OrderSelect()  -разницы нет, даже в тестере МТ4, если и есть то очень незначительная , по крайне мере в ТС где число ордеров 1-5 , больше не делал в МТ4


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

"месяц закончился история ордеров изменилась" как это противоречит проверке количества ордеров <сейчас - на прошлой проверке> ?

"брокер на новостях обрубил связь" как это противоречит проверке количества ордеров <сейчас - на прошлой проверке> ?

"скорость OrderSelect() очень большая, что хранить структуры с ордерами (или массивы с тикетами), что использовать OrderSelect()" где я говорил про структуры с ордерами и как это противоречит проверке количества ордеров <сейчас - на прошлой проверке> ?

"имхо, неоправданное усложнение кода только светит и скорее всего придется писать две версии - для тестера и для реала, чтобы ситуации все учесть" как это противоречит проверке количества ордеров <сейчас - на прошлой проверке> ?

Проверка количества "сейчас и на прошлой проверке" - это неоправданное усложнение кода? А мотать циклы на каждом тике вместо проверки необходимости их крутить - это оправдано для тестера и оптимизации?

Или вам нужно просто что-нибудь сказать против именно моих сообщений - ну тогда не буду отвлекать от развлечений. Продолжайте.
 
Artyom Trishkin:

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

То есть вариант одновременного удаления ордера из рабочих и открытия нового ордера не учитывается? 

Это еще не рассматривался вопрос изменения параметров существующих ордеров.

 
Ihor Herasko:

То есть вариант одновременного удаления ордера из рабочих и открытия нового ордера не учитывается? 

Это еще не рассматривался вопрос изменения параметров существующих ордеров.

Учитывается. Удалённый ордер попадает в историю - история меняется и меняется текущее состояние.

Удалили ордер: поменялся список рыночных ордеров и поменялся список истории

Открыли позицию - поменялся список рыночных ордеров, но список истории не изменился.

Кажется, что при одновременном выполнении таких действий всё остаётся в том же самом состоянии. Однако нет - меняется хэш-сумма. А так как мы сравниваем состояния двух списков по отдельности, то изменение любого из них требует проверить что же произошло. Нет желания расписывать алгоритм уже единожды реализованный, расписанный и опубликованный. Если конечно когда-нибудь мне сообщат, что алгоритм даёт сбои, то буду разбираться и дорабатывать. Но пока работает...

 

технический форум без единой строчки кода 

))))

вот проверил, что писал - время написания, ну минут 5 с перекурами вышло

void OnTick()
{
   while(OrdersTotal() < 10)
   {
      int cmd = rand() % 2 == 0 ? OP_BUY : OP_SELL;
      if(OrderSend(_Symbol, cmd, 0.1, cmd == OP_BUY ? Ask : Bid, 30, 0, 0) > 0) Sleep(50);
   }

   int count = 0;
   ulong t_start = GetMicrosecondCount();
   while(count < 1e6)
   {
      for(int i = OrdersTotal() - 1; i >= 0; i--)
      {
         if(OrderSelect(i, SELECT_BY_POS) && OrderSymbol() == _Symbol && OrderMagicNumber() == 0) count++;
      }
   }
   printf("count = %i, time = %f  second", count, double(GetMicrosecondCount() - t_start) / 1e6);
}
//+------------------------------------------------------------------+

на демосчете лог:

2020.06.05 20:35:45.503 tst_OrderSelect EURUSD,M1: count = 1000000, time = 0.115478  second

2020.06.05 20:35:45.387 tst_OrderSelect EURUSD,M1: count = 1000000, time = 0.117530  second

2020.06.05 20:35:45.269 tst_OrderSelect EURUSD,M1: count = 1000000, time = 0.123952  second

2020.06.05 20:35:45.145 tst_OrderSelect EURUSD,M1: count = 1000000, time = 0.117710  second

2020.06.05 20:35:44.997 tst_OrderSelect EURUSD,M1: count = 1000000, time = 0.113512  second

2020.06.05 20:35:43.341 tst_OrderSelect EURUSD,M1: count = 1000000, time = 0.115087  second

2020.06.05 20:35:41.375 tst_OrderSelect EURUSD,M1: count = 1000000, time = 0.116344  second

2020.06.05 20:35:41.166 tst_OrderSelect EURUSD,M1: count = 1000000, time = 0.114655  second

2020.06.05 20:35:40.590 tst_OrderSelect EURUSD,M1: count = 1000000, time = 0.120553  second

2020.06.05 20:35:40.349 tst_OrderSelect EURUSD,M1: count = 1000000, time = 0.113959  second

2020.06.05 20:35:40.022 tst_OrderSelect EURUSD,M1: count = 1000000, time = 0.114623  second

2020.06.05 20:35:39.908 tst_OrderSelect EURUSD,M1: count = 1000000, time = 0.113841  second

2020.06.05 20:35:39.794 tst_OrderSelect EURUSD,M1: count = 1000000, time = 0.113418  second

2020.06.05 20:35:39.680 tst_OrderSelect EURUSD,M1: count = 1000000, time = 0.116059  second

2020.06.05 20:35:39.564 tst_OrderSelect EURUSD,M1: count = 1000000, time = 0.113499  second

2020.06.05 20:35:39.450 tst_OrderSelect EURUSD,M1: count = 1000000, time = 0.119475  second

2020.06.05 20:35:36.684 tst_OrderSelect EURUSD,M1: count = 1000000, time = 0.113704  second

2020.06.05 20:35:34.418 tst_OrderSelect EURUSD,M1: count = 1000000, time = 0.116404  second

2020.06.05 20:35:34.276 tst_OrderSelect EURUSD,M1: count = 1000000, time = 0.118184  second

2020.06.05 20:35:31.661 tst_OrderSelect EURUSD,M1: count = 1000000, time = 0.120466  second

2020.06.05 20:35:31.541 tst_OrderSelect EURUSD,M1: count = 1000000, time = 0.117142  second




итого перебор по 10-ти ордерам по 1 млн раз (с учетом проверки символа и магика) занимает 0.11 секунды...ну как бы есть куда расти

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