Grid maker 1.1 - página 4

 
desculpe cori, tenho apenas um pedido para qualquer posição da grade e testei praticamente todas as variações - ao longo de várias semanas.

Ocasionalmente eu apago todos os pedidos abertos para que nossos amigos do MT4 não fiquem chateados.

u terá este problema nos testes posteriores, mas isto não é um problema de script... mas um problema de teste posterior do MT4.

Se continuar, por favor me avise ou me envie alguns relatórios mostrando o problema...

thanks and reagrds,

hugues
 
Eu o encontrei. E eu não me divirto com isso.

O conselheiro está criando a grade com meu comentário "GridEURUSD". Este comentário fica no campo de comentários enquanto a ordem estiver esperando. Se a ordem for ativada, o comentário muda para "activate/auto". Afinal de contas, está claro que este comportamento se refere ao problema descrito.

Eu estou negociando com a Alpari. Eles estão apoiando o MT4 em contas de demonstração.

Vou verificar, se posso contornar este comportamento, ou seja, usar a magia da ordem como identificador para a grade e informá-lo dos resultados.

Ao testar isso, também fiz modificações no roteiro de limpeza da grade. Também acrescentei funcionalidade para fechar as ordens abertas. Infelizmente recebo um erro 129 que significa Ordem bloqueada, se eu tentar fechar uma ordem aberta. Mas ele apaga todas as ordens pendentes para a grade dada.

//+------------------------------------------------------------------+//| RemoveGrid.mq4 |//| Copyright © 2005, hdb |//| http://www.dubois1.net/hdb |//+------------------------------------------------------------------+#property copyright "Copyright © 2005, hdb "#property link "http://www.dubois1.net/hdb "external string GridName = "Grid";external bool closeOpen = false;//+------------------------------------------------------------------+//| script program start function |//+------------------------------------------------------------------+int start() { #property show_inputs // mostra os parâmetros - obrigado Slawa... 

//---- int total = OrderTotal(); int i ; for(i=total-1; i>=0;i--) { OrderSelect(i, SELECT_BY_POS); int type = OrderType(); if ( OrderSymbol()==Symbol() && OrderComment() == GridName ) { bool result = false; switch(type) { case OP_BUY : if ( closeOpen ) { result = OrderClose( OrderTicket(), OrderLots(), Ask, 0, Blue ); } break; case OP_SELLL : if ( closeOpen ) { result = OrderClose( OrderTicket(), OrderLots(), Bid, 0, Blue ); } break; //Close Order pending case OP_BUYLIMIT : resultado = OrderDelete( OrderTicket() ); break; case OP_BUYSTOP : resultado = OrderDelete( OrderTicket() ); pausa; caso OP_SELLLIMIT : resultado = OrderDelete( OrderTicket() ); pausa; caso OP_SELLSTOP : resultado = OrderDelete( OrderTicket() ); pausa; } if(result == falso) { Print("Order " , OrderTicket() , " não fechou. Erro:" , GetLastError() ); // Sleep(3000); }  
        } } //---- return(0); }//+------------------------------------------------------------------+




cori

 
ok cori, obrigado...

me avise se funcionar e eu vou usar a magia... como eu não sabia que o corretor faz coisas estranhas como essa!!

obrigado e cumprimentos,

hugues
 
Agora, é isso mesmo.

Eu mudei o gridMaker para usar o OrderMagicNumber em vez do comentário. Fiz também algumas pequenas modificações sobre a construção do comentário.

Aqui está o resultado.

//+------------------------------------------------------------------+//| MakeGrid.mq4 |//| Copyright © 2005, hdb |//| http://www.dubois1.net/hdb |//+------------------------------------------------------------------+#property copyright "Copyright © 2005, hdb "#property link "http://www.dubois1.net/hdb"//#property version "1.4beta"// modificado por cori. Usando OrderMagicNumber para identificar as negociações do gridextern int uniqueGridMagic = 11111; // Número mágico das negociações. deve ser único para identificar // as negociações de uma grade dupla externa Lotes = 0.1; // tamanho duplo de grades externas = 6; // pips entre ordens - grades ou grades de tamanho duplo de grades externas = 12; // número total de ordens para colocar grades duplas externas TakeProfit = 6; // número de ticks para obter lucro. normalmente é = tamanho da grade, mas u pode substituir a grade dupla StopLoss = 0; // se você quiser adicionar um stop loss. grelhas normais não usam stop lossesextern double UpdateInterval = 1; // ordens de atualização a cada x minutesextern bool wantLongs = true; // queremos bool posição compridasexternos bool wantShorts = true; // queremos bool posição curtasexternos bool wantBreakout = true;       // queremos longs above price, shorts below priceextern bool wantCounter = true; // queremos longs below price, shorts above priceextern bool limitEMA34 = false; // queremos longs above ema only, shorts below ema only/ modificado por cori. variáveis internas somente LastUpdate = 0; // contador usado para anotar o tempo da última atualização do último GridMaxOpen = 0; // número máximo de posições abertas GridName = "Grid"; // identifica a grade. permite várias grades coexistentess//+------------------------------------------------------------------+//| função de inicialização de especialista |//+------------------------------------------------------------------+int init() {//---- #property show_inputs // mostra os parâmetros - obrigado Slawa...    
 if ( TakeProfit <= 0 ) // { TakeProfit = GridSize; }//---- GridName = StringConcatenate( "Grid", Symbol() ); return(0);
  }//+------------------------------------------------------------------------+//| testa se há uma posição aberta ou ordem na região de atRate |//| verificará por longos períodos se checkLongs é verdadeiro, caso contrário verificará |//+------------------------------------------------------------------------+bool IsPosition(double atRate, double inRange, bool checkLongs ) { int totalorder = OrderTotal(); for(int j=0;j<totalorder;j+++) // verifica todos os pedidos e posições.... { OrderSelect(j, SELECT_BY_POS); // modificado por cori. Usando OrderMagicNumber para identificar os negócios da grade se ( OrderSymbol()==Symbol() && OrderMagicNumber() == uniqueGridMagic )  // só procurar se mygrid e símbolo... { int type = OrderType(); if (MathAbs( OrderOpenPrice() - atRate ) < inRange) // não procurar preço exato mas proximidade de preço (menos que o tamanho da grade) { if ( ( checkLongs && ( type == OP_BUY ||| type == OP_BUYLIMIT || type == OP_BUYSTOP ) )  ||| (!checkLongs && ( type == OP_SELLL || type == OP_SELLLIMIT ||| type == OP_SELLSTOP ) ) { return(true); } } } } } 

   return(false); }//+------------------------------------------------------------------+//| função script program start |//+------------------------------------------------------------------+int start() {//---- int i, j,k, ticket, entermode, totalorders; bool doit; double point, startrate, traderate; //---- if (MathAbs(CurTime()-LastUpdate)> UpdateInterval*60) // atualizamos a primeira vez que é chamado e a cada minuto do UpdateInterval { LastUpdate = CurTime();
   Print("Updating"); point = MarketInfo(Symbol(),MODE_POINT); startrate = ( Ask + point*GridSize/2 ) / point / GridSize; // redondo para um número de ticks divisíveis por GridSize k = startrate ; k = k * GridSize ; startrate = k * point - GridSize*GridSteps/2*point ;          // calcular o ponto de entrada mais baixo duplo EMA34=iMA(NULL,0,34,0,MODE_EMA,PRICE_CLOSE,0); for( i=0;i<GridSteps;i++) { traderate = startrate + i*point*GridSize; if ( wantLongs && (!limitEMA34 || traderate > EMA34)) { if ( IsPosition(traderate,point*GridSize,true) == falso )           // testar se não tenho ordens abertas próximas ao meu preço: se sim, colocar uma em { double myStopLoss = 0; se ( StopLoss > 0 ) { myStopLoss = traderate-point*StopLoss ; } if ( traderate > Ask ) { entermode = OP_BUYSTOP; } 
              else { entermode = OP_BUYLIMIT ; } 
              
              if ((traderate > Ask ) && (wantBreakout)) || ((traderate <= Ask ) && (wantCounter)) ) 

              { // modificado pela cori. Usando OrderMagicNumber para identificar os negócios da grade ticket=OrderSend(Symbol(),entermode,Lots,traderate,0,myStopLoss,traderate+point*TakeProfit,GridName,uniqueGridMagic,0,Green); } } } } if ( wantShorts && (!limitEMA34 || traderate < EMA34)) { if (IsPosition(traderate,point*GridSize,false)== false )           // testar se não tenho ordens abertas próximas ao meu preço: se sim, colocar uma em { myStopLoss = 0; se ( StopLoss > 0 ) { myStopLoss = traderate+point*StopLoss ; } if ( traderate > Bid ) { entermode = OP_SELLLIMIT; } 
              else { entermode = OP_SELLSTOP ; } 
              
              if ((traderate < Bid ) && (wantBreakout)) || ((traderate >= Bid ) && (wantCounter)) ) 
               { // modificado pela cori. Usando OrderMagicNumber para identificar os negócios da grade ticket=OrderSend(Symbol(),entermode,Lots,traderate,0,myStopLoss,traderate-point*TakeProfit,GridName,uniqueGridMagic,0,Red); } } } } } return(0); }//+------------------------------------------------------------------+



com respeito, cori

 
obrigado cori...

já que eu mesmo já havia feito algumas mudanças, integrei suas mudanças na versão mais recente.

Eu fiz 1 pequena variação: para manter minhas grades atuais ativas, eu coloquei um teste em Magic OR gridname...

você pode verificar se eu o fiz corretamente?



//+------------------------------------------------------------------+//| MakeGrid.mq4 |//| Copyright © 2005, hdb |//| http://www.dubois1.net/hdb |//+------------------------------------------------------------------+#property copyright "Copyright © 2005, hdb "# linkproperty "http://www.dubois1.net/hdb"//# versãoproperty "1.6beta"// modificada pela cori. Usando OrderMagicNumber para identificar as negociações do gridextern int uniqueGridMagic = 11111; // Número mágico das negociações. deve ser único para identificar // as negociações de uma grade dupla externa Lotes = 0.1; // tamanho duplo de grades externas = 6; // pips entre ordens - grades ou grades de tamanho duplo de grades externas = 12; // número total de ordens para colocar grades duplas externas TakeProfit = 12; // número de ticks para obter lucro. normalmente é = tamanho da grade, mas u pode substituir a grade dupla StopLoss = 0; // se você quiser adicionar um stop loss. grelhas normais não usam stop lossesextern double UpdateInterval = 1; // ordens de atualização a cada x minutesextern bool wantLongs = true; // queremos posição longasextern bool wantShorts = false; // queremos posição curtasextern bool wantBreakout = true;     // queremos longs above price, shorts below priceextern bool wantCounter = true; // queremos longs below price, shorts above priceextern bool limitEMA34 = true; // queremos longs above ema only, shorts below ema onlyextern double GridMaxOpen = 0; // número máximo de posições abertas : ainda não implementado..bool externo UseMACD = true; // se verdadeiro, usará macd >0 somente para longs, macd >0 somente para shorts // no crossover, cancelará todas as ordens pendentes. Isto anulará qualquer // wantLongs e wantShort - pelo menos por enquanto.external bool CloseOpenPositions = false;// se UseMACD, também fechamos posições abertas com uma perda?// modificado por cori. internal variables onlystring GridName = "Grid"; // identifica a grade. permite a coexistência de várias LastUpdate = 0; // contador usado para anotar o tempo da última atualização///+------------------------------------------------------------------+//| função de inicialização de especialista |///+------------------------------------------------------------------+int init() {//---- #property show_inputs // mostra os parâmetros - graças a Slawa...    
 if ( TakeProfit <= 0 ) // { TakeProfit = GridSize; }//----// adicionei meu corri e removido por hdb!! lol... apenas para permanecer compatível com grades abertas...
// GridName = StringConcatenate( "Grid", Symbol() ); return(0); }//+------------------------------------------------------------------------+//| testa se há uma posição aberta ou ordem na região de atRate |//| verificará se o checkLongs é verdadeiro, caso contrário, verificará |//+------------------------------------------------------------------------+bool IsPosition(double atRate, double inRange, bool checkLongs ) { int totalorder = OrderTotal();
     for(int j=0;j<totalordens;j++) // escanear todas as ordens e posições.... { OrderSelect(j, SELECT_BY_POS);// modificado por cori. Usando OrderMagicNumber para identificar os negócios da grade // hdb adicionado ou gridname para compatibilidade se ( OrderSymbol()==Symbol() && ( (OrderMagicNumber() == uniqueGridMagic) || (OrderComment() == GridName)) )  // só procurar se mygrid e símbolo... { int type = OrderType(); if (MathAbs( OrderOpenPrice() - atRate ) < inRange) // não procurar preço exato mas proximidade de preço (menos que o tamanho da grade) { if ( ( checkLongs && ( type == OP_BUY ||| type == OP_BUYLIMIT || type == OP_BUYSTOP ) )  ||| (!checkLongs && ( type == OP_SELLL || type == OP_SELLLIMIT ||| type == OP_SELLSTOP ) ) { return(true); } } } } } 
   return(false); }//+------------------------------------------------------------------------+//| cancela todas as ordens pendentes |//+------------------------------------------------------------------------+void CloseAllPendingOrders( ) { int totalorders = OrdersTotal(); for(int j=totalorders-1;j>=0;j--) // escaneia todas as ordens e posições... { OrderSelect(j, SELECT_BY_POS);// modificado conforme cori. Usando OrderMagicNumber para identificar as negociações da grade // hdb adicionado ou gridname para compatibilidade se ( OrderSymbol()==Symbol() && ( (OrderMagicNumber() == uniqueGridMagic) || (OrderComment() == GridName)) )  // só olhar se mygrid e símbolo...
         { int type = OrderType(); bool result = false; switch(type) { case OP_BUY : resultado = true ; case OP_SELL : resultado = true ; //Close order pending case OP_BUYLIMIT : resultado = OrderDelete( OrderTicket() ); caso OP_BUYSTOP : resultado = OrderDelete( OrderTicket() ); caso OP_SELLLIMIT : resultado = OrderDelete( OrderTicket() ); caso OP_SELLSTOP : resultado = OrderDelete( OrderTicket() ); } } } } } } 
   return; }//+------------------------------------------------------------------------+//| cancela todas as ordens pendentes e fecha as posições abertas |//+------------------------------------------------------------------------+void CloseOpenOrders(){ int total = OrderTotal(); for(int i=total-1;i>=0;i--) { OrderSelect(i, SELECT_BY_POS); int type = OrderType(); bool result = false;// modificado por cori. Usando OrderMagicNumber para identificar as negociações da grade // hdb adicionado ou gridname para compatibilidade se ( OrderSymbol()==Symbol() && ( (OrderMagicNumber() == uniqueGridMagic) || (OrderComment() == GridName)) )  // só olhar se mygrid e símbolo...
     {// Imprimir("Fechando 2 ",tipo); switch(type) { //Close abrir caixa de posições longas OP_BUY : resultado = OrderClose( OrderTicket(), OrderLots(), MarketInfo(OrderSymbol(), MODE_BID), 5, Vermelho ); break; //Close abrir caixa de posições curtas OP_SELL : resultado = OrderClose( OrderTicket(), OrderLots(), MarketInfo(OrderSymbol(), MODE_ASK), 5, Vermelho ); pausa; //Close o caso de ordens pendentes OP_BUYLIMIT : caso OP_BUYSTOP :
           caso OP_SELLLIMIT : caso OP_SELLSTOP : resultado = OrderDelete( OrderTicket() ); } } if(result == false) { // Alert("Order " , OrderTicket() , " não fechou. Erro:" , GetLastError() ); // Sleep(3000); }  
  } return;}//+------------------------------------------------------------------+//| função script program start |//+------------------------------------------------------------------+int start() {//---- int i, j,k, ticket, entermode, totalorders; bool doit; double point, startrate, traderate;//---- if (MathAbs(CurTime()-LastUpdate)> UpdateInterval*60) // atualizamos a primeira vez que é chamado e a cada minuto do UpdateInterval { LastUpdate = CurTime();
   point = MarketInfo(Symbol(),MODE_POINT); startrate = ( Ask + point*GridSize/2 ) / point / GridSize; // redondo para um número de ticks divisíveis por GridSize k = startrate ; k = k * GridSize ;
   startrate = k * ponto - GridSize*GridSteps/2* ponto ; // calcular o ponto de entrada mais baixo duplo EMA34=iMA(NULL,0,34,0,MODE_EMA,PRICE_CLOSE,0); se ( UseMACD ) { double Macd0=iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_MAIN,0);
      double Macd1=iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_MAIN,1); double Macd2=iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_MAIN,2); if( Macd0>0 && Macd1>0 && Macd2<0) // cross up { CloseAllPendingOrders();
         if ( CloseOpenPositions == true ) { CloseOpenOrders(); } } if( Macd0<0 && Macd1<0 && Macd2>0) // cross down { CloseAllPendingOrders(); if ( CloseOpenPositions == true ) { CloseOpenOrders(); } } wantLongs = false; wantShorts = false; if( Macd0>0 && Macd1>0 && Macd2>0) // está bem acima de zero { wantLongs = true; } if( Macd0<0 && Macd1<0 && Macd2<0) // está bem abaixo de zero { wantShorts = true; } } for( i=0;i<GridSteps;i++) { traderate = startrate + i*point*GridSize; if ( wantLongs && (!limitEMA34 || traderate > EMA34)) { if ( IsPosition(traderate,point*GridSize,true) == falso )           // testar se não tenho ordens abertas próximas ao meu preço: se sim, colocar uma em { double myStopLoss = 0; se ( StopLoss > 0 ) { myStopLoss = traderate-point*StopLoss ; } if ( traderate > Ask ) { entermode = OP_BUYSTOP; } 
              else { entermode = OP_BUYLIMIT ; } 
              if ((traderate > Ask ) && (wantBreakout)) || ((traderate <= Ask ) && (wantCounter)) ) 
              { // modificado pela cori. Usando OrderMagicNumber para identificar os negócios da grade ticket=OrderSend(Symbol(),entermode,Lots,traderate,0,myStopLoss,traderate+point*TakeProfit,GridName,uniqueGridMagic,0,Green); } } } } if ( wantShorts && (!limitEMA34 || traderate < EMA34)) { if (IsPosition(traderate,point*GridSize,false)== false )           // testar se não tenho ordens abertas próximas ao meu preço: se sim, colocar uma em { myStopLoss = 0; se ( StopLoss > 0 ) { myStopLoss = traderate+point*StopLoss ; } if ( traderate > Bid ) { entermode = OP_SELLLIMIT; } 
              else { entermode = OP_SELLSTOP ; } 
              
              if ((traderate < Bid ) && (wantBreakout)) || ((traderate >= Bid ) && (wantCounter)) ) 
                { // modificado pela cori. Usando OrderMagicNumber para identificar os negócios da grade ticket=OrderSend(Symbol(),entermode,Lots,traderate,0,myStopLoss,traderate-point*TakeProfit,GridName,uniqueGridMagic,0,Red); } } } } } } return(0); }//+------------------------------------------------------------------+
 
Olá hdb,

parece ok. Mas você deve definir o GridName como externo, que eu mudei, porque não precisei dele como parâmetro.

saudações, cori
 
ATENÇÃO todos os usuários do GridMaker - há um bug na função IsPosition - o resultado é que nem todos os slots da grade são preenchidos.

Você pode mudar a linha :

if (MathAbs( OrderOpenPrice() - atRate ) < inRange ) // não procurar preço exato mas proximidade de preço (menos que o tamanho da grade)

para

if (MathAbs( OrderOpenPrice() - atRate ) < (inRange*0.9)) // não procurar preço exato, mas proximidade de preço (menos que o tamanho da grade) - acrescentou 0,9 por causa de erros de pont flutuante


e isto corrige o problema.

Desculpe por qualquer inconveniente...

hugues
 
Oi hugues,

Este problema já está aí?

Encontrei algo semelhante na antiga MQL2.

A maneira realmente segura de contornar este problema é fazer algo parecido:

intOOP = MathRound( OrdeOpenPrice() / Point );

para todas as suas variáveis duplas. Então você tem todas as variáveis int retas que são comparáveis sem falhas.

É um pouco mais para escrever para mantê-lo claro e compreensível, mas é menos defeituoso.

com respeito,

cori
 
U estão certos Cori, isso é muito mais elegante! Só eu sendo preguiçoso!

cumprimentos,
hugues
 
Aqui está uma atualização para o GridMaker EA. Nesta versão, eu tenho:

1) alterei a lógica para UseMACD, wantLongs, wantShorts. Anteriormente, se o UseMACD era definido, a EA tomava longas e curtas, irrecusáveis bandeiras wnatLongs e wantShorts. Agora, useMACD não sobreporá essas bandeiras para que você possa ser longo apenas com useMACD ou curto apenas.

2) Eu adicionei uma verificação adicional para fazer shure não havia ordens abertas do lado errado do EMA se o limiteEMA34 estivesse definido. O que costumava acontecer era que as ordens eram bem colocadas acima ou abaixo do EMA, mas depois de algumas horas o EMA se movia... então havia ordens em ambos os lados do EMA.

3) Parece haver um bug na declaração do interruptor no OrderType()... não tenho certeza do que é, mas ele realmente se comporta de forma engraçada. Eu simplesmente eliminei as declarações de troca e as substituí por "se"... eu não gosto, mas funciona!

4) Eu fiz a variável de período EMA... agradável para o backtesting...

Também tenho alguns roteiros complementares se alguém quiser:

1) remover ordens abertas não preenchidas para um par
2) remover todas as ordens abertas para todos os pares de uma só vez
3) fechar todas as posições e remover as ordens abertas.
4) obter algumas estatísticas simples sobre o comportamento da grade a partir das posições abertas e histórico.

Aqui está o código da V1.08:


//+------------------------------------------------------------------+//| MakeGrid.mq4 |//| Copyright © 2005, hdb |//|
------------------------------------------------------------------.
net/hdb |//+------------------------------------------------------------------+#property copyright "Copyright © 2005, hdb "# linkproperty "http://www.dubois1.net/hdb"//#property version "1.8"// DISCLAIMER ***** NOTA IMPORTANTE ***** LEIA ANTES DE USAR ***** // Este assessor especializado pode abrir e fechar posições reais e, portanto, fazer negócios reais e perder dinheiro real.
// Este não é um 'sistema de negociação', mas um simples robô que coloca as operações de acordo com regras fixas.// O autor não tem pretensões quanto à rentabilidade deste sistema e não sugere o uso// deste EA a não ser para fins de teste em contas demo.// O uso deste sistema é gratuito - mas você não pode revendê-lo - e não tem qualquer garantia quanto a ele// adequação a qualquer propósito.
// Ao utilizar este programa, você reconhece implicitamente que compreende o que ele faz e concorda que // o autor não tem qualquer responsabilidade por quaisquer perdas.// Antes de utilizar, verifique também com seu corretor que seus sistemas estão adaptados para as operações mais freqüentes// associados a este especialista.// 1.8 mudanças// feitas em variáveis locais. Anteriormente, se você definir o UseMACD como verdadeiro, // ele fazia longLongs e shorts e simplesmente ignorava as bandeiras de wantLongs e wantShorts. 
// Agora, estas bandeiras não são ignoradas.// adicionou um loop para verificar se há ordens 'ilícitas' abertas acima ou abaixo da EMA quando a bandeira limiteEMA34// é usada. Estas se acumulam com o tempo e nunca são removidas e é devido à movimentação do EMA.// removeu a instrução de troca, pois não parecem funcionar - substituída por se as instruções// fizessem a variável de período EMA////// modificada pelo cori. Usando OrderMagicNumber para identificar os tráfegos do gridxtern int uniqueGridMagic = 11111; // Número mágico dos tráfegos. deve ser único para identificar // os tráfegos de um grid double Lots externos = 0.1; // tamanho duplo de grades externas = 6; // pips entre ordens - grades ou grades de tamanho duplo de grades externas = 12; // número total de ordens para colocar grades duplas externas TakeProfit = 12; // número de ticks para obter lucro. normalmente é = tamanho da grade, mas u pode substituir a grade dupla StopLoss = 0; // se você quiser adicionar um stop loss. grelhas normais não usam stop lossesextern double UpdateInterval = 1; // ordens de atualização a cada x minutesextern bool wantLongs = true; // queremos bool posição compridasexternos bool wantShorts = true; // queremos bool posição curtasexternos bool wantBreakout = true;     // queremos longas acima do preço, shorts abaixo do preço bool wantCounter = true; // queremos longas abaixo do preço, shorts acima do preço bool limitEMA = true; // queremos longas acima do ema only, shorts abaixo do ema onlyextern int EMAperiod = 34; // o comprimento do EMA.. foi previamente fixado em 34externos duplo GridMaxOpen = 0; // número máximo de posições abertas: ainda não implementado...bool externo UseMACD = true; // se verdadeiro, usará macd >0 somente para longs, macd >0 somente para shorts // no crossover, cancelará todas as ordens pendentes. Isto anulará qualquer // wantLongs and wantShort settings - pelo menos por enquanto.external bool CloseOpenPositions = false;// se UseMACD, também fechamos posições abertas com perda?external bool doHouseKeeping = true; // apenas um teste/// modificado por cori. internal bool onlystring GridName = "Grid"; // identifica a grade. permite a coexistência de várias LastUpdate = 0; // contador usado para anotar o tempo da última atualização///+------------------------------------------------------------------+//| função de inicialização de especialista |///+------------------------------------------------------------------+int init() {//---- #property show_inputs // mostra os parâmetros - graças a Slawa...    
//----// adicionei meu corri e removido por hdb! lol... apenas para permanecer compatível com grades abertas...
// GridName = StringConcatenate( "Grid", Symbol() ); return(0); }//+------------------------------------------------------------------------+//| testa se há uma posição aberta ou ordem na região de atRate |//| verificará se o checkLongs é verdadeiro, caso contrário, verificará |//+------------------------------------------------------------------------+bool IsPosition(double atRate, double inRange, bool checkLongs ) { int totalorder = OrderTotal();
     for(int j=0;j<totalordens;j++) // escanear todas as ordens e posições.... { OrderSelect(j, SELECT_BY_POS);// modificado por cori. Usando OrderMagicNumber para identificar os negócios da grade // hdb adicionado ou gridname para compatibilidade se ( OrderSymbol()==Symbol() && ( (OrderMagicNumber() == uniqueGridMagic) || (OrderComment() == GridName)) )  // só olhar se mygrid e símbolo... { tipo int = OrderType(); if (MathAbs( OrderOpenPrice() - atRate ) < (inRange*0.9)) // não procurar preço exato mas proximidade de preço (menor que o tamanho da grade) - adicionado 0,9 devido a erros de ponto flutuante { if ( checkLongs && ( type == OP_BUY || type == OP_BUYLIMIT || type == OP_BUYSTOP ) )  ||| (!checkLongs && ( type == OP_SELLL || type == OP_SELLLIMIT ||| type == OP_SELLSTOP ) ) { return(true); } } } } } 
   return(false); }//+------------------------------------------------------------------------+//| cancela todas as ordens pendentes |//+------------------------------------------------------------------------+void CloseAllPendingOrders( ) { int totalorders = OrdersTotal(); for(int j=totalorders-1;j>=0;j--) // escaneia todas as ordens e posições... { OrderSelect(j, SELECT_BY_POS);// modificado conforme cori. Usando OrderMagicNumber para identificar as negociações da grade // hdb adicionado ou gridname para compatibilidade se ( OrderSymbol()==Symbol() && ( (OrderMagicNumber() == uniqueGridMagic) || (OrderComment() == GridName)) )  // só olhar se mygrid e símbolo... { int type = OrderType(); if ( type > 1 ) bool result = OrderDelete( OrderTicket() ); } } } 
   return; }//+------------------------------------------------------------------------+//| cancela todas as ordens pendentes e fecha as posições abertas |//+------------------------------------------------------------------------+void CloseOpenOrders(){ int total = OrderTotal(); for(int i=total-1;i>=0;i--) { OrderSelect(i, SELECT_BY_POS); int type = OrderType(); bool result = false;// modificado por cori. Usando OrderMagicNumber para identificar as negociações da grade // hdb adicionado ou gridname para compatibilidade se ( OrderSymbol()==Symbol() && ( (OrderMagicNumber() == uniqueGridMagic) || (OrderComment() == GridName)) )  // só olhar se mygrid e símbolo...
     { //Close posições longas abertas se ( tipo == OP_BUY ) resultado = OrderClose( OrderTicket(), OrderLots(), MarketInfo(OrderSymbol(), MODE_BID), 5, Vermelho );
           //Close posições curtas abertas se ( tipo == OP_SELL ) resultado = OrderClose( OrderTicket(), OrderLots(), MarketInfo(OrderSymbol(), MODE_ASK), 5, Vermelho ); //Close ordens pendentes se ( tipo > 1 ) resultado = OrderDelete( OrderTicket() ); } } } retorno;
}//+------------------------------------------------------------------------+//| cancela todas as ordens abertas que caem no lado errado da EMA |//+------------------------------------------------------------------------+void CloseOrdersfersfromA( double theEMAValue ) { int totalorders = OrderTotal(); for(int j=totalorders-1;j>=0;j--) // escaneia todas as ordens e posições.... { OrderSelect(j, SELECT_BY_POS); if ( OrderSymbol()==Symbol() && ( (OrderMagicNumber() == uniqueGridMagic) ||| (OrderComment() == GridName)) )  // só olhar se mygrid e símbolo...
         { int type = OrderType(); bool result = false;//if (type > 1) Print(type," ",theEMAValue," ",OrderOpenPrice()); if ( type == OP_BUYLIMIT && OrderOpenPrice() <= theEMAValue ) result = OrderDelete( OrderTicket() ); if ( type == OP_BUYSTOP && OrderOpenPrice() <= theEMAValue ) resultado = OrderDelete( OrderTicket() ); if ( type == OP_SELLLIMIT && OrderOpenPrice() >= theEMAValue ) resultado = OrderDelete( OrderTicket() ); if ( type == OP_SELLSTOP && OrderOpenPrice() >= theEMAValue ) resultado = OrderDelete( OrderTicket() ); } } } 
   return; }//+------------------------------------------------------------------+//| script program start function |//+------------------------------------------------------------------+int start() {//---- int i, j,k, ticket, entermode, totalorders; bool doit; double point, startrate, traderate;//---- setup parameters if ( TakeProfit <= 0 ) // { TakeProfit = GridSize; } bool myWantLongs = wantLongs;
 bool myWantShorts = wantShorts;//---- if (MathAbs(CurTime()-LastUpdate)> UpdateInterval*60) // atualizamos a primeira vez que é chamado e a cada minuto do UpdateInterval { LastUpdate = CurTime();
   point = MarketInfo(Symbol(),MODE_POINT); startrate = ( Ask + point*GridSize/2 ) / point / GridSize; // redondo para um número de ticks divisíveis por GridSize k = startrate ; k = k * GridSize ; startrate = k * point - GridSize*GridSteps/2*point ;          // calcular o ponto de entrada mais baixo duplo myEMA=iMA(NULL,0,EMAperiod,0,MODE_EMA,PRICE_CLOSE,0); if (limitEMA) { if (doHouseKeeping) CloseOrdersfersfromEMA(myEMA); } if ( UseMACD ) { double Macd0=iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_MAIN,0);
      double Macd1=iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_MAIN,1); double Macd2=iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_MAIN,2); if( Macd0>0 && Macd1>0 && Macd2<0) // cross up { CloseAllPendingOrders(); if ( CloseOpenPositions == true ) { CloseOpenOrders(); } } if( Macd0<0 && Macd1<0 && Macd2>0) // cross down { CloseAllPendingOrders();
         if ( CloseOpenPositions == true ) { ClosOpenOrders(); } } myWantLongs = false; myWantShorts = false; if( Macd0>0 && Macd1>0 && Macd2>0 && wantLongs )     // está bem acima de zero { myWantLongs = true; } if( Macd0<0 && Macd1<0 && Macd2<0 && wantShorts )     // está bem abaixo de zero { myWantShorts = true; } } for( i=0;i<GridSteps;i++) { traderate = startrate + i*point*GridSize; if ( myWantLongs && (!limitEMA || traderate > myEMA)) { if ( IsPosition(traderate,point*GridSize,true) == false )           // testar se não tenho ordens abertas próximas ao meu preço: se sim, colocar uma em { double myStopLoss = 0; se ( StopLoss > 0 ) { myStopLoss = traderate-point*StopLoss ; } if ( traderate > Ask ) { entermode = OP_BUYSTOP; } 
              else { entermode = OP_BUYLIMIT ; } 
              if ((traderate > Ask ) && (wantBreakout)) || ((traderate <= Ask ) && (wantCounter)) ) 
              { // modificado pela cori. Usando OrderMagicNumber para identificar os negócios da grade ticket=OrderSend(Symbol(),entermode,Lots,traderate,0,myStopLoss,traderate+point*TakeProfit,GridName,uniqueGridMagic,0,Green); } } } if ( myWantShorts && (!limitEMA || traderate < myEMA)) { if (IsPosition(traderate,point*GridSize,false)== false )           // testar se não tenho ordens abertas próximas ao meu preço: se sim, colocar uma em { myStopLoss = 0; se ( StopLoss > 0 ) { myStopLoss = traderate+point*StopLoss ; } if ( traderate > Bid ) { entermode = OP_SELLLIMIT; } 
              else { entermode = OP_SELLSTOP ; } 
              
              if ((traderate < Bid ) && (wantBreakout)) || ((traderate >= Bid ) && (wantCounter)) ) 
                { // modificado pela cori. Usando OrderMagicNumber para identificar os negócios da grade ticket=OrderSend(Symbol(),entermode,Lots,traderate,0,myStopLoss,traderate-point*TakeProfit,GridName,uniqueGridMagic,0,Red); } } } } } } return(0); }//+------------------------------------------------------------------+