Olá,
Criei um EA para rodar no MT5 com algumas regras para se eu já estiver posicionado, ele não entrar novamente, porém percebo que ele acaba entrando duplicado quando tenho o sinal de compra ou de venda. ordens vão em um intervalo de milésimos de segundos. e nem todas as vezes duplica também.
O código que eu criei para essa validação e a ordem, sabem o que pode estar acontecendo para ele duplicar as ordens?
ok, mas ONDE você enfiou esse código??
De nada adianta mostrar um pedaço... O PRINCIPAL você não mencionou...
ok, mas ONDE você enfiou esse código??
De nada adianta mostrar um pedaço... O PRINCIPAL você não mencionou...
//+------------------------------------------------------------------+ //| Teste.mq5 | //| Felipe Sena | //| | //+------------------------------------------------------------------+ #property copyright "Felipe Sena" #property link "" #property version "1.00" //+------------------------------------------------------------------+ //| INCLUDES | //+------------------------------------------------------------------+ #include <Trade\Trade.mqh> CTrade trade; //+------------------------------------------------------------------+ //| INPUTS | //+------------------------------------------------------------------+ input int var_lote = 1; // Lotes input int var_periodoMedia = 9; input float var_variacaoMedia = 50.0; input float tp_buy = 250.0; // Gain em Operações de Compra. input float tp_sell = 250.0; // Gain em Operações de Venda. input float sl_buy = 300.0; // Loss em Operações de Compra. input float sl_sell = 300.0; // Loss em Operações de Venda. input string var_horario_Inicio = "09:10"; // Hora Inicio input string var_horario_limite = "17:30"; // Hora Fim input string var_encerraPosicao = "17:40"; // Encerrar Posições string CurrentTime; bool TradingIsAllowed=false; bool EncerrarPosicao=false; bool fezParcial=false; bool fezBreakEven=false; bool CheckTradingTime() { if(StringSubstr(CurrentTime,0,5) == var_horario_Inicio) TradingIsAllowed=true; EncerrarPosicao=false; if(StringSubstr(CurrentTime,0,5) == var_horario_limite) TradingIsAllowed=false; return TradingIsAllowed; //EncerrarPosicao; } bool CheckEncerrarPosicao() { if(StringSubstr(CurrentTime,0,5) == var_encerraPosicao) EncerrarPosicao=true; return EncerrarPosicao; } // GLOBAIS //////////////////////////////////////////////////////////////// int mediaHandle = INVALID_HANDLE; double media[]; double high[]; double low[]; MqlRates PriceInformation[]; //////////////////////////////////////////////////////////////////////////// int OnInit() { ArraySetAsSeries(media, true); mediaHandle = iMA(_Symbol,_Period,var_periodoMedia,0,MODE_EMA,PRICE_CLOSE); return(INIT_SUCCEEDED); } //////////////////////////////////////////////////////////////////////////// void OnTick() //| Inicio On Tick { //| OBTER DADOS int copy = CopyBuffer(mediaHandle,0,0,7,media); int data = CopyRates(_Symbol,_Period,0,Bars(_Symbol,_Period),PriceInformation); double preco = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_ASK),_Digits); bool sinalCompra = false; bool sinalVenda = false; double BarHigh0=iHigh(Symbol(),NULL,0); double BarHigh1=iHigh(Symbol(),NULL,1); double BarHigh2=iHigh(Symbol(),NULL,2); double BarHigh3=iHigh(Symbol(),NULL,3); double BarHigh4=iHigh(Symbol(),NULL,4); double BarHigh5=iHigh(Symbol(),NULL,5); double BarHigh6=iHigh(Symbol(),NULL,6); double BarLow0=iLow(Symbol(),NULL,0); double BarLow1=iLow(Symbol(),NULL,1); double BarLow2=iLow(Symbol(),NULL,2); double BarLow3=iLow(Symbol(),NULL,3); double BarLow4=iLow(Symbol(),NULL,4); double BarLow5=iLow(Symbol(),NULL,5); double BarLow6=iLow(Symbol(),NULL,6); double BarClose0=iClose(Symbol(),NULL,0); datetime time = TimeLocal(); CurrentTime = TimeToString(time,TIME_MINUTES); double Ask = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_ASK),_Digits); double Bid = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_BID),_Digits); // LOGICA SINAIS DE COMPRA E VENDA if (copy==7 && CheckTradingTime()==true) { if ( BarClose0 <= (media[0] + var_variacaoMedia) && BarClose0 > (media[0] - 20) && BarLow1 > media[1] ) { sinalCompra = true; } if ( BarClose0 >= (media[0] - var_variacaoMedia) && BarClose0 < (media[0] + 20) && BarHigh1 < media[1] ) { sinalVenda = true; } } //| VERIFICAR SE ESTOU POSICIONADO bool comprado = false; bool vendido = false; if(PositionSelect(_Symbol)) { if (PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY) { comprado = true; } if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_SELL) { vendido = true; } } //| LOGICA DE ROTEAMENTO if(!comprado && !vendido) { if(sinalCompra && !comprado) { trade.Buy(var_lote,_Symbol,Bid,(Bid - sl_buy+ var_variacaoMedia),(Bid + tp_buy + var_variacaoMedia),"Compra a Mercado"); } if(sinalVenda && !vendido) { trade.Sell(var_lote,_Symbol,Ask,(Ask + sl_sell - var_variacaoMedia),(Ask-tp_sell - var_variacaoMedia),"Venda a Mercado"); } } else { if(comprado) { if(sinalVenda && !vendido) { trade.Sell(var_lote*2,_Symbol,Ask,(Ask+ sl_sell - var_variacaoMedia),(Ask-tp_sell - var_variacaoMedia),"Virada de mão (compra->venda)"); } } else if (vendido) { if(sinalCompra && !comprado) { trade.Buy(var_lote*2,_Symbol,Bid,(Bid - sl_buy + var_variacaoMedia),(Bid + tp_buy + var_variacaoMedia),"Virada de mão (venda->compra)"); } } } //| ENCERRAR POSIÇÃO if(comprado && CheckEncerrarPosicao()==true) { trade.Sell(var_lote,_Symbol,Ask,0,(Ask * _Point),"Encerrar Posição"); } if(vendido && CheckEncerrarPosicao()==true) { trade.Buy(var_lote,_Symbol,Ask,0,(Ask * _Point),"Encerrar Posição"); } } //| Fim On Tick
Esse é código completo,
não entendo tanto de programação dos Experts Advisors..
No backtest ele funciona perfeitamente, só duplica mesmo quando estou no ambiente real. e como mencionei, não duplica em todas as entradas.
Esse é código completo,
não entendo tanto de programação dos Experts Advisors..
No backtest ele funciona perfeitamente, só duplica mesmo quando estou no ambiente real. e como mencionei, não duplica em todas as entradas.
Bem-vindo ao inferno que é programar em MQL5.
Segregue a checagem no OnTrade() ou no OnTrdeTransaction()..
POSITION_TYPE
pode falhar. OnTick() é muito veloz...
Bem-vindo ao inferno que é programar em MQL5.
Segregue a checagem no OnTrade() ou no OnTrdeTransaction()..
pode falhar. OnTick() é muito veloz...Desculpa minha ignorancia, rsrs'
Não sei bem estruturar dessa forma, Mas não será que antes de ler o OnTrade() ele iria sair executando varias ordens no OnTick() até entender que está posicionado?
Pensei em talvez colocar um Sleep(1000) logo após a execução da ordem, talvez faça ele parar um pouco antes de ler novamente e assim dar um tempo para ele validar a checagem. acha que vale o teste também?
Desculpa minha ignorancia, rsrs'
Não sei bem estruturar dessa forma, Mas não será que antes de ler o OnTrade() ele iria sair executando varias ordens no OnTick() até entender que está posicionado?
Pensei em talvez colocar um Sleep(1000) logo após a execução da ordem, talvez faça ele parar um pouco antes de ler novamente e assim dar um tempo para ele validar a checagem. acha que vale o teste também?
Como o Flavio, OnTick() pode executar quando a posição ainda não foi completamente criada ou a ordem (inicial) ainda não foi criada e isso faz voce ter mais posições do que gostaria. O Sleep resolve? Minha opinião que não por ser arbitrario, mas pode diminuir a ocorrencia. Entretanto, tu vai perder analise.
Parece que o Sleep(1000) já resolveu, foram 2 dias sem duplicar, mas vou tentar o OnTradeTransaction também. (:
- www.mql5.com
Parece que o Sleep(1000) já resolveu, foram 2 dias sem duplicar, mas vou tentar o OnTradeTransaction também. (:
Esse é código completo,
não entendo tanto de programação dos Experts Advisors..
No backtest ele funciona perfeitamente, só duplica mesmo quando estou no ambiente real. e como mencionei, não duplica em todas as entradas.
E se vc colocasse o IF antes do trade.buy e trade.sell e tranferindo o valor true para comprado ou vendido tipo:
if(sinaldecompra && !comprado ){ // se deu sinal de compra e não estou comprado
if ( trade.buy(...)) { // efetua o trade de compra e caso o trade.buy seja executado com sucesso (true) então
comprado=true; // comprado recebe true.. Se o evento ontick passar de novo dentro dessa rotina ele vai encontrar o sinal de comprado como true ignorando o resto
}
}
//------------------------------------------
Faça os testes pois se não me falha a memoria meu robo (ainda em fase de testes) fazia algo parecido e depois que implementei uma logica desse tipo não percebi duplicidade.
Acho que o evento Ontick é tão rápido que se vc não der uma tapa no bicho ele vai fazendo cagada rsrsrs
Tente fazer uso também das estruturas MqlTradeRequest e MqlTradeResult em vez da Ctrade. Acredito que possa ser útil também nesse sentido apesar de ainda não tê-lo explorado com afinco
Att
Josue
Recomendo a implementação do Jonathan... É inclusive como eu uso no meu engine... Não dá pra ter certeza de nada em contas reais. SEMPRE assuma o pior... Do contrário algum dia você vai zerar sua conta...
É por isso que é tão complexo desenvolver verdadeiros robôs em MQL5. Não dá pra fazer um robô com 100 linhas de código...
;)
- 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á,
Criei um EA para rodar no MT5 com algumas regras para se eu já estiver posicionado, ele não entrar novamente, porém percebo que ele acaba entrando duplicado quando tenho o sinal de compra ou de venda. ordens vão em um intervalo de milésimos de segundos. e nem todas as vezes duplica também.
O código que eu criei para essa validação e a ordem, sabem o que pode estar acontecendo para ele duplicar as ordens?