Здравствуйте. Для хранения истории ордеров использую следующую конструкцию, логику которой когда-то подсмотрел здесь на форуме.
Я вот о чем подумал. У пользователя стоял период истории счета "вся история". Допустим, в истории было 1000 ордеров. Потом ему захотелось поставить период истории счета "за последнюю неделю". После чего в истории стало 100 ордеров.
Когда было 1000 ордеров, соответственно значение переменной lastOrdersHistTotal равнялось 1000. Теперь OrdersHistoryTotal() вернет 100. Условие цикла index < OrdersHistoryTotal() больше не выполняется, новые ордера в массив не добавляются.
При смене периода истории счета пользователем в терминале, события init и deinit не генерируются.
Как избежать такой ситуации?
Выходов много: 1) очищать, обнулять, сбрасывать хранилище каждый раз 2) отказаться от хранения истории, потому что а) историю легко добыть из истории б) ну какая разница для будущей торговли что пол-месяца назад была совершена прибыльная или убыточная сделка? Трейдер набрался опыта, робот оптимизирован и получил другие параметры 3) смотреть дату последней сделки в хранилище и добавлять свежие, ориентируясь по дате вместо количества
1) Очищать слишком затратно. В таком случае нужно будет каждый раз "пробегаться" по всей истории. А в истории может быть не одна тысяча ордеров.
2.а) То-же самое, нужно будет каждый раз "пробегаться" по всей истории.
2.б) В моем случае разница есть.
3) Дату открытия или закрытия? Как узнать какие ордера являются свежими, используя дату последнего ордера в хранилище? Ордера в истории ордеров (account history) сортируются (могут быть отсортированы) неизвестным образом.
1) Очищать слишком затратно. В таком случае нужно будет каждый раз "пробегаться" по всей истории. А в истории может быть не одна тысяча ордеров.
2.а) То-же самое, нужно будет каждый раз "пробегаться" по всей истории.
2.б) В моем случае разница есть.
3) Дату открытия или закрытия? Как узнать какие ордера являются свежими, используя дату последнего ордера в хранилище? Ордера в истории ордеров (account history) сортируются (могут быть отсортированы) неизвестным образом.
У вас уже есть все значения, поэтому можно добавить ещё один if(...), и в нём делать простейшую проверку: Если в массиве количество больше чем в истории - выход, очищаем массив, и заполняем заново.
Очень просто. Добавлять в свою БД ордера из истории счета, которые имеют время закрытия, большее, чем время закрытия последнего ордера в БД.
Не пойму как это должно работать. Разве что, если условится, что ордера в истории счета отсортированы по времени закрытия? Но ведь нельзя быть в этом уверенным.
У вас уже есть все значения, поэтому можно добавить ещё один if(...), и в нём делать простейшую проверку: Если в массиве количество больше чем в истории - выход, очищаем массив, и заполняем заново.
Спасибо. Есть похожая идея. Подумаю, потестирую и напишу в эту ветку.
Не пойму как это должно работать. Разве что, если условится, что ордера в истории счета отсортированы по времени закрытия? Но ведь нельзя быть в этом уверенным.
Спасибо. Есть похожая идея. Подумаю, потестирую и напишу в эту ветку.
У меня это сделано немного по-другому, Я не вызываю на каждом тике, а только при изменении количества в истории/текущие. Если изменилось количество, то вызываем функцию, иначе нет смысла дергать на каждом тике
Примерно так:
int HT=OrdersHistoryTotal(); if(HT != TotalHist) { // Если изменилось количество TotalHist=HT; // Запомним новое значение GetHistory(); // Функция для заполнения }
У меня это сделано немного по-другому, Я не вызываю на каждом тике, а только при изменении количества в истории/текущие. Если изменилось количество, то вызываем функцию, иначе нет смысла дергать на каждом тике
Примерно так:
В GetHistory() каждый раз заново история заполняется, или только добавляются новые ордера?
В моем случае тоже история дописывается только при изменении количества ордеров в истории счета. Точнее, при увеличении количества. Управление перейдет в тело цикла, только если OrdersHistoryTotal() вернет значение больше, чем она вернула на предыдущем тике.
1) Очищать слишком затратно. В таком случае нужно будет каждый раз "пробегаться" по всей истории. А в истории может быть не одна тысяча ордеров.
2.а) То-же самое, нужно будет каждый раз "пробегаться" по всей истории.
О затратах времени на пробег по истории.
Случайно в одном из работающих в скриптов у меня нашлись отладочные данные по затратам времени на создание своих стейтментов, что также требует пробега по всей истории (MT5). Вот протоколы генерации стейтментов в моменты около полуночи, меня в первую очередь интересовало быстродействие, поэтому отметка времени в миллисекундах есть в каждой строке:
2018.02.28 00:00:11 Перед HistorySelect(0,TimeCurrent()) мс=0
2018.02.28 00:00:11 Перед ArrayResize(CB,i+1) мс=0
2018.02.28 00:00:11 Перед циклом занесения 428 тикетов мс=15
2018.02.28 00:00:11 После цикла занесения и упорядочивания 428 тикетов, мс=15
2018.02.28 00:00:11 После цикла заполнения всех свойств 428 тикетов, мс=31
2018.02.28 00:00:11 Перед плавающей прибылью мс=31
2018.02.28 00:00:11 Все, стейтмент записан на диск мс=78
2018.03.01 00:00:13 Перед HistorySelect(0,TimeCurrent()) мс=0
2018.03.01 00:00:13 Перед ArrayResize(CB,i+1) мс=0
2018.03.01 00:00:13 Перед циклом занесения 428 тикетов мс=0
2018.03.01 00:00:13 После цикла занесения и упорядочивания 428 тикетов, мс=16
2018.03.01 00:00:13 После цикла заполнения всех свойств 428 тикетов, мс=32
2018.03.01 00:00:13 Перед плавающей прибылью мс=32
2018.03.01 00:00:13 Все, стейтмент записан на диск мс=32
В первом случае видно, что работа скрипта приостанавливалась принудительно планировщиком потоков. Помню, ставил эксперименты по генерации стейтментов для 36 тысяч сделок, вышло намного меньше секунды (350 мс, кажется). Цифры 15-16, 32 характеризуют шаг системного таймера.
Не пойму как это должно работать. Разве что, если условится, что ордера в истории счета отсортированы по времени закрытия? Но ведь нельзя быть в этом уверенным.
Они там, действительно, не сортированы. Сортировка получается сама собой, т. к. новые ордера попадают в список позже других. Сортировка из списка в закладке истории счета никак не влияет на этот порядок. Проверьте. Я тоже был удивлен в свое время.
Отображение в закладке "История счета" влияет только на количество ордеров, которое будет получено в программе, но не на порядок их следования.
![MQL5 - Язык торговых стратегий для клиентского терминала MetaTrader 5](https://c.mql5.com/i/registerlandings/logo-2.png)
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования
Здравствуйте. Для хранения истории ордеров использую следующую конструкцию, логику которой когда-то подсмотрел здесь на форуме.
Я вот о чем подумал. У пользователя стоял период истории счета "вся история". Допустим, в истории было 1000 ордеров. Потом ему захотелось поставить период истории счета "за последнюю неделю". После чего в истории стало 100 ордеров.
Когда было 1000 ордеров, соответственно значение переменной lastOrdersHistTotal равнялось 1000. Теперь OrdersHistoryTotal() вернет 100. Условие цикла index < OrdersHistoryTotal() больше не выполняется, новые ордера в массив не добавляются.
При смене периода истории счета пользователем в терминале, события init и deinit не генерируются.
Как избежать такой ситуации?