По моей просьбе MetaQutoes полностью локализовала последнее обновление библиотеки на английский язык. Последняя сборка библиотеки теперь доступна на английской странице с комментариями в исходном коде, переведенными на английский язык.
Это отличается от предыдущей версии, которая была доступна на англоязычной странице.
// Список изменений:// 02.11.2018// Исправление: теперь цена открытия позиции в MT4 не может быть нулевой до ее срабатывания.// Исправление: учтены некоторые редкие аспекты исполнения некоторых торговых серверов.// 26.11.2018// Исправление: Магия и комментарий закрытой позиции MT4: приоритет соответствующих полей для открывающих сделок выше, чем для закрывающих.// Исправление: редкие изменения в MT5-OrdersTotal и MT5-PositionsTotal учитываются при расчете MT4-OrdersTotal и MT4-OrderSelect.// Исправление: Библиотека не учитывала ордера, которые открыли позицию, но еще не были удалены из MT5.// 17.01.2019// Исправление: Исправлена досадная ошибка при выборе отложенных ордеров.// 08.02.2019// Добавление: Комментарий позиции сохраняется при частичном закрытии через OrderClose.// Если вам нужно изменить комментарий к открытой позиции при частичном закрытии, вы можете указать его в OrderClose.// 20.02.2019// Исправление: В случае отсутствия ордера MT5, библиотека будет ожидать синхронизации истории от существующей транзакции MT5. В случае неудачи она сообщит об этом.// 13.03.2019// Добавление: Добавлена функция OrderTicketID() - идентификатор позиции сделки MT5 или позиции MT5, а также тикет отложенного ордера MT4.// Добавьте: SELECT_BY_TICKET работает для всех тикетов MT5 (и MT5-PositionID).// 02.11.2019// Исправление: исправлены лот, комиссия и цена закрытия для позиций CloseBy.// 12.01.2020// Исправление: OrderTicketID() для сделок с балансом теперь возвращает корректное значение.// Исправление: Исправлен SELECT_BY_TICKET - выбор по OrderTicketID() (MT5-PositionID).// Исправление: изменено название метода внутренней библиотеки для большей совместимости с макросами.// 10.04.2020// Исправление: частично исполненный живой отложенный ордер не попадал в OrdersTotal().// 09.06.2020// Добавление: StopLoss/TakeProfit/ClosePriceRequest для закрытых позиций теперь лучше определены.// 10.06.2020// Добавление: Добавлены миллисекунды, удалено округление цены и ордера в OrderPrint().// 13.08.2020// Добавление: Добавлена возможность проверки работоспособности частей библиотеки с помощью макроса MT4ORDERS_BENCHMARK_MINTIME.// 20.08.2020// Фикс: Учет выявленных особенностей выполнения частичных заказов.// 29.08.2020// Исправление: Реализована более быстрая работа с историей сделок.// 24.09.2020// Добавить: Если вам нужно увеличить приоритет ордера MT5 над позицией MT5 при выборе ордера MT4 по SELECT_BY_TICKET (те же самые билеты),// это можно сделать, изменив размер билета на отрицательный: OrderSelect(-Ticket, SELECT_BY_TICKET).// Добавить: Если вам нужно указать выбор только MT5-ордера при модификации живого MT4-ордера (те же тикеты),// это можно сделать, изменив размер билета на отрицательный: OrderModify(-Ticket, ...).// Добавляем: OrderSelect(INT_MAX, SELECT_BY_POS) - переключение на позицию MT5 без проверки существования и обновления.// OrderSelect(INT_MIN, SELECT_BY_POS) - переключение на живой ордер MT5 без проверки существования и обновления.// Исправление: Реализована более быстрая работа с историей сделок.// 30.09.2020// Исправление: Реализована более быстрая работа с историей сделок.// 08.10.2020// Исправление: OrderSend рыночного ордера мог выполняться дольше из-за недостатка в свежем поиске сделок в MT5.// 21.10.2020// Добавление: Для обеспечения совместимости с MT4 добавлена функция OrderTicketID() - возвращает OrderTicket().// 11.11.2020// Исправление: OrderTicketID() и OrderTicketOpen() возвращают тип значения, указанный в TICKET_TYPE.// 06.12.2020// Исправление: Теперь учитываются случаи некорректных записей об исполнении SL/TP в истории торговли MT5.// Добавление: Рынок MT4ORDERS_TESTER_SELECT_BY_TICKET заставляет SELECT_BY_TICKET работать в тестере только через OrderTicketID().// 04.05.2021// Исправление: Ордера MT5, которые открывают позиции и не исчезают, больше не добавляются в список ордеров MT4.// Исправление: ордера CloseBy MT5 больше не отображались в списке ордеров MT4.// 12.05.2021// Добавить: Макрос MT4ORDERS_BYPASS_MAXTIME изменяет постоянно возникающие случаи рассинхронизации торговых сред в MT5.// 13.05.2021// Исправление: Исправлена ошибка в функции OrderOpenReason().// 14.05.2021// Исправление: механизм BYPASS больше не влияет на OrderSelect(INT_MAX, SELECT_BY_POS) и OrderSelect(INT_MIN, SELECT_BY_POS).// 01.06.2021// Исправление: Совместимость с компилятором сборки 2449 и выше.// Исправление: улучшена синхронизация. ByPass.mqh должен быть последней версии.// Добавляем: OrderLots(true) - синхронизированный размер выбранной позиции, учитывающий все ордера, которые закрывают эту позицию.
Я рекомендую использовать последнюю версию вместе с механизмом синхронизации. Тогда все проблемы, которые не может решить ни одна торговая библиотека, будут незаметны.
#define MT4ORDERS_BYPASS_MAXTIME 1000000// Максимальное время (в микросекундах) ожидания синхронизации торговой среды#include <MT4Orders.mqh> // https://www.mql5.com/en/code/16006
Чтобы механизм заработал, необходимо скачать эту библиотеку. Все сложные и эффективные проверки корректности работы торговой среды будут выполняться автоматически, не отвлекая пользователя при написании торговой логики.
Сломали! Не рекомендую обновлять MT5. Кто понимает, помогите объяснить, что прежнее поведение MT5 было правильным. Сейчас - нет.
Печально.
Если не вернут как было, то можно сделать костыль. Я навскидку набросал код, как можно отследить вставку ордера в историю и обновить ее в классе TradesID только на "сдвинутом" периоде + не более 100 позиций истории, т.е. малой кровью.
НЕ тестировал код, плюс он конечно, неоптимален - просто демонстрация идеи. (желтым - что изменено к вашему оригиналу)
//примерная идея отслеживания вставки ордеров и кэш истории//!!не отслеживает удаление или изменения номеров тикетов//на основе Trades ID#include "Classificator.mqh"class TRADESID
{
CLASSIFICATOR<ulong, ulong> OrdersID;
CLASSIFICATOR<ulong, ulong> DealsID;
int LastTotalOrders;
int LastTotalDeals;
//тикеты ордера на каждой сотой позиции в историиulong OrderTickets[];void RefreshOrders(void)
{
staticulong LastOrderTicket = -1; //тикет ордера, взятого из предыдущего проходаif(::HistorySelect(0, INT_MAX))
{
constint Total = ::HistoryOrdersTotal();
if(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);
}
while(this.LastTotalOrders < Total)
{
constulong Ticket = LastOrderTicket = ::HistoryOrderGetTicket(this.LastTotalOrders); //(this.LastTotalOrders++)//для каждой сотой позиции истории добавляем тикет в массивif(LastTotalOrders++ % 100 == 0)
OrderTickets[::ArrayResize(OrderTickets, ::ArraySize(OrderTickets) + 1) - 1] = Ticket;
constulong PositionID = ::HistoryOrderGetInteger(Ticket, ORDER_POSITION_ID);
if(PositionID)
{
this.OrdersID.Add(PositionID, Ticket);
constulong PositionBy = ::HistoryOrderGetInteger(Ticket, ORDER_POSITION_BY_ID);
if(PositionBy)
this.OrdersID.Add(PositionBy, Ticket);
}
}
}
return;
}
};
Отследить удаление/изменения ордеров намного сложнее, но это и ваша библа не решала.
Конечно, для подобной корректировки ByPASS и MT4HISTORY нужен алгоритм понавороченнее, но ничего сложного, кажется нет (пока не изучил их).
Если не вернут как было, то можно сделать костыль. Я навскидку набросал код, как можно отследить вставку ордера в историю и обновить ее в классе TradesID только на "сдвинутом" периоде + не более 100 позиций истории, т.е. малой кровью.
НЕ тестировал код, плюс он конечно, неоптимален - просто демонстрация идеи. (желтым - что изменено к вашему оригиналу)
Если правильно понял идею, Вы ищите сотню, в которой произошел сдвиг. Но не понял, как находится после этого в этой сотне сам новый Ticket. Особенно, если их несколько и они лежат в разных сотнях.
Отследить удаление/изменения ордеров намного сложнее, но это и ваша библа не решала.
Не понял. Что именно не отслеживается? Предлагаю пока остановиться на b2958.
Если идет речь про правку истории задним числом - это не стоит того. Не занудства ради все же создаются решения, а для торговли.
Конечно, для подобной корректировки ByPASS и MT4HISTORY нужен алгоритм понавороченнее, но ничего сложного, кажется нет (пока не изучил их).
Проблема в том, что чем больше вызывается штатных функций на каждом проходе, тем выше вероятность лага. Советник начинает подвешиваться. Несколько советников - еще хуже. Когда же несколько терминалов - совсем плохо. Тормозит даже приход OnTradeTransaction - например, OrderSend начинает выдавать время в несколько раз больше пинга. Помимо того, что костыль предполагает дикую по скурпулезности отладку, так и еще он будет создавать лаги. Представьте только, что во время перебора история обновилась и т.д. Там огромное количество багов будет вылезать.
Ведь главное, что все идеально работало. Просто поломали на ровном месте и никак не комментируют.
ЗЫ Для меня загадка, почему почти никто не понимает, о чем идет речь.
Если правильно понял идею, Вы ищите сотню, в которой произошел сдвиг. Но не понял, как находится после этого в этой сотне сам новый Ticket. Особенно, если их несколько и они лежат в разных сотнях.
Если произшли только вставки без удаления, то цикл
ищет начало самой ранней сотни, в которой произошли вставки. Сам тикет искать не надо - надо просто заново пройти все ордера, начиная с этой сотни и следущие (более новые), и добавить их в хэшмэп. Это делается как обычно в цикле while(this.LastTotalOrders < Total). Почти всегда это будет 1-2 последних сотни.
Может быть лучше уменьшить шаг - не по 100, а по 40 или по 20.
На случай, если во время for история изменится - что-то вставится ДО найденной сотни, то можно вложить в цикл:
void RefreshOrders(void)
{
staticulong 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);
}
constint Total = ::HistoryOrdersTotal();
while(this.LastTotalOrders < Total)
{
constulong Ticket = LastOrderTicket = ::HistoryOrderGetTicket(this.LastTotalOrders);
//для каждой сотой позиции истории добавляем тикет в массивif(LastTotalOrders++ % 100 == 0)
OrderTickets[::ArrayResize(OrderTickets, ::ArraySize(OrderTickets) + 1) - 1] = Ticket;
constulong PositionID = ::HistoryOrderGetInteger(Ticket, ORDER_POSITION_ID);
if(PositionID)
{
this.OrdersID.Add(PositionID, Ticket);
constulong PositionBy = ::HistoryOrderGetInteger(Ticket, ORDER_POSITION_BY_ID);
if(PositionBy)
this.OrdersID.Add(PositionBy, Ticket);
}
}
}
return;
}
Если произшли только вставки без удаления, то цикл
ищет начало самой ранней сотни, в которой произошли вставки. Сам тикет искать не надо - надо просто заново пройти все ордера, начиная с этой сотни и следущие (более новые), и добавить их в хэшмэп. Это делается как обычно в цикле while(this.LastTotalOrders < Total). Почти всегда это будет 1-2 последних сотни.
Т.е. использовать, что повторное добавление в хэшмэп одного и того же тикета не поменяет хэшмэп?
У меня ордера попадали и в восьмую сотню. При активной торговле это рядовое явление с новыми билдами. В таком случае надо хэшмэпить несколько сотен ордеров.
Т.е. использовать, что повторное добавление в хэшмэп одного и того же тикета не поменяет хэшмэп?
Да, только сейчас заметил - если добавить тикет OrdersID.Add(PositionID, Ticket) повторно, то в OrdersID.ValuesID[] этот тикет задвоится. Т.е. хэшмэп будет разбухать.
Нужно как-то делать проверку. Или использвать для VALUESID не структуру с массивом, а HashSet. Или что-то аналогичное.
Для авторизации и пользования сайтом MQL5.com необходимо разрешить использование файлов Сookie.
Пожалуйста, включите в вашем браузере данную настройку, иначе вы не сможете авторизоваться.
Вы вошли в аккаунт. Двухфакторная аутентификация отключена. Настройте её заново и отсканируйте новый QR-код или продолжите с отключённой двухфакторной аутентификацией.
Форум о трейдинге, автоматизированных торговых системах и тестировании торговых стратегий
Библиотеки: MT4Orders
fxsaber, 2021.06.02 10:09
По моей просьбе MetaQutoes полностью локализовала последнее обновление библиотеки на английский язык. Последняя сборка библиотеки теперь доступна на английской странице с комментариями в исходном коде, переведенными на английский язык.
Это отличается от предыдущей версии, которая была доступна на англоязычной странице.
Я рекомендую использовать последнюю версию вместе с механизмом синхронизации. Тогда все проблемы, которые не может решить ни одна торговая библиотека, будут незаметны.
Чтобы механизм заработал, необходимо скачать эту библиотеку. Все сложные и эффективные проверки корректности работы торговой среды будут выполняться автоматически, не отвлекая пользователя при написании торговой логики.
MT4Orders (+ByPass) работает только с HistorySelect(0, INT_MAX), поэтому не создает текущих проблем с добавлением только что удаленных отложек в конец таблицы истории (+синхронизация).
Сломали! Не рекомендую обновлять MT5. Кто понимает, помогите объяснить, что прежнее поведение MT5 было правильным. Сейчас - нет.
Сломали! Не рекомендую обновлять MT5. Кто понимает, помогите объяснить, что прежнее поведение MT5 было правильным. Сейчас - нет.
Печально.
Если не вернут как было, то можно сделать костыль. Я навскидку набросал код, как можно отследить вставку ордера в историю и обновить ее в классе TradesID только на "сдвинутом" периоде + не более 100 позиций истории, т.е. малой кровью.
НЕ тестировал код, плюс он конечно, неоптимален - просто демонстрация идеи. (желтым - что изменено к вашему оригиналу)
Отследить удаление/изменения ордеров намного сложнее, но это и ваша библа не решала.
Конечно, для подобной корректировки ByPASS и MT4HISTORY нужен алгоритм понавороченнее, но ничего сложного, кажется нет (пока не изучил их).
Также можно отслеживать транзакции TRADE_TRANSACTION_HISTORY_UPDATE и TRADE_TRANSACTION_HISTORY_DELETE, как вы писали:
https://www.mql5.com/ru/forum/366029/page2#comment_22442705
Если они дадут номер тикета, и ордера в истории отсортированы по тикету, то положение ордера в истории легко отследить через массив OrderTickets.
P.S. на крайняк, можно еще HashMap добавить...
Печально.
Если не вернут как было, то можно сделать костыль. Я навскидку набросал код, как можно отследить вставку ордера в историю и обновить ее в классе TradesID только на "сдвинутом" периоде + не более 100 позиций истории, т.е. малой кровью.
НЕ тестировал код, плюс он конечно, неоптимален - просто демонстрация идеи. (желтым - что изменено к вашему оригиналу)
Если правильно понял идею, Вы ищите сотню, в которой произошел сдвиг. Но не понял, как находится после этого в этой сотне сам новый Ticket. Особенно, если их несколько и они лежат в разных сотнях.
Отследить удаление/изменения ордеров намного сложнее, но это и ваша библа не решала.
Не понял. Что именно не отслеживается? Предлагаю пока остановиться на b2958.
Если идет речь про правку истории задним числом - это не стоит того. Не занудства ради все же создаются решения, а для торговли.
Конечно, для подобной корректировки ByPASS и MT4HISTORY нужен алгоритм понавороченнее, но ничего сложного, кажется нет (пока не изучил их).
Проблема в том, что чем больше вызывается штатных функций на каждом проходе, тем выше вероятность лага. Советник начинает подвешиваться. Несколько советников - еще хуже. Когда же несколько терминалов - совсем плохо. Тормозит даже приход OnTradeTransaction - например, OrderSend начинает выдавать время в несколько раз больше пинга. Помимо того, что костыль предполагает дикую по скурпулезности отладку, так и еще он будет создавать лаги. Представьте только, что во время перебора история обновилась и т.д. Там огромное количество багов будет вылезать.
Ведь главное, что все идеально работало. Просто поломали на ровном месте и никак не комментируют.
ЗЫ Для меня загадка, почему почти никто не понимает, о чем идет речь.
ЗЫ Для меня загадка, почему почти никто не понимает, о чем идет речь.
Потому что никто не пытался реализовать работу с ордерами в МТ5 а) легко, б) правильно и в) быстро. В том числе, я.
Если правильно понял идею, Вы ищите сотню, в которой произошел сдвиг. Но не понял, как находится после этого в этой сотне сам новый Ticket. Особенно, если их несколько и они лежат в разных сотнях.
Если произшли только вставки без удаления, то цикл
ищет начало самой ранней сотни, в которой произошли вставки. Сам тикет искать не надо - надо просто заново пройти все ордера, начиная с этой сотни и следущие (более новые), и добавить их в хэшмэп. Это делается как обычно в цикле while(this.LastTotalOrders < Total). Почти всегда это будет 1-2 последних сотни.
Может быть лучше уменьшить шаг - не по 100, а по 40 или по 20.
На случай, если во время for история изменится - что-то вставится ДО найденной сотни, то можно вложить в цикл:
Но это будет очень редко.
Если произшли только вставки без удаления, то цикл
ищет начало самой ранней сотни, в которой произошли вставки. Сам тикет искать не надо - надо просто заново пройти все ордера, начиная с этой сотни и следущие (более новые), и добавить их в хэшмэп. Это делается как обычно в цикле while(this.LastTotalOrders < Total). Почти всегда это будет 1-2 последних сотни.
Т.е. использовать, что повторное добавление в хэшмэп одного и того же тикета не поменяет хэшмэп?
У меня ордера попадали и в восьмую сотню. При активной торговле это рядовое явление с новыми билдами. В таком случае надо хэшмэпить несколько сотен ордеров.
Т.е. использовать, что повторное добавление в хэшмэп одного и того же тикета не поменяет хэшмэп?
Да, только сейчас заметил - если добавить тикет OrdersID.Add(PositionID, Ticket) повторно, то в OrdersID.ValuesID[] этот тикет задвоится. Т.е. хэшмэп будет разбухать.
Нужно как-то делать проверку. Или использвать для VALUESID не структуру с массивом, а HashSet. Или что-то аналогичное.