Erro para encerrar posições no fim do dia: 10036 - TRADE_RETCODE_POSITION_CLOSED
Olá pessoal!
Estou quebrando a cabeça há dias com erros que estou tendo para encerrar posições no fim do dia por horário caso ainda esteja posicionado. Já pesquisei no forum e no Google e não achei nada que resolvesse.
Sempre usei essa lógica há anos e sempre funcionou, mas recentemente começou a dar erros. As posições são fechadas corretamente no horário parametrizado, mas o erro ocorre.
Na verdade os erros variam, na ordem que mais acontecem:
- 10036 - TRADE_RETCODE_POSITION_CLOSED
- 10039 - TRADE_RETCODE_CLOSE_ORDER_EXIST
- 10014 - TRADE_RETCODE_INVALID_VOLUME
Minha suspeita era que a chamada do PositionClose da classe CTrade estava sendo chamada mais de uma vez devido ao alto volume de negócios do míni índice (WIN), que quando até finalizar o processando de um tick com a posição encerrada, outro tick já estava chamando o procedimento OnTick simultaneamente e com isso estava chamando o PositionClose repetidamente. Depois pesquisei mais detalhadamente o funcionamento do MT5 e na documentação consta que os ticks não rodam em paralelo e nem enfileiram, um novo tick só será processado ao finalizar o processamento do anterior. Portanto acabei descardando essa opção.
Também pensei que poderia ser algum problema com o loop para achar a posição do respectivo EA, pois como há dias como hoje que haviam 6 posições abertas no fim do dia e todas encerraram no mesmo momento, se a primeira posição tivesse sido fechada antes do último EA processar o loop por completo e selecionar a sua posição, poderia dar alguma problema na seleção da posição, uma vez que a ordens das posições mudam e interfere na função PositionGetTicket. Porém se não tivesse achando a posição, nem teria executado o comando de PositionClose, portanto não teria dado o erro. E mesmo que houver essa interferência no loop e não achar a posição no OnTick, no próximo tick a função seria executada novamente e acharia a posição. Mas não é o caso pois como veremos no log mais abaixo, a função só está sendo chamada uma vez.
Meu código inteiro é bem grande então vou colocar os trechos relevantes. Coloquei alguns prints extras para tentar identificar o problema.
Esse trecho está numa função chamada pelo OnTick:
Experimentei até por um Sleep para não executar outra chamada de fechamento sem ter concluído a anterior.
Esta é a função FechaPosicao chamada no trecho anterior.
Nela eu trato conta hedge e netting. Estou usando conta hedge e opero múltiplos robôs no mesmo ativo.
Agora o log da aba Experts da execução de hoje:
Reparem que pelas mensagens tanto o trecho do primeiro código quanto a função FechaPosicao é executada somente uma vez por EA. Portanto está ilógico o erro de Posição já ter sido fechada. Se olhar na aba Histórico, as 6 posições foram fechadas corretamente nesse mesmo horário do log.
Esse é o log detalhado das operações:
A lógica de encerramento de posição é bem simples, não tem firula. Está parecendo algum problema interno na classe CTrade talvez.
Alguém tem alguma ideia ou direcionamento para resolver esses erros?
Obrigado!
Bom dia,
Tenho uma pergunta: Você deseja encerrar TODAS as posições abertas incondicionalmente e independente se é HEDGE ou NETTING? Se positivo você poderá substituir por apenas essas linhas abaixo. Eu utilizo essas linhas abaixo tanto nos meus EA´s Hedge quanto Netting, e são fechadas sempre nunca tive erro até hoje. Muitas vezes com várias posições simultâneas abertas e todas fecham imediatamente.
Utilizo a CTrade.
//INI: Fechar todas as Posições void FecharTodasPosicoes() { int i=PositionsTotal()-1; while (i>=0) { if (negocio.PositionClose(PositionGetSymbol(i))) i--; } } //FIM: Fechar todas as Posições
Bom dia,
Tenho uma pergunta: Você deseja encerrar TODAS as posições abertas incondicionalmente e independente se é HEDGE ou NETTING? Se positivo você poderá substituir por apenas essas linhas abaixo. Eu utilizo essas linhas abaixo tanto nos meus EA´s Hedge quanto Netting, e são fechadas sempre nunca tive erro até hoje. Muitas vezes com várias posições simultâneas abertas e todas fecham imediatamente.
Utilizo a CTrade.
Olá Ruy obrigado pela resposta.
Na verdade vários robôs rodam independentemente e a ideia seria cada um fechar a sua posição. No WIN eu encerro todas as posições mas tem ativos como o CCM que eu faço swing trade, portanto as posições não são encerradas no fim do dia.
Mas é um teste que posso fazer para ver se um robô encerrar todas as posições dará o erro também.
Boa tarde rosdibin,
Estou passando pelo mesmo problema que você. Tenho um robô rodando na [EDITADO]. Quando dá a condição de fechar a operação a mercado, utilizo o CTrade trade.PositionClose(), mas não fecha a posição, embora mostrar no log do mt5 que a posição foi "fechada". Como a posição ainda está aberta, na aba "Negociações" da caixa de ferramentas, fica uma ordem com status "requesting..." e, para fechar a posição, tenho que pausar o EA, cancelar essa ordem e depois fechar manualmente a posição.
Ainda não consegui resolver esse problema da função trade.PositionClose() não fechar a posição.
Seguem partes do código referente ao fechamento da posição.
#include <Trade\Trade.mqh> input ENUM_ORDER_TYPE_FILLING preenchimento = ORDER_FILLING_RETURN;//Preenchimento da Ordem input ulong magicNum = 123456;//Magic Number CTrade trade; int OnInit() { trade.SetTypeFilling(preenchimento); trade.SetExpertMagicNumber(magicNum); } void OnTick { //condição de fechamento da posição if(counterPositionSymbol > 0 && NumeroDias < nDiasStop && bar_index != -1) { for(int j=PositionsTotal()-1; j>=0 ; j--) // look at all positions { // get the ticket number for the current position ulong ticket = PositionGetInteger(POSITION_TICKET); string positionSymb= PositionGetString(POSITION_SYMBOL); if(positionSymb==Ativos[i]) { // close the current position if(!trade.PositionClose(ticket)) { Print("Preço acima da média superior: PositionClose() falhou. Return code=",trade.ResultRetcode(),". Descrição do código: ",trade.ResultRetcodeDescription()); } else { Print("Preço acima da média superior. Posição fechada: ", Ativos[i]); Print("Preço acima da média superior: PositionClose() executado corretamente. Return code=",trade.ResultRetcode()," (",trade.ResultRetcodeDescription(),")"); } } } // end the for loop } }
Seguem os logs do robô tentando fechar:
GL 0 10:08:11.267 Trades ' xxxxx ': exchange sell 1.4K RADL3 at market, close #626899252 buy 1.4K RADL3 22.27929
CL 0 10:08:11.316 Trades ' xxxxx ': accepted exchange sell 1.4K RADL3 at market, close #626899252 buy 1.4K RADL3 22.27929
HS 0 10:08:11.316 Trades ' xxxxx ': exchange sell 1.4K RADL3 at market, close #626899252 buy 1.4K RADL3 22.27929 placed for execution (Order received. Sending to OMS.)
IE 0 10:08:14.457 Trades ' xxxxx ': order #629818917 sell 1.4K / 1.4K RADL3 at market done in 3190.487 ms
QM 0 10:08:14.457 Trades ' xxxxx ': exchange sell 1.4K RADL3 at market, close #626899252 buy 1.4K RADL3 22.27929
HR 2 10:08:14.503 Trades 'xxxxx': failed exchange sell 1.4K RADL3 at market, close #626899252 buy 1.4K RADL3 22.27929 [Order to close this position already exists]
.....continua esse erro
Seguem os logs do cancelamento manual da ordem que o EA enviou e o fechamento manual da posição:
HH 0 10:09:32.124 Experts automated trading is disabled
RM 0 10:09:36.350 Trades ' xxxxx ': cancel order #629818917 sell 1.4K RADL3 at market
MQ 0 10:09:36.394 Trades ' xxxxx ': accepted cancel order #629818917 sell 1.4K RADL3 at market
NG 0 10:09:36.394 Trades ' xxxxx ': cancel order #629818917 sell 1.4K RADL3 at market placed for execution (Cancel received. Sending to OMS)
GI 0 10:09:41.314 Trades ' xxxxx ': cancel #629818917 sell 1.4K RADL3 at market done in 4963.680 ms
LH 0 10:09:42.746 Trades ' xxxxx ': exchange sell 1.4K RADL3 at market, close #626899252 buy 1.4K RADL3 22.27929
HH 0 10:09:42.802 Trades ' xxxxx ': accepted exchange sell 1.4K RADL3 at market, close #626899252 buy 1.4K RADL3 22.27929
LF 0 10:09:42.803 Trades ' xxxxx ': exchange sell 1.4K RADL3 at market, close #626899252 buy 1.4K RADL3 22.27929 placed for execution (Order received. Sending to OMS.)
CJ 0 10:09:46.841 Trades ' xxxxx ': order #629822341 sell 1.4K / 1.4K RADL3 at market done in 4095.016 ms
KH 0 10:09:46.841 Trades ' xxxxx ': deal #178884333 sell 400 RADL3 at 22.46 done (based on order #629822341)
PJ 0 10:09:46.842 Trades ' xxxxx ': deal #178884334 sell 300 RADL3 at 22.46 done (based on order #629822341)
GM 0 10:09:46.842 Trades ' xxxxx ': deal #178884335 sell 100 RADL3 at 22.46 done (based on order #629822341)
RO 0 10:09:46.843 Trades ' xxxxx ': deal #178884336 sell 600 RADL3 at 22.46 done (based on order #629822341)
Seguem os logs do EA:
FN 0 10:08:14.457 Preço acima da média superior. Posição fechada: RADL3
FN 0 10:08:14.457 Preço acima da média superior: PositionClose() executado corretamente. Return code=10009 (done)
MN 0 10:08:14.503 CTrade::OrderSend: exchange sell 1400.00 RADL3 [close order already exists]
QD 0 10:08:14.503 Preço acima da média superior: PositionClose() falhou. Return code=10039. Descrição do código: close order already exists
PG 0 10:08:14.603 CTrade::OrderSend: exchange sell 1400.00 RADL3 [close order already exists]
QO 0 10:08:14.604 Preço acima da média superior: PositionClose() falhou. Return code=10039. Descrição do código: close order already exists
OO 0 10:08:14.697 CTrade::OrderSend: exchange sell 1400.00 RADL3 [close order already exists]
.....continua esse erro
Boa tarde rosdibin,
Olá,
no caso você esqueceu de obter a da posição, antes de manusear os dados!
PositionGetSymbol ( J );
Olá,
no caso você esqueceu de obter a da posição, antes de manusear os dados!
PositionGetSymbol ( J );
Muito obrigado Rogério,
Fiz a correção. Vou analisar os próximos fechamentos de posição para ver se solucionou o problema. Contudo, ele rodava assim antigamente e fechava as posições normalmente.
Valeu!
Muito obrigado Rogério,
Fiz a correção. Vou analisar os próximos fechamentos de posição para ver se solucionou o problema. Contudo, ele rodava assim antigamente e fechava as posições normalmente.
Valeu!
Então,
ou em outro ponto do programa você selecionou a POSIÇÃO, ou quando só tem uma POSIÇÃO o código "pode" dar certo (dúvido muito, mas...).
Você já verificou o código da CTrade , para ver se o problema não está em como é criada a ordem para fechar?
Por exemplo, estava pensando se durante o leilão de fechamento ele vai fechar de modo garantido. Olha só a lógica desse método:
bool CTrade::PositionClose(const string symbol,const ulong deviation) { bool partial_close=false; int retry_count =10; uint retcode =TRADE_RETCODE_REJECT; //--- check stopped if(IsStopped(__FUNCTION__)) return(false); //--- clean ClearStructures(); //--- check filling if(!FillingCheck(symbol)) return(false); do { //--- check if(SelectPosition(symbol)) { if((ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY) { //--- prepare request for close BUY position m_request.type =ORDER_TYPE_SELL; m_request.price=SymbolInfoDouble(symbol,SYMBOL_BID); } else { //--- prepare request for close SELL position m_request.type =ORDER_TYPE_BUY; m_request.price=SymbolInfoDouble(symbol,SYMBOL_ASK); } }
Veja que ele pega o bid/ask para montar a ordem. Mas no leilão esses preços podem ficar bem distorcidos. Suponha que você quer vender e então pega o bid do leilão como preço de venda. Mas o bid pode estar muito acima do ask nesse caso e você pode não conseguir executar a ordem, porque colocou um preço ruim...
Ainda estou pensando como fazer isso, mas usar esse método da CTrade não parece ser uma boa ideia nos casos de leilão.
Olá pessoal!
Estou quebrando a cabeça há dias com erros que estou tendo para encerrar posições no fim do dia por horário caso ainda esteja posicionado. Já pesquisei no forum e no Google e não achei nada que resolvesse.
Sempre usei essa lógica há anos e sempre funcionou, mas recentemente começou a dar erros. As posições são fechadas corretamente no horário parametrizado, mas o erro ocorre.
Na verdade os erros variam, na ordem que mais acontecem:
Minha suspeita era que a chamada do PositionClose da classe CTrade estava sendo chamada mais de uma vez devido ao alto volume de negócios do míni índice (WIN), que quando até finalizar o processando de um tick com a posição encerrada, outro tick já estava chamando o procedimento OnTick simultaneamente e com isso estava chamando o PositionClose repetidamente. Depois pesquisei mais detalhadamente o funcionamento do MT5 e na documentação consta que os ticks não rodam em paralelo e nem enfileiram, um novo tick só será processado ao finalizar o processamento do anterior. Portanto acabei descardando essa opção.
Também pensei que poderia ser algum problema com o loop para achar a posição do respectivo EA, pois como há dias como hoje que haviam 6 posições abertas no fim do dia e todas encerraram no mesmo momento, se a primeira posição tivesse sido fechada antes do último EA processar o loop por completo e selecionar a sua posição, poderia dar alguma problema na seleção da posição, uma vez que a ordens das posições mudam e interfere na função PositionGetTicket. Porém se não tivesse achando a posição, nem teria executado o comando de PositionClose, portanto não teria dado o erro. E mesmo que houver essa interferência no loop e não achar a posição no OnTick, no próximo tick a função seria executada novamente e acharia a posição. Mas não é o caso pois como veremos no log mais abaixo, a função só está sendo chamada uma vez.
Meu código inteiro é bem grande então vou colocar os trechos relevantes. Coloquei alguns prints extras para tentar identificar o problema.
Esse trecho está numa função chamada pelo OnTick:
Experimentei até por um Sleep para não executar outra chamada de fechamento sem ter concluído a anterior.
Esta é a função FechaPosicao chamada no trecho anterior.
Nela eu trato conta hedge e netting. Estou usando conta hedge e opero múltiplos robôs no mesmo ativo.
Agora o log da aba Experts da execução de hoje:
Reparem que pelas mensagens tanto o trecho do primeiro código quanto a função FechaPosicao é executada somente uma vez por EA. Portanto está ilógico o erro de Posição já ter sido fechada. Se olhar na aba Histórico, as 6 posições foram fechadas corretamente nesse mesmo horário do log.
Esse é o log detalhado das operações:
A lógica de encerramento de posição é bem simples, não tem firula. Está parecendo algum problema interno na classe CTrade talvez.
Alguém tem alguma ideia ou direcionamento para resolver esses erros?
Obrigado!