Подскажите пожалуйста, как поменять код что бы после закрытия позиции BUY или SELL, по S/L или T/P, она открывалась в другую сторону?
Вот тут есть всё необходимое для программной реализации такого алгоритма.
https://www.mql5.com/ru/forum/107476/page21
Функция isCloseLastPosByStop().
Эта функция возвращает флаг закрытия последней позиции по стопу. Флаг поднят - True - сработал StopLoss. Флаг опущен - False - позиция была закрыта по другой причине. Более точный отбор учитываемых позиций задаётся внешними параметрами:
- sy - Наименование рыночного инструмента. Если задать этот параметр, то функция учтёт позиции только заданного инструмента. Значение по умолчанию - "" означает любой рыночный инструмент. NULL означает текущий инструмент.
- op - Торговая операция, тип позиции. Допустимые значения: OP_BUY, OP_SELL или -1. Значение по умолчанию -1 означает любую позицию.
- mn - Идентификатор позиции, MagicNumber. Значение по умолчанию -1 означает любой идентификатор.
//+----------------------------------------------------------------------------+ //| Автор : Ким Игорь В. aka KimIV, http://www.kimiv.ru | //+----------------------------------------------------------------------------+ //| Версия : 19.05.2008 | //| Описание : Возвращает флаг закрытия последней позиции по стопу. | //+----------------------------------------------------------------------------+ //| Параметры: | //| sy - наименование инструмента ("" - любой символ, | //| NULL - текущий символ) | //| op - операция (-1 - любая позиция) | //| mn - MagicNumber (-1 - любой магик) | //+----------------------------------------------------------------------------+ bool isCloseLastPosByStop(string sy="", int op=-1, int mn=-1) { datetime t; double ocp, osl; int dg, i, j=-1, k=OrdersHistoryTotal(); if (sy=="0") sy=Symbol(); for (i=0; i<k; i++) { if (OrderSelect(i, SELECT_BY_POS, MODE_HISTORY)) { if (OrderSymbol()==sy || sy=="") { if (OrderType()==OP_BUY || OrderType()==OP_SELL) { if (op<0 || OrderType()==op) { if (mn<0 || OrderMagicNumber()==mn) { if (t<OrderCloseTime()) { t=OrderCloseTime(); j=i; } } } } } } } if (OrderSelect(j, SELECT_BY_POS, MODE_HISTORY)) { dg=MarketInfo(sy, MODE_DIGITS); if (dg==0) if (StringFind(OrderSymbol(), "JPY")<0) dg=4; else dg=2; ocp=NormalizeDouble(OrderClosePrice(), dg); osl=NormalizeDouble(OrderStopLoss(), dg); if (ocp==osl) return(True); } return(False); }
Функция isCloseLastPosByTake().
Эта функция возвращает флаг закрытия последней позиции по тейку. Флаг поднят - True - сработал TakeProfit. Флаг опущен - False - позиция была закрыта по другой причине. Более точный отбор учитываемых позиций задаётся внешними параметрами:
- sy - Наименование рыночного инструмента. Если задать этот параметр, то функция учтёт позиции только заданного инструмента. Значение по умолчанию - "" означает любой рыночный инструмент. NULL означает текущий инструмент.
- op - Торговая операция, тип позиции. Допустимые значения: OP_BUY, OP_SELL или -1. Значение по умолчанию -1 означает любую позицию.
- mn - Идентификатор позиции, MagicNumber. Значение по умолчанию -1 означает любой идентификатор.
//+----------------------------------------------------------------------------+ //| Автор : Ким Игорь В. aka KimIV, http://www.kimiv.ru | //+----------------------------------------------------------------------------+ //| Версия : 19.05.2008 | //| Описание : Возвращает флаг закрытия последней позиции по тейку. | //+----------------------------------------------------------------------------+ //| Параметры: | //| sy - наименование инструмента ("" - любой символ, | //| NULL - текущий символ) | //| op - операция (-1 - любая позиция) | //| mn - MagicNumber (-1 - любой магик) | //+----------------------------------------------------------------------------+ bool isCloseLastPosByTake(string sy="", int op=-1, int mn=-1) { datetime t; double ocp, otp; int dg, i, j=-1, k=OrdersHistoryTotal(); if (sy=="0") sy=Symbol(); for (i=0; i<k; i++) { if (OrderSelect(i, SELECT_BY_POS, MODE_HISTORY)) { if (OrderSymbol()==sy || sy=="") { if (OrderType()==OP_BUY || OrderType()==OP_SELL) { if (op<0 || OrderType()==op) { if (mn<0 || OrderMagicNumber()==mn) { if (t<OrderCloseTime()) { t=OrderCloseTime(); j=i; } } } } } } } if (OrderSelect(j, SELECT_BY_POS, MODE_HISTORY)) { dg=MarketInfo(sy, MODE_DIGITS); if (dg==0) if (StringFind(OrderSymbol(), "JPY")<0) dg=4; else dg=2; ocp=NormalizeDouble(OrderClosePrice(), dg); otp=NormalizeDouble(OrderTakeProfit(), dg); if (ocp==otp) return(True); } return(False); }
Иначе говоря, нужно эти две функции расположить вне функции INT START() вашего эксперта.
Где-то я все это видел...
- Но сначала нужно определить тип последней закрытой позиции .
- Это можно сделать используя функцию : https://www.mql5.com/ru/forum/107476/page20
Функция GetTypeLastClosePos().
Эта функция возвращает тип последней закрытой позиции или -1. Более точный отбор учитываемых позиций задаётся внешними параметрами:
- sy - Наименование рыночного инструмента. Если задать этот параметр, то функция учтёт позиции только заданного инструмента. Значение по умолчанию - "" означает любой рыночный инструмент. NULL означает текущий инструмент.
- mn - Идентификатор позиции, MagicNumber. Значение по умолчанию -1 означает любой идентификатор.
//+----------------------------------------------------------------------------+ //| Автор : Ким Игорь В. aka KimIV, http://www.kimiv.ru | //+----------------------------------------------------------------------------+ //| Версия : 19.02.2008 | //| Описание : Возвращает тип последней закрытой позиции или -1 | //+----------------------------------------------------------------------------+ //| Параметры: | //| sy - наименование инструмента ("" - любой символ, | //| NULL - текущий символ) | //| mn - MagicNumber (-1 - любой магик) | //+----------------------------------------------------------------------------+ int GetTypeLastClosePos(string sy="", int mn=-1) { datetime t; int i, k=OrdersHistoryTotal(), r=-1; if (sy=="0") sy=Symbol(); for (i=0; i<k; i++) { if (OrderSelect(i, SELECT_BY_POS, MODE_HISTORY)) { if ((OrderSymbol()==sy || sy=="") && (mn<0 || OrderMagicNumber()==mn)) { if (OrderType()==OP_BUY || OrderType()==OP_SELL) { if (t<OrderCloseTime()) { t=OrderCloseTime(); r=OrderType(); } } } } } return(r); }
Эту функция тож - в самый конец кода.
- А позиции открывать, - задавая условия :
if ( GetTypeLastClosePos(NULL, Magic)==OP_BUY) { //если посл. закрытая позиция была - бай позиция if (CloseLastPosByTake(NULL, OP_BUY, Magic)==1 { //если посл. позиция ьай закрылась по тейку, опять покупаем ticket = OrderSend(Symbol(), OP_BUY, Lots, Ask, Slippage, Ask - SL * Point, Ask + TP * Point, "хи-хи"+ Symbol(), Magic, 0, DarkGreen); } if (isCloseLastPosByStop(NULL, OP_BUY , Magic)==1) { // если посл. позиция бай закрылась по стоплоссу, то продаем ticket = OrderSend(Symbol(), OP_SELL, Lots, Bid,3, Bid + SL * Point, Bid - TP * Point, "хи-хи"+ Symbol(), Magic, 0, DeepPink); } } //жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж if ( GetTypeLastClosePos(NULL, Magic) ==OP_SELL ) { //если посл. закрытая позиция была - селл позиция if (CloseLastPosByTake(NULL, OP_SELL, Magic)==1 { // если посл. позиция селл закрылась по тейкпрофиту, то опять продаем ticket = OrderSend(Symbol(), OP_SELL, Lots, Bid,3, Bid + SL * Point, Bid - TP * Point, "хи-хи"+ Symbol(), Magic, 0, DeepPink); } if (isCloseLastPosByStop(NULL, OP_SELL , Magic)==1) { //если посл. позиция селл закрылась по стоплоссу, то покупаем ticket = OrderSend(Symbol(), OP_BUY, Lots, Ask, Slippage, Ask - SL * Point, Ask + TP * Point, "хи-хи"+ Symbol(), Magic, 0, DarkGreen); } }
- Только вот, как открыть самую первую позицию - я, что то никак не соображу !
Так и не сообразил я, как при такой тактике открыть САМУЮ ПЕРВУЮ позицию. Чтобы далее позиция открывалась, взавис. от вида закрытия предыд. позиции.
Пож., подскажите, кто-ниб. ?
if ( GetTypeLastClosePos(NULL, Magic)==OP_BUY) { //если посл. закрытая позиция была - бай позиция if (CloseLastPosByTake(NULL, OP_BUY, Magic)==1 { //если посл. позиция ьай закрылась по тейку, опять покупаем ticket = OrderSend(Symbol(), OP_BUY, Lots, Ask, Slippage, Ask - SL * Point, Ask + TP * Point, "хи-хи"+ Symbol(), Magic, 0, DarkGreen); } if (isCloseLastPosByStop(NULL, OP_BUY , Magic)==1) { // если посл. позиция бай закрылась по стоплоссу, то продаем ticket = OrderSend(Symbol(), OP_SELL, Lots, Bid,3, Bid + SL * Point, Bid - TP * Point, "хи-хи"+ Symbol(), Magic, 0, DeepPink); } } //жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж if ( GetTypeLastClosePos(NULL, Magic) ==OP_SELL ) { //если посл. закрытая позиция была - селл позиция if (CloseLastPosByTake(NULL, OP_SELL, Magic)==1 { // если посл. позиция селл закрылась по тейкпрофиту, то опять продаем ticket = OrderSend(Symbol(), OP_SELL, Lots, Bid,3, Bid + SL * Point, Bid - TP * Point, "хи-хи"+ Symbol(), Magic, 0, DeepPink); } if (isCloseLastPosByStop(NULL, OP_SELL , Magic)==1) { //если посл. позиция селл закрылась по стоплоссу, то покупаем ticket = OrderSend(Symbol(), OP_BUY, Lots, Ask, Slippage, Ask - SL * Point, Ask + TP * Point, "хи-хи"+ Symbol(), Magic, 0, DarkGreen); } }
А нужен ли в таких делах вообще АЛГОРИТМ?
Вижу 2 варианта:
1. Если позиция кроется по ТП/СЛ, то на это же место (цену) выставлять переворотный отложенный ордер.
2. Если кроется по сигналу, то сразу по закрытию (если OrderSend() вернул положительный тикет) основной позиции открывать встречную.
Подскажите пожалуйста, как поменять код что бы после закрытия позиции BUY или SELL, по S/L или T/P, она открывалась в другую сторону?
Вот так:
//Ставим в начало int old_n_buy = 0; int old_n_sell = 0; //В функции start int n_buy = 0; int n_sell = 0; for(int cnt = 0; cnt < OrdersTotal(); cnt++) { OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES); if(OrderType()==OP_BUY) n_buy++; if(OrderType()==OP_SELL) n_sell++; } if ((old_n_buy - n_buy) > 0) { old_n_buy = n_buy; /* Тут открываем sell причём количеством (old_n_buy - n_buy) зделок*/} if ((old_n_sell - n_sell) > 0) { old_n_sell = n_sell; /* Тут открываем buy причём количеством (old_n_sell - n_sell) зделок */}
Да, пожалуй... Можно и так.
А вот я сейчас только что еще вариант сообразил.
При использовании функциий
Функция isCloseLastPosByStop().
Функция isCloseLastPosByTake().
Эти функции возвращает флаг закрытия последней позиции по стопам . Флаг поднят - True - сработал стоп. Флаг опущен - False - позиция была закрыта по другой причине.
Можно использовть момент, когда функции возвращают "-1"(False).
Это значит, что на этом сигнале можно сформировать сигнал изначального запуска эксперта.
"Не прошло и года".....
Вот так сделал (на скорую руку) изначальное открытие:
//изначальное открытие позиций: if (isCloseLastPosByTake(NULL,-1, Magic)==0 && isCloseLastPosByStop(NULL, OP_BUY , Magic)==0) // если последняя закрытая позиция закрылась принудительно (не по стопам), // то открываем всегда - бай - сделку ticket = OrderSend(Symbol(), OP_BUY, Lots, Ask, Slippage, Ask - SL * Point, Ask + TP * Point, "хи-хи"+ Symbol(), Magic, 0, DarkGreen);
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования
Подскажите пожалуйста, как поменять код что бы после закрытия позиции BUY или SELL, по S/L или T/P, она открывалась в другую сторону?
Я начинающий, так что отнеситесь с пониманием! Заранее благодарен.
int start(){
//----
if(OrdersTotal()==0)
if(OrderSend(Symbol(),OP_BUY,Lots,Ask,10,Ask-StopLoss*Point,Ask+TakeProfit*Point) >0)
Alert("Ордер buy открыт успешно!");
//----
return(0);
//+------------------------------------------------------------------+
}