Отличный ответ, Roger, но компьютер включен, метатрейдер тоже, советник прикреплен к графику, советники разрешены, сделки открываются и соответственно есть что тралить! А вот что в коде не так, в этом и заключался вопрос.
artmedia70: Используйте OrderOpenTime() Ибо - а нафига он нужен-то тогда?
Так то да, но по порядковому номеру у меня получилось довольно коротко а с OrderOpenTime я как-то не понимаю что делать, надо куда-то положить время открытия, сравнить со следующим ордером в списке, если время больше, переписать переменную итд. Не врубаюсь в алгоритм пока.
CreAndr: Отличный ответ, Roger, но компьютер включен, метатрейдер тоже, советник прикреплен к графику, советники разрешены, сделки открываются и соответственно есть что тралить! А вот что в коде не так, в этом и заключался вопрос.
Сначала кода не было, Вы его потом прикрепили.
Наверное потому не работает, что Вы засунули трейлинг в функцию открытия ордера, т.е условия по открытию ордера таки наступают, ордер открывается, а уж дальше может и не попасть.
Так то да, но по порядковому номеру у меня получилось довольно коротко а с OrderOpenTime я как-то не понимаю что делать, надо куда-то положить время открытия, сравнить со следующим ордером в списке, если время больше, переписать переменную итд. Не врубаюсь в алгоритм пока.
По порядковому номеру ненадежно, в этой нумерации никто ничего не гарантирует, только для тестера. Парой страниц ранее писал код для поиска последнего закрытого ордера, для открытых аналогично. Все просто, перебрали, запомнили тикет, потом выбрали ордер или позу по тикету вот и все:
int lastclosetime=-1;
int lastcloseticket=-1;
int lastdealtype=0;
for (int i=0; i<OrdersHistoryTotal(); i++)
{
if (!OrderSelect(i, SELECT_BY_POS, MODE_HISTORY)) continue;
if (OrderSymbol()==symbol || OrderMagicNumber()==magic)
{
if (lastclosetime<OrderCloseTime())
{
lastclosetime=OrderCloseTime();
lastcloseticket=OrderTicket();
}
}
}
if (OrderSelect(lastcloseticket, SELECT_BY_TICKET, MODE_HISTORY))
{
if (OrderType()==OP_BUY) lastdealtype=1;
if (OrderType()==OP_SELL) lastdealtype=-1;
}
По порядковому номеру ненадежно, в этой нумерации никто ничего не гарантирует, только для тестера. Парой страниц ранее писал код для поиска последнего закрытого ордера, для открытых аналогично. Все просто, перебрали, запомнили тикет, потом выбрали ордер или позу по тикету вот и все:
Спасибо, действительно все просто. Буду разбираться.
Наверное потому не работает, что Вы засунули трейлинг в функцию открытия ордера, т.е условия по открытию ордера таки наступают, ордер открывается, а уж дальше может и не попасть.
По порядковому номеру ненадежно, в этой нумерации никто ничего не гарантирует, только для тестера. Парой страниц ранее писал код для поиска последнего закрытого ордера, для открытых аналогично. Все просто, перебрали, запомнили тикет, потом выбрали ордер или позу по тикету вот и все:
Код неверный.
Во-первых вот это:
if (OrderSymbol()==symbol|| OrderMagicNumber()==magic)
Если символ ордера равен заданному символу в переменной symbol илимагик ордера равен магику magic... Значит, если будет выбран любой ордер с символом symbol, а магик будет другой или отсутствовать, то условие будет выполнено. Потому что илито илито... Соответственно нужно ставить ивместо или, а лучше разнести проверки в отдельные строки - цикл быстрее будет, что значимо для оптимизации.
Далее... Выбор по тикету: параметр pool игнорируется, т.е. его и писать-то тут бессмысленно.
if (OrderSelect(lastcloseticket, SELECT_BY_TICKET, MODE_HISTORY))
после успешного выбора ордера по тикету, необходимо проверить из какого списка ордеров он был выбран - из рыночных или из закрытых. Для этого нужно проверить время закрытия ордера и, если оно больше нуля, то ордер однозначно был закрытым. У открытых позиций этот параметр всегда равен нулю. ИМХО, после выбора последнего ордера нужно сразу проверить его тип и вписать его в переменную.
Теперь функция примет такой вид:
int GetTypeLastClosePos(int symbol, int magic) // Функция возвращает 0 если последний закрытый Бай, 1 - если Селл и -1 при ошибке
{
int i, lastclosetime=0,
lastdealtype=-1;
for (i=0; i<OrdersHistoryTotal(); i++) {
if (OrderSelect(i, SELECT_BY_POS, MODE_HISTORY)) { // Если выбрали ордер в историиif (OrderSymbol()!=symbol) continue; // Если его символ не равен переданному в функцию - идём к следующемуif (OrderMagicNumber()!=magic) continue; // Если его магик не равен переданному в функцию - идём к следующемуif (OrderType()>1) continue; // Если ищем только Бай и Селл, значит если больше единицы - к следующему// ... теперь выбранный ордер соответствует критериям поиска по символу, магику и типуif (lastclosetime<OrderCloseTime()) { // Посмотрим время его закрытия и если оно больше предыдущего, то...
lastclosetime=OrderCloseTime(); // ... запишем его как предыдущее
lastdealtype=OrderType(); // Тип текущего закрытого ордера: 0 для Бай, 1 для Селл
}
}
elseif (!OrderSelect(i, SELECT_BY_POS, MODE_HISTORY)) { // Иначе, если не удалось выбрать ордер в историиPrint ("Func: GetTypeLastClosePos, Ошибка выбора ордера - ",GetLastError()); // Посмотрим номер ошибкиbreak; // Выходим из цикла перебора ордеров
}
}
return(lastdealtype);
}
Теперь, чтобы проверить только Бай или Селл текущего графика и какой из них был последним закрытым, вызываем эту функцию таким образом:
int LastPoseType=GetTypeLastClosePos(Symbol(), Magic);
if (LastPoseType==OP_BUY) {
// ... код, если последний закрытый Buy ...
}
if (LastPoseType==OP_SELL) {
// ... код, если последний закрытый Sell ...
}
else {// ... код обработки ошибки ... }
Для обработки ошибки, в принципе, можно завести глобальную переменную, напр. int err; и в теле самой функции запоминать номер ошибки в этой переменной:
elseif (!OrderSelect(i, SELECT_BY_POS, MODE_HISTORY)) { // Иначе, если не удалось выбрать ордер в истории
err=GetLastError(); // Посмотрим номер ошибкиPrint ("Func: GetTypeLastClosePos, Ошибка выбора ордера - ",err); // Сообщим об ошибке и в какой ф-ции она произошлаbreak; // Выходим из цикла перебора ордеров
}
Тогда для обработки ошибки после вызова ф-ции ...
GetTypeLastClosePos(Symbol(), Magic);
... и возникновения ошибки, её номер будет находиться в переменной err и в блоке обработки этот номер обработать.
else {
if (err==???) {
// обработка этой ошибки
}
if (err==???) {
// обработка этой ошибки
}
// ... и т.д. ...
}
Для авторизации и пользования сайтом MQL5.com необходимо разрешить использование файлов Сookie.
Пожалуйста, включите в вашем браузере данную настройку, иначе вы не сможете авторизоваться.
Вы вошли в аккаунт. Двухфакторная аутентификация отключена. Настройте её заново и отсканируйте новый QR-код или продолжите с отключённой двухфакторной аутентификацией.
У меня вопрос по тралу, кто может подскажите. Вроде правильный трал в безубыток, а не работает.
Здесь есть трал: https://www.mql5.com/ru/forum/131859
Чтобы вставить в текст код, нажмите кнопочку SRC, которая находится над полем ввода текста.
Здесь есть трал: https://www.mql5.com/ru/forum/131859
Чтобы вставить в текст код, нажмите кнопочку SRC, которая находится над полем ввода текста.
Спасибо.
У меня вопрос по тралу, кто может подскажите. Вроде правильный трал в безубыток, а не работает.
Перечисление причин по мере убывания значимости:
1. Не включен компьютер
2. Не включен Метатрейдер
3. Не установлен скрипт на график
4. Не разрешены советники
5. Нечего тралить.
6. Что-то в коде не так.
Перечисление причин по мере убывания значимости:
1. Не включен компьютер
2. Не включен Метатрейдер
3. Не установлен скрипт на график
4. Не разрешены советники
5. Нечего тралить.
6. Что-то в коде не так.
Используйте OrderOpenTime()
Ибо - а нафига он нужен-то тогда?
Так то да, но по порядковому номеру у меня получилось довольно коротко а с OrderOpenTime я как-то не понимаю что делать, надо куда-то положить время открытия, сравнить со следующим ордером в списке, если время больше, переписать переменную итд. Не врубаюсь в алгоритм пока.
Отличный ответ, Roger, но компьютер включен, метатрейдер тоже, советник прикреплен к графику, советники разрешены, сделки открываются и соответственно есть что тралить! А вот что в коде не так, в этом и заключался вопрос.
Сначала кода не было, Вы его потом прикрепили.
Наверное потому не работает, что Вы засунули трейлинг в функцию открытия ордера, т.е условия по открытию ордера таки наступают, ордер открывается, а уж дальше может и не попасть.
Так то да, но по порядковому номеру у меня получилось довольно коротко а с OrderOpenTime я как-то не понимаю что делать, надо куда-то положить время открытия, сравнить со следующим ордером в списке, если время больше, переписать переменную итд. Не врубаюсь в алгоритм пока.
По порядковому номеру ненадежно, в этой нумерации никто ничего не гарантирует, только для тестера. Парой страниц ранее писал код для поиска последнего закрытого ордера, для открытых аналогично. Все просто, перебрали, запомнили тикет, потом выбрали ордер или позу по тикету вот и все:
По порядковому номеру ненадежно, в этой нумерации никто ничего не гарантирует, только для тестера. Парой страниц ранее писал код для поиска последнего закрытого ордера, для открытых аналогично. Все просто, перебрали, запомнили тикет, потом выбрали ордер или позу по тикету вот и все:
Сначала кода не было, Вы его потом прикрепили.
Наверное потому не работает, что Вы засунули трейлинг в функцию открытия ордера, т.е условия по открытию ордера таки наступают, ордер открывается, а уж дальше может и не попасть.
По порядковому номеру ненадежно, в этой нумерации никто ничего не гарантирует, только для тестера. Парой страниц ранее писал код для поиска последнего закрытого ордера, для открытых аналогично. Все просто, перебрали, запомнили тикет, потом выбрали ордер или позу по тикету вот и все:
Код неверный.
Во-первых вот это:
Если символ ордера равен заданному символу в переменной symbol или магик ордера равен магику magic... Значит, если будет выбран любой ордер с символом symbol, а магик будет другой или отсутствовать, то условие будет выполнено. Потому что или то или то... Соответственно нужно ставить и вместо или, а лучше разнести проверки в отдельные строки - цикл быстрее будет, что значимо для оптимизации.
Далее... Выбор по тикету: параметр pool игнорируется, т.е. его и писать-то тут бессмысленно.
после успешного выбора ордера по тикету, необходимо проверить из какого списка ордеров он был выбран - из рыночных или из закрытых. Для этого нужно проверить время закрытия ордера и, если оно больше нуля, то ордер однозначно был закрытым. У открытых позиций этот параметр всегда равен нулю. ИМХО, после выбора последнего ордера нужно сразу проверить его тип и вписать его в переменную.
Теперь функция примет такой вид:
Теперь, чтобы проверить только Бай или Селл текущего графика и какой из них был последним закрытым, вызываем эту функцию таким образом:
Для обработки ошибки, в принципе, можно завести глобальную переменную, напр. int err; и в теле самой функции запоминать номер ошибки в этой переменной:
Тогда для обработки ошибки после вызова ф-ции ...
GetTypeLastClosePos(Symbol(), Magic);... и возникновения ошибки, её номер будет находиться в переменной err и в блоке обработки этот номер обработать.
А лучше использовать switch