BUY на SELL

 

Подскажите пожалуйста, как поменять код что бы после закрытия позиции 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);

//+------------------------------------------------------------------+

}
 
frimax писал(а) >>

Подскажите пожалуйста, как поменять код что бы после закрытия позиции 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);
}
}
 
rid писал(а) >>

Так и не сообразил я, как при такой тактике открыть САМУЮ ПЕРВУЮ позицию. Чтобы далее позиция открывалась, взавис. от вида закрытия предыд. позиции.

Пож., подскажите, кто-ниб. ?

Что, так никто и не подскажет ?

Похоже, я напрасно тут целую диссертацию выше написал....

 
rid >>:

Что, так никто и не подскажет ?

Похоже, я напрасно тут целую диссертацию выше написал....

предлагаю тупой вариант: запустить первую сделку скриптом с таким же магиком, как у эксперта...

своего рода электростимулятор... :))

 
rid >>:

Вот тут есть всё необходимое для программной реализации такого алгоритма.

А нужен ли в таких делах вообще АЛГОРИТМ?

Вижу 2 варианта:

1. Если позиция кроется по ТП/СЛ, то на это же место (цену) выставлять переворотный отложенный ордер.

2. Если кроется по сигналу, то сразу по закрытию (если OrderSend() вернул положительный тикет) основной позиции открывать встречную.

 
frimax писал(а) >>

Подскажите пожалуйста, как поменять код что бы после закрытия позиции 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);
Причина обращения: