Библиотеки: MT4Orders - страница 61

 
fxsaber:

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


Если произшли только вставки без удаления, то цикл

for(i = ArraySize(OrderTickets) - 1; i >= 0 && OrderTickets[i] !=::HistoryOrderGetTicket(i * 100) ; i--)
               ;

ищет начало самой ранней сотни, в которой произошли вставки. Сам тикет искать не надо - надо  просто заново пройти все ордера, начиная с этой сотни и следущие (более новые), и добавить их в хэшмэп. Это делается как обычно в цикле    while(this.LastTotalOrders < Total).  Почти всегда это будет 1-2 последних сотни.

Может быть лучше уменьшить шаг - не по 100, а по 40 или по 20.

На случай, если во время for история изменится - что-то вставится ДО найденной сотни, то можно вложить в цикл:

 void              RefreshOrders(void)
     {
      static ulong LastOrderTicket = -1;     //тикет ордера, взятого из предыдущего прохода

      if(::HistorySelect(0, INT_MAX))
        {
         // надо добавить проверку на IsStopped и на макс время выполнения
         while(this.LastTotalOrders > 0 && LastOrderTicket != ::HistoryOrderGetTicket(this.LastTotalOrders - 1))
           {
            int i;
            //проверка каждого сотого тикета в обратном порядке
            for(i = ArraySize(OrderTickets) - 1; i >= 0 && OrderTickets[i] !=::HistoryOrderGetTicket(i * 100) ; i--)
               ;
            if(i < 0)
               LastTotalOrders = 0;
            else
              {LastTotalOrders = i * 100 + 1; LastOrderTicket = OrderTickets[i];}
            ArrayResize(OrderTickets, i + 1);
            ::HistorySelect(0, INT_MAX);
           }

         const int Total = ::HistoryOrdersTotal();

         while(this.LastTotalOrders < Total)
           {
            const ulong Ticket = LastOrderTicket = ::HistoryOrderGetTicket(this.LastTotalOrders);

            //для каждой сотой позиции истории добавляем тикет в массив
            if(LastTotalOrders++ % 100 == 0)
               OrderTickets[::ArrayResize(OrderTickets, ::ArraySize(OrderTickets) + 1) - 1] = Ticket;


            const ulong PositionID = ::HistoryOrderGetInteger(Ticket, ORDER_POSITION_ID);

            if(PositionID)
              {
               this.OrdersID.Add(PositionID, Ticket);

               const ulong PositionBy = ::HistoryOrderGetInteger(Ticket, ORDER_POSITION_BY_ID);

               if(PositionBy)
                  this.OrdersID.Add(PositionBy, Ticket);

              }
           }
        } 
      return;
     }

Но это будет очень редко.

 
mktr8591:

Если произшли только вставки без удаления, то цикл

ищет начало самой ранней сотни, в которой произошли вставки. Сам тикет искать не надо - надо  просто заново пройти все ордера, начиная с этой сотни и следущие (более новые), и добавить их в хэшмэп. Это делается как обычно в цикле    while(this.LastTotalOrders < Total).  Почти всегда это будет 1-2 последних сотни.

Т.е. использовать, что повторное добавление в хэшмэп одного и того же тикета не поменяет хэшмэп?

У меня ордера попадали и в восьмую сотню. При активной торговле это рядовое явление с новыми билдами.  В таком случае надо хэшмэпить несколько сотен ордеров.

 
fxsaber:

Т.е. использовать, что повторное добавление в хэшмэп одного и того же тикета не поменяет хэшмэп?


Да, только сейчас заметил - если  добавить тикет OrdersID.Add(PositionID, Ticket) повторно, то в OrdersID.ValuesID[] этот тикет задвоится. Т.е. хэшмэп будет разбухать.

Нужно как-то делать проверку. Или использвать для VALUESID не структуру  с массивом, а HashSet. Или что-то аналогичное.

 
fxsaber:

У меня ордера попадали и в восьмую сотню. При активной торговле это рядовое явление с новыми билдами.  В таком случае надо хэшмэпить несколько сотен ордеров.

Но это же не каждые 15 минут происходит?
 
mktr8591:
Но это же не каждые 15 минут происходит?

Да.

 

Для тех, кто использует эту связку.

Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий

Библиотеки: MT4Orders

fxsaber, 2021.05.12 21:58

#define MT4ORDERS_BYPASS_MAXTIME 1000000 // Максимальное время (в мкс.) на ожидание синхронизации торгового окружения
#include <MT4Orders.mqh> // https://www.mql5.com/ru/code/16006

Рекомендую обновить синхронизатор.

Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий

Библиотеки: TradesID

fxsaber, 2021.06.30 15:53

Обновлен ByPass.mqh. Отрабатывает правильно ситуацию удаления частично исполненного ордера. Добавлено логирование при возникновении проблем.

Пока не исправили, рекомендую работать на b2958.

 
fxsaber:

Прошу прояснить несколько моментов по коду MT4Orders.mqh (от 2021.06.01):

1.  line 1413 HistoryDealSelect2():
else if (::HistoryDealGetInteger(DealTicket, DEAL_TIME_MSC) < OrderTimeFill)
            break;

здесь прерывается цикл по истории если время сделки меньше времени ордера.

Не бывает ли на практике так, что время сделки в мск меньше времени ордера, который сделка исполнила (я не имею в виду ситуации, когда ордер исполнился сразу несколькими сделками) ?

2. line 2259 MT4OrderSend():

return((arrow_color == INT_MAX) ? (MT4ORDERS::NewOrderCheck() ? 0 : -1) :
           ((((int)arrow_color != INT_MIN) || MT4ORDERS::NewOrderCheck()) &&
            MT4ORDERS::OrderSend(MT4ORDERS::LastTradeRequest, MT4ORDERS::LastTradeResult)
          #ifdef MT4ORDERS_BYPASS_MAXTIME
            && (!MT4ORDERS::IsHedging || _B2(MT4ORDERS::ByPass += MT4ORDERS::LastTradeResult.order))
          #endif // #ifdef MT4ORDERS_BYPASS_MAXTIME
                                                                                          ?
            (MT4ORDERS::IsHedging ? (long)MT4ORDERS::LastTradeResult.order : // PositionID == Result.order - особенность MT5-Hedge
             ((MT4ORDERS::LastTradeRequest.action == TRADE_ACTION_DEAL) ?
              (MT4ORDERS::IsTester ? (_B2(::PositionSelect(MT4ORDERS::LastTradeRequest.symbol)) ? PositionGetInteger(POSITION_TICKET) : 0) :
                                      // HistoryDealSelect в MT4ORDERS::OrderSend
                                      ::HistoryDealGetInteger(MT4ORDERS::LastTradeResult.deal, DEAL_POSITION_ID)) :
              (long)MT4ORDERS::LastTradeResult.order)) : -1));

Почему для неттинга ордер не добавляется в MT4ORDERS::ByPass+= ?

3.  В некоторых функциях  вы используете макрос WHILE(A)  : line 1088

#define WHILE(A) while ((!(Res = (A))) && MT4ORDERS::Waiting())

Почему вы не делаете проверку на IsStopped()?  Для оптимизации времени ?  А если вдруг пользователь задаст  OrderSend_MaxPause в несколько секунд?

4. Обратил внимание, что перед OrderSend(LastTradeRequest, LastTradeResult) вы не делаете очистку LastTradeResult. Это делает сама функция? Типа недокументированная возможность?

 
mktr8591:

Прошу прояснить несколько моментов по коду MT4Orders.mqh (от 2021.06.01):

1.  line 1413 HistoryDealSelect2():

здесь прерывается цикл по истории если время сделки меньше времени ордера.

Не бывает ли на практике так, что время сделки в мск меньше времени ордера, который сделка исполнила (я не имею в виду ситуации, когда ордер исполнился сразу несколькими сделками) ?

Вырвали сильно из контекста. Посмотрите, где вызывается HistoryDealSelect2. Там находится Result.deal, когда он нулевой при исполненном полностью Result.order. По времени ограничение для экономии. прохода по циклу. Возможно, проверял на большой истории вопрос. Не помню уже. Сам не использую встроенный синхронизатор в OrderSend, т.к. беру нулевой MT4ORDERS::OrderSend_MaxPause.

 
mktr8591:

2. line 2259 MT4OrderSend():

Почему для неттинга ордер не добавляется в MT4ORDERS::ByPass+= ?

Не продумывал ByPass для неттинга. Для себя же пишу.
 
mktr8591:

3.  В некоторых функциях  вы используете макрос WHILE(A)  : line 1088

Почему вы не делаете проверку на IsStopped()?  Для оптимизации времени ?  А если вдруг пользователь задаст  OrderSend_MaxPause в несколько секунд?

На практике не вижу здесь проблемы. Не добавлял точно не из-за забывчивости.