Обсуждение статьи "Библиотека для простого и быстрого создания программ для MetaTrader (Часть XXXIV): Отложенные торговые запросы - удаление ордеров, модификация ордеров и позиций по условиям" - страница 2

 
Artyom Trishkin:
Да, так и будет. Потому что там изменился подход к хранению данных аккаунта. Об этом написано в конце статьи в качестве предупреждения:
-----
Для справки:
Поскольку мы изменили структуру объекта счета (изменили размер массивов uchar для хранения строковых свойств счета и добавили еще одно целочисленное свойство), все ранее сохраненные файлы объектов счета больше не будут загружаться корректно. Если они находятся в общей папке терминалов в каталоге \Files\DoEasy\Accounts\, то их необходимо удалить перед запуском этого тестового советника - они будут заново созданы при переходе от одного счета к другому с новым размером структуры объектов.
-----

Я удалил все BIN-файлы счетов в общей папке, чтобы убедиться, что ваш код загружается полностью. Он загружается без ошибки `CAccount::Load` (но основная проблема была в неправильном игнорировании событий и все еще существует).

Затем я открыл несколько сделок вручную и закрыл их скриптом как можно быстрее. И снова получил эту ошибку:

CEventsCollection::CreateNewEvent, Line 768: Это событие уже есть в списке

Мы знаем, что эти события были от закрытия разных позиций в MT4, но код `движка` не может этого понять. Способен ли вообще движок понять несколько закрытий сделок/событий за короткое время?


Вот все сообщения журнала:

2020.08.21 21:23:50.604 mhdbzr-34 AUDCAD,H1: OnDoEasyEvent: Позиция закрыта

2020.08.21 21:23:50.600 mhdbzr-34 AUDCAD,H1: - Позиция закрыта: 2020.08.21 19:51:47.000 -.

AUDCAD Закрыта покупка #573142748 по цене 0.94405, Прибыль -0.22 USD

2020.08.21 21:23:50.368 Скрипт CloseTradesFast4Test AUDCAD,H1: удален

2020.08.21 21:23:50.364 CloseTradesFast4Test AUDCAD,H1: uninit reason 0

2020.08.21 21:23:50.364 CloseTradesFast4Test AUDCAD,H1: close #573142747 buy 0.01 AUDCAD at 0.94404 at price 0.94375

2020.08.21 21:23:50.148 mhdbzr-34 AUDCAD,H1: OnDoEasyEvent: Позиция закрыта

2020.08.21 21:23:50.146 mhdbzr-34 AUDCAD,H1: - Позиция закрыта: 2020.08.21 19:51:47.000 -...

AUDCAD Закрыта покупка #573142748 по цене 0.94405, Прибыль -0.22 USD

2020.08.21 21:23:49.942 CloseTradesFast4Test AUDCAD,H1: close #573142748 buy 0.01 AUDCAD at 0.94405 at price 0.94376

2020.08.21 21:23:49.725 mhdbzr-34 AUDCAD,H1: CEventsCollection::CreateNewEvent, Line 768: Это событие уже есть в списке

2020.08.21 21:23:49.520 CloseTradesFast4Test AUDCAD,H1: close #573142752 buy 0.01 AUDCAD at 0.94406 at price 0.94376

2020.08.21 21:23:49.257 mhdbzr-34 AUDCAD,H1: OnDoEasyEvent: Позиция закрыта

2020.08.21 21:23:49.255 mhdbzr-34 AUDCAD,H1: - Позиция закрыта: 2020.08.21 19:51:52.000 -.

AUDCAD Закрыто Продать #573142755 по цене 0.94366, Прибыль -0.37 USD

2020.08.21 21:23:49.086 CloseTradesFast4Test AUDCAD,H1: close #573142755 sell 0.01 AUDCAD at 0.94366 at price 0.94414

2020.08.21 21:23:48.815 mhdbzr-34 AUDCAD,H1: OnDoEasyEvent: Позиция закрыта

2020.08.21 21:23:48.812 mhdbzr-34 AUDCAD,H1: - Позиция закрыта: 2020.08.21 19:51:53.000 -...

AUDCAD Закрыта Продажа #573142757 по цене 0.94366, Прибыль -0.37 USD

2020.08.21 21:23:48.661 CloseTradesFast4Test AUDCAD,H1: close #573142756 sell 0.01 AUDCAD at 0.94366 at price 0.94415

2020.08.21 21:23:48.352 mhdbzr-34 AUDCAD,H1: OnDoEasyEvent: Позиция закрыта

2020.08.21 21:23:48.350 mhdbzr-34 AUDCAD,H1: - Позиция закрыта: 2020.08.21 19:51:53.000 -.

AUDCAD Закрыто Продать #573142757 по цене 0.94366, Прибыль -0.37 USD

2020.08.21 21:23:48.237 CloseTradesFast4Test AUDCAD,H1: close #573142757 sell 0.01 AUDCAD at 0.94366 at price 0.94415

2020.08.21 21:23:47.537 CloseTradesFast4Test AUDCAD,H1: initialized

2020.08.21 21:23:47.520 Скрипт CloseTradesFast4Test AUDCAD,H1: успешно загружен

2020.08.21 21:23:31.762 Автоматическая торговля включена

 
Mohammad Bazrkar :

Я удалил все BIN-файлы аккаунта в общей папке, чтобы убедиться, что ваш код загрузился полностью. Он загружается без ошибки `CAccount::Load` (но основная проблема заключалась в неправильном игнорировании событий и все еще существует).

Затем я открыл несколько сделок вручную и закрыл их скриптом как можно быстрее. И снова получил эту ошибку:

CEventsCollection::CreateNewEvent, Line 768: Это событие уже есть в списке

Мы знаем, что эти события были от закрытия разных позиций в MT4, но код `движка` не может этого понять. Способен ли вообще движок понять несколько закрытий сделок/событий за короткое время?

Пожалуйста, опишите шаг за шагом, что вы делаете, чтобы получить эту ошибку.

 
Artyom Trishkin:

Пожалуйста, опишите шаг за шагом, что вы делаете, чтобы получить эту ошибку.

Я модифицировал код вашего советника, чтобы он получал только события. (Я прикрепил модифицированную версию в предыдущих сообщениях, она называется `mhdbzr-34`)

  1. Запустите советник, чтобы начать наблюдение.
  2. открыть несколько сделок на покупку/продажу на демо-счете с теми же лотами, быстро (быстро нажимая на кнопку buy/sell на графике).
  3. запустите скрипт, чтобы закрыть эти сделки как можно быстрее. (название моего скрипта `CloseTradesFast4Test`)
  4. проверьте сообщения журнала, вы увидите, что движок пропустил закрытие некоторых позиций, вероятно, с тем красным сообщением об ошибке, которое я написал здесь.
 
Mohammad Bazrkar :

Я модифицировал код вашего советника, чтобы он получал только события. (Я прикрепил модифицированную версию в предыдущих сообщениях, она называется `mhdbzr-34`)

  1. Запустите советник, чтобы начать наблюдение.
  2. открыть несколько сделок на покупку/продажу на демо-счете с теми же лотами, быстро (быстро нажимая на кнопку buy/sell на графике).
  3. запустите скрипт, чтобы закрыть эти сделки как можно быстрее. (название моего скрипта ` CloseTradesFast4Test` )
  4. Проверьте сообщения журнала, вы увидите, что движок пропустил закрытие некоторых позиций, вероятно, с тем красным сообщением об ошибке, которое я написал здесь.

Дайте свой скрипт для закрытия позиций.

 
Artyom Trishkin:

Дайте свой сценарий для закрытия позиций.

Вот код:

void OnStart()
{
   for(int i=OrdersTotal()-1; i>-1; i--)
   {
      if(!OrderSelect(i, SELECT_BY_POS, MODE_TRADES)){ continue; }
      if(OrderSymbol()!= _Symbol){ continue;}
      //--
      RefreshRates();
      int res = OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 100);
   }
}
 

вот еще один тест, на этот раз он не распознал закрытые позиции, в двух случаях пропустил их вместе с предыдущими.

2020.08.27 20:30:18.880 Expert mhdbzr-34 AUDCAD,H1: удалено

2020.08.27 20:30:18.869 mhdbzr-34 AUDCAD,H1: uninit reason 1

2020.08.27 20:28:35.617 mhdbzr-34 AUDCAD,H1: OnDoEasyEvent: Позиция закрыта

2020.08.27 20:28:35.617 mhdbzr-34 AUDCAD,H1: OnDoEasyEvent: Позиция закрыта

2020.08.27 20:28:35.617 mhdbzr-34 AUDCAD,H1: - Позиция закрыта: 2020.08.27 18:58:03.000 - AUDCAD Закрыта покупка #573721560 по цене 0.95218, Профит -2.29 USD

2020.08.27 20:28:35.614 mhdbzr-34 AUDCAD,H1: - Позиция закрыта: 2020.08.27 18:58:04.000 - AUDCAD Закрыта Покупка #573721562 по цене 0.95218, Прибыль -2.29 USD

2020.08.27 20:28:35.582 Скрипт CloseTradesFast4Test AUDCAD,H1: удален

2020.08.27 20:28:35.577 CloseTradesFast4Test AUDCAD,H1: uninit reason 0

2020.08.27 20:28:35.577 CloseTradesFast4Test AUDCAD,H1: close #573721560 buy 0.10 AUDCAD at 0.95218 at price 0.95188

2020.08.27 20:28:35.177 CloseTradesFast4Test AUDCAD,H1: close #573721562 buy 0.10 AUDCAD at 0.95218 at price 0.95188

2020.08.27 20:28:35.161 mhdbzr-34 AUDCAD,H1: OnDoEasyEvent: Позиция закрыта

2020.08.27 20:28:35.158 mhdbzr-34 AUDCAD,H1: - Позиция закрыта: 2020.08.27 18:58:06.000 - AUDCAD Закрыта продажа #573721573 по цене 0.95190, Профит -2.06 USD

2020.08.27 20:28:34.739 CloseTradesFast4Test AUDCAD,H1: close #573721571 buy 0.10 AUDCAD at 0.95224 at price 0.95191

2020.08.27 20:28:34.695 mhdbzr-34 AUDCAD,H1: OnDoEasyEvent: Позиция закрыта

2020.08.27 20:28:34.691 mhdbzr-34 AUDCAD,H1: - Позиция закрыта: 2020.08.27 18:58:06.000 - AUDCAD Закрыта продажа #573721573 по цене 0.95190, Профит -2.06 USD

2020.08.27 20:28:34.306 CloseTradesFast4Test AUDCAD,H1: close #573721573 sell 0.10 AUDCAD at 0.95190 at price 0.95217

2020.08.27 20:28:34.180 mhdbzr-34 AUDCAD,H1: OnDoEasyEvent: Позиция закрыта

2020.08.27 20:28:34.177 mhdbzr-34 AUDCAD,H1: - Позиция закрыта: 2020.08.27 18:58:09.000 - AUDCAD Закрыта продажа #573721582 по цене 0.95190, Профит -2.14 USD

2020.08.27 20:28:33.883 CloseTradesFast4Test AUDCAD,H1: close #573721577 sell 0.10 AUDCAD at 0.95190 at price 0.95217

2020.08.27 20:28:33.664 mhdbzr-34 AUDCAD,H1: OnDoEasyEvent: Позиция закрыта

2020.08.27 20:28:33.660 mhdbzr-34 AUDCAD,H1: - Позиция закрыта: 2020.08.27 18:58:09.000 - AUDCAD Закрыта продажа #573721582 по цене 0.95190, Профит -2.14 USD

2020.08.27 20:28:33.440 CloseTradesFast4Test AUDCAD,H1: close #573721582 sell 0.10 AUDCAD at 0.95190 at price 0.95218

2020.08.27 20:28:32.946 CloseTradesFast4Test AUDCAD,H1: initialized

2020.08.27 20:28:32.928 Скрипт CloseTradesFast4Test AUDCAD,H1: успешно загружен

2020.08.27 20:28:09.413 mhdbzr-34 AUDCAD,H1: OnDoEasyEvent: Позиция открыта

2020.08.27 20:28:09.411 mhdbzr-34 AUDCAD,H1: - Позиция открыта: 2020.08.27 18:58:09.000 - AUDCAD Opened 0.10 Sell #573721582 [0.10 Market-order Sell #573721582] at price 0.95190

2020.08.27 20:28:07.664 mhdbzr-34 AUDCAD,H1: OnDoEasyEvent: Позиция открыта

2020.08.27 20:28:07.659 mhdbzr-34 AUDCAD,H1: - Позиция открыта: 2020.08.27 18:58:07.000 - AUDCAD Opened 0.10 Sell #573721577 [0.10 Market-order Sell #573721577] at price 0.95190

2020.08.27 20:28:06.755 mhdbzr-34 AUDCAD,H1: OnDoEasyEvent: Позиция открыта

2020.08.27 20:28:06.752 mhdbzr-34 AUDCAD,H1: - Позиция открыта: 2020.08.27 18:58:06.000 - AUDCAD Opened 0.10 Sell #573721573 [0.10 Market-order Sell #573721573] at price 0.95190

2020.08.27 20:28:05.911 mhdbzr-34 AUDCAD,H1: OnDoEasyEvent: Позиция открыта

2020.08.27 20:28:05.909 mhdbzr-34 AUDCAD,H1: - Позиция открыта: 2020.08.27 18:58:05.000 - AUDCAD Opened 0.10 Buy #573721571 [0.10 Market-order Buy #573721571] at price 0.95224

2020.08.27 20:28:04.587 mhdbzr-34 AUDCAD,H1: OnDoEasyEvent: Позиция открыта

2020.08.27 20:28:04.582 mhdbzr-34 AUDCAD,H1: - Позиция открыта: 2020.08.27 18:58:04.000 - AUDCAD Opened 0.10 Buy #573721562 [0.10 Market-order Buy #573721562] at price 0.95218

2020.08.27 20:28:04.101 mhdbzr-34 AUDCAD,H1: OnDoEasyEvent: Позиция открыта

2020.08.27 20:28:04.099 mhdbzr-34 AUDCAD,H1: - Позиция открыта: 2020.08.27 18:58:03.000 - AUDCAD Opened 0.10 Buy #573721560 [0.10 Market-order Buy #573721560] at price 0.95218

2020.08.27 20:27:59.245 mhdbzr-34 AUDCAD,H1: initialized

2020.08.27 20:27:59.244 mhdbzr-34 AUDCAD,H1: Счет 13278180: mhdbzr test (Alpari) 5537.01 USD, 1:100, Hedge, Демо-счет MetaTrader 4

2020.08.27 20:27:49.794 Эксперт TestDoEasy\Part34\mhdbzr-34 AUDCAD,H1: успешно загружен

Я открыл эти сделки вручную на реальном рынке на демо-счете, не используя среду тестера. (и закрыл с помощью скрипта, как я делал раньше)

(вот скриншот, чтобы убедиться, что это произошло)

Файлы:
 
Mohammad Bazrkar :

Вот еще один тест; на этот раз он не распознал закрытые позиции, в двух случаях он пропустил их вместе с предыдущими.

Я открыл эти сделки вручную на реальном рынке на демо-счете, не используя среду тестера. (и закрыл скриптом, как и раньше).

(вот скриншот, чтобы убедиться, что это произошло)

Я ищу причину проблемы. Это не будет быстро. Спасибо за тесты.

 
Artyom Trishkin:

Я ищу причину проблемы. Это не будет быстро. Спасибо за тесты.

(вот мое мнение)

эти закрытые позиции находятся в одной секунде, одна из них обработана в предыдущем тике, поэтому в новом тике у него `new_history_orders=1`, но две позиции в `списке` и отсортированы, вероятно, неправильно, потому что у двух позиций одинаковое время закрытия в секунде.

            //--- Получите список закрытых позиций (EventsCollection.mqh строки 205-230)
            CArrayObj* list=this.GetListHistoryPositions(list_history);
            if(list!=NULL)
              {
               //--- Сортировка нового списка по времени закрытия позиции
               list.Sort(SORT_BY_ORDER_TIME_CLOSE);
               //--- Забираем из конца списка в цикле количество позиций, равное количеству новых закрытых позиций (последние N событий)
               int total=list.Total(), n=new_history_orders;
               for(int i=total-1; i>WRONG_VALUE && n>0; i--,n--)
                 {
                  //--- Получаем позицию из списка. Если это позиция, выполните поиск данных об открытии ордера и установите торговое событие
                  COrder* position=list.At(i);
                  if(position!=NULL && position.Status()==ORDER_STATUS_HISTORY_ORDER)
                    {
                     //--- Если есть управляющий приказ закрытого положения
                     COrderControl* ctrl=this.GetOrderControlByTicket(list_control,position.Ticket());
                     if(ctrl!=NULL)
                       {
                        //--- Установите (1) тип ордера, который привел к открытию позиции, и (2) идентификатор позиции, а также создайте событие закрытия позиции
                        this.m_type_first=(ENUM_ORDER_TYPE)ctrl.TypeOrder();
                        this.m_position_id=position.Ticket();
                        this.CreateNewEvent(position,list_history,list_market,list_control);
                       }
                    }
                 }
              }

Если ордер уже находится в списке и выдает сообщение об ошибке, то он удаляет объект позиции и возобновляет подсчет в этом цикле for, но я думаю, что он не должен считать n, когда ордер был удален внутрифункции CreateNewEvent , чтобы поймать следующую действительную позицию.

Также нам нужно понимать недавно обработанные позиции, чтобы пропустить неправильно отсортированные заказы и не вести отсчет по `n`.

 
Mohammad Bazrkar :

(вот мое мнение)

эти закрытые позиции находятся в одной секунде, одна из них обработана в предыдущем тике, поэтому в новом тике она имеет `new_history_orders =1`, но две позиции в `списке` и отсортированы, вероятно, неправильно, потому что два элемента имеют одинаковое время закрытия в секунде.

Если ордер уже находится в списке и выдает сообщение об ошибке, то он удаляет объект позиции и возобновляет подсчет в этом цикле for, но я думаю, что он не должен считать n, когда ордер был удален внутри функции CreateNewEvent , чтобы поймать следующую действительную позицию.

Также нам нужно понимать недавно обработанные позиции, чтобы пропустить неправильно отсортированные заказы и не вести отсчет по `n`.

Спасибо, я разберусь с этим.

 

Здравствуйте, Артем, я помню, как вы упоминали о будущей графической оболочке, когда я впервые читал эти статьи несколько недель назад... Не могли бы вы рассказать подробнее о вашем видении этого и о том, что это позволит нам делать на практике?