Stop Loss e Take Profit

 
Quando o Stop Loss e Take Profit é disparado, o positionType é atualizado?

 

No meu robô eu testo se diferente de "positionType != POSITION_TYPE_SELL" para poder realizar a venda, contudo por favor observe a ordem 3 e 4 no anexo, a venda é feita pelo SL e mais tarde realiza nova venda, sem estar comprado.

Parece que após o disparo de SL ou TP o positionType não é atualizado. É isso mesmo?

Obrigada!

Arquivos anexados:
RESUMO.jpg  89 kb
 
Pierangela:
Quando o Stop Loss e Take Profit é disparado, o positionType é atualizado?

 

No meu robô eu testo se diferente de "positionType != POSITION_TYPE_SELL" para poder realizar a venda, contudo por favor observe a ordem 3 e 4 no anexo, a venda é feita pelo SL e mais tarde realiza nova venda, sem estar comprado.

Parece que após o disparo de SL ou TP o positionType não é atualizado. É isso mesmo?

Obrigada!

Olá Pierangela,

muito interessante sua pergunta... pra poder te ajudar a resolver o teu problema, seria interessante saber como e onde, dentro do código, você faz a verificação de posição em aberto (ou fechada) para poder enviar uma nova ordem.

A ideia é simples:

if(PositionSelect(_Symbol))
  {
   //---
   Print("Sem permissão para abrir novas posições (posição já aberta)");
  }
else
  {
   //---
   Print("Permissão para abertura de novas posições");
  }

É claro que a verificação não é tão simplista assim. Mas a lógica por trás dela é que realmente interessa. Entretanto, como disse, seria interessante se você pudesse nos dar maiores informações sobre como você desenvolveu a sua lógica de verificação de posições para podermos te ajudar a resolver o problema.

Abraços,
Malacarne 

 
Malacarne:

Olá Pierangela,

muito interessante sua pergunta... pra poder te ajudar a resolver o teu problema, seria interessante saber como e onde, dentro do código, você faz a verificação de posição em aberto (ou fechada) para poder enviar uma nova ordem.

A ideia é simples:

É claro que a verificação não é tão simplista assim. Mas a lógica por trás dela é que realmente interessa. Entretanto, como disse, seria interessante se você pudesse nos dar maiores informações sobre como você desenvolveu a sua lógica de verificação de posições para podermos te ajudar a resolver o problema.

Abraços,
Malacarne 

Oi Malacarne,

Obrigada pela a sua resposta ;-)

Estou postando o código aqui, conforme solicitado. Inclusive este código é do livro "Expert Advisor Programming for meta trader 5" ( Andrew R. Young). Estou testando e entendo como ele funciona, para então usá-lo como base para aplicar novas estratégias.

abcs, Pierangela 

//+------------------------------------------------------------------+
//|                                                        livro.mq5 |
//|                                                       Pierangela |
//|                                              http://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Pierangela"
#property link      "http://www.mql5.com"
#property version   "1.00"

input double TradeVolume=1;
input int StopLoss=1000;
input int TakeProfit=1000;
input int MAPeriod=10;

//global variables
bool glBuyPlaced, glSellPlaced;

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
    //trade structures
    MqlTradeRequest request;
    MqlTradeResult result;
    ZeroMemory(request);
    
    //Moving Average
    double ma[];
    ArraySetAsSeries(ma,true);
    
    int maHandle=iMA(_Symbol,0,MAPeriod,MODE_SMA,0,PRICE_CLOSE);
    CopyBuffer(maHandle,0,0,1,ma);
    
    //Close price
    double close[];
    ArraySetAsSeries(close,true);
    CopyClose(_Symbol,0,0,1,close);
    
    //current position information
    bool openPosition = PositionSelect(_Symbol);
    long positionType = PositionGetInteger(POSITION_TYPE);
    
    double currentVolume = 0;
    if(openPosition == true) currentVolume = PositionGetDouble(POSITION_VOLUME);
    
    // open buy market order
    if((close[0] > ma[0]) && (glBuyPlaced ==  false) && (positionType != POSITION_TYPE_BUY || openPosition == false))
     {
       request.action = TRADE_ACTION_DEAL;
       request.type = ORDER_TYPE_BUY;
       request.symbol = _Symbol;
       request.volume =  TradeVolume; // + currentVolume ;
       request.type_filling = ORDER_FILLING_FOK;
       request.price = SymbolInfoDouble(_Symbol , SYMBOL_ASK);
       request.sl = 0;
       request.tp = 0;
       request.deviation = 50;
       OrderSend(request,result);
    
       //modify sl/tp
       if(result.retcode == TRADE_RETCODE_DONE || result.retcode == TRADE_RETCODE_PLACED)
        {
         request.action = TRADE_ACTION_SLTP;
         
         do Sleep(100); while(PositionSelect(_Symbol) == false);
         
         double positionOpenPrice = PositionGetDouble(POSITION_PRICE_OPEN);
         
         if (StopLoss>0) request.sl = positionOpenPrice - (StopLoss * _Point);
         if (TakeProfit>0) request.tp = positionOpenPrice + (TakeProfit * _Point);
         
         if (request.sl>0 && request.tp>0) OrderSend(request,result);
         
         glBuyPlaced = true;
         glSellPlaced =  false;      
        } //modify sl/tp
       } // open buy market order
        
    // open SELL market order
    if((close[0] < ma[0]) && (glSellPlaced ==  false) && (positionType != POSITION_TYPE_SELL))
     {
       request.action = TRADE_ACTION_DEAL;
       request.type = ORDER_TYPE_SELL;
       request.symbol = _Symbol;
       request.volume =  TradeVolume; // + currentVolume ;
       request.type_filling = ORDER_FILLING_FOK;
       request.price = SymbolInfoDouble(_Symbol , SYMBOL_BID);
       request.sl = 0;
       request.tp = 0;
       request.deviation = 50;
       OrderSend(request,result);
    
       //modify sl/tp
       if((result.retcode == TRADE_RETCODE_DONE || result.retcode == TRADE_RETCODE_PLACED) 
          && ( StopLoss > 0 || TakeProfit > 0))
        {
         request.action = TRADE_ACTION_SLTP;
         
         do Sleep(100); while(PositionSelect(_Symbol) == false);
                  
         double positionOpenPrice = PositionGetDouble(POSITION_PRICE_OPEN);
         
         if (StopLoss>0) request.sl = positionOpenPrice + (StopLoss * _Point);
         if (TakeProfit>0) request.tp = positionOpenPrice - (TakeProfit * _Point);
         
         if (request.sl>0 && request.tp>0) OrderSend(request,result);
         
         glBuyPlaced = false;
         glSellPlaced =  true;      
        } //modify sl/tp
       } // open sell market order
  } // onTick
//+------------------------------------------------------------------+
 

Malacarne,

 Acho que se vc executar para o período de 27/10/2014 até 29/10/2014, WIN$ e período M30, fica mais fácil de analisar, pois somente ocorre uma vez a venda sucessiva, embora na condição de venda tenha também

"positionType != POSITION_TYPE_SELL"

Anexei o print do resultado.

Continuo tentando verificar o que ocorre, se conseguir antes da sua resposta, enviarei ;-)

Como eu sei que uma trigger de um SL ou TP foi disparada? 

 

execucao_resumo_27_ate_29102014 

abcs, Pierangela 

 
Pierangela:

Malacarne,

 Acho que se vc executar para o período de 27/10/2014 até 29/10/2014, WIN$ e período M30, fica mais fácil de analisar, pois somente ocorre uma vez a venda sucessiva, embora na condição de venda tenha também

Como eu sei que uma trigger de um SL ou TP foi disparada? 

Olá Pierangela,

não consegui entender muito bem algumas lógicas dentro do seu código ... na verdade eu até entendi, só não consegui compreender o porquê delas ...

Por exemplo, ao invés de você enviar uma ordem já com o TP e o SL definidos, você deixa para definir esses valores apenas após obter a confirmação da execução da ordem ... até aí tudo bem, mas qual seria o "problema" aqui ? Um problema de latência onde o preço de execução fosse diferente do bid ou ask do momento do envio da ordem? A abordagem em si é interessante, entretanto, isso pode atrasar um pouco a lógica de execução de outras passagens dentro de OnTick...

Já com relação ao tópico principal, a saber a compra ou venda sucessiva, após olhar a imagem com as setas vermelhas que você enviou, eu percebi que o horário das duas ordens sucessivas (as que você marcou) é relativamente espaçado (quase duas horas, na verdade). Logo, não seria isso função da própria lógica de envio de ordens de seu robô? Do contrário, não sei bem se compreendi seu problema.

Abraços,
Malacarne 

 
Malacarne:

Olá Pierangela,

não consegui entender muito bem algumas lógicas dentro do seu código ... na verdade eu até entendi, só não consegui compreender o porquê delas ...

Por exemplo, ao invés de você enviar uma ordem já com o TP e o SL definidos, você deixa para definir esses valores apenas após obter a confirmação da execução da ordem ... até aí tudo bem, mas qual seria o "problema" aqui ? Um problema de latência onde o preço de execução fosse diferente do bid ou ask do momento do envio da ordem? A abordagem em si é interessante, entretanto, isso pode atrasar um pouco a lógica de execução de outras passagens dentro de OnTick...

Já com relação ao tópico principal, a saber a compra ou venda sucessiva, após olhar a imagem com as setas vermelhas que você enviou, eu percebi que o horário das duas ordens sucessivas (as que você marcou) é relativamente espaçado (quase duas horas, na verdade). Logo, não seria isso função da própria lógica de envio de ordens de seu robô? Do contrário, não sei bem se compreendi seu problema.

Abraços,
Malacarne 

Oi Malacarne,

Ok! Muito obrigada. Acho que de fato ficou confuso o q postei. Estou conseguindo caminhar... 

Até breve! 

abcs, Pierangela 

 
Pierangela:

Oi Malacarne,

Ok! Muito obrigada. Acho que de fato ficou confuso o q postei. Estou conseguindo caminhar... 

Até breve! 

abcs, Pierangela 

Olá Pierangela,

fiquei devendo uma resposta pra você, mas demorei pra achar o tópico no fórum em inglês... :-)

Finalmente o encontrei. Por favor dê uma olhada nesse post, que discute exatamente como detectar se uma ordem foi executada pelo stop loss ou take profit.

Abraços,
Malacarne 

 

boa njoite. gostaria de colocar no meu robô stop los e trailyng stop com faço?

//+------------------------------------------------------------------+
//|                                             Robô Média Móvel.mq5 |
//|                                                      DeltaTrader |
//|                                           www.deltatrader.com.br |
//+------------------------------------------------------------------+
#property copyright "DeltaTrader"
#property link      "www.deltatrader.com.br"
#property version   "1.00"
//+------------------------------------------------------------------+
//| INCLUDES                                                         |
//+------------------------------------------------------------------+
#include <Trade/Trade.mqh> // biblioteca-padrão CTrade
//+------------------------------------------------------------------+
//| INPUTS                                                           |
//+------------------------------------------------------------------+
input float lote = 0.10;
input int periodoCurta = 13;
input int periodoLonga = 26;
//+------------------------------------------------------------------+
//| GLOBAIS                                                          |
//+------------------------------------------------------------------+
//--- manipuladores dos indicadores de média móvel
int curtaHandle = INVALID_HANDLE;
int longaHandle = INVALID_HANDLE;
//--- vetores de dados dos indicadores de média móvel
double mediaCurta[];
double mediaLonga[];
//--- declarara variável trade
CTrade trade;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   ArraySetAsSeries(mediaCurta,true);
   ArraySetAsSeries(mediaLonga,true);
//--- atribuir p/ os manupuladores de média móvel
   curtaHandle = iMA(_Symbol,_Period,periodoCurta,0,MODE_SMA,PRICE_CLOSE);
   longaHandle = iMA(_Symbol,_Period,periodoLonga,0,MODE_SMA,PRICE_CLOSE);
   
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
   
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
   if(isNewBar())
     {
      // execute a lógica operacional do robô
      
      //+------------------------------------------------------------------+
      //| OBTENÇÃO DOS DADOS                                               |
      //+------------------------------------------------------------------+
      int copied1 = CopyBuffer(curtaHandle,0,0,3,mediaCurta);
      int copied2 = CopyBuffer(longaHandle,0,0,3,mediaLonga);
      //---
      bool sinalCompra = false;
      bool sinalVenda = false;
      //--- se os dados tiverem sido copiados corretamente
      if(copied1==3 && copied2==3)
        {
         //--- sinal de compra
         if( mediaCurta[1]>mediaLonga[1] && mediaCurta[2]<mediaLonga[2] )
           {
            sinalCompra = true;
           }
         //--- sinal de venda
         if( mediaCurta[1]<mediaLonga[1] && mediaCurta[2]>mediaLonga[2] )
           {
            sinalVenda = true;
           }
        }
      
      //+------------------------------------------------------------------+
      //| VERIFICAR SE ESTOU POSICIONADO                                   |
      //+------------------------------------------------------------------+
      bool comprado = false;
      bool vendido = false;
      if(PositionSelect(_Symbol))
        {
         //--- se a posição for comprada
         if( PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY )
           {
            comprado = true;
           }
         //--- se a posição for vendida
         if( PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_SELL )
           {
            vendido = true;
           }
        }
      
      //+------------------------------------------------------------------+
      //| LÓGICA DE ROTEAMENTO                                             |
      //+------------------------------------------------------------------+
      //--- ZERADO
      if( !comprado && !vendido )
        {
         //--- sinal de compra
         if( sinalCompra )
           {
            trade.Buy(lote,_Symbol,0,0,0,"Compra a mercado");
           }
         //--- sinal de venda
         if( sinalVenda )
           {
            trade.Sell(lote,_Symbol,0,0,0,"Venda a mercado");
           }
        }
      else
        {
         //--- estou comprado
         if( comprado )
           {
            if( sinalVenda )
              {
               trade.Sell(lote*2,_Symbol,0,0,0,"Virada de mão (compra->venda)");
              }
           }
         //--- estou vendido
         else if( vendido )
           {
            if( sinalCompra )
              {
               trade.Buy(lote*2,_Symbol,0,0,0,"Virada de mão (venda->compra)");
              }
           }
        }
      
      
     }
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
bool isNewBar()
  {
//--- memorize the time of opening of the last bar in the static variable
   static datetime last_time=0;
//--- current time
   datetime lastbar_time=(datetime)SeriesInfoInteger(Symbol(),Period(),SERIES_LASTBAR_DATE);
//--- if it is the first call of the function
   if(last_time==0)
     {
      //--- set the time and exit
      last_time=lastbar_time;
      return(false);
     }
//--- if the time differs
   if(last_time!=lastbar_time)
     {
      //--- memorize the time and return true
      last_time=lastbar_time;
      return(true);
     }
//--- if we passed to this line, then the bar is not new; return false
   return(false);
  }
 

Boa tarde pessoal.


É possível definir o tp e sl em um preço dado? por exemplo, sl em 1.00000 e tp em 1.00100; 

A unica forma que encontrei definir o sl e tp é colocando "price - x * point" ou algo nesse sentido. Preciso colocar o stop em um ponto fixo, independente de quantos pontos este tem do ponto de entrada. Alguem consegue me ajudar?

 
Rafael Marrega #Boa tarde pessoal. É possível definir o tp e sl em um preço dado? por exemplo, sl em 1.00000 e tp em 1.00100; A unica forma que encontrei definir o sl e tp é colocando "price - x * point" ou algo nesse sentido. Preciso colocar o stop em um ponto fixo, independente de quantos pontos este tem do ponto de entrada. Alguem consegue me ajudar?

Bom dia!! Sim, é possível, desde que sejam preços válidos para o símbolo negociado. Segue exemplo básico:

   input double InpStopLoss   = 1.00000;  // Stop Loss
   input double InpTakeProfit = 1.00100;  // Take Profit
//---
   double sl = InpStopLoss, tp = InpTakeProfit;
//---
   if(!m_trade.Buy(LOT, _Symbol, ASK, sl, tp, COMMENT))
     {
      Print(m_trade.ResultRetcode(), " ", m_trade.ResultRetcodeDescription());
      return;
     }
 
Rafael Marrega #:

Boa tarde pessoal.


É possível definir o tp e sl em um preço dado? por exemplo, sl em 1.00000 e tp em 1.00100; 

A unica forma que encontrei definir o sl e tp é colocando "price - x * point" ou algo nesse sentido. Preciso colocar o stop em um ponto fixo, independente de quantos pontos este tem do ponto de entrada. Alguem consegue me ajudar?

O código do vinicius já lhe atenderia me parece, mas queria dizer que pode ter algumas restrições se o preço estiver muito próximo do ponto "fixo" ele pode não obdecer a configuração do ativo que diz respeito a "stop level" (a configuração depende da corretora e pode ser visto na especificação do instrumento). Dai a recomendação seria partir para ordens colocadas.
Razão: