Prezados,
Pesquisei bastante no fórum antes de abrir novo tópico e até encontrei temas semelhantes, mas nada que se encaixasse no meu problema. Sou estudante de MQL e estou a desenvolver um robozinho tosco de teste e aí me deparei com o seguinte problema: O trailing stop acompanha o indicador customizado ATR com uma distância de segurança de 10 pontos de dólar. Até aí tudo perfeito, conforme o trade evolui ele vai embora sem problemas, porém observo no log que o robô está tentando incessantemente modificar posições já modificadas (para o mesmo nível de preço) vindo a ocasionar o erro 10016 (stop inválido). Já criei algumas funções booleanas com for loop para 'avisar' que o trailing já foi ativado e modificar o stop loss somente uma vez, mas ao contrário, o trailing para de funcionar. Segue parte do código para que alguém possa me ajudar a encontrar onde está minha falha, que talvez possam ser muitas. Resumindo, quero que o robô pare de tentar alterar incessantemente, através do trade.PositionModify, a posição desnecessariamente, esperando que o indicador ATR se altere para, aí sim, modificar a posição. De antemão já agradeço pelos bons préstimos e paciência.
Poste o código inteiro... ninguém consegue adivinhar o começo de tudo, inclusive do problema...
Lembre-se sempre que em mercados de alta volatilidade você tem que checar se não está re-enviando os stops para os lugares de Preços Inválidos...
;)
Poste o código inteiro... ninguém consegue adivinhar o começo de tudo, inclusive do problema...
Lembre-se sempre que em mercados de alta volatilidade você tem que checar se não está re-enviando os stops para os lugares de Preços Inválidos...
;)
Caro Flavio, muito obrigado pela atenção!
Segue o código completo:
//---bibliotecas e classes #include <Trade\Trade.mqh> CTrade trade; //--- input int vol=2;//Qtd. de contratos input ulong _deviation=3.00;//slippage //---Magic Number //ulong magicNum = 123456; //---handles int h_maM15; int h_atr; //---buffers double maM15[]; double upAtr[]; double downAtr[]; //---structs: MqlRates ratesM15[]; MqlTick negocio; //--- double STL; double PRC; //--- bool ordPend;//para verificação de ordens pendentes //--- int OnInit() { //---média móvel em 15' h_maM15=iMA(_Symbol,PERIOD_M15,21,0,MODE_EMA,PRICE_CLOSE); if(h_maM15==INVALID_HANDLE) { Print("Erro ao criar a MA no PERIOD_M15. Código = ",GetLastError()); return(INIT_FAILED); } //---atr h_atr=iCustom(_Symbol,PERIOD_M15,"Mod_ATR_Trailing_Stop",14,2); if(h_atr==INVALID_HANDLE) { Print("Erro ao criar o indicador ATR. Código do Terminal nº ",GetLastError()); return(INIT_FAILED); } //--- ArraySetAsSeries(maM15,true); ArraySetAsSeries(ratesM15,true); ArraySetAsSeries(upAtr,true); ArraySetAsSeries(downAtr,true); //--- return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { //--- } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { //---média móvel em 15' if(CopyBuffer(h_maM15,0,0,4,maM15)<0) { Alert("Erro ao copiar os dados da MA_M15 - Erro = ",GetLastError()); return; } //---vela de 15' if(CopyRates(_Symbol,PERIOD_M15,0,4,ratesM15)<0) { Alert("Erro ao copiar as informações da vela de 15 minutos - Erro = ",GetLastError()); return; } //---upAtr if(CopyBuffer(h_atr,0,0,4,upAtr)<0) { Alert("Erro ao copiar dados para o indicador ATR - Erro = ",GetLastError()); return; } //---downAtr if(CopyBuffer(h_atr,1,0,4,downAtr)<0) { Alert("Erro ao copiar dados para o indicador ATR - Erro = ",GetLastError()); return; } //---preço if(!SymbolInfoTick(_Symbol,negocio)) { Alert("Erro ao copiar dados de preços. Erro nº ",GetLastError()); return; } //---verificação de ordens pendentes: ordPend=false; for(int i=OrdersTotal()-1; i>=0; i--) { ulong _ticket = OrderGetTicket(i); string _symbol = OrderGetString(ORDER_SYMBOL); //ulong _magic = OrderGetInteger(ORDER_MAGIC); if(_symbol==_Symbol/*&&_magic==magicNum*/) { ordPend=true; break; Print("Já existe ordem pendente!"); } } //---estratégia de compra (exemplo) if(!PositionSelect(_Symbol) && !ordPend) { if(ratesM15[1].close>maM15[1] && downAtr[1]!=EMPTY_VALUE && ratesM15[0].open>maM15[0] && ratesM15[1].close>ratesM15[2].close && ratesM15[2].close>ratesM15[3].close) { LOen(); } } //---estratégia de venda (exemplo) if(!PositionSelect(_Symbol) && !ordPend) { if(ratesM15[1].close<maM15[1] && upAtr[1]!=EMPTY_VALUE && ratesM15[0].open<maM15[0] && ratesM15[1].close<ratesM15[2].close && ratesM15[2].close<ratesM15[3].close) { SHen(); } } //---Venda à mercado para encerrar operação de compra mais trailing-stop if(PositionSelect(_Symbol)) { if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY) { trailingStopDown(); } if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY && downAtr[1]==EMPTY_VALUE) { Exit(); } } //---Compra à mercado para encerrar operação de venda mais trailing-stop if(PositionSelect(_Symbol)) { if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_SELL) { trailingStopUp(); } if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_SELL && upAtr[1]==EMPTY_VALUE) { Exit(); } } } //---Abertura de posição com compra à mercado void LOen() { PRC=NormalizeDouble(negocio.ask,_Digits); if(trade.Buy(2,_Symbol,PRC,STL,0,"LOen")) { Print("Compra realizada com sucesso. Cód. do Servidor nº ",trade.ResultRetcode(),"\nDescrição: ",trade.ResultRetcodeDescription()); } else { Print("Falha na compra. Cód. do Servidor nº ",trade.ResultRetcode(),"\nDescrição: ",trade.ResultRetcodeDescription()); } } //---Abertura de posição com venda à mercado void SHen() { PRC=NormalizeDouble(negocio.bid,_Digits); if(trade.Sell(2,_Symbol,PRC,STL,0,"SHen")) { Print("Venda realizada com sucesso. Cód. do Servidor nº ",trade.ResultRetcode(),"\nDescrição: ",trade.ResultRetcodeDescription()); } else { Print("Falha na venda. Cód. do Servidor nº ",trade.ResultRetcode(),"\nDescrição: ",trade.ResultRetcodeDescription()); } } //---Fechamento de posição à mercado void Exit() { for(int i=PositionsTotal()-1; i>=0; i--) { string _symbol = PositionGetSymbol(i); ulong _ticket = PositionGetInteger(POSITION_TICKET); if(_symbol==_Symbol) { if(trade.PositionClose(_ticket,_deviation)) { Print("Operação finalizada com sucesso. Cód. do Servidor nº ",trade.ResultRetcode(),"\nDescrição: ",trade.ResultRetcodeDescription()); } else { Print("Falha no encerramento de posição. Cód. do Servidor nº ",trade.ResultRetcode(),"\nDescrição: ",trade.ResultRetcodeDescription()); } } } } //---Trailing-stop em posição comprada void trailingStopDown() { for(int i=PositionsTotal()-1; i>=0; i--) { string _symbol = PositionGetSymbol(i); //ulong _magic = PositionGetInteger(POSITION_MAGIC); if(_symbol==_Symbol/*&&_magic==magicNum*/) { double priceOpen=PositionGetDouble(POSITION_PRICE_OPEN); ulong _ticket=PositionGetInteger(POSITION_TICKET);//ok double _stlAtual=PositionGetDouble(POSITION_SL);//ok if(downAtr[1]!=EMPTY_VALUE && downAtr[1]>_stlAtual+10) { double newSTL=NormalizeDouble(downAtr[1],_Digits)-MathMod(NormalizeDouble(downAtr[1],_Digits),0.5)-10; if(trade.PositionModify(_ticket,newSTL,0)) { Print("Trailing-Stop funcionando corretamente. Cód. Servidor = ",trade.ResultRetcode(),"\nDescrição: ",trade.ResultRetcodeDescription()); Comment("Dif Stop-Atr = ",MathAbs(newSTL-downAtr[1])-MathMod(MathAbs(newSTL-downAtr[1]),0.5)); } else { Print("Trailing-Stop NÃO está funcionando corretamente. Cód. Servidor = ",trade.ResultRetcode(),"\nDescrição: ",trade.ResultRetcodeDescription()); } } } } } //---Trailing-stop em posição vendida void trailingStopUp() { for(int i=PositionsTotal()-1; i>=0; i--) { string _symbol = PositionGetSymbol(i); //ulong _magic = PositionGetInteger(POSITION_MAGIC); if(_symbol==_Symbol/*&&_magic==magicNum*/) { double priceOpen=PositionGetDouble(POSITION_PRICE_OPEN); ulong _ticket=PositionGetInteger(POSITION_TICKET);//ok double _stlAtual=PositionGetDouble(POSITION_SL);//ok if(upAtr[1]!=EMPTY_VALUE) { double newSTL=NormalizeDouble(upAtr[1],_Digits)-MathMod(NormalizeDouble(upAtr[1],_Digits),0.5)+10; if(trade.PositionModify(_ticket,newSTL,0)) { Print("Trailing-Stop funcionando corretamente. Cód. Servidor = ",trade.ResultRetcode(),"\nDescrição: ",trade.ResultRetcodeDescription()); Comment("Dif Stop-Atr = ",MathAbs(newSTL-upAtr[1])-MathMod(MathAbs(newSTL-upAtr[1]),0.5)); } else { Print("Trailing-Stop NÃO está funcionando corretamente. Cód. Servidor = ",trade.ResultRetcode(),"\nDescrição: ",trade.ResultRetcodeDescription()); } } } } } //---End
Problema solucionado! Tanto pela função 'bool isNewBar()' quanto, com algumas modificações, pela biblioteca Lib CisNewBar.mqh. Só ainda não verifiquei qual das duas formas vai deixar o EA mais rápido, nem seus prós e contras.
Obrigado.
Problema solucionado! Tanto pela função 'bool isNewBar()' quanto, com algumas modificações, pela biblioteca Lib CisNewBar.mqh. Só ainda não verifiquei qual das duas formas vai deixar o EA mais rápido, nem seus prós e contras.
Obrigado.
poderia me explicar como fez a correção? desde ja agradeç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
Prezados,
Pesquisei bastante no fórum antes de abrir novo tópico e até encontrei temas semelhantes, mas nada que se encaixasse no meu problema. Sou estudante de MQL e estou a desenvolver um robozinho tosco de teste e aí me deparei com o seguinte problema: O trailing stop acompanha o indicador customizado ATR com uma distância de segurança de 10 pontos de dólar. Até aí tudo perfeito, conforme o trade evolui ele vai embora sem problemas, porém observo no log que o robô está tentando incessantemente modificar posições já modificadas (para o mesmo nível de preço) vindo a ocasionar o erro 10016 (stop inválido). Já criei algumas funções booleanas com for loop para 'avisar' que o trailing já foi ativado e modificar o stop loss somente uma vez, mas ao contrário, o trailing para de funcionar. Segue parte do código para que alguém possa me ajudar a encontrar onde está minha falha, que talvez possam ser muitas. Resumindo, quero que o robô pare de tentar alterar incessantemente, através do trade.PositionModify, a posição desnecessariamente, esperando que o indicador ATR se altere para, aí sim, modificar a posição. De antemão já agradeço pelos bons préstimos e paciência.