Creatore di griglie 1.1

 
Ecco la versione 1.1 del 'Grid maker'... uno script o un expert advisor che imposta e mantiene una serie di ordini di acquisto o vendita uniformemente distanziati.
Questa versione è sia uno script che un expert advisor, è possibile cambiare la frequenza di aggiornamento, selezionare long e/o short, ecc... vedere i parametri per una spiegazione.

Penso di aver testato la maggior parte delle varianti, ma non ci sono garanzie che funzioni in tutti i casi! Se lo provate e trovate problemi, fatemelo sapere.

Questa è probabilmente l'ultima versione che pubblico. L'ho sviluppata per testare MT4. Le versioni future saranno più complesse e avranno bisogno di dati esterni come i livelli di supporto e resistenza, quindi non sarà opportuno postarle.



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

Sto seguendo questa idea da molto tempo sui forum di MoneyTec (Simspeed), ET (ElectricSavant) e Oanda (MarkVH e Sympatico) e ho pensato a come sviluppare qualche esperto per migliorare il primo script che hai inviato al forum, forse potremmo lavorare insieme per arrivare a qualcosa di più veloce :) Per favore fatemi sapere se siete interessati la mia e-mail è artefactodigital@gmail.com

Cordiali saluti,
Fernando.

Ecco la versione 1.1 del 'Grid maker'... uno script o expert advisor che imposta e mantiene una serie di ordini di acquisto o di vendita uniformemente distanziati. <br / translate="no"> Questa versione è sia uno script che un expert advisor, è possibile cambiare la frequenza di aggiornamento, selezionare long e/o short, ecc... vedere i parametri per una spiegazione.

Penso di aver testato la maggior parte delle varianti, ma non ci sono garanzie che funzioni in tutti i casi! Se lo provate e trovate problemi, fatemelo sapere.

Questa è probabilmente l'ultima versione che pubblico. L'ho sviluppata per testare MT4. Le versioni future saranno più complesse e avranno bisogno di dati esterni come i livelli di supporto e resistenza, quindi non sarà opportuno postarle.
 
ok suona bene... vedi la mia email...
 
A proposito, siete liberi di provarlo, usarlo, cambiarlo ma per favore non vendetelo!

Non fornisco alcuna garanzia sulla sua effettiva condizione di lavoro e qualsiasi operazione di trading che puoi fare con esso è a tuo rischio e pericolo.
Non mi assumo alcuna responsabilità per perdite dirette o indirette dovute a questo script.


Se lo usi, per favore pubblica ogni tanto un feedback - risultati, impostazioni, bug, osservazioni, ecc.

godetevi
 
Ok, eccoci qua... una grande mossa di mercato dopo, la griglia sopravvive! Ho aperto un conto demo due settimane fa con 50k.
Ho perso 1k testando il gridmaker e poi poco prima del crollo dell'euro ho messo il GridMaker expert di default su 9 coppie di valute:
EUR/CHF, USD/JPY, GBP/JPY, EUR/GBP, USD/CHF, AUD/USD, GBP/USD, EUR/USD, EUR/JPY.

La spaziatura della griglia è di 6 tick per tutte le valute, e il TP a 6 tick. Ho posizionato 0,1 lotti. Sono andato lungo e corto ogni 6 tick per ogni coppia di valute.
Il refresh è stato ogni 15 minuti (cioè la griglia è stata rigenerata ogni 15 minuti) tranne che per EUR/USD e GBP/USD a 5 minuti.

Il saldo è aumentato di 10k (20%), il margine usato è di 13k (26%), il margine libero è di 26k (52%) e il p&l non realizzato è -19k.

Il risultato netto del botto di euro (finora) è che sono sotto di -9k. Mi aspettavo molto peggio di così!

La rete sta aggiungendo al bilancio al ritmo di 600-2000 al giorno!

Non vedo l'ora di vedere come sarà la prossima settimana.

Lunga vita alla griglia!
 
Bene, bene, una settimana dopo e la griglia ha davvero preso una bella botta! Colpa mia perché non ho fatto i necessari calcoli sulla dimensione del lotto e la spaziatura della griglia
necessari per vedere quanto colpo si può prendere con il capitale disponibile.

Ad ogni modo, il bilancio sta girando abbastanza bene: 700 a 1800 al giorno di aumento - il bilancio è ora 65k (iniziato con 49k, quindi questo è +16k)
Il margine usato è ora 15k, il margine disponibile 21k - ancora molto spazio per aggiungere posizioni quando necessario.
Il p&l non realizzato è -29k, dando una perdita netta di 13k, 4 peggio della scorsa settimana.

Il lato positivo è che ho cambiato le impostazioni per evitare le contrattazioni (CounterTrade flag false) e il p&l non realizzato sembra essersi stabilizzato.
A un certo punto era a -36k.

Quello che mi piace di questo test in avanti è che è iniziato con un grosso colpo - il calo dell'euro della scorsa settimana - quindi sarà interessante vedere come e quando il
sistema si riprende. Non ho dubbi che lo farà.

Non vedo l'ora di vedere i risultati la prossima settimana!

ps. Ho una v1.2 con la possibilità di cambiare il TP e aggiungere uno SL. Posta qui se la vuoi.
 
Ho giocato un bel po' con questo, facendo funzionare tutto di default su tutte le coppie.
Devo dire che sono rimasto molto impressionato da come si è comportato.

C'è solo un grande problema con questo...

permette di prendere solo posizioni short... quando il prezzo scende gli ordini short vengono attivati... ma molte volte si possono avere 2 ordini sul lato short prima che il prezzo decida di invertire.

cioè il take profit è allo stesso prezzo del prossimo short da avviare e non prende in considerazione lo spread cioè i prezzi bid e ask.

quindi per evitare di avere 2 ordini aperti prima che i prezzi invertano sul lato long il TP deve avvenire allo stesso tempo del prossimo ordine short.

Penso che se questo è possibile il mio drawdown attualmente potrebbe essere tagliato a metà...

Immagino che la tua ultima versione di questo risolverebbe questo problema.

Quindi se potessi postarla sarebbe fantastico...
 
Ciao,

sono contento che tu lo trovi divertente... anche io...

non c'è modo di avere allo stesso tempo un TP = dimensione della griglia ed eliminare la possibilità di avere 2 posizioni aperte su un'inversione.
questo non è un problema di software ma semplicemente legato agli spreads.

l'unica possibilità di eliminare teoricamente del tutto questo è quella di perdere lo spread ogni volta:
cioè vai corto a 1,2006 (bid), TP a 1,2000 (ask) e corto a 1,1996 (bid) se hai uno spread di 4 tick.
Perdi semplicemente 4/10 del range.

nella nuova versione, è possibile impostare la dimensione della griglia e il TP su numeri diversi in modo da poter implementare ciò che stai
cercando: u impostare la griglia a 10 e TP a 6 se hai uno spread di 4 punti.

Non sono sicuro che ridurrà il dd della metà - ma certamente ridurrà il tuo profitto in modo significativo.

Fatemi sapere.

ps.. v1.2 nel prossimo post
 
Ecco la v1.2 di gridmaker.

le uniche differenze sono:
1) ho aggiunto uno stoploss opzionale se ne volete uno. 0 significa nessuno stop loss, qualsiasi numero positivo significa uno stoploss.
se usi uno stop loss in una griglia, dovresti renderlo grande...
2) puoi specificare un TP diverso dalla dimensione della griglia. darkstonexa, nel post precedente, vuole eliminare le posizioni doppie 'appese'.
La mia intenzione iniziale era di provare TP più grandi rispetto alla dimensione della griglia.

salvarlo nella cartella expert advisor (qualcosa come C:\Program Files\MetaTrader 4\experts\) e una copia opzionale nella cartella scripts
se lo vuoi come script (C:\Program Files\MetaTrader 4\experts\scripts\).

Ho uno script per rimuovere gli ordini aperti in griglia se vuoi... è abbastanza utile se vuoi cambiare le impostazioni.

NOTA: le impostazioni di default potrebbero essere cambiate dall'ultima versione. assicuratevi di mettere le vostre impostazioni preferite prima di ricompilare.

DOMANDA a un amministratore: forse dovrei mettere questo tipo di cose nella libreria degli expert advisor... è corretto?

//+------------------------------------------------------------------+
//|                                                     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);
  }
//+------------------------------------------------------------------+
 
Questo è fantastico...

Solo la soluzione al problema al momento di avere un'opzione TP.

Potrei aver sovrastimato la quantità di drawdown ... ma si spera che fermerà molti dei casi in cui ho visto 2 ordini alla fine di un intervallo
ciascuno con una perdita di $2000 + sarà una cosa del passato :)

ora l'ultima cosa che potrebbe essere utile è capire come impostare l'opzione di scadenza sugli ordini limite...
attualmente l'hai impostato in modo che non scadano ...
quindi devi cancellare manualmente.

Attualmente ho un mucchio di ordini che sono circa 3 giorni vecchi e non è probabile che siano colpiti in qualsiasi momento presto ...

Beh, vorrei dire grande lavoro ... :)
 
Ecco uno script per rimuovere tutti gli ordini aperti per una particolare coppia di valute. il codice è un po' sgradevole ma sembra funzionare...

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