Fechar operação no TP - página 3

 

Boa tarde,

Retificando:  Os EA(s) que rodam no AWS encerra as posições e cancela as ordensp endentes  30 min. antes do fechamento de cada mercado.  O EA monitor roda em casa e encerra as posições e cancela ordens pendentes faltando 29 min para fechar cada um dos mercados.

A ideia é que se der um pau nas instâncias MT5 no AWS, ou no próprio AWS,  o programa monitor não vai permitir que as posições/ordens fiquem abertas.

Observação: O programa monitor faz o testes de saldo no evento OnTick() e de encerramento no evento OnTimer () ajustado em  EventSetTimer(1).

 
@mcronline conseguiu uma saída funcional para a situação? Estou no mesmo caso.
 
tfdcoelho:
@mcronline conseguiu uma saída funcional para a situação? Estou no mesmo caso.

Aqui foram discutidos os motivos. Você não compreendeu?

 

Pessoal, excelente tópico e discussão em alto nível.

Apesar dos meus EAs possuírem fechamento/cancelamento de ordens pendentes por horário rodando na VPS, também utilizo um outro EA (similar ao comentado pelo @Rogerio Giannetti Torres) rodando como backup na minha máquina para o fechamento de posições/ordens que eventualmente tenham ficado abertas. No entanto, no último dia 17/06 houve uma falha nos servidores da B3 e nenhum dos EAs conseguiu fechar as ordens e posições automaticamente. Neste dia, por sorte pude entrar em contato a tempo com a mesa da corretora para o fechamento das posições abertas.

Então como procedimento adicional ao invés de fechar as 17:30, antecipei o fechamento das mesmas na VPS e na minha máquina,pois caso algo dê errado, ainda terei tempo o suficiente para entrar em contato com a mesa.

 

Excelente tópico!!!

Essa discussão, além de ampliar os horizontes no desenvolvimento dos EA´s com algumas práticas que estão, ao meu ver, num nível mais avançado, economiza algumas horas de estudo e planejamento dos nossos próprios EA's...

Aprender com a experiência alheia não tem preço...

 

Senhores, tive o mesmo problema com o TP e SL e por causa desta discusão pude achar uma solucão que deu certo para mim, vejam se faz sentido


fiz uma variaval chamada contador

uchar contador = 0;


criei 4 funçoes chamadas:

Comprar();    Compra acoes 

ModificaSL();  Coloca uma Ordem Sell_Stop onde eu quero o meu STOP

ModificaTP(); Coloca uma Ordem Sell_Limit onde eu quero o meu TAKE

CancelasPendentes(); Cancela todas as ordens pendentes após o o STOP ou TAKE ser realizado.


coloquei o contador no manipulador OnTrade.


Quando as funcoes Comprar(); ModificaSL(); e ModificaTP(); são acionadas o contador está em 19.

No momento em que uma dar ordens de SL e TP é executada o contador salta para 23. Assim fiz o


no manipulador OnTick fiz um if

if(contador > 21){

CancelaPendentes();

}


Assim ele cancela as ordens pendentes que sobrarm, independente se a ordem foi parcialmente executada, esse meu robo opera somente na compra, então não sei como ficaria a questão de ele ter um TAKE parcial e a funcao CancelaPendentes cancelar tudo e ficar com contratos ou ações sobrando, como opero com pouco lotes isso é dificil de acontecer comigo, mas pode acontecer.

Qualquer ambiguidade ou critica que ficou por favor fiquem a vontade para falar

 
mateustavares48:

Senhores, tive o mesmo problema com o TP e SL e por causa desta discusão pude achar uma solucão que deu certo para mim, vejam se faz sentido


fiz uma variaval chamada contador

uchar contador = 0;


criei 4 funçoes chamadas:

Comprar();    Compra acoes 

ModificaSL();  Coloca uma Ordem Sell_Stop onde eu quero o meu STOP

ModificaTP(); Coloca uma Ordem Sell_Limit onde eu quero o meu TAKE

CancelasPendentes(); Cancela todas as ordens pendentes após o o STOP ou TAKE ser realizado.


coloquei o contador no manipulador OnTrade.


Quando as funcoes Comprar(); ModificaSL(); e ModificaTP(); são acionadas o contador está em 19.

No momento em que uma dar ordens de SL e TP é executada o contador salta para 23. Assim fiz o


no manipulador OnTick fiz um if

if(contador > 21){

CancelaPendentes();

}


Assim ele cancela as ordens pendentes que sobrarm, independente se a ordem foi parcialmente executada, esse meu robo opera somente na compra, então não sei como ficaria a questão de ele ter um TAKE parcial e a funcao CancelaPendentes cancelar tudo e ficar com contratos ou ações sobrando, como opero com pouco lotes isso é dificil de acontecer comigo, mas pode acontecer.

Qualquer ambiguidade ou critica que ficou por favor fiquem a vontade para falar

A ordem de execução vai ainda sim depender da fila do Book, e pode variar o valor de execução da ordem enviada pelo seu robô. Por essas razões não é arriscado fazer scalps pela diferenciação dos tempos de disparo e liquidação da ordem.

 

Boa noite pessoal!

Estou aprendendo, bem devagar, um pouco sobre MQL5. Estou tentando um EA, e estou tendo dois problemas:

1 - Conforme já comentado aqui... O preço alcança o  TP e SL e não fecha a ordem.

2 - Ele está enviando diversas ordens seguidamente.


Alguém pode ajudar?


Como funciona o freelance?


Os parâmetros que estão na configuração dos indicadores estão aleatórios.

//+------------------------------------------------------------------+
//|                                                         teste.mq5 |
//|                                                                   |
//+------------------------------------------------------------------+
#property copyright 
#property link      
#property version   
// Inclusão de bibliotecas utilizadas
#include <Trade/Trade.mqh>
#include <Trade/SymbolInfo.mqh>

input group              "Configurações gerais"
input ulong              Magic               = 123456;  // Número mágico
input group              "Configurações operacionais"
input double             SL                   = 0.0;    // Stop Loss
input double             TP                   = 0.0;    // Take Profit
input double             Volume               = 1;      // Volume
input group              "Configurações do indicador"
input int                ADX_Period           = 7;      // ADX Period
input double             Adx_Min              = 1;               // Minimum ADX Value
input int                OsMA_fast_ema_period = 24;    // OsMA: EMA Rápida 
input int                OsMA_slow_ema_period = 52;     // OsMA: EMA Lenta 
input int                OsMA_signal_period   = 18;    // OsMA: MACD
input int                OsMA_Venda           = -100;              // OsMA: Mínimo para Venda 
input int                OsMA_Compra          = 20;              // OsMA: Mínimo para Compra 
input ENUM_APPLIED_PRICE Preco          = PRICE_CLOSE; // Preço Aplicado
input group              "Configurações de horários"
input string             inicio         = "09:00";    
 // Horário de Início (entradas)
input string             termino        = "16:00";     // Horário de Término (entradas)
input string             fechamento     = "17:10";     // Horário de Fechamento (posições)

int         adxHandle;
int      handle_iOsMA;
string      shortname;

//--- vetores de dados dos indicadores de média móvel

CTrade      negocio; // Classe responsável pela execução de negócios
CSymbolInfo simbolo; // Classe responsãvel pelos dados do ativo

// Estruturas de tempo para manipulação de horários
MqlDateTime horario_inicio, horario_termino, horario_fechamento, horario_atual;

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---

// Definição do símbolo utilizado para a classe responsável
   if(!simbolo.Name(_Symbol))
     {
      printf("Ativo Inválido!");
      return INIT_FAILED;
     }

// Criação dos manipulador
   adxHandle = iADX(_Symbol,PERIOD_CURRENT,ADX_Period);
   
// Verificação do resultado da criação dos manipuladores
   if(adxHandle == INVALID_HANDLE)
     {
      Print("Erro na criação dos manipuladores");
      return INIT_FAILED;
     }

   if(!ChartIndicatorAdd(0, 1, adxHandle))
     {
      Print("Erro na adição do indicador ao gráfico");
      return INIT_FAILED;
     }
     
   shortname = ChartIndicatorName(0, 1, ChartIndicatorsTotal(0, 1)-1);
   
 // Criação dos manipulador
 
  handle_iOsMA = iOsMA(_Symbol,_Period,OsMA_fast_ema_period,OsMA_slow_ema_period,OsMA_signal_period,Preco);

// Verificação do resultado da criação dos manipuladores
   if(handle_iOsMA == INVALID_HANDLE)
     {
      Print("Erro na criação dos manipuladores");
      return INIT_FAILED;
     }

   if(!ChartIndicatorAdd(0, 1, handle_iOsMA))
     {
      Print("Erro na adição do indicador ao gráfico");
      return INIT_FAILED;
     }
     
   shortname = ChartIndicatorName(0, 1, ChartIndicatorsTotal(0, 1)-1);
//---

// Criação das structs de tempo
   TimeToStruct(StringToTime(inicio), horario_inicio);
   TimeToStruct(StringToTime(termino), horario_termino);
   TimeToStruct(StringToTime(fechamento), horario_fechamento);

// Verificação de inconsistências nos parâmetros de entrada
   if(horario_inicio.hour > horario_termino.hour || (horario_inicio.hour == horario_termino.hour && horario_inicio.min > horario_termino.min))
     {
      printf("Parâmetros de Horário inválidos!");
      return INIT_FAILED;
     }

// Verificação de inconsistências nos parâmetros de entrada
   if(horario_termino.hour > horario_fechamento.hour || (horario_termino.hour == horario_fechamento.hour && horario_termino.min > horario_fechamento.min))
     {
      printf("Parâmetros de Horário inválidos!");
      return INIT_FAILED;
     }

   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
   ChartIndicatorDelete(0, 1, shortname);
   
// Motivo da desinicialização do EA
   printf("Deinit reason: %d", reason);
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
// Atualização dos dados do ativo
   if(!simbolo.RefreshRates())
      return;

// EA em horário de entrada em novas operações
   if(HorarioEntrada())
     {
      // EA não está posicionado
      if(SemPosicao())
        {
         // Verificar estratégia e determinar compra ou venda
         int resultado = Sinal();

         // Estratégia indicou compra
         if(resultado  == 1)
            Compra();
         // Estratégia indicou venda
         if(resultado  == -1)
            Venda();
        }
     }

// EA em horário de fechamento de posições abertas
   if(HorarioFechamento())
     {
      // EA está posicionado, fechar posição
      if(!SemPosicao())
         Fechar();
     }

  }
//+------------------------------------------------------------------+
//| Checar se horário atual está dentro do horário de entradas       |
//+------------------------------------------------------------------+
bool HorarioEntrada()
  {
   TimeToStruct(TimeCurrent(), horario_atual); // Obtenção do horário atual

// Hora dentro do horário de entradas
   if(horario_atual.hour >= horario_inicio.hour && horario_atual.hour <= horario_termino.hour)
     {
      // Hora atual igual a de início
      if(horario_atual.hour == horario_inicio.hour)
         // Se minuto atual maior ou igual ao de início => está no horário de entradas
         if(horario_atual.min >= horario_inicio.min)
            return true;
      // Do contrário não está no horário de entradas
         else
            return false;

      // Hora atual igual a de término
      if(horario_atual.hour == horario_termino.hour)
         // Se minuto atual menor ou igual ao de término => está no horário de entradas
         if(horario_atual.min <= horario_termino.min)
            return true;
      // Do contrário não está no horário de entradas
         else
            return false;

      // Hora atual maior que a de início e menor que a de término
      return true;
     }

// Hora fora do horário de entradas
   return false;
  }
//+------------------------------------------------------------------+
//| Checar se horário atual está dentro do horário de fechamento     |
//+------------------------------------------------------------------+
bool HorarioFechamento()
  {
   TimeToStruct(TimeCurrent(), horario_atual); // Obtenção do horário atual

// Hora dentro do horário de fechamento
   if(horario_atual.hour >= horario_fechamento.hour)
     {
      // Hora atual igual a de fechamento
      if(horario_atual.hour == horario_fechamento.hour)
         // Se minuto atual maior ou igual ao de fechamento => está no horário de fechamento
         if(horario_atual.min >= horario_fechamento.min)
            return true;
      // Do contrário não está no horário de fechamento
         else
            return false;

      // Hora atual maior que a de fechamento
      return true;
     }

// Hora fora do horário de fechamento
   return false;
  }
//+------------------------------------------------------------------+
//| Realizar compra com parâmetros especificados por input           |
//+------------------------------------------------------------------+
void Compra()
  {
   double price = simbolo.Ask();
   double stoploss = simbolo.NormalizePrice(price - SL); // Cálculo normalizado do stoploss
   double takeprofit = simbolo.NormalizePrice(price + TP); // Cálculo normalizado do takeprofit
   negocio.Buy(Volume, _Symbol, price, stoploss, takeprofit, "Compra"); // Envio da ordem de compra pela classe responsável
  }
//+------------------------------------------------------------------+
//| Realizar venda com parâmetros especificados por input            |
//+------------------------------------------------------------------+
void Venda()
  {
   double price = simbolo.Bid();
   double stoploss = simbolo.NormalizePrice(price + SL); // Cálculo normalizado do stoploss
   double takeprofit = simbolo.NormalizePrice(price - TP); // Cálculo normalizado do takeprofit
   negocio.Sell(Volume, _Symbol, price, stoploss, takeprofit, "Venda"); // Envio da ordem de compra pela classe responsável
  }
//+------------------------------------------------------------------+
//| Fechar posição aberta                                            |
//+------------------------------------------------------------------+
void Fechar()
  {
// Verificação de posição aberta
   int total = PositionsTotal();
   for(int i=total-1; i>=0; i--)
     {
      ulong ticket = PositionGetTicket(i);
      if(!PositionSelectByTicket(ticket))
         continue;
      if(PositionGetString(POSITION_SYMBOL)!=_Symbol || PositionGetInteger(POSITION_MAGIC)!=Magic)
         continue;
      negocio.PositionClose(ticket);
     }
  }
//+------------------------------------------------------------------+
//| Verificar se há posição aberta                                   |
//+------------------------------------------------------------------+
bool SemPosicao()
  {
   int total = PositionsTotal();
   for(int i=total-1; i>=0; i--)
     {
      ulong ticket = PositionGetTicket(i);
      if(!PositionSelectByTicket(ticket))
         continue;
      if(PositionGetString(POSITION_SYMBOL)!=_Symbol || PositionGetInteger(POSITION_MAGIC)!=Magic)
         continue;
      return false;
     }
     
   return true;
  }
//+------------------------------------------------------------------+
//| Estratégia                                                       |
//+------------------------------------------------------------------+
int Sinal()
  {
  double diMais[],diMenos[],adx[], OsMA_signal[]; // Dynamic arrays to hold the values of +DI, -DI and ADX values for each bars

   ArraySetAsSeries(adx,true);
   ArraySetAsSeries(diMais,true);
   ArraySetAsSeries(diMenos,true);
   ArraySetAsSeries(OsMA_signal,true);
   
   CopyBuffer(adxHandle,0,0,3,adx);
   CopyBuffer(adxHandle,1,0,3,diMais);
   CopyBuffer(adxHandle,2,0,3,diMenos);
   CopyBuffer(handle_iOsMA,0,0,3,OsMA_signal);
   
   if(OsMA_signal[0]>OsMA_Compra && adx[0]>Adx_Min && diMais[1]>diMenos[1] && diMais[2]<diMenos[2])
      return 1;
   if(OsMA_signal[0]<OsMA_Venda && adx[0]>Adx_Min && diMais[1]<diMenos[1] && diMais[2]>diMenos[2])
      return -1;
   
   return 0;
  }
//+------------------------------------------------------------------+

Se puderem ajudar. Agradeço! Abraço!

Razão: