Stop Loss e Take Profit

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!

Arquivos anexados:
RESUMO.jpg  89 kb
Rodrigo Malacarne  
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 

Pierangela  
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
//+------------------------------------------------------------------+
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

"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 

Rodrigo Malacarne  
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 

Pierangela  
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 

Rodrigo Malacarne  
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 

Romario Valverde  

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);

  }

Razão: