Покажите как это было реализовано - найдут и ошибку.
А если просто "нипонЯла я" - то в джоб -> https://www.mql5.com/ru/job
Есть ли у кого-н. подобная функция? Нужно чтоб закрывалось по достижению определённого уровня по мере удаления от цены открытия .. либо фикс. значениями лота, либо процентом от лота. На форуме подобного не нашёл, поэтому и спрашиваю.
Я почитал. При закрытии частичном меняется мэджик, и в ордер вносится коммент.. Т.е. выбирать нужно ордер для модификации по цене открытия и по времени открытия. Примерный алгоритм представляю, но что-то у меня не совсем выходит.. В общем, нужна помощь.
Покажите как это было реализовано - найдут и ошибку.
А если просто "нипонЯла я" - то в джоб -> https://www.mql5.com/ru/job
Да не вопрос! Вот смотри:
Глобальные переменные для этих функций:
extern int i_takeProfit1 = 10; // Величина 1-ого тейк-профита extern int i_takeProfit2 = 20; // Величина 2-го тейк-профита extern int i_takeProfit3 = 0; // Величина 3-го тейк-профита extern int i_tp1Percent = 50; // Процент от основного лота для закрытия 1-го тейк- профита extern int i_tp2Percent = 30; // Процент от основного лота для закрытия 2-го тейк-профита extern int i_tp3Percent = 0; // Процент от основного лота для закрытия 3-го тейк-профита extern int i_slippage = 2;
В int init помещаем это:
int init() { minLot = MarketInfo(Symbol(), MODE_MINLOT); maxLot = MarketInfo(Symbol(), MODE_MAXLOT); lotStep = MarketInfo(Symbol(), MODE_LOTSTEP);
Дальше вот фукнкции:
//+-------------------------------------------------------------------------------------+ //| TakeProfitLots | //+-------------------------------------------------------------------------------------+ double TakeProfitLots(double lotPrimary, int approach) { double lotDealToClose; // лот для закрытия на данном уровне тейк-профита if (approach == 1) lotDealToClose = lotPrimary * i_tp1Percent / 100.0; return (LotRound(lotDealToClose)); if (approach == 2) lotDealToClose = lotPrimary * i_tp2Percent / 100.0; return (LotRound(lotDealToClose)); if (approach == 3) lotDealToClose = lotPrimary * i_tp3Percent / 100.0; return (LotRound(lotDealToClose)); } //+-------------------------------------------------------------------------------------+ //| Проверка объема на корректность и округление | //+-------------------------------------------------------------------------------------+ double LotRound(double L) { return(MathRound(MathMin(MathMax(L, minLot), maxLot)/lotStep)*lotStep); } //+-------------------------------------------------------------------------------------+ //| Определяем количество закрытий ордеров | //+-------------------------------------------------------------------------------------+ int OrderCloseCount(double ordOpPrice, datetime ordOpTime) { int count = 0; for (int i = 0; i < OrdersHistoryTotal(); i ++) { if (OrderSelect(i, SELECT_BY_POS, MODE_HISTORY)) { if (OrderSymbol() != Symbol()) continue; if (OrderOpenPrice() == ordOpPrice && OrderOpenTime() == ordOpTime) count++; } } return (count); } //+-------------------------------------------------------------------------------------+ //| Определяем тейк-профиты | //+-------------------------------------------------------------------------------------+ void TakeProfits() { int type; double OOP; datetime OOT; double lotik; int ticket; int counterOfCloses; for (int i = OrdersTotal() - 1; i >= 0; i --) { if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) { if (OrderSymbol() != Symbol()) continue; type = OrderType(); OOP = OrderOpenPrice(); OOT = OrderOpenTime(); lotik = OrderLots(); ticket = OrderTicket(); counterOfCloses = OrderCloseCount(OOP, OOT); RefreshRates(); if (type == OP_SELL) { if (i_takeProfit1 > 0) if (Ask <= OOP - i_takeProfit1 * pt && counterOfCloses < 1) OrderClose(ticket, TakeProfitLots(lotik, 1), Ask, i_slippage, Black); if (i_takeProfit2 > 0) if (Ask <= OOP - i_takeProfit2 * pt && counterOfCloses < 2) OrderClose(ticket, TakeProfitLots(lotik, 2), Ask, i_slippage, Black); if (i_takeProfit3 > 0) if (Ask <= OOP - i_takeProfit3 * pt && counterOfCloses < 3) OrderClose(ticket, TakeProfitLots(lotik, 3), Ask, i_slippage, Black); } if (type == OP_BUY) { if (i_takeProfit1 > 0) if (Bid >= OOP + i_takeProfit1 * pt && counterOfCloses < 1) OrderClose(ticket, TakeProfitLots(lotik, 1), Bid, i_slippage, Black); if (i_takeProfit2 > 0) if (Bid >= OOP + i_takeProfit2 * pt && counterOfCloses < 2) OrderClose(ticket, TakeProfitLots(lotik, 2), Bid, i_slippage, Black); if (i_takeProfit3 > 0) if (Bid >= OOP + i_takeProfit3 * pt && counterOfCloses < 3) OrderClose(ticket, TakeProfitLots(lotik, 3), Bid, i_slippage, Black); } } } }
Тут странно как-то. Вся позиция (3 части) закрывается пачкой сразу..
Хотя нет, как оказалось, что-то не все ордера подхватываются.
Что-то странно работает. Некоторые ордера как-будто пропускает и они висят мёртвым грузом. Что тут не так?
Вот что имеется касательно частичного закрытия лота:
Это в init:
minLot = MarketInfo(Symbol(), MODE_MINLOT); maxLot = MarketInfo(Symbol(), MODE_MAXLOT); lotStep = MarketInfo(Symbol(), MODE_LOTSTEP);
Касательно переменных объявленных на глобальном уровне, которых тут не видно вот что нужно:
extern int i_takeProfit1 = 10; // Величина 1-ого тейк-профита extern int i_takeProfit2 = 20; // Величина 2-го тейк-профита extern int i_takeProfit3 = 25; // Величина 3-го тейк-профита extern int i_tp1Percent = 50; // Процент от основного лота для закрытия 1-го тейк- профита extern int i_tp2Percent = 30; // Процент от основного лота для закрытия 2-го тейк-профита extern int i_tp3Percent = 20; // Процент от основного лота для закрытия 3-го тейк-профита extern int i_slippage = 2; extern double i_lot = 0.1; #define SIGNAL_BUY 0 // Сигнал на покупку #define SIGNAL_SELL 1 // Сигнал на продажу #define SIGNAL_NO -1 // Сигнала нет
А вот сами функции:
//+-------------------------------------------------------------------------------------+ //|TakeProfitLots | //+-------------------------------------------------------------------------------------+ double TakeProfitLots(double lotPrimary, int approach) { double lotDealToClose; // лот для закрытия на данном уровне тейк-профита if (approach == 1) lotDealToClose = lotPrimary * i_tp1Percent / 100; return (LotRound(lotDealToClose)); if (approach == 2) lotDealToClose = lotPrimary * i_tp2Percent / 100; return (LotRound(lotDealToClose)); if (approach == 3) lotDealToClose = lotPrimary * i_tp3Percent / 100; return (LotRound(lotDealToClose)); } //+-------------------------------------------------------------------------------------+ //| Проверка объема на корректность и округление | //+-------------------------------------------------------------------------------------+ double LotRound(double L) { return(MathRound(MathMin(MathMax(L, minLot), maxLot)/lotStep)*lotStep); } //+-------------------------------------------------------------------------------------+ //| Определяем количество закрытий ордеров | //+-------------------------------------------------------------------------------------+ int OrderCloseCount(double ordOpPrice, datetime ordOpTime) { int count = 0; for (int i = OrdersHistoryTotal() - 1; i >= 0 ; i--) { if (!OrderSelect(i, SELECT_BY_POS, MODE_HISTORY)) continue; if (OrderSymbol() != Symbol()) continue; if (OrderOpenPrice() == ordOpPrice && OrderOpenTime() == ordOpTime) count++; } return (count); } //+-------------------------------------------------------------------------------------+ //| Определяем тейк-профиты | //+-------------------------------------------------------------------------------------+ void TakeProfits() { int type; double OOP; datetime OOT; int ticket; int counterOfCloses; for (int i = OrdersTotal() - 1; i >= 0; i--) { if (!OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) continue; if (OrderSymbol() != Symbol()) continue; type = OrderType(); OOP = OrderOpenPrice(); OOT = OrderOpenTime(); i_lot = OrderLots(); ticket = OrderTicket(); counterOfCloses = OrderCloseCount(OOP, OOT); RefreshRates(); if (type == OP_SELL) { if (i_takeProfit1 > 0) if (Ask <= OOP - i_takeProfit1 * pt && counterOfCloses == 0) OrderClose(ticket, TakeProfitLots(i_lot, 1), Ask, i_slippage, Black); if (i_takeProfit2 > 0) if (Ask <= OOP - i_takeProfit2 * pt && counterOfCloses == 1) OrderClose(ticket, TakeProfitLots(i_lot, 2), Ask, i_slippage, Black); if (i_takeProfit3 > 0) if (Ask <= OOP - i_takeProfit3 * pt && counterOfCloses == 2) OrderClose(ticket, TakeProfitLots(i_lot, 3), Ask, i_slippage, Black); } if (type == OP_BUY) { if (i_takeProfit1 > 0) if (Bid >= OOP + i_takeProfit1 * pt && counterOfCloses == 0) OrderClose(ticket, TakeProfitLots(i_lot, 1), Bid, i_slippage, Black); if (i_takeProfit2 > 0) if (Bid >= OOP + i_takeProfit2 * pt && counterOfCloses == 1) OrderClose(ticket, TakeProfitLots(i_lot, 2), Bid, i_slippage, Black); if (i_takeProfit3 > 0) if (Bid >= OOP + i_takeProfit3 * pt && counterOfCloses == 2) OrderClose(ticket, TakeProfitLots(i_lot, 3), Bid, i_slippage, Black); } } }
Вот скрины, на которых видны недочёты:
Виктор,, есть надёжный и проверенный способ. Представляете одну позицию в виде группы позиций. И на каждого "члена" этой группы устанавливаете свой ТР и SL. Этот способ тем более удобен, если вы применяете отложенные ордера.
Т.е. в минус или в плюс идем - неважно, все равно закрываем ордер?
И что делает функция OrderCloseCount(), опишите подробнее.
Алгоритм прост как бублик.
При частичном закрытии не меняется Magic. Тикет меняется, а магик - нет.
Есть открытая поза, есть уровни, на которых эта поза должна частями закрываться.
Допустим Level1, Level2 и Level3.
Если поза Buy в профите и Bid >= Level1 && Bid< Level2 ---> закрываем первую часть позиции (лотом, меньшим, чем лот этой позиции, при условии, что оставшийся лот не будет меньше минимального лота), далее:
Если Bid >= Level2 && Bid< Level3 ---> закрываем вторую часть позиции (лотом, меньшим, чем лот этой позиции, при условии, что оставшийся лот не будет меньше минимального лота), далее:
Если Bid >= Level3 ---> закрываем третью часть позиции (лотом, меньшим, чем лот этой позиции, при условии, что оставшийся лот не будет меньше минимального лота), далее:
1. Если при третьем частичном закрытии на уровне Bid>=Level3 лот стал меньше минимального ---> закрываем всю позицию
2. Если после третьего закрытия на уровне Bid>=Level3 ещё осталась позиция, либо сопровождаем оставшуюся позу тралом, либо закрываем её всю.
Это всё.
Для Sell смотрим по Ask: Ask<=Level1 && Ask>Level2 ... и т.д. ...
Делаем цикл по всем нашим позам, выбираем каждую по индексу, высчитываем для выбранной позиции её уровни и закрываемые лоты и получаем удовольствие от работающего алгоритма ... :)
При этом не нужно в памяти (в переменных) эксперта хратить значения этих уровней, что очень удобно - если эксперт по какой-либо причине завершит работу, то после возобновления он не потеряет данные об уровнях - он их для каждой позиции будет на лету пересчитывать.
И ещё: после частичного закрытия не забывайте подтягивать защитный стоп. После закрытия на уровне1 - стоп в безубыток, после закрытия на уровне2 - стоп на уровень1, после закрытия на уровне 3 - стоп на уровень2...
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования
Есть ли у кого-н. подобная функция? Нужно чтоб закрывалось по достижению определённого уровня по мере удаления от цены открытия .. либо фикс. значениями лота, либо процентом от лота. На форуме подобного не нашёл, поэтому и спрашиваю.
Я почитал. При закрытии частичном меняется мэджик, и в ордер вносится коммент.. Т.е. выбирать нужно ордер для модификации по цене открытия и по времени открытия. Примерный алгоритм представляю, но что-то у меня не совсем выходит.. В общем, нужна помощь.