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.
- Aplicativos de negociação gratuitos
- 8 000+ sinais para cópia
- Notícias econômicas para análise dos mercados financeiros
Você concorda com a política do site e com os termos de uso
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!