Créateur de grilles 1.1

 
Voici la version 1.1 du 'Grid maker'... un script ou un conseiller expert qui met en place et maintient une série d'ordres d' achat ou de vente régulièrement espacés.
Cette version est soit un script soit un expert advisor, vous pouvez changer la fréquence de mise à jour, sélectionner des longs et/ou des shorts, etc... voir les paramètres pour une explication.

Je pense avoir testé la plupart des variantes mais il n'y a aucune garantie que cela fonctionne dans tous les cas ! Si vous l'essayez et trouvez des problèmes, faites-le moi savoir.

C'est probablement la dernière version que je poste. Je l'ai développée pour tester MT4. Les futures versions seront plus complexes, nécessitant des données externes telles que les niveaux de support et de résistance, il ne sera donc pas approprié de les poster.



//+------------------------------------------------------------------+
//|                                                     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);
  }
//+------------------------------------------------------------------+
 
Salut hdb,

Je suis cette idée depuis longtemps sur les forums de MoneyTec (Simspeed), ET (ElectricSavant) et Oanda (MarkVH et Sympatico) et j'ai réfléchi à la façon de développer un expert pour améliorer le premier script que vous avez envoyé au forum, peut-être pourrions-nous travailler ensemble pour arriver à quelque chose plus rapidement :) S'il vous plaît laissez-moi savoir si vous êtes intéressé mon e-mail est artefactodigital@gmail.com

Meilleures salutations,
Fernando.

Voici la version 1.1 du 'Grid maker'... un script ou un conseiller expert qui met en place et maintient une série d'ordres d'achat ou de vente régulièrement espacés. <br / translate="no">Cette version est soit un script soit un conseiller expert, u peut changer la fréquence de mise à jour, sélectionner des longs et/ou des shorts, etc... voir les paramètres pour une explication.

Je pense que j'ai testé la plupart des variantes, mais il n'y a aucune garantie qu'il fonctionne dans tous les cas ! Si vous l'essayez et trouvez des problèmes, faites-le moi savoir.

C'est probablement la dernière version que je poste. Je l'ai développée pour tester MT4. Les futures versions seront plus complexes, nécessitant des données externes telles que les niveaux de support et de résistance, il ne sera donc pas approprié de les poster.
 
ok, ça me va... voir mon email...
 
d'ailleurs, vous êtes libre de l'essayer, de l'utiliser, de le modifier mais ne le vendez pas !

Je ne fournis aucune garantie quant à son fonctionnement effectif et tout commerce que vous pouvez faire avec ce script est à vos propres risques.
Je n'assume aucune responsabilité pour les pertes directes ou indirectes dues à ce script.


Si vous l'utilisez, veuillez me faire part de vos commentaires de temps en temps - résultats, paramètres, bugs, observations, etc.

Bonne lecture
 
ok, c'est parti... un mouvement majeur du marché plus tard, la grille a survécu !! J'ai ouvert un compte de démonstration il y a deux semaines avec 50k.
J'ai perdu 1k en testant le gridmaker et juste avant le plongeon de l'euro, j'ai mis l'expert GridMaker par défaut sur 9 paires de devises :
EUR/CHF, USD/JPY, GBP/JPY, EUR/GBP, USD/CHF, AUD/USD, GBP/USD, EUR/USD, EUR/JPY.

L'espacement de la grille est de 6 ticks pour toutes les devises, et le TP à 6 ticks. J'ai placé une taille de lot de 0,1. Je suis allé long ET court tous les 6 ticks pour chaque paire de devises.
Le rafraîchissement s'est fait toutes les 15 minutes (c'est-à-dire que la grille s'est régénérée toutes les 15 minutes) sauf pour EUR/USD et GBP/USD à 5 minutes.

Le solde est en hausse de 10k (20%), la marge utilisée est de 13k (26%), la marge libre est de 26k (52%) et le p&l non réalisé est de -19k.

Le résultat net de l'euro bang (jusqu'à présent) est que je suis en baisse de -9k. Je m'attendais à bien pire que cela !

Le réseau ajoute à la balance au rythme de 600 à 2000 par jour !

J'ai hâte de voir ce que cela donnera la semaine prochaine.

Longue vie à la grille !
 
Eh bien, eh bien, une semaine plus tard, la grille a vraiment pris un coup ! C'est ma faute, car je n'ai pas fait les calculs nécessaires sur la taille des lots et l'espacement des grilles.
nécessaires pour voir combien d'un coup on peut prendre avec l'équité disponible.

Quoi qu'il en soit, le solde se porte plutôt bien : augmentation de 700 à 1800 par jour - le solde est maintenant de 65k (il a commencé avec 49k, donc c'est +16k ).
La marge utilisée est maintenant de 15k, la marge disponible de 21k - encore beaucoup de place pour ajouter des positions si nécessaire.
Le p&l non réalisé est de -29k, soit une perte nette de 13k, 4 de moins que la semaine dernière.

Le côté positif est que j'ai changé les paramètres pour éviter les contre-opérations (CounterTrade flag false) et le p&l non réalisé semble s'être stabilisé.
Il était à -36k à un moment donné.

Ce que j'aime dans ce test, c'est qu'il a commencé par un gros choc - la chute de l'euro la semaine dernière - et il sera donc intéressant de voir comment et quand le système se rétablira.
système se rétablira. Je ne doute pas qu'il le fera.

J'ai hâte de voir les résultats la semaine prochaine !!!

ps. J'ai une v1.2 avec la possibilité de changer le TP et d'ajouter un SL. Postez ici si vous le voulez.
 
J'ai joué avec celui-ci un peu. J'ai juste exécuté tout par défaut sur toutes les paires...
Je dois dire que j'ai été très impressionné par ses performances.

Il n'y a qu'un seul gros problème...

Prenons uniquement des positions courtes... lorsque le prix baisse, les ordres courts sont activés... mais il arrive souvent que l'on ait 2 ordres courts avant que le prix ne décide de s'inverser.

c'est à dire que le take profit est au même prix que le prochain court à être initié et ne prend pas en compte le spread c'est à dire les prix d'achat et de vente.

donc pour éviter d'avoir 2 ordres ouverts avant que les prix ne s'inversent du côté long, le TP doit se produire en même temps que le prochain ordre court est placé.

Je pense que si cela est possible, mon drawdown actuel pourrait être réduit de moitié...

J'imagine que votre dernière version résoudrait ce problème.

Donc si vous pouviez la poster, ce serait fantastique...
 
Bonjour,

je suis content que tu trouves ça amusant... moi aussi...

il n'y a aucun moyen d'avoir en même temps un TP = taille de grille et d'éliminer la possibilité d'avoir 2 positions ouvertes sur un retournement.
Ce n'est pas un problème de logiciel mais simplement lié aux spreads.

La seule possibilité d'éliminer totalement ce problème en théorie est de perdre le spread à chaque fois :
i.e. vous êtes short à 1.2006 (bid), TP à 1.2000 (ask) et short à 1.1996 (bid) si vous avez un spread de 4 tick.
Vous perdez simplement 4/10ème de la fourchette.

Dans la nouvelle version, vous pouvez définir la taille de la grille et le TP à des nombres différents, donc vous pouvez mettre en œuvre ce que vous recherchez.
ce que vous recherchez : vous définissez la grille à 10 et le TP à 6 si vous avez un écart de 4 points.

je ne suis pas sûr que cela réduira le dd de moitié - mais cela réduira certainement votre profit de manière significative.

Tenez-moi au courant.

ps... v1.2 dans le prochain post
 
voici la v1.2 de gridmaker.

les seules différences sont :
1) j'ai ajouté un stoploss optionnel si vous en voulez un. 0 signifie pas de stoploss, tout nombre positif signifie un stoploss.
si vous utilisez un stoploss dans une grille, vous devriez le faire grand...
2) vous pouvez spécifier un TP différent de la taille de la grille. darkstonexa, dans le post précédent, veut éliminer les positions doubles 'suspendues'.
mon intention initiale était d'essayer des TP plus grands par rapport à la taille de la grille.

enregistrez-le dans le dossier expert advisor ( quelque chose comme C:\Program Files\MetaTrader 4\experts\ ) et une copie facultative dans le dossier scripts
si vous le voulez comme un script (C:\Program Files\MetaTrader 4\experts\scripts\).

J'ai un script pour supprimer les ordres de grille ouverts si vous le souhaitez... c'est très utile si vous voulez changer les paramètres.

NOTE : les paramètres par défaut peuvent avoir changé depuis la dernière version. assurez-vous que vous mettez vos paramètres préférés avant de recompiler.

QUESTION à un administrateur : peut-être que je devrais mettre ce genre de choses dans la bibliothèque des conseillers experts... est-ce correct ?

//+------------------------------------------------------------------+
//|                                                     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);
  }
//+------------------------------------------------------------------+
 
C'est génial.

C'est la solution au problème actuel d'avoir une option TP.

J'ai peut-être surestimé le montant du drawdown... mais j'espère que cela mettra fin à beaucoup de cas où j'ai vu 2 ordres à la fin d'une fourchette
chacun avec une perte de plus de 2000 $ sera une chose du passé :)

Maintenant, la dernière chose qui pourrait être utile est de travailler sur le réglage de l'option d'expiration des ordres à cours limité...
actuellement, ils n'expirent pas...
donc vous devez les supprimer manuellement.

Actuellement, j'ai un tas d'ordres qui datent d'environ 3 jours et qui ne sont pas susceptibles d'être touchés de sitôt...

Eh bien, je tiens à dire que c'est du bon travail... :)
 
voici un script pour supprimer tous les ordres ouverts pour une paire de devises particulière. le code est un peu méchant mais il semble fonctionner...

//+------------------------------------------------------------------+
//|                                                   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);
  }
//+------------------------------------------------------------------+