Caros, boa noite.
Tenho o código em anexo e uma das partes do código é a leitura da posição atual para impedir novas entradas quando já existir uma posição em andamento.
Oque acontece é que o código que estou usando para ler a posição atual "aparentemente" não está funcionando/retornando o resultado esperado (figura 2), inclusive no alert colocado após o envio da segunda ordem (que gerou sobreposição) retorna um false.
Natural que retorne um false, caso contrário não entraria no código de envio da ordem, a questão que não consigo entender é porque não vejo a posição que foi iniciada as 2009.09.21 09:19:59 (figura 1)
Eu preciso que caso já exista uma posição (não ordem) em aberto não seja gerado uma nova entrada.
Alguém pode por favor me ajudar.
Olá rflsjppr,
Quando você envia uma ordem do tipo Buy Stop ou Sell Stop, esse tipo de ordem não abre IMEDIATAMENTE uma posição. É preciso esperar o preço tocar no seu gatilho e, apenas aí, uma posição será aberta.
O que você está verificando é se existe uma POSIÇÃO aberta, quando na verdade você deveria verificar se existe alguma ORDEM pendente.
Vale a pena verificar a diferença entre ORDEM e POSIÇÃO antes de desenvolver seu EA. Pra isso, sugiro a leitura do seguinte artigo: https://www.mql5.com/pt/articles/211
Abraços,
Malacarne
![Ordens, posições e negócios no MetaTrader 5 Ordens, posições e negócios no MetaTrader 5](https://c.mql5.com/36/7/ordens-posicoes-e-negocios-no-metatrader.png)
- 2014.01.10
- MetaQuotes Software Corp.
- www.mql5.com
Malacarne.
Excelente, obrigado pela ajuda.
Foi justamente oque pensei, mas segundo a figura entrada_1 a ordem tinha como gatilho o 310 e o preço foi até 300, assim a ordem foi acionada e efetivada as 2009.09.21 09:19:59, correto?
Srs.
Acho que meu código estava errado, alterei agora para primeiro chamar a posição pelo Symbol() e pois pelo magic number e funcionou, ou seja, não abriu nova posição na barra de 2009.09.21 09:20:00 (figura ok).
////////INICIO INSPECAO PARA NÃO ABRIR SOBREPOSIÇÕES Buy_opened=false; Sell_opened=false; if(PositionSelect(Symbol())) if(PositionGetInteger(POSITION_MAGIC)==EA_Magic) { long type=PositionGetInteger(POSITION_TYPE); if(type==(long)POSITION_TYPE_BUY) Buy_opened=true; if(type==(long)POSITION_TYPE_SELL) Sell_opened=true; } ////////FIM INSPECAO PARA ABRIR SOBREPOSIÇÕES
Obrigado a todos.
Srs.
Acho que meu código estava errado, alterei agora para primeiro chamar a posição pelo Symbol() e pois pelo magic number e funcionou, ou seja, não abriu nova posição na barra de 2009.09.21 09:20:00 (figura ok).
Obrigado a todos.
Olá rflsjppr, exatamente, você deve chamar antes o PositionSelect(), como corrigido.
Pelo código original, a leitura de PositionGetInteger() estava sempre falhando e retornando 0, mascarando a existência de posições abertas.
Aliás, esse seria um bom teste para uma prova sobre MQL5!
Srs.
Acho que meu código estava errado, alterei agora para primeiro chamar a posição pelo Symbol() e pois pelo magic number e funcionou, ou seja, não abriu nova posição na barra de 2009.09.21 09:20:00 (figura ok).
Obrigado a todos.
rflsjppr,
analisando o EA fonte do seu projeto, eu percebi algo que não sei se está correto.
este comando "força" a leitura do sinal, pelo que eu li num outro tutorial.
ENUM_ORDER_TYPE signal=WRONG_VALUE
porém abaixo deste comando teria que ter este outro que "força a leitura" e eu não
então acho que teria que ter esse comando logo abaixo, pois ele é quem "força a leitura" quando o primeiro comando acima é "setado"
GetSymbolProperties(symbol_number,S_ALL);
ou seja.
ENUM_ORDER_TYPE signal=WRONG_VALUE;
GetSymbolProperties(symbol_number,S_ALL);
//fonte original do robô que vc postou
//--- verifica os sinais
ENUM_ORDER_TYPE signal=WRONG_VALUE; GetSymbolProperties(symbol_number,S_ALL); //<<eu acho que precisaria desta linha adicional, não? teste e veja se dá diferença. if(rt[0].open>ma[0] && rt[0].close<ma[0]) signal=ORDER_TYPE_SELL; // condição de venda else { if(rt[0].open<ma[0] && rt[0].close>ma[0]) signal=ORDER_TYPE_BUY; // condição de compra } //--- verificações adicionais
Estou com o mesmo problema do amigo acima..
Coloquei o código para verificar se existe uma posição aberta e impedir que seja aberta uma nova ordem quando existir uma posição já aberta... mas acontece que a cada tick abre uma nova ordem mesmo tendo posição aberta(em 1 minuto chega a ficar com 300 ordens abertas :( )...
Não consigo achar onde esta o erro...
//+------------------------------------------------------------------+
//| ADXGradiente.mq5 |
//| APTO |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "APTO"
#property link "https://www.mql5.com"
#property version "1.00"
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
#include <Trade\Trade.mqh>
CTrade trade;
input int periodADX = 14;//Periodo ADX
input double lote = 1.0;//Volume
input double stopLoss = 2.0;//Stop Loss
input double takeprofit = 10.0;//Take Profit
input ulong magicNum = 123;//Mágic Number
input ulong desvPts = 50;//Spread(Pontos)
input ENUM_ORDER_TYPE_FILLING preenchimento = ORDER_FILLING_RETURN;//Preenchimento da Ordem
double PRC;
double STL;
double TKP;
bool posAberta;//variavel verificar se há posição aberta para o ativo em questão
int handleADX;
MqlTick ultimoTick; //saber preço do ativo(Último Preço, Preço de Compra, Preço de Venda e Volume)
int OnInit()
{
//---
//Criar manipulador indicador
handleADX = iADX(_Symbol,_Period,periodADX);
//Adicionar indicador no gráfico
ChartIndicatorAdd(0, 0, handleADX);
//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
trade.SetTypeFilling(ORDER_FILLING_RETURN);//Tipo de preenchimento das Ordens
trade.SetDeviationInPoints(desvPts); // Desvio em pontos Spread;
trade.SetExpertMagicNumber(magicNum);//Útil quando utiliza mais de 1 robo na mesma conta;
//---
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
//---
SymbolInfoTick(_Symbol, ultimoTick);//Verificar o ultimo preço negociado no ativo
//Declaração dos Arrays:
double sinal[];
double ADXC[];
double ADXV[];
//Usar ArraySetAsSeries para mudar a ordem do array(a partir do mais recente para o mais antigo)
ArraySetAsSeries(sinal, true);
ArraySetAsSeries(ADXC, true);
ArraySetAsSeries(ADXV, true);
//Copiando os valores do manipulador para o array
CopyBuffer(handleADX,0,0,2,sinal);
CopyBuffer(handleADX,1,0,2,ADXC);
CopyBuffer(handleADX,2,0,2,ADXV);
posAberta = false;//ver se tem posição em aberto no ativo e robo em questão(numero magico)
for (int i = PositionsTotal()-1; i>=0; i--)//enquanto Posições abertas for >=0 fazer decremento;
{
string symbol = PositionGetSymbol(i);//declara variavel para armazenar o ativo da posição selecionada;
ulong magic = PositionGetInteger(POSITION_MAGIC);//declara a variavel para armazenar o numero magico da posição selecionada;
if(symbol == _Symbol && magic == magicNum )//se a variavel que armazena o ativo da posição for = ao ativo atual e numero magico atual,então é verdadeira;
{
posAberta = true;
break;
}
}
//Criar metricas para compra e venda com if e if else:
if(ADXC[1]>ADXV[1] && sinal[1]>=30 && !posAberta)
{
PRC = NormalizeDouble(ultimoTick.ask, _Digits);
STL = NormalizeDouble(PRC - stopLoss, _Digits);
TKP = NormalizeDouble(PRC + takeprofit, _Digits);
if(trade.Buy(lote, _Symbol, PRC, STL, TKP,"Compra"))//Executar uma Ordem de Compra a mercado:
{
Print("Ordem de Compra - sem falha. ResulRetcode: ", trade.ResultRetcode()," ", "RetcodeDescription: ", trade.ResultRetcodeDescription());
}
else
{
Print("Ordem de Compra - com falha. ResulRetcode: ", trade.ResultRetcode()," ", "RetcodeDescription: ", trade.ResultRetcodeDescription());
}
}
else if (ADXC[1]<ADXV[1] && sinal[1]>=30 && !posAberta)
{
PRC = NormalizeDouble(ultimoTick.bid, _Digits);
STL = NormalizeDouble(PRC + stopLoss, _Digits);
TKP = NormalizeDouble(PRC - takeprofit, _Digits);
if(trade.Sell(lote, _Symbol, PRC , STL , TKP, "Venda"))//Executar uma Ordem de Venda a mercado:
{
Print("Ordem de Venda - sem falha. ResulRetcode: ", trade.ResultRetcode()," ", "RetcodeDescription: ", trade.ResultRetcodeDescription());
}
else
{
Print("Ordem de Venda - com falha. ResulRetcode: ", trade.ResultRetcode()," ", "RetcodeDescription: ", trade.ResultRetcodeDescription());
}
}
}
//+------------------------------------------------------------------+
Estou com o mesmo problema do amigo acima..
Coloquei o código para verificar se existe uma posição aberta e impedir que seja aberta uma nova ordem quando existir uma posição já aberta... mas acontece que a cada tick abre uma nova ordem mesmo tendo posição aberta(em 1 minuto chega a ficar com 300 ordens abertas :( )...
Não consigo achar onde esta o erro...
int OnInit()
{
//---
//Criar manipulador indicador
handleADX = iADX(_Symbol,_Period,periodADX);
//Adicionar indicador no gráfico
ChartIndicatorAdd(0, 0, handleADX);
//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
trade.SetTypeFilling(ORDER_FILLING_RETURN);//Tipo de preenchimento das Ordens
trade.SetDeviationInPoints(desvPts); // Desvio em pontos Spread;
trade.SetExpertMagicNumber(magicNum);//Útil quando utiliza mais de 1 robo na mesma conta;
//---
}
É que você inseriu o comando trade.SetExpertMagicNumber(magicNum) no OnDeinit().
Com isso as suas posições não estão com o Magic Number que vc usa pra comparar.
A solução é inserir trade.SetExpertMagicNumber(magicNum) no OnInit() e não no OnDeinit().
Aliás, também há outros comandos no OnDeinit(), como o SetTypeFilling e o SetDeviationPoints, que também deveriam estar no OnInit().
É que você inseriu o comando trade.SetExpertMagicNumber(magicNum) no OnDeinit().
Com isso as suas posições não estão com o Magic Number que vc usa pra comparar.
A solução é inserir trade.SetExpertMagicNumber(magicNum) no OnInit() e não no OnDeinit().
Aliás, também há outros comandos no OnDeinit(), como o SetTypeFilling e o SetDeviationPoints, que também deveriam estar no OnInit().
Olá!
Você tem toda razão rsrs...
Desculpe minha falta de atenção e muito obrigada pela ajuda hehe
Olá!
Você tem toda razão rsrs...
Desculpe minha falta de atenção e muito obrigada pela ajuda hehe
![MQL5 - Linguagem para estratégias de negociação inseridas no terminal do cliente MetaTrader 5](https://c.mql5.com/i/registerlandings/logo-2.png)
- 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
Caros, boa noite.
Tenho o código em anexo e uma das partes do código é a leitura da posição atual para impedir novas entradas quando já existir uma posição em andamento.
Oque acontece é que o código que estou usando para ler a posição atual "aparentemente" não está funcionando/retornando o resultado esperado (figura 2), inclusive no alert colocado após o envio da segunda ordem (que gerou sobreposição) retorna um false.
Natural que retorne um false, caso contrário não entraria no código de envio da ordem, a questão que não consigo entender é porque não vejo a posição que foi iniciada as 2009.09.21 09:19:59 (figura 1)
Eu preciso que caso já exista uma posição (não ordem) em aberto não seja gerado uma nova entrada.
Alguém pode por favor me ajudar.