- 2021.04.20
- www.mql5.com
- Testador com EA para operação manual...
- MEU EA NÃO ESTA COLOCANDO STOP LOSS NEM TAKE PROFIT
- Armadilha EA para NEWS!!
Boa noite!
Eu corrigi os alertas ao compilar. Teste aí se mudou alguma coisa:
//+------------------------------------------------------------------+ //| my_first_ea.mq5 | //| Copyright 2021, MetaQuotes Ltd. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2021, MetaQuotes Ltd." #property link "https://www.mql5.com" #property version "1.00" #property strict //--- PARÂMETROS DE ENTRADA input int Stop_Loss=30; // STOP LOSS input int Stop_Gain=10; // STOP GAIN input int EA_Magic_Number=12345; // MAGIC NUMBER input double Lote=1.0; // TAMANHO DO LOTE input int Periodo_ADX=9; // PERIODO ADX input int adx_atr=1; // ATRASO ADX input int adx_max=26; // FILTRO ADX MAXIMO input int Periodo_Bollinger=20; // PERIODO BOLLINGER input double Desvio_Bollinger=2.5; // DESVIO BANDAS DE BOLLINGER input double Afastamento_Maximo_BB=200.0; // AFASTAMENTO MAXIMO BANDAS DE BOLLINGER //--- OUTROS PARÂMETROS int Manipulador_ADX; // HANDLE ADX int Manipulador_BB; // HANDLE BB double DI_Mais[]; // ARRAY DE ARMAZENAMENTO DI MAIS double DI_menos[]; // ARRAY DE ARMAZENAMENTO DI MENOS double Valor_ADX[]; // ARRAY DE ARMAZENAMENTO ADX double BB_Sup[]; // ARRAY DE ARMAZENAMENTO BB SUPERIOR double BB_Inf[]; // ARRAY DE ARMAZENAMENTO INFERIOR double BB_Med[]; // ARRAY DE ARMAZENAMENTO BB MEDIA double p_close; // VARIAVEL PARA ARMAZENAR O VALOR DO FECHAMENTO double p_open; // VARIAVEL PARA ARMAZENAR O VALOR DA ABERTURA double p_max; // VARIAVEL PARA ARMAZENAR O VALOR DA MAXIMA double p_min; // VARIAVEL PARA ARMAZENAR O VALOR DA MINIMA int STL; // STOP LOSS int STG; // STOP GAIN //+------------------------------------------------------------------+ //| Função de inicialização do EA | //+------------------------------------------------------------------+ int OnInit() { //--- Manipulador_ADX = iADX(_Symbol,PERIOD_CURRENT,Periodo_ADX); Manipulador_BB = iBands(_Symbol,PERIOD_CURRENT,Periodo_Bollinger,0,Desvio_Bollinger,PRICE_CLOSE); if (Manipulador_ADX < 0 || Manipulador_BB < 0) { Alert("Erro ao criar handles para indicadores - erro: ",GetLastError(),"!!"); return(-1); } //--- Let us handle currency pairs with 5 or 3 digit prices instead of 4 STL = Stop_Loss; STG = Stop_Gain; if(_Digits==5 || _Digits==3) { STL = STL*10; STG = STG*10; } return(0); } //+------------------------------------------------------------------+ //| Função de finalização do EA | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { IndicatorRelease(Manipulador_ADX); // FINALIZAR HANDLE ADX IndicatorRelease(Manipulador_BB); // FINALIZAR HANDLE BB } //+------------------------------------------------------------------+ //| Função tick EA | //+------------------------------------------------------------------+ void OnTick() { //--- Verificar se temos candles suficientes if(Bars(_Symbol,_Period)<60) // se o total de candles for inferior a 60 { Alert("Temos menos de 60 barras!!"); return; } static datetime Old_Time; // Usaremos a variável estática Old_Time para servir o horário do bar. datetime New_Time[1]; // A cada execução do OnTick verificaremos o tempo de compasso atual com o salvo. bool IsNewBar=false; // Se o tempo da barra não for igual ao tempo economizado, indica que temos um novo tique. int copied = CopyTime(_Symbol,PERIOD_CURRENT,0,1,New_Time); // Copiando a última barra de tempo para o elemento New_Time [0] if (copied > 0) // Ok, os dados foram copiados com sucesso { if (Old_Time != New_Time[0]) // Se Old_time for diferente de New_time da barra atual { IsNewBar=true; if(MQL5InfoInteger(MQL5_DEBUGGING)) Print("Temos um newbar aqui",New_Time[0]," oldtime era ",Old_Time); Old_Time=New_Time[0]; // saving bar time } } else { Alert("Erro ao copiar dados de tempos históricos, erro =",GetLastError()); ResetLastError(); return; } // A EA só deve verificar se há novas negociações se tivermos uma nova barra if(IsNewBar==false) { return; } // --- Temos barras suficientes para trabalhar int Mybars=Bars(_Symbol,_Period); if(Mybars<60) // se o total de barras for inferior a 60 barras { Alert("Temos menos de 60 barras!!"); return; } // --- Definir algumas estruturas MQL5 que usaremos para nossos trades MqlDateTime min; MqlTick latest_price; // Para ser usado para obter cotações de preços recentes / mais recentes MqlTradeRequest mrequest; // Para ser usado para enviar nossos pedidos de trading MqlTradeResult mresult; // Para ser usado para obter nossos resultados dos trades MqlRates mrate[]; // Para ser usado para armazenar os preços, volumes e spread de cada barra ZeroMemory(mrequest); // Inicialização da estrutura mrequest /* Let's make sure our arrays values for the Rates, ADX Values and MA values is store serially similar to the timeseries array */ // the rates arrays ArraySetAsSeries(mrate,true); // Array dos valores de DI+ ArraySetAsSeries(DI_Mais,true); // Array dos valores de DI- ArraySetAsSeries(DI_menos,true); // Array dos valores de ADX ArraySetAsSeries(Valor_ADX,true); // Array dos valores de BB superior ArraySetAsSeries(BB_Sup,true); // Array dos valores de BB inferior ArraySetAsSeries(BB_Inf,true); // Array dos valores de BB media ArraySetAsSeries(BB_Med,true); // --- Obtenha a última cotação de preço usando a estrutura MQL5 MqlTick if(!SymbolInfoTick(_Symbol,latest_price)) { Alert("Erro ao obter a última cotação de preço - erro:",GetLastError(),"!!"); return; } // --- Obtenha os detalhes das últimas 3 barras if(CopyRates(_Symbol,_Period,0,3,mrate)<0) { Alert("Erro ao copiar taxas / dados de histórico - erro:",GetLastError(),"!!"); ResetLastError(); return; } // --- Copie os novos valores de nossos indicadores para buffers (arrays) usando o identificador if(CopyBuffer(Manipulador_ADX,0,0,3,Valor_ADX)<0 || CopyBuffer(Manipulador_ADX,1,0,3,DI_Mais)<0 || CopyBuffer(Manipulador_ADX,2,0,3,DI_menos)<0) { Alert("Erro ao copiar buffers do indicador ADX - error:",GetLastError(),"!!"); ResetLastError(); return; } if(CopyBuffer(Manipulador_BB,0,0,3,BB_Inf)<0 || CopyBuffer(Manipulador_BB,1,0,3,BB_Sup)<0 || CopyBuffer(Manipulador_BB,2,0,3,BB_Med)<0) { Alert("Erro ao copiar o buffer do indicador de BB - erro:",GetLastError()); ResetLastError(); return; } // --- não temos erros, então continue // --- Já temos posições abertas? bool Buy_opened=false; // variável para manter o resultado da posição de compra aberta bool Sell_opened=false; // variáveis para manter o resultado da posição de venda aberta if(PositionSelect(_Symbol)==true) // Nos temos posiçoes abertas { if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY) { Buy_opened=true; //It is a Buy } else if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_SELL) { Sell_opened=true; // It is a Sell } } // Copia o preço de fechamento da barra anterior antes da barra atual, ou seja, Barra 1 p_open = mrate[1].open; // barra 1 preço de abertura p_close = mrate[1].close; // barra 1 preço de fechamento p_max = mrate[1].high; // barra 1 preço maximo p_min = mrate[1].low; // barra 1 preço minimo /* 1. Verificar requisitos para compra: */ // --- variáveis do tipo bool para verificar condições de compra bool Buy_Condition_1 = (p_min<BB_Inf[0]) && ((BB_Sup[0] - BB_Inf[0]) < Afastamento_Maximo_BB); // verifica se a minima ultrapassou a banda inferior e o afastamento das bandas // bool Buy_Condition_2 = ((DI_Mais[adx_atr] && DI_menos[adx_atr] && Valor_ADX[adx_atr]) < adx_max); // verifica se di+, di- e adx estão menores que filtro adx bool Buy_Condition_2 = (DI_Mais[adx_atr] < adx_max && DI_menos[adx_atr] < adx_max && Valor_ADX[adx_atr] < adx_max); // verifica se di+, di- e adx estão menores que filtro adx // --- Juntando tudo if(Buy_Condition_1 && Buy_Condition_2) { // alguma posição de compra aberta? if(Buy_opened) { Alert("Já temos uma posição de compra!!!"); return; // Não abra uma nova posição de compra } ZeroMemory(mrequest); mrequest.action = TRADE_ACTION_DEAL; // Execução imediata da ordem mrequest.price = NormalizeDouble(latest_price.ask,_Digits); // Ultimo preço de venda mrequest.sl = NormalizeDouble(latest_price.ask - STL*_Point,_Digits); // Stop Loss mrequest.tp = NormalizeDouble(latest_price.ask + STG*_Point,_Digits); // Take Profit mrequest.symbol = _Symbol; // Ativo mrequest.volume = Lote; // Numero de lotes mrequest.magic = EA_Magic_Number; // Numero Magico da ordem mrequest.type = ORDER_TYPE_BUY; // Ordem de compra mrequest.type_filling = ORDER_FILLING_FOK; // Tipo de execução da ordem mrequest.deviation=100; // Desvio do preço atual //--- envio da ordem if(OrderSend(mrequest,mresult)) // resultado do codigo // if(mresult.retcode==10009 || mresult.retcode==10008) //A solicitação foi concluída ou o pedido foi feito { Alert("Ordem de compra executada com sucesso, ticket: #:",mresult.order,"!!"); } else { Alert("Falha na ordem de compra, ERRO:",GetLastError()); ResetLastError(); return; } } /* 1. Verificar requisitos para venda: */ // --- variáveis do tipo bool para verificar condições de venda bool Sell_Condition_1 = (p_max>BB_Sup[0]) && ((BB_Sup[0] - BB_Inf[0]) < Afastamento_Maximo_BB); // verifica se a maxima ultrapassou a banda superior e o afastamento das bandas // bool Sell_Condition_2 = ((DI_Mais[adx_atr] && DI_menos[adx_atr] && Valor_ADX[adx_atr]) < adx_max); // verifica se di+, di- e adx estão menores que filtro adx bool Sell_Condition_2 = (DI_Mais[adx_atr] < adx_max && DI_menos[adx_atr] < adx_max && Valor_ADX[adx_atr] < adx_max); // verifica se di+, di- e adx estão menores que filtro adx //--- Juntando tudo if(Sell_Condition_1 && Sell_Condition_2) { // alguma posição de venda aberta? if(Sell_opened) { Alert("Já temos uma posição de venda!!!"); return; // Não abra uma nova posição de venda } ZeroMemory(mrequest); mrequest.action=TRADE_ACTION_DEAL; // Execução imediata da ordem mrequest.price = NormalizeDouble(latest_price.bid,_Digits); // Ultimo preço de compra mrequest.sl = NormalizeDouble(latest_price.bid + STL*_Point,_Digits); // Stop Loss mrequest.tp = NormalizeDouble(latest_price.bid - STG*_Point,_Digits); // Take Profit mrequest.symbol = _Symbol; // Ativo mrequest.volume = Lote; // Numero de lotes mrequest.magic = EA_Magic_Number; // Numero Magico da ordem mrequest.type= ORDER_TYPE_SELL; // Ordem de venda mrequest.type_filling = ORDER_FILLING_FOK; // Tipo de execução da ordeme mrequest.deviation=100; // Desvio do preço atual //--- envio da ordem if(OrderSend(mrequest,mresult)) // resultado do codigo // if(mresult.retcode==10009 || mresult.retcode==10008) //A solicitação foi concluída ou o pedido foi feito { Alert("Venda foi feita sucesso, Ticket#:",mresult.order,"!!"); } else { Alert("A solicitação do pedido de venda não pôde ser concluída - erro:",GetLastError()); ResetLastError(); return; } } return; } //+------------------------------------------------------------------+
Em relação ao horário, dê uma olhada nessa classe.
- www.mql5.com
funcionou muito bem, obrigado, adicionei a classe e incorporei ao EA as alterações porem agora o EA não abre nenhuma posição, aparece
4807 | Manuseio de indicador errado |
//+------------------------------------------------------------------+ //| my_first_ea.mq5 | //| Copyright 2021, MetaQuotes Ltd. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2021, MetaQuotes Ltd." #property link "https://www.mql5.com" #property version "1.00" #property strict //--- PARÂMETROS DE ENTRADA input int Stop_Loss=30; // STOP LOSS input int Stop_Gain=10; // STOP GAIN input int EA_Magic_Number=12345; // MAGIC NUMBER input double Lote=1.0; // TAMANHO DO LOTE sinput string InpStartTime = "09:02"; sinput string InpEndTime = "16:06"; sinput string InpClosingTime = "17:32"; input int Periodo_ADX=9; // PERIODO ADX input int adx_atr=1; // ATRASO ADX input int adx_max=26; // FILTRO ADX MAXIMO input int Periodo_Bollinger=20; // PERIODO BOLLINGER input double Desvio_Bollinger=2.5; // DESVIO BANDAS DE BOLLINGER input double Afastamento_Maximo_BB=200.0; // AFASTAMENTO MAXIMO BANDAS DE BOLLINGER #include <TimeTrade.mqh> //--- OUTROS PARÂMETROS int Manipulador_ADX; // HANDLE ADX int Manipulador_BB; // HANDLE BB double DI_Mais[]; // ARRAY DE ARMAZENAMENTO DI MAIS double DI_menos[]; // ARRAY DE ARMAZENAMENTO DI MENOS double Valor_ADX[]; // ARRAY DE ARMAZENAMENTO ADX double BB_Sup[]; // ARRAY DE ARMAZENAMENTO BB SUPERIOR double BB_Inf[]; // ARRAY DE ARMAZENAMENTO INFERIOR double BB_Med[]; // ARRAY DE ARMAZENAMENTO BB MEDIA double p_close; // VARIAVEL PARA ARMAZENAR O VALOR DO FECHAMENTO double p_open; // VARIAVEL PARA ARMAZENAR O VALOR DA ABERTURA double p_max; // VARIAVEL PARA ARMAZENAR O VALOR DA MAXIMA double p_min; // VARIAVEL PARA ARMAZENAR O VALOR DA MINIMA int STL; // STOP LOSS int STG; // STOP GAIN CTimeTrade *timeTrade; //+------------------------------------------------------------------+ //| Função de inicialização do EA | //+------------------------------------------------------------------+ int OnInit() { //--- if(timeTrade == NULL) timeTrade = new CTimeTrade(); timeTrade.SetTime(InpStartTime, InpEndTime, InpClosingTime); timeTrade.TimeAdjustment(); //--- return(INIT_SUCCEEDED); Manipulador_ADX = iADX(_Symbol,PERIOD_CURRENT,Periodo_ADX); Manipulador_BB = iBands(_Symbol,PERIOD_CURRENT,Periodo_Bollinger,0,Desvio_Bollinger,PRICE_CLOSE); if (Manipulador_ADX < 0 || Manipulador_BB < 0) { Alert("Erro ao criar handles para indicadores - erro: ",GetLastError(),"!!"); return(-1); } //--- Let us handle currency pairs with 5 or 3 digit prices instead of 4 STL = Stop_Loss; STG = Stop_Gain; if(_Digits==5 || _Digits==3) { STL = STL*10; STG = STG*10; } return(0); } //+------------------------------------------------------------------+ //| Função de finalização do EA | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { IndicatorRelease(Manipulador_ADX); // FINALIZAR HANDLE ADX IndicatorRelease(Manipulador_BB); // FINALIZAR HANDLE BB if(timeTrade != NULL) { delete timeTrade; timeTrade = NULL; } } //+------------------------------------------------------------------+ //| Função tick EA | //+------------------------------------------------------------------+ void OnTick() { if(timeTrade.CheckTimeEndTrade()) { Print("Horário de encerramento de ordens"); return; } if(!timeTrade.CheckTimeTrade()) { Print("Horário de parar de abir ordens"); return; } //--- Verificar se temos candles suficientes if(Bars(_Symbol,_Period)<60) // se o total de candles for inferior a 60 { Alert("Temos menos de 60 barras!!"); return; } static datetime Old_Time; // Usaremos a variável estática Old_Time para servir o horário do bar. datetime New_Time[1]; // A cada execução do OnTick verificaremos o tempo de compasso atual com o salvo. bool IsNewBar=false; // Se o tempo da barra não for igual ao tempo economizado, indica que temos um novo tique. int copied = CopyTime(_Symbol,PERIOD_CURRENT,0,1,New_Time); // Copiando a última barra de tempo para o elemento New_Time [0] if (copied > 0) // Ok, os dados foram copiados com sucesso { if (Old_Time != New_Time[0]) // Se Old_time for diferente de New_time da barra atual { IsNewBar=true; if(MQL5InfoInteger(MQL5_DEBUGGING)) Print("Temos um newbar aqui",New_Time[0]," oldtime era ",Old_Time); Old_Time=New_Time[0]; // saving bar time } } else { Alert("Erro ao copiar dados de tempos históricos, erro =",GetLastError()); ResetLastError(); return; } // A EA só deve verificar se há novas negociações se tivermos uma nova barra if(IsNewBar==false) { return; } // --- Temos barras suficientes para trabalhar int Mybars=Bars(_Symbol,_Period); if(Mybars<60) // se o total de barras for inferior a 60 barras { Alert("Temos menos de 60 barras!!"); return; } // --- Definir algumas estruturas MQL5 que usaremos para nossos trades MqlDateTime min; MqlTick latest_price; // Para ser usado para obter cotações de preços recentes / mais recentes MqlTradeRequest mrequest; // Para ser usado para enviar nossos pedidos de trading MqlTradeResult mresult; // Para ser usado para obter nossos resultados dos trades MqlRates mrate[]; // Para ser usado para armazenar os preços, volumes e spread de cada barra ZeroMemory(mrequest); // Inicialização da estrutura mrequest /* Let's make sure our arrays values for the Rates, ADX Values and MA values is store serially similar to the timeseries array */ // the rates arrays ArraySetAsSeries(mrate,true); // Array dos valores de DI+ ArraySetAsSeries(DI_Mais,true); // Array dos valores de DI- ArraySetAsSeries(DI_menos,true); // Array dos valores de ADX ArraySetAsSeries(Valor_ADX,true); // Array dos valores de BB superior ArraySetAsSeries(BB_Sup,true); // Array dos valores de BB inferior ArraySetAsSeries(BB_Inf,true); // Array dos valores de BB media ArraySetAsSeries(BB_Med,true); // --- Obtenha a última cotação de preço usando a estrutura MQL5 MqlTick if(!SymbolInfoTick(_Symbol,latest_price)) { Alert("Erro ao obter a última cotação de preço - erro:",GetLastError(),"!!"); return; } // --- Obtenha os detalhes das últimas 3 barras if(CopyRates(_Symbol,_Period,0,3,mrate)<0) { Alert("Erro ao copiar taxas / dados de histórico - erro:",GetLastError(),"!!"); ResetLastError(); return; } // --- Copie os novos valores de nossos indicadores para buffers (arrays) usando o identificador if(CopyBuffer(Manipulador_ADX,0,0,3,Valor_ADX)<0 || CopyBuffer(Manipulador_ADX,1,0,3,DI_Mais)<0 || CopyBuffer(Manipulador_ADX,2,0,3,DI_menos)<0) { Alert("Erro ao copiar buffers do indicador ADX - error:",GetLastError(),"!!"); ResetLastError(); return; } if(CopyBuffer(Manipulador_BB,0,0,3,BB_Inf)<0 || CopyBuffer(Manipulador_BB,1,0,3,BB_Sup)<0 || CopyBuffer(Manipulador_BB,2,0,3,BB_Med)<0) { Alert("Erro ao copiar o buffer do indicador de BB - erro:",GetLastError()); ResetLastError(); return; } // --- não temos erros, então continue // --- Já temos posições abertas? bool Buy_opened=false; // variável para manter o resultado da posição de compra aberta bool Sell_opened=false; // variáveis para manter o resultado da posição de venda aberta if(PositionSelect(_Symbol)==true) // Nos temos posiçoes abertas { if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY) { Buy_opened=true; //It is a Buy } else if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_SELL) { Sell_opened=true; // It is a Sell } } // Copia o preço de fechamento da barra anterior antes da barra atual, ou seja, Barra 1 p_open = mrate[1].open; // barra 1 preço de abertura p_close = mrate[1].close; // barra 1 preço de fechamento p_max = mrate[1].high; // barra 1 preço maximo p_min = mrate[1].low; // barra 1 preço minimo /* 1. Verificar requisitos para compra: */ // --- variáveis do tipo bool para verificar condições de compra bool Buy_Condition_1 = (p_min<BB_Inf[0]) && ((BB_Sup[0] - BB_Inf[0]) < Afastamento_Maximo_BB); // verifica se a minima ultrapassou a banda inferior e o afastamento das bandas bool Buy_Condition_2 = (DI_Mais[adx_atr] < adx_max && DI_menos[adx_atr] < adx_max && Valor_ADX[adx_atr] < adx_max); // verifica se di+, di- e adx estão menores que filtro adx // --- Juntando tudo if(Buy_Condition_1 && Buy_Condition_2) { // alguma posição de compra aberta? if(Buy_opened) { Alert("Já temos uma posição de compra!!!"); return; // Não abra uma nova posição de compra } ZeroMemory(mrequest); mrequest.action = TRADE_ACTION_DEAL; // Execução imediata da ordem mrequest.price = NormalizeDouble(latest_price.ask,_Digits); // Ultimo preço de venda mrequest.sl = NormalizeDouble(latest_price.ask - STL*_Point,_Digits); // Stop Loss mrequest.tp = NormalizeDouble(latest_price.ask + STG*_Point,_Digits); // Take Profit mrequest.symbol = _Symbol; // Ativo mrequest.volume = Lote; // Numero de lotes mrequest.magic = EA_Magic_Number; // Numero Magico da ordem mrequest.type = ORDER_TYPE_BUY; // Ordem de compra mrequest.type_filling = ORDER_FILLING_FOK; // Tipo de execução da ordem mrequest.deviation=100; // Desvio do preço atual //--- envio da ordem if(OrderSend(mrequest,mresult)) // resultado do codigo // if(mresult.retcode==10009 || mresult.retcode==10008) //A solicitação foi concluída ou o pedido foi feito { Alert("Ordem de compra executada com sucesso, ticket: #:",mresult.order,"!!"); } else { Alert("Falha na ordem de compra, ERRO:",GetLastError()); ResetLastError(); return; } } /* 1. Verificar requisitos para venda: */ // --- variáveis do tipo bool para verificar condições de venda bool Sell_Condition_1 = (p_max>BB_Sup[0]) && ((BB_Sup[0] - BB_Inf[0]) < Afastamento_Maximo_BB); // verifica se a maxima ultrapassou a banda superior e o afastamento das bandas // bool Sell_Condition_2 = ((DI_Mais[adx_atr] && DI_menos[adx_atr] && Valor_ADX[adx_atr]) < adx_max); // verifica se di+, di- e adx estão menores que filtro adx bool Sell_Condition_2 = (DI_Mais[adx_atr] < adx_max && DI_menos[adx_atr] < adx_max && Valor_ADX[adx_atr] < adx_max); // verifica se di+, di- e adx estão menores que filtro adx //--- Juntando tudo if(Sell_Condition_1 && Sell_Condition_2) { // alguma posição de venda aberta? if(Sell_opened) { Alert("Já temos uma posição de venda!!!"); return; // Não abra uma nova posição de venda } ZeroMemory(mrequest); mrequest.action=TRADE_ACTION_DEAL; // Execução imediata da ordem mrequest.price = NormalizeDouble(latest_price.bid,_Digits); // Ultimo preço de compra mrequest.sl = NormalizeDouble(latest_price.bid + STL*_Point,_Digits); // Stop Loss mrequest.tp = NormalizeDouble(latest_price.bid - STG*_Point,_Digits); // Take Profit mrequest.symbol = _Symbol; // Ativo mrequest.volume = Lote; // Numero de lotes mrequest.magic = EA_Magic_Number; // Numero Magico da ordem mrequest.type= ORDER_TYPE_SELL; // Ordem de venda mrequest.type_filling = ORDER_FILLING_FOK; // Tipo de execução da ordeme mrequest.deviation=100; // Desvio do preço atual //--- envio da ordem if(OrderSend(mrequest,mresult)) // resultado do codigo // if(mresult.retcode==10009 || mresult.retcode==10008) //A solicitação foi concluída ou o pedido foi feito { Alert("Venda foi feita sucesso, Ticket#:",mresult.order,"!!"); } else { Alert("A solicitação do pedido de venda não pôde ser concluída - erro:",GetLastError()); ResetLastError(); return; } } return; } //+------------------------------------------------------------------+
funcionou muito bem, obrigado, adicionei a classe e incorporei ao EA as alterações porem agora o EA não abre nenhuma posição, aparece
4807 | Manuseio de indicador errado |
Bom dia!
- Em OnInit(), esse return(INIT_SUCCEEDED) tem que ir lá pro final, no lugar de return(0), senão os comandos seguintes não são executados.
- Essa verificação da quantidade de barras disponíveis no histórico está em duplicidade (desnecessário).
- Nessas verificações dos horários, o timeTrade.CheckTimeEndTrade() é útil caso você queira encerrar as posições abertas naquele horário. Então, se for utilizar, inclua um código / função para encerrar posições.
Bom dia!
- Em OnInit(), esse return(INIT_SUCCEEDED) tem que ir lá pro final, no lugar de return(0), senão os comandos seguintes não são executados.
- Essa verificação da quantidade de barras disponíveis no histórico está em duplicidade (desnecessário).
- Nessas verificações dos horários, o timeTrade.CheckTimeEndTrade() é útil caso você queira encerrar as posições abertas naquele horário. Então, se for utilizar, inclua um código / função para encerrar posições.
Obrigado Vinicius, ficou perfeito, vc sabe me dizer se no forum existe alguma classe já pronta pra gerenciamento de risco com meta de lucro ou perdas?
Opa, Romeu! Bom que deu certo! 🤝
No fórum existem algumas sugestões de funções para essa finalidade, que com pequenos ajustes, devem lhe atender, como nesse tópico (veja correção da função inicial no comentário #3).
Essa busca retorna outros exemplos que podem ser úteis.
... Lembrando também que, caso não encontre um código da forma que você esperava, há sempre a possibilidade de registrar a sua encomenda no Freelance. 👍
- 2020.05.30
- www.mql5.com
Boa tarde @Romeu Masselai!
Você não testou o código que lhe sugeri acima e está abrindo vários tópicos com a mesma dúvida, né? 😃
Teste o código (com pequenas alterações) e dê algum retorno: 👍
//--- Número de vitórias: int WinNumber() { int Res = 0; datetime time_start = (datetime) (86400*(((ulong)TimeCurrent())/86400)); if(HistorySelect(time_start,TimeCurrent())) for(int i = HistoryDealsTotal() - 1; i >= 0; i--) { const ulong Ticket = HistoryDealGetTicket(i); if(HistoryDealGetInteger(Ticket, DEAL_MAGIC) == MAGICNUM && HistoryDealGetString(Ticket, DEAL_SYMBOL) == _Symbol && HistoryDealGetDouble(Ticket, DEAL_PROFIT) > 0.0) Res ++; } return(Res); } //--- Número de perdas: int LossNumber() { int Res = 0; datetime time_start = (datetime) (86400*(((ulong)TimeCurrent())/86400)); if(HistorySelect(time_start,TimeCurrent())) for(int i = HistoryDealsTotal() - 1; i >= 0; i--) { const ulong Ticket = HistoryDealGetTicket(i); if(HistoryDealGetInteger(Ticket, DEAL_MAGIC) == MAGICNUM && HistoryDealGetString(Ticket, DEAL_SYMBOL) == _Symbol && HistoryDealGetDouble(Ticket, DEAL_PROFIT) < 0.0) Res ++; } return(Res); } //--- A versão original da função retorna o resultado do dia (lucro ou prejuízo): double Profit() { double Res = 0.0; datetime time_start = (datetime) (86400*(((ulong)TimeCurrent())/86400)); if(HistorySelect(time_start,TimeCurrent())) for(int i = HistoryDealsTotal() - 1; i >= 0; i--) { const ulong Ticket = HistoryDealGetTicket(i); if(HistoryDealGetInteger(Ticket, DEAL_MAGIC) == MAGICNUM && HistoryDealGetString(Ticket, DEAL_SYMBOL) == _Symbol) Res += HistoryDealGetDouble(Ticket, DEAL_PROFIT); } return(Res); }
Acho que time_start pode ser informado também assim (mais simples):
datetime time_start = iTime(_Symbol, PERIOD_D1, 0);
Para agilizar, as funções podem ser unificadas.
Boa tarde @Romeu Masselai!
Você não testou o código que lhe sugeri acima e está abrindo vários tópicos com a mesma dúvida, né? 😃
Teste o código (com pequenas alterações) e dê algum retorno: 👍
Acho que time_start pode ser informado também assim (mais simples):
Para agilizar, as funções podem ser unificadas.
Boa tarde, muito obrigado pela ajuda Vinicius, incorporei a função no EA, mas devo ter feito algo errado, ele compila sem erros mas o EA não faz o que é pra fazer
sinput group "------ Gerenciamento Financeiro $" input int maxloss = 2; // LIMITE DE LOSS DIARIO input int maxgain = 10; // LIMITE DE GAIN DIARIO
bool Buy_Condition_3 = ((WinNumber() <= maxgain) && (LossNumber() >= maxloss));
//--- Número de vitórias: int WinNumber() { int Res = 0; datetime time_start = (datetime) (86400*(((ulong)TimeCurrent())/86400)); if(HistorySelect(time_start,TimeCurrent())) for(int i = HistoryDealsTotal() - 1; i >= 0; i--) { const ulong Ticket = HistoryDealGetTicket(i); if(HistoryDealGetInteger(Ticket, DEAL_MAGIC) == EA_Magic_Number && HistoryDealGetString(Ticket, DEAL_SYMBOL) == _Symbol && HistoryDealGetDouble(Ticket, DEAL_PROFIT) > 0.0) Res ++; } return(Res); } //--- Número de perdas: int LossNumber() { int Res = 0; datetime time_start = (datetime) (86400*(((ulong)TimeCurrent())/86400)); if(HistorySelect(time_start,TimeCurrent())) for(int i = HistoryDealsTotal() - 1; i >= 0; i--) { const ulong Ticket = HistoryDealGetTicket(i); if(HistoryDealGetInteger(Ticket, DEAL_MAGIC) == EA_Magic_Number && HistoryDealGetString(Ticket, DEAL_SYMBOL) == _Symbol && HistoryDealGetDouble(Ticket, DEAL_PROFIT) < 0.0) Res ++; } return(Res); }
Boa tarde, muito obrigado pela ajuda Vinicius, incorporei a função no EA, mas devo ter feito algo errado, ele compila sem erros mas o EA não faz o que é pra fazer
Olá Romeu!
Corrija a condição para:
bool Buy_Condition_3 = ((WinNumber() <= maxgain) && (LossNumber() <= maxloss));
... E dê um retorno ...
Olá Romeu!
Corrija a condição para:
... E dê um retorno ...
Aparentemente funcionou :) vou testar mais afundo e com tempo, muito obrigado pela sua ajuda, estava tão pilhado nisso, que não percebi esse detalhe, por isso é bom um olhar externo.
- 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