Identificação de Operação que sofreu Stoploss

 

Prezados,

Minha EA esta com bug por conta de operações que sofrem Stoploss... Sera que alguém consegue me ajudar?

Preciso de um codigo capaz de identificar o nome do ativo que sofreu stoploss...

            uint total_deals=HistoryDealsTotal();

            uint total_deals_analised=total_deals-1;

            ulong ticket_history_deal=0;

            string str_deal_reason;

            long     deal_reason;

            long     deal_ticket;

            long     last_ticket;

            string   deal_symbol;

            bool     deal;


      //----------------------LIMPEZA DE VARIAVEIS POR STOPLOSS-------------------------------//        

           

            for(uint c=total_deals_analised;c<total_deals;c++)

               {

               if((ticket_history_deal=HistoryDealGetTicket(i))>0)

                  {

                  deal              =HistoryDealGetString(ticket_history_deal,DEAL_SYMBOL,deal_symbol);

                  deal_ticket       =HistoryDealGetInteger(ticket_history_deal,DEAL_TICKET);

                  deal_reason       =HistoryDealGetInteger(ticket_history_deal,DEAL_REASON);       

                  }

               }

               

         //---

         if(deal_reason>100000000 && (deal_ticket!=last_ticket) && (Estrategia.At(i)==1 || Estrategia.At(i)==2))       

           {

            Print("Deu Stoploss no ativo ",SymbolName(i,true),"!");

            Print("Deal = ",deal);

            Print("Deal Ticket: ",deal_ticket);

            Print("Deal Symbol = ",deal_symbol);

}

 
Não tá capturando o deal symbol...
 
igorlpmartins:
Não tá capturando o deal symbol...

Igor,

no croqui abaixo temos o momento que uma posição é encerrada por 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
   if(type==TRADE_TRANSACTION_DEAL_ADD)
     {
      long     deal_entry        =0;
      string   deal_symbol       ="";
      long     deal_magic        =0;
      long     deal_reason       =0;
      if(HistoryDealSelect(trans.deal))
        {
         deal_symbol=HistoryDealGetString(trans.deal,DEAL_SYMBOL);
         deal_magic=HistoryDealGetInteger(trans.deal,DEAL_MAGIC);
         deal_entry=HistoryDealGetInteger(trans.deal,DEAL_ENTRY);
         if(deal_symbol==Symbol() && deal_magic==MagicNumber
            && (ENUM_DEAL_ENTRY)deal_entry==DEAL_ENTRY_OUT)
           {
            deal_reason=HistoryDealGetInteger(trans.deal,DEAL_REASON);
            if( ((ENUM_DEAL_REASON) deal_reason==DEAL_REASON_SL)
            ||((ENUM_DEAL_REASON) deal_reason==DEAL_REASON_TP) )
              {
                ...
                ...
              }
           }
        }
     }
  }
 
Rogerio Giannetti Torres:

Igor,

no croqui abaixo temos o momento que uma posição é encerrada por SL/TP .


Tudo bem, Rogerio?

Implementei este código e funcionou, porém, quando uma ordem possui mais de uma operação, ele passa algumas vezes pela função.

Ex:

JR 0 09:30:19.740 Trades '1234': exchange sell 10.00 DOLV19 at market, close #130466531 buy 10.00 DOLV19 4170.000

OS 0 09:30:19.740 Trades '1234': deal #117416038 sell 5.00 DOLV19 at 4166.000 done (based on order #130468601)

JE 0 09:30:19.753 Trades '1234': deal #117416040 sell 5.00 DOLV19 at 4166.000 done (based on order #130468601)


No cenário acima, ele passará duas vezes pelo ponto:

		deal_reason=HistoryDealGetInteger(trans.deal,DEAL_REASON);
            	if( ((ENUM_DEAL_REASON) deal_reason==DEAL_REASON_SL


Ocorre que preciso capturar o stop loss com seu total de contratos uma única vez. Utilizando o exemplo acima, meu retorno esperado é 10 Contratos em uma única linha e não duas linhas de 5 contratos.

Não sei se consegui me explicar.

Você teria alguma dica para chegar no meu objetivo?

Agradeço desde já.

Att, Rodrigo

 
Rodrigo Slongo:

Boa tarde Rodrigo,

TRADE_TRANSACTION_DEAL_ADD   ocorre para cada deal e não tem como ser diferente.

 
Rogerio Giannetti Torres:

Boa tarde Rodrigo,

TRADE_TRANSACTION_DEAL_ADD   ocorre para cada deal e não tem como ser diferente.

Muito obrigado, Rogerio!


Vou buscar aluma alternativa, talvez implementar uma variável que sinalize quando o stop loss foi acionado. Vou dar uma estudada.


Grande abraço,

Rodrigo

 

Ola Rodrigo, tudo bom?


Vi esse post agora em 2021, e me encontrei numa situação similar a sua, e acabei resolvendo a lógica para evitar entradas no mesmo candle em caso de stop com a seguinte lógica:

Manipulando um double chamado travaloss(baixo se buy, cima se sell), e jogando ele na condição para abrir compra ou abrir venda. se rates[0].low > que travalossbaixo na compra, ou rates[0].high < travalosscima, ele abre a operação de compra/venda. Caso contrário, a ordem de compra/venda não seria atendida nesse candle, e a operação só aconteceria no candle seguinte. Isso resolveu minha questão e espero que ajude quem estiver procurando solução similar.

Abs!

void addTakeStop(double p_sl, double p_tp)

   {

   for(int i = PositionsTotal() -1; i>=0; i--)

      {

      string symbol = PositionGetSymbol(i);

      if(symbol == Symbol ())

        {

        ulong ticket = PositionGetInteger(POSITION_TICKET);

        double precoEntrada = PositionGetDouble(POSITION_PRICE_OPEN);

        double novoSL;

        double novoTP;        

        if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY)

          {

           novoSL = NormalizeDouble(precoEntrada - (p_sl), _Digits);

           travalossbaixo = novoSL +2;

           novoTP = NormalizeDouble(p_tp, _Digits);   

           m_trade.PositionModify(ticket, novoSL, novoTP);

          }

   else if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL)

          {

           novoSL = NormalizeDouble(precoEntrada + (p_sl), _Digits);

           travalosscima = novoSL -2;

           novoTP = NormalizeDouble(p_tp, _Digits); 

           m_trade.PositionModify(ticket, novoSL, novoTP);

          }

        }

      }

   }

Razão: