EA operando com mini dólar (WDOG20) fica com posição pendente pelo resto do dia

Para adicionar comentários, por favor Faça o login ou registrar
Igor Brites
26
Igor Brites  

Olá pessoas!

Estou tentando fazer um EA para operar com mini índices e mini dólar, mas estou apanhando pra uma coisa simples: quando tento entrar vendido ou comprado (no caso é uma ordem a limite com data de expiração), a posição fica aberta pelo resto do dia, mesmo com os valores de SL e TP sendo atingidos várias vezes durante o dia, assim como a data de expiração. Onde estou errando?

Segue o código que estou usando:

#define MAGIC_NUMBER 9264926492192;

bool SetOrder(ENUM_ORDER_TYPE operation) {
  MqlTradeRequest request = {0};
  MqlTradeResult result = {0};
  MqlTradeCheckResult checkResult = {0};

  double loss = 5;
  double gain = 1.5;

  datetime orderExpiration = (datetime)(TimeCurrent() + 60);

  request.symbol = Symbol();
  request.volume = 1;
  request.type = operation;
  request.action = TRADE_ACTION_PENDING;
  request.type_filling = ORDER_FILLING_RETURN;
  request.type_time = ORDER_TIME_DAY;
  request.deviation = 1;
  request.expiration = orderExpiration;
  request.magic = MAGIC_NUMBER;

  switch (operation) {
    case ORDER_TYPE_BUY_LIMIT:
      entryPrice = NormalizeDouble(SymbolInfoDouble(Symbol(), SYMBOL_ASK), Digits());
      request.sl = NormalizeDouble(entryPrice - loss, Digits());
      request.tp = NormalizeDouble(entryPrice + gain, Digits());
      break;
    case ORDER_TYPE_SELL_LIMIT:
      entryPrice = NormalizeDouble(SymbolInfoDouble(Symbol(), SYMBOL_BID), Digits());
      request.sl = NormalizeDouble(entryPrice + loss, Digits());
      request.tp = NormalizeDouble(entryPrice - gain, Digits());
      break;
  }

  request.price = entryPrice;

  if (!OrderCheck(request, checkResult)) {
    Print("Error checking order: ", checkResult.retcode);
    return false;
  }

  if (!OrderSend(request, result)) {
    Print("Error sending order: ", result.retcode);
    return false;
  }

  if (result.retcode != TRADE_RETCODE_DONE && result.retcode != TRADE_RETCODE_PLACED) {
    Print("Error executing order: ", result.retcode);
    return false;
  }
  
  Print("Status: ", result.retcode);

  return true;
}

Desde já agradeço!

Romeu Bertho
6011
Romeu Bertho  

Bom dia!

Você está utilizando o type_time errado para esta finalidade, de qualquer maneira nossa bolsa não suporta esta funcionalidade.

Você precisará gerenciar suas ordens de maneira independente.

Abs. 

Igor Brites
26
Igor Brites  
Romeu Bertho:

Bom dia!

Você está utilizando o type_time errado para esta finalidade, de qualquer maneira nossa bolsa não suporta esta funcionalidade.

Você precisará gerenciar suas ordens de maneira independente.

Abs. 

Obrigado pela resposta Romeu!

Sobre o time_type, se eu executo o "SymbolInfoInteger(Symbol(), SYMBOL_EXPIRATION_MODE)" ele me retorna "SYMBOL_EXPIRATION_DAY", e em outros posts aqui no fórum (como esse) disseram que ativos futuros só funcionam com "ORDER_TIME_DAY".

Agora sobre a bolsa não suportar, não é possível fazer um EA para trabalhar com ativos futuros porque a BMF não permite? O que exatamente nossa bolsa não suporta?

Obrigado!

Como programar Pending Orders para o mini-dólar
Como programar Pending Orders para o mini-dólar
  • 2015.01.28
  • www.mql5.com
Depois mudei o EA e coloquei Pending Orders, mas, para a minha surpresa, nos backtests sempre aparecia a mensagem "Invalid Expiration" para a BUY STOP/SELL STOP order, testando no WDO@.
Rogerio Giannetti Torres
3254
Rogerio Giannetti Torres  
Igor Brites:

Olá pessoas!

.... a posição fica aberta pelo resto do dia, mesmo com os valores de SL e TP sendo atingidos várias vezes durante o dia, assim como a data de expiração. Onde estou errando!

...

Bom dia, 

O tipo de ordem permitido e a validade permitida para um instrumento você pode ver na especificação deste instrumento nos campos, MODO GTC  e TERMINO VALIDADE.

Quanto ao SL/TP da posição não ser executada apesar de ter negócios executados no preços de start é muito estranho, tem como evidenciar essa informação no LOG DIÁRIO?



Romeu Bertho
6011
Romeu Bertho  
Igor Brites:

Obrigado pela resposta Romeu!

Sobre o time_type, se eu executo o "SymbolInfoInteger(Symbol(), SYMBOL_EXPIRATION_MODE)" ele me retorna "SYMBOL_EXPIRATION_DAY", e em outros posts aqui no fórum (como esse) disseram que ativos futuros só funcionam com "ORDER_TIME_DAY".

Agora sobre a bolsa não suportar, não é possível fazer um EA para trabalhar com ativos futuros porque a BMF não permite? O que exatamente nossa bolsa não suporta?

Obrigado!

Boa tarde!

ORDER_TIME_GTC e ORDER_TIME_DAY funcionam.

Você não consegue enviar uma ordem com um determinado tempo de expiração para o seu cancelamento automático, pois esta configuração de ordem a nossa bolsa não suporta (ordem pendente com expiração). Para isso você/EA precisa monitorar a ordem pendente e cancelar quando julgar necessário (1 min após a colocação da ordem, por ex).

Abs.  

Igor Brites
26
Igor Brites  
Romeu Bertho:

Boa tarde!

ORDER_TIME_GTC e ORDER_TIME_DAY funcionam.

Você não consegue enviar uma ordem com um determinado tempo de expiração para o seu cancelamento automático, pois esta configuração de ordem a nossa bolsa não suporta (ordem pendente com expiração). Para isso você/EA precisa monitorar a ordem pendente e cancelar quando julgar necessário (1 min após a colocação da ordem, por ex).

Abs.  

Entendi, então vou controlar o tempo de expiração "manualmente". Mas ainda não entendi o porque de a posição não ser encerrada pelo SL ou TP. Vou precisar controlar estes manualmente também?

Edit: usando ORDER_TIME_GTC, independente da data de expiração (ou se simplesmente não defino uma) ele retorna TRADE_RETCODE_INVALID_EXPIRATION.
Igor Brites
26
Igor Brites  
Rogerio Giannetti Torres:

Bom dia, 

O tipo de ordem permitido e a validade permitida para um instrumento você pode ver na especificação deste instrumento nos campos, MODO GTC  e TERMINO VALIDADE.

Quanto ao SL/TP da posição não ser executada apesar de ter negócios executados no preços de start é muito estranho, tem como evidenciar essa informação no LOG DIÁRIO?


É isso que você pediu Rogério?

Edit: não sei como adicionar imagem no corpo da mensagem #noob
Arquivos anexados:
Rogerio Giannetti Torres
3254
Rogerio Giannetti Torres  

Bom dia Igor,

estava desconfiando você estava se referindo a uma ordem pendente, então respondendo a pergunta: SL/TP são gatilhos para uma POSIÇÃO e não para uma ORDEM.

Se você quer abrir uma posição vendida ou comprada a um preço limite, use ordens pendentes tipo  SELL_LIMIT ou BUY_LIMIT.



Documentação do MT5

Ao usar o registro de posições com "cobertura" (ACCOUNT_MARGIN_MODE_RETAIL_NETTING e ACCOUNT_MARGIN_MODE_EXCHANGE) segundo cada símbolo, a qualquer momento, pode estar aberta apenas a posição que seja o resultado de uma o mais transações. Não confunda as posições e as ordens pendentes ativas que são exibidas na guia "Negociação" na janela "Caixa de ferramentas".

Ao usar a exibição independente de posições, (ACCOUNT_MARGIN_MODE_RETAIL_HEDGING) segundo cada símbolo, podem ao mesmo tempo existir várias posições.

Igor Brites
26
Igor Brites  
Rogerio Giannetti Torres:

Bom dia Igor,

estava desconfiando você estava se referindo a uma ordem pendente, então respondendo a pergunta: SL/TP são gatilhos para uma POSIÇÃO e não para uma ORDEM.

Se você quer abrir uma posição vendida ou comprada a um preço limite, use ordens pendentes tipo  SELL_LIMIT ou BUY_LIMIT.



Documentação do MT5

Ao usar o registro de posições com "cobertura" (ACCOUNT_MARGIN_MODE_RETAIL_NETTING e ACCOUNT_MARGIN_MODE_EXCHANGE) segundo cada símbolo, a qualquer momento, pode estar aberta apenas a posição que seja o resultado de uma o mais transações. Não confunda as posições e as ordens pendentes ativas que são exibidas na guia "Negociação" na janela "Caixa de ferramentas".

Ao usar a exibição independente de posições, (ACCOUNT_MARGIN_MODE_RETAIL_HEDGING) segundo cada símbolo, podem ao mesmo tempo existir várias posições.

Rogério, muito obrigado pela resposta!

Sobre as ordens pendentes, estou usando ORDER_TYPE_BUY_LIMIT e ORDER_TYPE_SELL_LIMIT, ao criar o objeto do MqlTradeRequest. Mas agora fiquei confuso com relação a diferença entre ordem e posição: uma posição se transforma em uma ordem quando o SL ou o TP são atingidos? Ou o contrário? Ou nenhuma delas? (Entendo de programação, mas bem pouco de mercado)


Adiciono aqui o log da operação quando o programa (acredito eu) cria a posição:

2020.01.02 09:46:00   [Tick] Entrou vendido 2020.01.02 09:46:00
2020.01.02 09:46:00   sell limit 1.00 WDOG20 at 4018.000 sl: 4023.000 tp: 4016.500 (4018.000 / 4018.500 / 4018.000)
2020.01.02 09:46:00   order [#2 sell limit 1.00 WDOG20 at 4018.000] triggered
2020.01.02 09:46:00   deal #2 sell 1.00 WDOG20 at 4018.000 done (based on order #2)
2020.01.02 09:46:00   deal performed [#2 sell 1.00 WDOG20 at 4018.000]
2020.01.02 09:46:00   order performed sell 1.00 at 4018.000 [#2 sell limit 1.00 WDOG20 at 4018.000]
2020.01.02 09:46:00   [Operator] Ordem de Venda Executada; Status: Solicitação concluída
2020.01.02 09:46:00   [SetOrder] Ordem setada!
2020.01.02 09:46:00   [OnTrade] Entrou no OnTrade
2020.01.02 09:46:00   [OrderInfo] No order selected with ticket 2
2020.01.02 09:46:00   [TradeManager] Iniciando TradeManager
2020.01.02 09:46:00   [TradeManager] O número de posições abertas foi alterado de 0 para 1
2020.01.02 09:46:00   [TradeManager] O número de transações foi alterado de 1 para 2
2020.01.02 09:46:00   [TradeManager] O número de ordens no histórico foi alterado de 0 para 1
2020.01.02 09:46:00   [TradeManager] Finalizando TradeManager
2020.01.02 09:47:00   [PositionInfo] POSITION_TICKET: 2
2020.01.02 09:47:00   [PositionInfo] POSITION_TIME: 2020.01.02 09:46:00
2020.01.02 09:47:00   [PositionInfo] POSITION_TYPE: POSITION_TYPE_SELL
2020.01.02 09:47:00   [PositionInfo] POSITION_MAGIC: 9264926492192
2020.01.02 09:47:00   [PositionInfo] POSITION_IDENTIFIER: 2
2020.01.02 09:47:00   [PositionInfo] POSITION_VOLUME: 1.0
2020.01.02 09:47:00   [PositionInfo] POSITION_PRICE_OPEN: 4018.0
2020.01.02 09:47:00   [PositionInfo] POSITION_SL: 4023.0
2020.01.02 09:47:00   [PositionInfo] POSITION_TP: 4016.5
2020.01.02 09:47:00   [PositionInfo] POSITION_PRICE_CURRENT: 4018.0
2020.01.02 09:47:00   [PositionInfo] POSITION_SWAP: 0.0
2020.01.02 09:47:00   [PositionInfo] POSITION_PROFIT: 0.0
2020.01.02 09:47:00   [PositionInfo] POSITION_SYMBOL: WDOG20
2020.01.02 09:47:00   [PositionInfo] POSITION_COMMENT: 
2020.01.02 09:47:00   [PositionInfo] POSITION_EXTERNAL_ID: 

Esse PositionInfo é uma classe que fiz que imprime todas as informações de uma posição, se a mesma foi selecionada no PositionSelect(Symbol()). Ele se repete com essas informações até o fim do dia. O TradeManager é só uma classe onde controlo os contadores de ordens, posições e negócios.

Poderia indicar no meu código onde estou errando? Ou me enviar algum exemplo que funcione com o WDO? Segue o código:

#define MAGIC_NUMBER 9264926492192;

bool SetOrder(ENUM_ORDER_TYPE operation) {
  MqlTradeRequest request = {0};
  MqlTradeResult result = {0};
  MqlTradeCheckResult checkResult = {0};

  double loss = 5;
  double gain = 1.5;

  datetime orderExpiration = (datetime)(TimeCurrent() + 60);

  request.symbol = Symbol();
  request.volume = 1;
  request.type = operation;
  request.action = TRADE_ACTION_PENDING;
  request.type_filling = ORDER_FILLING_RETURN;
  request.type_time = ORDER_TIME_DAY;
  request.deviation = 1;
  request.expiration = orderExpiration;
  request.magic = MAGIC_NUMBER;

  switch (operation) {
    case ORDER_TYPE_BUY_LIMIT:
      entryPrice = NormalizeDouble(SymbolInfoDouble(Symbol(), SYMBOL_ASK), Digits());
      request.sl = NormalizeDouble(entryPrice - loss, Digits());
      request.tp = NormalizeDouble(entryPrice + gain, Digits());
      break;
    case ORDER_TYPE_SELL_LIMIT:
      entryPrice = NormalizeDouble(SymbolInfoDouble(Symbol(), SYMBOL_BID), Digits());
      request.sl = NormalizeDouble(entryPrice + loss, Digits());
      request.tp = NormalizeDouble(entryPrice - gain, Digits());
      break;
  }

  request.price = entryPrice;

  if (!OrderCheck(request, checkResult)) {
    Print("Error checking order: ", checkResult.retcode);
    return false;
  }

  if (!OrderSend(request, result)) {
    Print("Error sending order: ", result.retcode);
    return false;
  }

  if (result.retcode != TRADE_RETCODE_DONE && result.retcode != TRADE_RETCODE_PLACED) {
    Print("Error executing order: ", result.retcode);
    return false;
  }
  
  Print("Status: ", result.retcode);

  return true;
}
Vou dar uma lida nesse artigo pra entender as diferenças.
Ordens, posições e negócios no MetaTrader 5
Ordens, posições e negócios no MetaTrader 5
  • www.mql5.com
O maior objetivo de um comerciante é extrair lucros através dos meios de operações de negociação nos mercados financeiros. Esse artigo descreve os termos e processos da plataforma de negociação MetaTrader 5, o conhecimento necessário para uma compreensão adequada do desenvolvimento das funções comerciais da linguagem MQL5. Ordens — são as...
Rogerio Giannetti Torres
3254
Rogerio Giannetti Torres  

Olá Igor,

todo ativo tem um atributo chamado TICKSIZE (se não sabe o que é, veja a definição no google ).  Pois bem, tudo que tem referencia a preço em uma ORDEM, esse preço precisa obedecer ao TICKSIZE do instrumento.

Veja na documentação da classe CSymbolInfo a função NormalizePrice().

Documentação sobre MQL5: Biblioteca Padrão / Classes de negociação / CSymbolInfo
Documentação sobre MQL5: Biblioteca Padrão / Classes de negociação / CSymbolInfo
  • www.mql5.com
Biblioteca Padrão / Classes de negociação / CSymbolInfo - Referência sobre algorítimo/automatização de negociação na linguagem para MetaTrader 5
Igor Brites
26
Igor Brites  
Rogerio Giannetti Torres:

Olá Igor,

todo ativo tem um atributo chamado TICKSIZE (se não sabe o que é, veja a definição no google ).  Pois bem, tudo que tem referencia a preço em uma ORDEM, esse preço precisa obedecer ao TICKSIZE do instrumento.

Veja na documentação da classe CSymbolInfo a função NormalizePrice().

Vi que esses valores para o WDO estão da seguinte forma:

SYMBOL_TRADE_TICK_VALUE: 5.0
SYMBOL_TRADE_TICK_VALUE_PROFIT: 5.0
SYMBOL_TRADE_TICK_VALUE_LOSS: 5.0
SYMBOL_TRADE_TICK_SIZE: 0.5

De fato, eu já sabia que o mini dólar se move de meio em meio ponto (se você reparar no meu log do post anterior, vai ver que os valores respeitam esse tamanho do tick). Mas uma coisa que me deixou curioso foi o SYMBOL_TRADE_TICK_VALUE_PROFIT e SYMBOL_TRADE_TICK_VALUE_LOSS. Na documentação consta como "Preço de tick calculado para uma posição lucrativa/perdedora". O que isso quer dizer? Eu tentei até definir meu SL e TP com esses valores, mas a posição continua presa por todo o dia.

Sobre o NormalizePrice, achei a definição dele no GitHub e apliquei o mesmo cálculo no meu programa, mas também não ajudou no problema da posição presa.

gsemet/mt5-include
gsemet/mt5-include
  • gsemet
  • github.com
Contribute to gsemet/mt5-include development by creating an account on GitHub.
12
Para adicionar comentários, por favor Faça o login ou registrar