Navigation´╝ÜHome > Content >

Makegrid.mq4

Time: 2010-08-09 | Download file:Makegrid.mq4

//+------------------------------------------------------------------+
//|                                                  MakeGrid193.mq4 |
#property link      "http://www.forex-instruments.info/"
extern int    uniqueGridMagic = 11111; // Magic number of the trades. must be unique to identify
 extern bool      CONTINUE=false;                                      // the trades of one grid    
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 = 10 ;        // 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 int    trailStop = 0;           // will trail if > 0
extern int    BEPips = 0;              // will move the stoploss to BE after x pips of movement
extern double UpdateInterval = 1;      // update orders every x minutes
extern bool   wantLongs = false;        // 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   limitEMA = true;         // do we want longs above ema only, shorts below ema only
extern int    EMAperiod = 34;          // the length of the EMA.. was previously fixed at 34
extern double GridMaxOpen = 0;         // maximum number of open positions : implemented in v1.92
extern bool   UseMACD = true;          // if true, will use macd >0 for longs only, macd <0 for shorts only
                                      // on crossover, will cancel all pending orders. Works in conjunction with wantLongs and wantShorts.
extern bool   UseOsMA = false;         // if true, will use OSMA > 0 for longs only, OSMA <0 for shorts only. used in same way as MACD. 
                                       // If both UseMACD and UseOSMA atr true, OSMA is taken.
extern bool CloseOpenPositions = false;// if UseMACD, do we also close open positions with a loss?
extern bool   doHouseKeeping = true;   // this will remove long orders below the 34 ema and vv if limitEMA flag is true
extern double keepOpenTimeLimit = 0;   // in hours - if > 0, all open orders or positions will be closed after this period. fractions are permitted
extern int    emaFast = 12;            // parameters for MACD and OSMA
extern int    emaSlow = 26;            // parameters for MACD and OSMA
extern int    signalPeriod = 9;        // parameters for MACD and OSMA
extern int    timeFrame = 0;           // parameters for MACD and OSMA
extern int    minFromPrice = 0;        // minimum distance from price to place trades.
extern int    tradeForMinutes=0;       // will trade for this number of minutes after being initialised. 
                                       // add/readd the EA before news and it will trade for these minutes then close out all positions at end
extern int    gridOffset = 0;          // positions are opened at price modulo GridSize and offset with this parameter.
                                       // used essentially to enter at non round numbers
// the following flags set bounds on the prices at which orders may be placed
// this code was developed for and is kindly made public by Exc_ite2

extern double longGridCenter = 0;      // defines the center point of a fixed width long grid                                       
extern double shortGridCenter = 0;     // defines the center point of a fixed width short grid                                       

extern double longGridLow = 0;         // defines the bottom of a fixed width long grid
extern double longGridHigh = 0;        // defines the top of a fixed width long grid

extern double shortGridLow = 0;         // defines the bottom of a fixed width short grid
extern double shortGridHigh = 0;        // defines the top of a fixed width short grid

extern double profitTarget = 15000;     // if > 0, will close out all positions once the $ target has been met

extern bool   suspendGrid = false;       // if set to true, will close all unfilled Orders 
extern bool   shutdownGrid = false;      // if set to true, will close all orders and positions.
                                       
// modified by cori. internal variables only
string   GridName = "Grid";              // identifies the grid. allows for several co-existing grids - old variable.. shold not use any more
double   LastUpdate = 0;                 // counter used to note time of last update
double   startTime = 0;                  // counter to note trade start time.
double   closedProfit = 0;               // counts closed p&l
double   openProfit = 0;                 // counts open p&l
double   accumulatedProfit = 0;          // for back testing only
bool     haveHitTarget = false;          //  if there is a target, this flag says we have hit it
int      openLongs = 0;                  //  how many longs are open 
int      openShorts = 0;                 // how many shorts are open 
bool     gridActive = true;              // is the grid active
bool     gridOneShot = false;       // is this a one shot? if so, it stops after the profitTarget has been reached
bool stop=false,line=false;double Price;
int n1;
//+------------------------------------------------------------------+
//| expert initialization function                                   |
//+------------------------------------------------------------------+
int init()
  {
//---- 
 #property show_inputs                  // shows the parameters - thanks Slawa...    
//----
   GridName = StringConcatenate( "Grid-", Symbol(),"-",uniqueGridMagic );
   stop=false;
   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 i=0;i=0;i--)
     OrderSelect(i, SELECT_BY_POS, MODE_TRADES);
// we use iTime so it works in backtesting
     if ( OrderSymbol()==Symbol() && ( (OrderMagicNumber() == uniqueGridMagic) || (OrderComment() == GridName)) )  // only look if mygrid and symbol...
        {
            if (( MathAbs(iTime(Symbol(),5,0)-OrderOpenTime()) >= xHours*60*60 ) && (iTime(Symbol(),5,0)>0))
            {  bool result = false;
               //Close opened long position
               if ( OrderType() == OP_BUY )  result = OrderClose( OrderTicket(), OrderLots(), MarketInfo(OrderSymbol(), MODE_BID), 5, Red );
               //Close opened short position
               if ( OrderType() == OP_SELL )  result = OrderClose( OrderTicket(), OrderLots(), MarketInfo(OrderSymbol(), MODE_ASK), 5, Red );
               //Close pending order
               if ( OrderType() > 1 ) result = OrderDelete( OrderTicket() );
           }
        }
	  
  } // proc DeleteAfter()


//+------------------------------------------------------------------------+
//| cancells all pending orders                                      |
//+------------------------------------------------------------------------+

void CloseAllPendingOrders( )
  {
     int totalorders = OrdersTotal();
     for(int i=totalorders-1;i>=0;i--)                                // scan all orders and positions...
      {
        OrderSelect(i, SELECT_BY_POS);
// modified as per cori. Using OrderMagicNumber to identify the trades of the grid // hdb added or gridname for compatibility
        if ( OrderSymbol()==Symbol() && ( (OrderMagicNumber() == uniqueGridMagic) || (OrderComment() == GridName)) )  // only look if mygrid and symbol...
         {  
          if ( OrderType() > 1 ) bool result = OrderDelete( OrderTicket() );
         }
      } 
   return;
  }
//+------------------------------------------------------------------------+
//| cancells all pending orders    and closes open positions               |
//+------------------------------------------------------------------------+

void ClosePendingOrdersAndPositions()
{
  int totalorders = OrdersTotal();
  for(int i=totalorders-1;i>=0;i--)
 {
    OrderSelect(i, SELECT_BY_POS);
    bool result = false;
// modified by cori. Using OrderMagicNumber to identify the trades of the grid // hdb added or gridname for compatibility
    if ( OrderSymbol()==Symbol() && ( (OrderMagicNumber() == uniqueGridMagic) || (OrderComment() == GridName)) )  // only look if mygrid and symbol...
     {
           //Close opened long positions
           if ( OrderType() == OP_BUY )  result = OrderClose( OrderTicket(), OrderLots(), MarketInfo(OrderSymbol(), MODE_BID), 5, Red );
           //Close opened short positions
           if ( OrderType() == OP_SELL )  result = OrderClose( OrderTicket(), OrderLots(), MarketInfo(OrderSymbol(), MODE_ASK), 5, Red );
           //Close pending orders
           if ( OrderType() > 1 ) result = OrderDelete( OrderTicket() );
      }
  }
  return;
}

//+------------------------------------------------------------------------+
//| cancells all open orders which fall on the wrong side of the EMA                                     |
//+------------------------------------------------------------------------+

void CloseOrdersfromEMA( double theEMAValue )
  {
     int totalorders = OrdersTotal();
     for(int i=totalorders-1;i>=0;i--)                                // scan all orders and positions...
      {
        OrderSelect(i, SELECT_BY_POS);
        if ( OrderSymbol()==Symbol() && ( (OrderMagicNumber() == uniqueGridMagic) || (OrderComment() == GridName)) )  // only look if mygrid and symbol...
         {  
          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 ) result = OrderDelete( OrderTicket() ); 
          if ( type == OP_SELLLIMIT && OrderOpenPrice() >= theEMAValue ) result = OrderDelete( OrderTicket() ); 
          if ( type == OP_SELLSTOP && OrderOpenPrice() >= theEMAValue ) result = OrderDelete( OrderTicket() ); 
         }
      } 
   return;
  }

//+------------------------------------------------------------------------+
//| counts the number of open positions                                    |
//+------------------------------------------------------------------------+

int openPositions(  )
  {  int op =0;
     int totalorders = OrdersTotal();
     for(int i=totalorders-1;i>=0;i--)                                // scan all orders and positions...
      {
        OrderSelect(i, SELECT_BY_POS);
        if ( OrderSymbol()==Symbol() && ( (OrderMagicNumber() == uniqueGridMagic) || (OrderComment() == GridName)) )  // only look if mygrid and symbol...
         {  
          int type = OrderType();
          if ( type == OP_BUY ) {op=op+1;} 
          if ( type == OP_SELL ) {op=op+1;} 
         }
      } 
   return(op);
  }

//+------------------------------------------------------------------+
//| Close on profit target                                           |
//+------------------------------------------------------------------+
void TestForProfit( int forMagic, double profittarget, bool testOpen, bool testHistory )                   // based on trailing stop code from MT site... but modified as per Hiro
  {
    if (profittarget > 0 )
     {
         closedProfit = 0;                // counts closed p&l

         if (testHistory == true) {
            int total = HistoryTotal();
            for(int i=0;i= (profittarget + accumulatedProfit) ) 
            {
               Print("Closing grid due to profit target");
               ClosePendingOrdersAndPositions();
               accumulatedProfit = accumulatedProfit + closedProfit + openProfit;
               haveHitTarget = true;
               if (gridOneShot==true) { gridActive = false; }
            }
     }
  }


//+------------------------------------------------------------------+
//| Trailing stop procedure                                          |
//+------------------------------------------------------------------+
void TrailIt( int byPips )                   // based on trailing stop code from MT site... thanks MT!
  {
  if (byPips >=5)
  {
  for (int i = 0; i < OrdersTotal(); i++) {
     OrderSelect(i, SELECT_BY_POS, MODE_TRADES);
     if ( OrderSymbol()==Symbol() && ( (OrderMagicNumber() == uniqueGridMagic) || (OrderComment() == GridName)) )  // only look if mygrid and symbol...
        {
            if (OrderType() == OP_BUY) {
               //if (Bid > (OrderValue(cnt,VAL_OPENPRICE) + TrailingStop * Point)) {
               //   OrderClose(OrderTicket(), OrderLots(), Bid, 3, Violet);
               //   break;
               //}
               if (Bid - OrderOpenPrice() > byPips * MarketInfo(OrderSymbol(), MODE_POINT)) {
                  if (OrderStopLoss() < Bid - byPips * MarketInfo(OrderSymbol(), MODE_POINT)) {
                     OrderModify(OrderTicket(), OrderOpenPrice(), Bid - byPips * MarketInfo(OrderSymbol(), MODE_POINT), OrderTakeProfit(), Red);
                  }
               }
            } else if (OrderType() == OP_SELL) {
               if (OrderOpenPrice() - Ask > byPips * MarketInfo(OrderSymbol(), MODE_POINT)) {
                  if ((OrderStopLoss() > Ask + byPips * MarketInfo(OrderSymbol(), MODE_POINT)) || 
                        (OrderStopLoss() == 0)) {
                     OrderModify(OrderTicket(), OrderOpenPrice(),
                        Ask + byPips * MarketInfo(OrderSymbol(), MODE_POINT), OrderTakeProfit(), Red);
                  }
               }
            }
        }
	  }
	  }

  } // proc TrailIt()
  
void DoBE(int byPips)
  {
    for (int i = 0; i < OrdersTotal(); i++) {
     OrderSelect(i, SELECT_BY_POS, MODE_TRADES);
     if ( OrderSymbol()==Symbol() && ( (OrderMagicNumber() == uniqueGridMagic) || (OrderComment() == GridName)) )  // only look if mygrid and symbol...
        {
            if (OrderType() == OP_BUY) if (Bid - OrderOpenPrice() > byPips * MarketInfo(OrderSymbol(), MODE_POINT)) if (OrderStopLoss() != (OrderOpenPrice() +  MarketInfo(OrderSymbol(), MODE_POINT))) OrderModify(OrderTicket(), OrderOpenPrice(), OrderOpenPrice() +  MarketInfo(OrderSymbol(), MODE_POINT), OrderTakeProfit(), Red);
            if (OrderType() == OP_SELL) if (OrderOpenPrice() - Ask > byPips * MarketInfo(OrderSymbol(), MODE_POINT)) if (OrderStopLoss() != (OrderOpenPrice() -  MarketInfo(OrderSymbol(), MODE_POINT))) OrderModify(OrderTicket(), OrderOpenPrice(), OrderOpenPrice() -  MarketInfo(OrderSymbol(), MODE_POINT), OrderTakeProfit(), Red);
        }
    }
  }

//+------------------------------------------------------------------+
//| script program start function                                    |
//+------------------------------------------------------------------+
int start()
  {
  if (CONTINUE==false)
  {
   int  n=0;
   for (int h = 0; h < OrdersTotal(); h++)
   {
     OrderSelect(h, SELECT_BY_POS, MODE_TRADES);
     if ( OrderSymbol()==Symbol() && ( (OrderMagicNumber() == uniqueGridMagic) || (OrderComment() == GridName)) )  // only look if mygrid and symbol...
        {
            if (OrderType() == OP_BUY||OrderType() == OP_SELL) 
           { stop=true;n++;}
        }
    }
  if ( n1>n &&n1!=0 )n=0;
  n1=n;
  
  if ( stop==true&&n==0)
  {
  ClosePendingOrdersAndPositions();
 
  if (ObjectFind("stop")!=0&&line==false){Price=Bid;ObjectCreate("stop",OBJ_HLINE,0,0,Price);ObjectSet("stop",OBJPROP_COLOR,Red);ObjectSet("stop",OBJPROP_WIDTH,2);line=true;}
 if (ObjectFind("stop")!=0&& line==true){line=false;stop=false;}
//---- 
  return(0);}
  
  }
  
   int    i, j,k, ticket, entermode, totalorders;
   bool   doit;
   double point, startrate, traderate, temp;
//---- setup parameters 

 if ( TakeProfit <= 0 )                 // 
   { TakeProfit = GridSize; }

 bool myWantLongs = wantLongs;
 bool myWantShorts = wantShorts;

//---- test if we want to shutdown or suspend
   if (suspendGrid == true) {       // close unfilled orders and then test if profit target
      CloseAllPendingOrders();
   }
   if (shutdownGrid == true) {      // close all positions and orders. then exit.. there is nothing more to do
      ClosePendingOrdersAndPositions();
      return(0);
   }
   if (haveHitTarget == true) {     // in case we hit target and there are still some open orders and positions
      ClosePendingOrdersAndPositions();
      if (gridOneShot==true) { gridActive = false; }
   }
//----
   if (gridActive == false) {       // if grid not active, do nothing.
     return(0);
   }

//----

  if (MathAbs(CurTime()-LastUpdate)> UpdateInterval*60)           // we update the first time it is called and every UpdateInterval minutes
   {
   
   if (profitTarget >0) 
      {
        TestForProfit(uniqueGridMagic, profitTarget, true, false );
        if (!IsTesting()) {
            Comment("Grid Type:  ","Short Only"
               );
            }
      }

   
   
   LastUpdate = CurTime();
   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 myEMA=iMA(NULL,0,EMAperiod,0,MODE_EMA,PRICE_CLOSE,0);
   int currentOpen = 0;
   if ( GridMaxOpen > 0 ) {
      currentOpen = openPositions();
      if (currentOpen >= GridMaxOpen) {CloseAllPendingOrders(); }
   }
   
   if (limitEMA) { if (doHouseKeeping) CloseOrdersfromEMA(myEMA);}
   if (keepOpenTimeLimit > 0) DeleteAfter(keepOpenTimeLimit);
   if (trailStop >0) TrailIt(trailStop);
   if (BEPips >0) DoBE(BEPips);
   if ( UseMACD || UseOsMA)  
     {
      if ( UseMACD ) 
        {
            double Trigger0=iMACD(NULL,timeFrame,emaFast,emaSlow,signalPeriod,PRICE_CLOSE,MODE_MAIN,0);
            double Trigger1=iMACD(NULL,timeFrame,emaFast,emaSlow,signalPeriod,PRICE_CLOSE,MODE_MAIN,1);
            double Trigger2=iMACD(NULL,timeFrame,emaFast,emaSlow,signalPeriod,PRICE_CLOSE,MODE_MAIN,2);
        }
      if ( UseOsMA ) 
        {
             Trigger0=iOsMA(NULL,timeFrame,emaFast,emaSlow,signalPeriod,PRICE_CLOSE,0);
             Trigger1=iOsMA(NULL,timeFrame,emaFast,emaSlow,signalPeriod,PRICE_CLOSE,1);
             Trigger2=iOsMA(NULL,timeFrame,emaFast,emaSlow,signalPeriod,PRICE_CLOSE,2);
        }

    
       if( (Trigger0 > 0) && (Trigger1 > 0)  &&  (Trigger2 < 0 ))     // cross up
        {
         CloseAllPendingOrders();
         if ( CloseOpenPositions == true ) { ClosePendingOrdersAndPositions(); }
        }
       if( (Trigger0<0) && (Trigger1<0)  &&  (Trigger2>0))     // cross down
        {
         CloseAllPendingOrders();
         if ( CloseOpenPositions == true ) { ClosePendingOrdersAndPositions(); }
        }
       myWantLongs = false;
       myWantShorts = false;
       if( (Trigger0>0) && (Trigger1>0)  &&  (Trigger2>0) && (wantLongs==true) )     // is well above zero
        {
         myWantLongs = true;
        }
       if( (Trigger0<0) && (Trigger1<0)  &&  (Trigger2<0) && (wantShorts== true) )     // is well below zero
        {
         myWantShorts = true;
        }
   }
   int myGridSteps = GridSteps;
   if (( GridMaxOpen > 0 ) && (currentOpen >= GridMaxOpen)) {
      myGridSteps = 0;
   }
   
    if (suspendGrid == true) {       //profit target and exit conditions tested so finished
      return(0);
   }

Print("Trigs ",    Trigger0,"  ",Trigger1,"  ",Trigger2,"  ",myWantLongs,"  ",myWantShorts,"  ",myGridSteps," ema ",myEMA," price ",Bid );

 //Print("start  1 ",startrate);     
 
   for( i=0;i myEMA))
       { if (longGridCenter > point) {
          temp = GridSteps / 2;
          k = temp;
          startrate = longGridCenter - k * GridSize * point;
         } else {
            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
         }
         traderate = startrate + i*point*GridSize + gridOffset*point;
         // now test if traderate within limits
         doit = true;
         if (traderate < longGridLow) {doit = false;}
         if ((traderate > longGridHigh) && (longGridHigh > point)) {doit = false;}
         
         if (( IsPosition(traderate,point*GridSize,true) == false ) && (doit == 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 +minFromPrice*Point) ) && (wantBreakout)) || ((traderate <= (Ask-minFromPrice*Point) ) && (wantCounter)) ) 
              { 
                  // modified by cori. Using OrderMagicNumber to identify the trades of the grid
                 ticket=OrderSend(Symbol(),entermode,Lots,traderate,0,myStopLoss,traderate+point*TakeProfit,GridName,uniqueGridMagic,0,Green); 
             }
          }
       }
     if ( myWantShorts && (!limitEMA || traderate < myEMA))
       { if (shortGridCenter > point) {
          temp = GridSteps / 2;
          k = temp;
          startrate = shortGridCenter - k * GridSize * point ;
         } else {
            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
         }
        traderate = startrate + i*point*GridSize + gridOffset*point;
          // now test if traderate within limits
        doit = true;
        if (traderate < shortGridLow) {doit = false;}
        if ((traderate > shortGridHigh) && (shortGridHigh > point)) {doit = false;}

        if ((IsPosition(traderate,point*GridSize,false)== false ) && (doit == true))          // 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 -minFromPrice*Point) ) && (wantBreakout)) || ((traderate >= (Bid+minFromPrice*Point) ) && (wantCounter)) ) 
                { 
                   // modified by cori. Using OrderMagicNumber to identify the trades of the grid
                   ticket=OrderSend(Symbol(),entermode,Lots,traderate,0,myStopLoss,traderate-point*TakeProfit,GridName,uniqueGridMagic,0,Red); 
                }
          }
       }
    }
   }
   return(0);
  }
//+------------------------------------------------------------------+

Recommend