Grid maker 1.1

 
Aqui está a versão 1.1 do 'Grid maker'... um script ou consultor especializado que estabelece e mantém uma série de ordens de compra ou venda uniformemente espaçadas.
Esta versão é ou um script ou um consultor especializado, você pode mudar a freqüência de atualização, selecionar longas e/ou curtas, etc... veja os parâmetros para uma explicação.

Acho que já testei a maioria das variantes, mas não há garantias de que funcione em todos os casos! Se você tentar e encontrar problemas, me avise.

Esta é provavelmente a última versão que eu postarei. Eu a desenvolvi para testar o MT4. As futuras versões serão mais complexas, necessitando de dados externos como suporte e níveis de resistência, portanto não será apropriado publicá-los.



//+------------------------------------------------------------------+
//|                                                     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.1beta"

extern string GridName = "Grid";       // identifies the grid. allows for several co-existing grids
extern double Lots = 0.1;              // 
extern double GridSize = 6;            // pips between orders - grid or mesh size
extern double GridSteps = 10;          // total number of orders to place
extern double UpdateInterval = 15;     // update orders every x minutes
extern bool   wantLongs = true;        //  do we want long positions
extern bool   wantShorts = true;       //  do we want short positions
extern bool   wantBreakout = true;     // do we want longs above price, shorts below price
extern bool   wantCounter = true;      // do we want longs below price, shorts above price
extern bool   limitEMA34 = false;      // do we want longs above ema only, shorts below ema only
extern double LastUpdate = 0;          // counter used to note time of last update
//+------------------------------------------------------------------+
//| expert initialization function                                   |
//+------------------------------------------------------------------+
int init()
  {
//---- 
 #property show_inputs              // shows the parameters - thanks Slawa...    
//----
   return(0);
  }
//+------------------------------------------------------------------------+
//| test if there is an open position or order in the region of atRate     |
//|     will check for longs if checkLongs is true, else will check        |
//|     for shorts                                                         |
//+------------------------------------------------------------------------+

bool IsPosition(double atRate, double inRange, bool checkLongs )
  {
  
     int totalorders = OrdersTotal();
     for(int j=0;j<totalorders;j++)                                // scan all orders and positions...
      {
        OrderSelect(j, SELECT_BY_POS);
        if ( OrderSymbol()==Symbol() && OrderComment() == GridName )  // only look if mygrid and symbol...
         {  int type = OrderType();
            if (MathAbs( OrderOpenPrice() - atRate) < inRange) // dont look for exact price but price proximity (less than gridsize)
              { if ( ( checkLongs && ( type == OP_BUY || type == OP_BUYLIMIT  || type == OP_BUYSTOP ) )  || (!checkLongs && ( type == OP_SELL || type == OP_SELLLIMIT  || type == OP_SELLSTOP ) ) )
                 { return(true); }
              }
         }
      } 

   return(false);
  }
//+------------------------------------------------------------------+
//| script program start function                                    |
//+------------------------------------------------------------------+
int start()
  {
//---- 
   int    i, j,k, ticket, entermode, totalorders;
   bool   doit;
   double point, startrate, traderate;
 
//----
  if (MathAbs(CurTime()-LastUpdate)> UpdateInterval*60)           // we update the first time it is called and every UpdateInterval minutes
   {
   LastUpdate = CurTime();
   Print("Updating");
   point = MarketInfo(Symbol(),MODE_POINT);
   startrate = ( Ask + point*GridSize/2 ) / point / GridSize;    // round to a number of ticks divisible by GridSize
   k = startrate ;
   k = k * GridSize ;
   startrate = k * point - GridSize*GridSteps/2*point ;          // calculate the lowest entry point
   
   double 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) )           // test if i have no open orders close to my price: if so, put one on
          {
             if ( traderate > Ask ) 
              { entermode = OP_BUYSTOP; } 
              else 
              { entermode = OP_BUYLIMIT ; } 
             if ( (traderate > Ask ) && (wantBreakout) || ((traderate < Ask ) && (wantCounter)) ) 
              { ticket=OrderSend(Symbol(),entermode,Lots,traderate,0,0,traderate+point*GridSize,GridName,16384,0,Green); }
          }
       }

     if ( wantShorts && (!limitEMA34 || traderate < EMA34))
       {
         if (!IsPosition(traderate,point*GridSize,false) )           // test if i have no open orders close to my price: if so, put one on
          {
             if ( traderate > Bid ) 
              { entermode = OP_SELLLIMIT; } 
              else 
              { entermode = OP_SELLSTOP ; } 
              
              if ( (traderate < Bid ) && (wantBreakout) || ((traderate > Bid ) && (wantCounter)) ) 
                { ticket=OrderSend(Symbol(),entermode,Lots,traderate,0,0,traderate-point*GridSize,GridName,16384,0,Red); }
          }
       }

    }
   }
   return(0);
  }
//+------------------------------------------------------------------+
 
Olá hdb,

Tenho seguido esta idéia há muito tempo nos fóruns MoneyTec (Simspeed), ET (ElectricSavant) e Oanda (MarkVH e Sympatico) e tenho pensado em como desenvolver algum especialista para melhorar o primeiro roteiro que você enviou ao fórum, talvez pudéssemos trabalhar juntos para chegar a algo mais rápido :) Se você estiver interessado, por favor me avise que meu e-mail é artefactodigital@gmail.com

Com os melhores cumprimentos,
Fernando.

Aqui está a versão 1.1 do 'Grid maker'... um script ou consultor especializado que estabelece e mantém uma série de ordens de compra ou venda igualmente espaçadas. <br / translate="no"> Esta versão ou é um script ou um consultor especializado, você pode mudar a freqüência de atualização, selecionar longs e/ou shorts, etc... veja os parâmetros para uma explicação.

Acho que testei a maioria das variantes, mas não há garantias de que funcione em todos os casos! Se você tentar e encontrar problemas, me avise.

Esta é provavelmente a última versão que eu postarei. Eu a desenvolvi para testar o MT4. As futuras versões serão mais complexas, necessitando de dados externos como suporte e níveis de resistência, portanto não será apropriado publicá-los.
 
ok soa bem... veja meu e-mail...
 
a propósito, você é livre para experimentá-lo, usá-lo, mudá-lo, mas por favor não o venda!

Eu não dou nenhuma garantia quanto à sua condição efetiva de trabalho e qualquer negociação que você possa fazer com ela por sua própria conta e risco.
Não assumo nenhuma responsabilidade por perdas diretas ou indiretas devidas a este roteiro.


Se você usá-lo, por favor, envie comentários ocasionais - resultados, configurações, bugs, observações, etc.

aproveite
 
ok, aqui vai... um grande movimento de mercado depois, a grade sobrevive!! Eu comecei uma conta demo há duas semanas com 50k.
Perdi 1k testando o gridmaker e, pouco antes da queda do euro, coloquei o especialista padrão do GridMaker em 9 pares de moedas:
EUR/CHF, USD/JPY, GBP/JPY, EUR/GBP, USD/CHF, AUD/USD, GBP/USD, EUR/USD, EUR/JPY.

O espaçamento da grade é de 6 ticks para todas as moedas, e TP de 6 ticks. Coloquei 0,1 tamanho de lote. Fui longo E curto a cada 6 carrapatos para cada par de moedas.
A atualização foi a cada 15 minutos (ou seja, a grade foi regerada a cada 15 minutos) exceto para EUR/USD e GBP/USD a 5 minutos.

O saldo é de 10k (20%), a margem utilizada é de 13k (26%), a margem livre é de 26k (52%) e o p&l não realizado é de -19k.

O resultado líquido do bang do euro (até agora) é que eu estou abaixo de -9k. Eu estava esperando muito pior do que isto!

A grelha está somando ao saldo à taxa de 600 a 2000 por dia!

Estou ansioso para ver como isto vai ficar na próxima semana.

Viva a grelha!!
 
Bem, bem, uma semana depois e a rede realmente levou uma surra! Minha culpa porque eu não fiz os cálculos necessários do tamanho do lote / espaçamento da grade
necessário para ver quanto de um acerto se pode aguentar com o patrimônio disponível.

De qualquer forma, o balanço está se agitando muito bem: 700 a 1800 por dia de aumento - o balanço agora é de 65k (iniciado com 49k, então isto é +16k )
A margem usada agora é de 15k, margem disponível 21k - ainda há muito espaço para adicionar posições quando necessário.
O p&l não realizado é de -29k, dando uma perda líquida de 13k, 4 pior do que na semana passada.

O lado positivo é que mudei as configurações para evitar contra-operações (bandeira do CounterTrade falsa) e o p&l não realizado parece ter se estabilizado.
Estava a -36k em uma etapa.

O que eu gosto sobre este teste de avanço é que ele começou com um grande sucesso - a queda do euro da semana passada - então agora será interessante ver como e quando o
recupera o sistema. Não tenho dúvida que sim.

Eu não posso esperar para ver os resultados na próxima semana!!!

ps. Eu tenho um v1.2 com a possibilidade de mudar o TP e adicionar um SL. Poste aqui se você quiser.
 
Eu tenho brincado bastante com este. Apenas correndo tudo por padrão em todos os pares.
Devo dizer que tenho ficado muito impressionado com a forma como ele é executado.

Há apenas uma grande preguiça com isto...

vamos tomar apenas positins curtos... à medida que o preço cai, as ordens curtas são ativadas... mas muitas vezes você pode receber 2 ordens no lado curto antes que o preço decida reverter.

ou seja, o lucro do take é o mesmo preço da próxima ordem curta a ser iniciada e não leva em conta o spread, ou seja, os preços de compra e venda.

assim, a fim de ajudar a evitar que 2 ordens abertas antes que os preços revertam para o lado longo TP precisa acontecer ao mesmo tempo em que a próxima ordem curta é colocada.

Se isto for possível, meu saque poderia ser cortado pela metade.

Suponho que sua última versão disto resolveria este problema.

Portanto, se você pudesse postar isso seria fantástico...
 
oi,

fico feliz que você ache isso divertido... eu também...

não há como eu ter ao mesmo tempo um TP = tamanho de grade e eliminar a possibilidade de ter 2 posições abertas em uma inversão.
isto não é um problema de software, mas simplesmente relacionado a spreads.

a única possibilidade de eliminar isto teoricamente totalmente é perder o spread a cada vez:
ou seja, u vai curto em 1.2006 (bid), TP em 1.2000 (ask) e curto em 1.1996 (bid) se você tiver um spread de 4 tick.
u simplesmente perde 4/10 do intervalo.

na nova versão, u pode definir o tamanho da grade e TP para números diferentes para que u possa implementar o que você é
procurando: u definir a grade para 10 e TP para 6 se você tiver um spread de 4 pontos.

Não tenho certeza se reduzirá o dd pela metade - mas certamente reduzirá seu lucro significativamente.

me avise.

ps. v1.2 no próximo post
 
aqui está o v1.2 do gridmaker.

as únicas diferenças são:
1) eu acrescentei um stoploss opcional, se você quiser um. 0 significa sem stop loss, qualquer número positivo significa um stop loss.
se u usar um stop loss em uma grade, u deve torná-la grande...
2) u pode especificar um TP diferente do tamanho da grade. darkstonexa , no posto anterior, quer eliminar posições duplas de 'pendurar'.
minha intenção inicial era tentar TPs maiores em relação ao tamanho da grade.

salve-o na pasta do consultor especializado ( algo como C:\Program Files\MetaTrader 4\experts\ ) e uma cópia opcional na pasta de scripts
se u o quiser como um script (C:\Program Files\MetaTrader 4\experts\scripts\).

Eu tenho um script para remover ordens de grade abertas se você quiser... é bastante útil se você quiser mudar as configurações.

NOTA: as configurações padrão podem ter mudado desde a última versão. certifique-se de colocar suas configurações preferidas antes de recompilar.

PERGUNTA a um administrador: talvez eu devesse colocar este tipo de coisa na biblioteca do consultor especializado... isto está correto?

//+------------------------------------------------------------------+
//|                                                     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.2beta"

extern string GridName = "Grid";       // identifies the grid. allows for several co-existing grids
extern double Lots = 0.1;              // 
extern double GridSize = 6;            // pips between orders - grid or mesh size
extern double GridSteps = 10;          // total number of orders to place
extern double TakeProfit = 6 ;         // number of ticks to take profit. normally is = grid size but u can override
extern double StopLoss = 0;            // if u want to add a stop loss. normal grids dont use stop losses
extern double UpdateInterval = 15;     // update orders every x minutes
extern bool   wantLongs = true;        //  do we want long positions
extern bool   wantShorts = true;       //  do we want short positions
extern bool   wantBreakout = true;     // do we want longs above price, shorts below price
extern bool   wantCounter = false;      // do we want longs below price, shorts above price
extern bool   limitEMA34 = false;      // do we want longs above ema only, shorts below ema only
extern double LastUpdate = 0;          // counter used to note time of last update
//+------------------------------------------------------------------+
//| expert initialization function                                   |
//+------------------------------------------------------------------+
int init()
  {
//---- 
 #property show_inputs                  // shows the parameters - thanks Slawa...    
 if ( TakeProfit <= 0 )                 // 
   { TakeProfit = GridSize; }
//----
   return(0);
  }
//+------------------------------------------------------------------------+
//| tests if there is an open position or order in the region of atRate    |
//|     will check for longs if checkLongs is true, else will check        |
//|     for shorts                                                         |
//+------------------------------------------------------------------------+

bool IsPosition(double atRate, double inRange, bool checkLongs )
  {
  
     int totalorders = OrdersTotal();
     for(int j=0;j<totalorders;j++)                                // scan all orders and positions...
      {
        OrderSelect(j, SELECT_BY_POS);
        if ( OrderSymbol()==Symbol() && OrderComment() == GridName )  // only look if mygrid and symbol...
         {  int type = OrderType();
            if (MathAbs( OrderOpenPrice() - atRate) < inRange) // dont look for exact price but price proximity (less than gridsize)
              { if ( ( checkLongs && ( type == OP_BUY || type == OP_BUYLIMIT  || type == OP_BUYSTOP ) )  || (!checkLongs && ( type == OP_SELL || type == OP_SELLLIMIT  || type == OP_SELLSTOP ) ) )
                 { return(true); }
              }
         }
      } 

   return(false);
  }
//+------------------------------------------------------------------+
//| script program start function                                    |
//+------------------------------------------------------------------+
int start()
  {
//---- 
   int    i, j,k, ticket, entermode, totalorders;
   bool   doit;
   double point, startrate, traderate;
 
//----
  if (MathAbs(CurTime()-LastUpdate)> UpdateInterval*60)           // we update the first time it is called and every UpdateInterval minutes
   {
   LastUpdate = CurTime();
   Print("Updating");
   point = MarketInfo(Symbol(),MODE_POINT);
   startrate = ( Ask + point*GridSize/2 ) / point / GridSize;    // round to a number of ticks divisible by GridSize
   k = startrate ;
   k = k * GridSize ;
   startrate = k * point - GridSize*GridSteps/2*point ;          // calculate the lowest entry point
   
   double 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) )           // test if i have no open orders close to my price: if so, put one on
          {
             double myStopLoss = 0;
             if ( StopLoss > 0 )
               { myStopLoss = traderate-point*StopLoss ; }
               
             if ( traderate > Ask ) 
              { entermode = OP_BUYSTOP; } 
              else 
              { entermode = OP_BUYLIMIT ; } 
             if ( (traderate > Ask ) && (wantBreakout) || ((traderate < Ask ) && (wantCounter)) ) 
              { ticket=OrderSend(Symbol(),entermode,Lots,traderate,0,myStopLoss,traderate+point*TakeProfit,GridName,16384,0,Green); }
          }
       }

     if ( wantShorts && (!limitEMA34 || traderate < EMA34))
       {
         if (!IsPosition(traderate,point*GridSize,false) )           // test if i have no open orders close to my price: if so, put one on
          {
             myStopLoss = 0;
             if ( StopLoss > 0 )
               { myStopLoss = traderate+point*StopLoss ; }
             if ( traderate > Bid ) 
              { entermode = OP_SELLLIMIT; } 
              else 
              { entermode = OP_SELLSTOP ; } 
              
              if ( (traderate < Bid ) && (wantBreakout) || ((traderate > Bid ) && (wantCounter)) ) 
                { ticket=OrderSend(Symbol(),entermode,Lots,traderate,0,myStopLoss,traderate-point*TakeProfit,GridName,16384,0,Red); }
          }
       }

    }
   }
   return(0);
  }
//+------------------------------------------------------------------+
 
Isso é ótimo...

Apenas a solução para o problema no momento, ter uma opção TP.

Eu posso ter estimado demais a quantidade de saque... mas espero que isso acabe com muitos dos casos em que vi 2 pedidos no final de uma faixa
cada um com uma perda de $2000 + será uma coisa do passado :)

agora a última coisa que pode ser útil é trabalhar para definir a opção de expiração em ordens limitadas.
atualmente está definida para que elas não expirem...
então você tem que apagar manualmente.

Atualmente eu tenho um monte de ordens que têm cerca de 3 dias e não é provável que sejam atingidas em breve...

Bem, eu gostaria de dizer um grande trabalho... :)
 
aqui está um script para remover todas as ordens abertas para um determinado par de moedas. o código é um pouco desagradável, mas parece funcionar...

//+------------------------------------------------------------------+
//|                                                   RemoveGrid.mq4 |
//|                                            Copyright © 2005, hdb |
//|                                       http://www.dubois1.net/hdb |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2005, hdb"
#property link      "http://www.dubois1.net/hdb"

extern string GridName = "Grid";

//+------------------------------------------------------------------+
//| script program start function                                    |
//+------------------------------------------------------------------+
int start()
  {

 #property show_inputs              // shows the parameters - thanks Slawa... 

//---- 
  int total = OrdersTotal();
  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       : result = true ;
      
            case OP_SELL      : result = true ;

            //Close pending orders
            case OP_BUYLIMIT  : result = OrderDelete( OrderTicket() ); 
            case OP_BUYSTOP   : result = OrderDelete( OrderTicket() ); 
            case OP_SELLLIMIT : result = OrderDelete( OrderTicket() ); 
            case OP_SELLSTOP  : result = OrderDelete( OrderTicket() ); 
          }
    
          if(result == false)
          {
     //       Alert("Order " , OrderTicket() , " failed to close. Error:" , GetLastError() );
     //       Sleep(3000);
          }  
        }
      }
 
//----
   return(0);
  }
//+------------------------------------------------------------------+
Razão: