Какой-то хитро закрученный вопрос, навтыкал интересные конструкции, если скажешь неправильно сделал - скажет , я знаю, просто мне так удобнее. Лучше промолчать :)
Вопрос простой:
Привести РАБОТАЮЩИЙ пример закрытия нескольких (например, 20-ть) ордеров.
Привести РАБОТАЮЩИЙ пример закрытия нескольких (например, 20-ть) ордеров.
//+------------------------------------------------------------------+ //| CloseAll.mq4 | //| Copyright © 2005, Irtron | //+------------------------------------------------------------------+ #property copyright "Copyright © 2005, Irtron" #include <WinUser32.mqh> #include <utilities.mqh> #define TRADE_TIMEOUT 1000 int start() { if (MessageBox("Close all orders immediately?", "Close All?", MB_YESNO | MB_ICONQUESTION) != IDYES) return(1); int total = OrdersTotal(); int left = total; while (left > 0 && !IsStopped()) { for (int i = left - 1; i >= 0; i--) { if (!OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) { PrintError("OrderSelect", GetLastError()); continue; } double closePrice = 0.; if (OrderType() == OP_BUY) closePrice = MarketInfo(OrderSymbol(), MODE_BID); else if (OrderType() == OP_SELL) closePrice = MarketInfo(OrderSymbol(), MODE_ASK); if (closePrice != 0.) { if (OrderClose(OrderTicket(), OrderLots(), closePrice, 50, Violet)) continue; PrintError(StringConcatenate(OrderTicket(), ", ", Symbol(), Period(), ", OrderClose"), GetLastError()); } } Sleep(TRADE_TIMEOUT); left = OrdersTotal(); } return (total); }
Не закрыть ордер, а удалить его - ошибся в формулировке.
Но я думаю, что пример можно переработать. Но, простого ожидания
Sleep(TRADE_TIMEOUT);
иногда не достаточно.
Проблема в том, что "OrderDelete" иногда проглатывается терминалом. Происходит заклинивание на каком-нибудь ордере.
Как отловить и избежать этого?
Вставил проверку после удаления на наличие ордера
Но я думаю, что пример можно переработать. Но, простого ожидания
Sleep(TRADE_TIMEOUT);
иногда не достаточно.
Проблема в том, что "OrderDelete" иногда проглатывается терминалом. Происходит заклинивание на каком-нибудь ордере.
Как отловить и избежать этого?
Вставил проверку после удаления на наличие ордера
int _OrderTicket = OrderTicket() ticket = OrderDelete(OrderTicket()); for (m = 0; m < 10; m++) { if (OrderSelect(_OrderTicket, SELECT_BY_TICKET, MODE_TRADES)) Sleep(1000); }
OrderSelect всегда выдает true, не зависимо от того удалился ордер или операция повисла.
Т.е в историю из trading pool удаленный орде переносится, похоже, не сразу.
Как же проверить, что ордер действительно удален?
Не закрыть ордер, а удалить его - ошибся в формулировке.
Ну вот, стараешься, блин, стараешься...
Но я думаю, что пример можно переработать.
Можно и просто разработать.
Но, простого ожидания
Sleep(TRADE_TIMEOUT);
иногда не достаточно.
Проблема в том, что "OrderDelete" иногда проглатывается терминалом. Происходит заклинивание на каком-нибудь ордере.
Как отловить и избежать этого?
Sleep(TRADE_TIMEOUT);
иногда не достаточно.
Проблема в том, что "OrderDelete" иногда проглатывается терминалом. Происходит заклинивание на каком-нибудь ордере.
Как отловить и избежать этого?
Скрипт не завершает работу, пока не останется ни одного ордера. Не зависимо от того, что проглатывается или не проглатывается терминалом, какие трейдконтекстбизи, таймауты, семафоры и прочие нелепости происходят.
Скрипт не завершает работу, пока не останется ни одного ордера.
Т.е. работает бесконечно, при заклинивании (невозможности удалить какой-нибудь ордер)?
Хотелось бы увидет вариант и разъяснения квотовцев, а то они скромно молчат.
Скрипт не завершает работу, пока не останется ни одного ордера.
Т.е. работает бесконечно, при заклинивании (невозможности удалить какой-нибудь ордер)?
Хотелось бы увидет вариант и разъяснения квотовцев, а то они скромно молчат.
Хотелось бы увидеть небо в алмазах :)
А что, у квотовцев логика совсем неземная? Хотя, судя по советам, как торговать с семафорами и таймаутами, чтобы заставить торговый движок работать хоть с какой-то отличной от нуля вероятностью, очень может быть. Даже есть последователи, придумывающие более "изящные" варианты, а по сути, более изощренные извращения :)
Вам нужно закрыть все ордера. Скрипт и пытается это сделать. Даже при "заклинивании".
Скрипт можно закрыть вручную примерно за две с половиной секунды. Все ошибки трассируются.
Вы сами-то при заклинивании ордера в ручном режиме что будете делать? Наверное, так же, как и скрипт, пытаться закрыть его еще раз.
Вы упускаете торговые возможности:
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Регистрация
Вход
Вы принимаете политику сайта и условия использования
Если у вас нет учетной записи, зарегистрируйтесь
Делаю в цикле:
int _OrdersTotal = OrdersTotal();
for (cnt=0; cnt < _OrdersTotal; cnt++)
{
OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);
ticket = OrderDelete(OrderTicket());
}
если использую номер cnt
OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);
то, после удаления ордера, номера оставшихся ордеров меняются и не соответствуют cnt
а если использую 0
OrderSelect(0, SELECT_BY_POS, MODE_TRADES);
то терминал дважды пытается закрыть один и тот же ордер - не ждет окончания OrderDelete.