Событие срабатывания TP или SL

 
Здравствуйте. Как можно отследить, как именно закрылась сделка, по TP или по SL и в зависимости от этого предпринимать какие-то действия?
 
Fresto:
Здравствуйте. Как можно отследить, как именно закрылась сделка, по TP или по SL и в зависимости от этого предпринимать какие-то действия?


Поздравляем, вы 100500-й участник форума, который задал этот вопрос и награждаетесь ценным призом! Поищите поиском, тут много обсуждений этого вопроса.

Вкратце - по цене закрытия и по комментарию.

 
Alexey Volchanskiy:


Поздравляем, вы 100500-й участник форума, который задал этот вопрос и награждаетесь ценным призом! Поищите поиском, тут много обсуждений этого вопроса.

Вкратце - по цене закрытия и по комментарию.


Я  тоже думал так, но там ведь может быть проскальзывание и на малых SL и TP может вообще неправильно закинуть)

P.s. по комментарию тогда попробую. Просто если есть комментарий, то значит программа поняла, что это SL или TP. А значит и можно понять нам)
 
Fresto:

Я  тоже думал так, но там ведь может быть проскальзывание и на малых SL и TP может вообще неправильно закинуть)

P.s. по комментарию тогда попробую. Просто если есть комментарий, то значит программа поняла, что это SL или TP. А значит и можно понять нам)


В истории находите интересующую вас закрытую позицию. Если цена закрытия позиции ниже или равна цене стоп лоса для ордера на покупку и если выше или равна цене стоп лоса для ордера на продажу то из это следует, что позиция закрылась по стопу. Если цена закрытия выше или равна цене ТР для покупки и ниже или равна цене ТР для продажи то закрытие было по ТП. 

Если цена закрытия позиции где то между ценой открытия и ценой ТР или ценой стоп лоса, то позиция была закрыта не дожидаясь достижения ТР или стоп лоса.

 
Fresto:

Я  тоже думал так, но там ведь может быть проскальзывание и на малых SL и TP может вообще неправильно закинуть)

P.s. по комментарию тогда попробую. Просто если есть комментарий, то значит программа поняла, что это SL или TP. А значит и можно понять нам)
Комментарии типа [tp 122.712] выставляет ДЦ, а не терминал. А уж там-то сервер знает, почему он закрыл позицицю.
 
Vitalii Ananev:


В истории находите интересующую вас закрытую позицию. Если цена закрытия позиции ниже или равна цене стоп лоса для ордера на покупку и если выше или равна цене стоп лоса для ордера на продажу то из это следует, что позиция закрылась по стопу. Если цена закрытия выше или равна цене ТР для покупки и ниже или равна цене ТР для продажи то закрытие было по ТП. 

Если цена закрытия позиции где то между ценой открытия и ценой ТР или ценой стоп лоса, то позиция была закрыта не дожидаясь достижения ТР или стоп лоса.

Когда позиция закрылась её свойства становятся недоступными. Так-же если стопы\тейки менялись, то они тоже становятся недосягаемо спрятанными. Так-что универсального способа, кроме как по комментарию определить нетуууу.
 
Alexey Viktorov:
Когда позиция закрылась её свойства становятся недоступными. Так-же если стопы\тейки менялись, то они тоже становятся недосягаемо спрятанными. Так-что универсального способа, кроме как по комментарию определить нетуууу.

То есть, если я правильно понял, вы хотите сказать, что в истории сделок нет информации о цене открытия сделки, цене стоп лоса, цене тейк профита и цене закрытия сделки? 
 
Vitalii Ananev:

То есть, если я правильно понял, вы хотите сказать, что в истории сделок нет информации о цене открытия сделки, цене стоп лоса, цене тейк профита и цене закрытия сделки

Ответ был на сообщение в котором говорилось о закрытых позициях

Vitalii Ananev:


В истории находите интересующую вас закрытую позицию. Если цена закрытия позиции ниже или равна цене стоп лоса для ордера на покупку и если выше или равна цене стоп лоса для ордера на продажу то из это следует, что позиция закрылась по стопу. Если цена закрытия выше или равна цене ТР для покупки и ниже или равна цене ТР для продажи то закрытие было по ТП. 

Если цена закрытия позиции где то между ценой открытия и ценой ТР или ценой стоп лоса, то позиция была закрыта не дожидаясь достижения ТР или стоп лоса.

И в моём ответе тоже говорилось о позициях. И даже обращаясь к сделкам и ордерам закрытой позиции не всегда можно определить стопы\тейки которые были установлены в период "жизни" позиции.

Алгоритм проверки:

1. Открываем позицию. Если счёт позволяет можно сразу с тейком и стопом.

2. Меняем стопы и тейки, то-есть Modify...

3. Когда позиция закрылась найти ордера и сделки позиции.

4. Определить какой тейк и какой стоп был у позиции.

А для netting счетов ещё хуже обстоят дела.

 
Fresto:
Здравствуйте. Как можно отследить, как именно закрылась сделка, по TP или по SL и в зависимости от этого предпринимать какие-то действия?

Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий

Особенности языка mql5, тонкости и приёмы работы

fxsaber, 2017.02.25 16:30

// Триггер срабатывания SL/TP - работает только на демо/реале (не в тестере).
void OnTradeTransaction ( const MqlTradeTransaction &Trans, const MqlTradeRequest &Request, const MqlTradeResult &Result )
{
  if ((Trans.type == TRADE_TRANSACTION_ORDER_ADD) &&
       PositionSelectByTicket(Trans.position) && OrderSelect(Trans.order) &&
       (PositionGetInteger(POSITION_TYPE) == 1 - OrderGetInteger(ORDER_TYPE)))
  {
    const double Price = OrderGetDouble(ORDER_PRICE_OPEN);
    
    if (Price == PositionGetDouble(POSITION_TP))
      Print("Position #" + (string)Trans.position + " - triggered TP.");    
    else if (Price == PositionGetDouble(POSITION_SL))
      Print("Position #" + (string)Trans.position + " - triggered SL.");    
  }
}

Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий

MQL5 Как узнать закрылась сделка по стоп-лоссу или нет?

fxsaber, 2017.02.14 19:46

Тикет ордера, который был причиной закрытия позиции, запихнуть сюда
#define ORDER_TYPE_TAKEPROFIT (-1)
#define ORDER_TYPE_STOPLOSS   (-2)

int GetOrderType(const ulong OrderTicket)
{
  int OrderType=(int)::HistoryOrderGetInteger(OrderTicket,ORDER_TYPE);

  if((OrderType==ORDER_TYPE_BUY) || (OrderType==ORDER_TYPE_SELL))
    {
     const string OrderComment=HistoryOrderGetString(OrderTicket,ORDER_COMMENT);
     const string OrderPrice=::DoubleToString(::HistoryOrderGetDouble(OrderTicket,ORDER_PRICE_OPEN),
                                              (int)::SymbolInfoInteger(HistoryOrderGetString(OrderTicket,ORDER_SYMBOL),SYMBOL_DIGITS));

     if(OrderComment=="tp "+OrderPrice)
        OrderType=ORDER_TYPE_TAKEPROFIT;
     else if(OrderComment=="sl "+OrderPrice)
        OrderType=ORDER_TYPE_STOPLOSS;
    }

  return(OrderType);
}
 
Вроде бы как-то написал тоже свой код. Но работает он не всегда исправен. Т.е. если у сделки есть коммент, то это сделка закрытия позиции и там указывается sl или tp. Но не всегда, потому что.

void OnTradeTransaction(const MqlTradeTransaction &trans,
                                  const MqlTradeRequest &request,
                                  const MqlTradeResult &result)
  {
//--- get transaction type as enumeration value 
    ENUM_TRADE_TRANSACTION_TYPE type=trans.type;
   
//--- if transaction is result of addition of the transaction in history
      string   deal_comm         ="";
      long     deal_entry        =0;
      long     deal_type         =0;
      string   deal_symbol       ="";
      long     deal_magic        =0;
   if(type==TRADE_TRANSACTION_DEAL_ADD)
     {    
      if(HistoryDealSelect(trans.deal))
        {
         deal_entry=HistoryDealGetInteger(trans.deal,DEAL_ENTRY);
         deal_type=HistoryDealGetInteger(trans.deal,DEAL_TYPE);
         deal_symbol=HistoryDealGetString(trans.deal,DEAL_SYMBOL);
         deal_magic=HistoryDealGetInteger(trans.deal,DEAL_MAGIC);
         deal_comm = HistoryDealGetString(trans.deal,DEAL_COMMENT);
        }
      else
         return;
         
      
      if(StringSubstr(deal_comm,0,2) == "sl")
      {
         lastCloseType = deal_type;
         lastCloseComm = StringSubstr(deal_comm,0,2);
      }
      if(StringSubstr(deal_comm,0,2) == "tp")
      {
         lastCloseType = deal_type;
         lastCloseComm = StringSubstr(deal_comm,0,2);
      }
      }
  }
Потому что вот явный пример

Здесь лонг закрылся по стопу ( закрылся продажей встречной), открылся шорт ( все правильно ). Шорт закрылся по стопу ( закрылся покупкой встречной ), открылся Шорт. Такого быть не должно. В коде прописано зеркально всё, ошибок не должно быть, а в итоге что-то выскакивает.
if(lastCloseComm == "sl")
      {
         if (Buy_opened || Sell_opened) 
         {
            Alert("Уже открыта позиция!!!");
            return; // не добавлять к открытой позиции на покупку
         }
         double spred;
         if(lastCloseType == POSITION_TYPE_BUY) // Если закрывается позиция ПОКУПКОЙ, то значит позиция была шортовая и надо покупать.
         {
            slLot = slLot*2;
            spred = MathAbs(mysymbol.Bid() - priceEnter);
            double BuyPrice=NormalizeDouble(mysymbol.Ask(),_Digits);               //--- последняя цена ask
            double stloss = NormalizePrice(_Symbol,mysymbol.Bid() - spred*_Point); //--- Stop Loss
            double profit = NormalizePrice(_Symbol,mysymbol.Bid() + TP*_Point);
            if(mytrade.Buy(slLot,_Symbol,BuyPrice,stloss,profit)) 
               {
                  Alert("Ордер на покупку был успешно размещен, Ticket#:",mytrade.ResultOrder(),"!!");
               }
            else
               {
                  Alert("Ордер на покупку объема:",mytrade.RequestVolume(), 
                        ", sl:", mytrade.RequestSL(),
                        ", цена:", mytrade.RequestPrice(), 
                        " не выполнен -ошибка:",mytrade.ResultRetcodeDescription());
                          return;
               }
         }
         if(lastCloseType == POSITION_TYPE_SELL) // Если позиция закрылась шортом, то это была покупка и надо продавать.
         {
            slLot= slLot*2;
            spred = MathAbs(priceEnter - mysymbol.Ask());   
            double SellPrice=NormalizeDouble(mysymbol.Bid(),_Digits);               //--- последняя цена ask
            double stloss = NormalizePrice(_Symbol,mysymbol.Ask() + spred*_Point); //--- Stop Loss
            double profit = NormalizePrice(_Symbol,mysymbol.Ask() - TP*_Point);
            if(mytrade.Sell(slLot,_Symbol,SellPrice,stloss,profit)) 
               {
                  Alert("Ордер на продажу был успешно размещен, Ticket#:",mytrade.ResultOrder(),"!!");
                  priceEnter = SellPrice;
               }
            else
               {
                  Alert("Ордер на продажу объема:",mytrade.RequestVolume(), 
                        ", sl:", mytrade.RequestSL(),
                        ", цена:", mytrade.RequestPrice(), 
                        " не выполнен -ошибка:",mytrade.ResultRetcodeDescription());
                          return;
               }
         }
      }



P.s. В итоге фишка была в том, что я торговал и до закрытия свечи, на тиках, и он не успевал обрабатывать всё, чтобы выводить правильно. Если выставить, что обновляться Советник не с каждым тиком, а после новой свечи, то алгоритм работает.
 
Fresto:
Вроде бы как-то написал тоже свой код. Но работает он не всегда исправен.
Триггер выше не использует комментарий.