Вопрос в том, как закрыть позиции без перебора. Я думаю, если в mql есть функция трейлинга из mt, то и функция глобального закрытия должна быть где то, только не могу ее найти
Сейчас для закрытия позиций использую такую функцию. Измерять не приходится, когда начинается закрытие, видно что сильно отстает он инструмента mt. Может у вас есть на примере функция проще?
Это самый худший вариант. Попробуйте то-же самое, только без использования СБ. Будет чуток быстрей.
Потом вместо закрытия позиций открывайте противоположные таким-же лотом в асинхронном режиме. OrderSendAsync()
Про ошибку в цикле, идущем по возрастанию, уже объяснили выше. Использую у себя такой метод в классе, который отвечает за открытие/закрытие позиций. Он закрывает все позиции по одному символу с нужным магиком:
class CVirtualSymbolReceiver : public CReceiver {
staticulong s_magic;
string m_symbol; // Символ
CPositionInfo m_position; // Объект для получения свойств рыночных позиций
CTrade m_trade; // Объект для совершения торговых операций
...
};
...
//+------------------------------------------------------------------+//| Полное закрытие объёма по символу |//+------------------------------------------------------------------+bool CVirtualSymbolReceiver::CloseFull() {
bool res = true;
ulong ticket;
bool found = true;
while(found && !IsStopped()) {
found = false;
for(int i = 0; i < PositionsTotal(); i++) {
if (m_position.SelectByIndex(i)) {
if(m_position.Magic() == s_magic && (m_position.Symbol() == m_symbol)) {
found = true;
ticket = m_position.Ticket();
res &= m_trade.PositionClose(ticket);
break;
}
}
}
if(!res) {
found = false;
}
}
return res;
}
Если вам нужно просто закрыть абсолютно все позиции, то код можно упростить примерно так:
//+------------------------------------------------------------------+//| Полное закрытие всех позиций |//+------------------------------------------------------------------+void CloseFull() {
CTrade trade;
CPosition position;
ulong ticket;
bool found = true;
while(found && !IsStopped()) {
found = false;
for(int i = PositionsTotal() - 1; i >= 0; i--) {
if (position.SelectByIndex(i)) {
found = true;
ticket = position.Ticket();
trade.PositionClose(ticket);
}
}
}
}
В этой функции даже если какая-то операция закрытия закончится неудачно, все открытые позиции будут перебираться повторно, пока не будут закрыты все.
Непонятно, зачем полное закрытие и модификации делать синхронными торговыми приказами? Всегда используйте для этого асинхронку без каких-либо обработок транзакций.
А если внимательнее посмотреть? Оператор break там неспроста. Он прерывает цикл for, как только найдена первая подходящая для закрытия позиция. А дальше цикл while снова запускает for для поиска следующей одной позиции для закрытия. В этом случае действительно не важно, с какой стороны списка позиций начинать поиск. Такой метод продолжает работать корректно при одновременной работе на счёте нескольких советников и торговле руками - советник будет закрывать только свои позиции.
Во втором коде порядок изменён, так как надо точно закрыть все-все позиции.
А если внимательнее посмотреть? Оператор break там неспроста. Он прерывает цикл for, как только найдена первая подходящая для закрытия позиция. А дальше цикл while снова запускает for для поиска следующей одной позиции для закрытия. В этом случае действительно не важно, с какой стороны списка позиций начинать поиск. Такой метод продолжает работать корректно при одновременной работе на счёте нескольких советников и торговле руками - советник будет закрывать только свои позиции.
Во втором коде порядок изменён, так как надо точно закрыть все-все позиции.
Сейчас для закрытия позиций использую такую функцию. Измерять не приходится, когда начинается закрытие, видно что сильно отстает он инструмента mt. Может у вас есть на примере функция проще?
Это самый худший вариант. Попробуйте то-же самое, только без использования СБ. Будет чуток быстрей.
Потом вместо закрытия позиций открывайте противоположные таким-же лотом в асинхронном режиме. OrderSendAsync()
А какая разница? что в одну что в другую сторону смысл будет один, просто закрываться будет в другую сторону
А какая разница? что в одну что в другую сторону смысл будет один, просто закрываться будет в другую сторону
После закрытия позиции она уходит из списка открытых позиций. К примеру есть 2 открытые позиции.
m_position.SelectByIndex(0)Вернет первую позицию, которую закроет
После закрытия осталась 1 открытая позиция и
m_position.SelectByIndex(1)вернет ошибку. И выход из цикла. Но осталась отрытая позиция, которая будет закрываться при следующем тике.
Следовательно, на каждом тике у Вас будет закрываться только половина открытых позиций. Отсюда большое время закрытия большого количества позиций.
После закрытия позиции она уходит из списка открытых позиций. К примеру есть 2 открытые позиции.
Вернет первую позицию, которую закроет
После закрытия осталась 1 открытая позиция и
вернет ошибку. И выход из цикла. Но осталась отрытая позиция, которая будет закрываться при следующем тике.
Следовательно, на каждом тике у Вас будет закрываться только половина открытых позиций. Отсюда большое время закрытия большого количества позиций.
Спасибо за разьяснение, попробую изменить)
Про ошибку в цикле, идущем по возрастанию, уже объяснили выше.
Использую у себя такой метод в классе, который отвечает за открытие/закрытие позиций. Он закрывает все позиции по одному символу с нужным магиком:
Если вам нужно просто закрыть абсолютно все позиции, то код можно упростить примерно так:
В этой функции даже если какая-то операция закрытия закончится неудачно, все открытые позиции будут перебираться повторно, пока не будут закрыты все.
Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий
Как закрыть позиции без перебора в советнике?
Yuriy Bykov, 2024.04.10 14:51
Про ошибку в цикле, идущем по возрастанию, уже объяснили выше.
А если внимательнее посмотреть? Оператор break там неспроста. Он прерывает цикл for, как только найдена первая подходящая для закрытия позиция. А дальше цикл while снова запускает for для поиска следующей одной позиции для закрытия. В этом случае действительно не важно, с какой стороны списка позиций начинать поиск. Такой метод продолжает работать корректно при одновременной работе на счёте нескольких советников и торговле руками - советник будет закрывать только свои позиции.
Во втором коде порядок изменён, так как надо точно закрыть все-все позиции.
А если внимательнее посмотреть? Оператор break там неспроста. Он прерывает цикл for, как только найдена первая подходящая для закрытия позиция. А дальше цикл while снова запускает for для поиска следующей одной позиции для закрытия. В этом случае действительно не важно, с какой стороны списка позиций начинать поиск. Такой метод продолжает работать корректно при одновременной работе на счёте нескольких советников и торговле руками - советник будет закрывать только свои позиции.
Во втором коде порядок изменён, так как надо точно закрыть все-все позиции.
Смотрел невнимательно, признаюсь.