//+------------------------------------------------------------------+
//|                                                  MakeGrid193.mq4 |
//|                                            Copyright © 2005, hdb |
//|                                       http://www.dubois1.net/hdb |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2005, hdb"
#property link      "http://www.dubois1.net/hdb"
//#property version      "1.93"
// DISCLAIMER ***** IMPORTANT NOTE ***** READ BEFORE USING ***** 
// This expert advisor can open and close real positions and hence do real trades and lose real money.
// This is not a 'trading system' but a simple robot that places trades according to fixed rules.
// The author has no pretentions as to the profitability of this system and does not suggest the use
// of this EA other than for testing purposes in demo accounts.
// Use of this system is free - but u may not resell it - and is without any garantee as to its
// suitability for any purpose.
// By using this program you implicitly acknowledge that you understand what it does and agree that 
// the author bears no responsibility for any losses.
// Before using, please also check with your broker that his systems are adapted for the frequest trades
// associated with this expert.
// 1.8 changes
// made wantLongs and wantShorts into local variables. Previously, if u set UseMACD to true, 
// it did longs and shorts and simply ignored the wantLongs and wantShorts flags. 
// Now, these flags are not ignored.
// added a loop to check if there are 'illicit' open orders above or below the EMA when the limitEMA34
// flag is used. These accumulate over time and are never removed and is due to the EMA moving.
// removed the switch instruction as they dont seem to work - replaced with if statements
// made the EMA period variable
//
// 1.9 changes - as per kind suggestions of Gideon
// Added a routine to delete orders and positions if they are older than keepOpenTimeLimit hours.
// Added OsMA as a possible filter. Acts exactly like MACD.
// Added 4 parameters for MACD or OsMA so that we can optimise
// Also cleaned up the code a bit.
// 1.92 changes by dave
// added function openPOsitions to count the number of open positions
// modified the order logic so that openPOsitions is not > GridMaxOpen 
// 1.93 added long term direction indicator 
// Added tradeForMinutes  - will only trade for this time then stop till EA is reset.
// 1.94 added Risk Fraction or also know as Money Management.  Spider4896~
// 1.95 seperated the BUYS and SELLS to funtion on different Risk Fractions.  Spider4896~
// 1.96 seperated out the GridSize from Buys and Sells and TakeProfit from Buys and Sells. Spider4896~
// 1.97 cleaned up code
// 
// NOTE:  **RISKFRACTION: Code line 443 - 444 were designed for InterbankFX MicroMini Lots on standard accounts.
//          If you would like to use it for other Brokers please adjust code properly.
//
// HINTS: 1.For long term use please keep in mind it will need a large account balance. Also for long term
//          use try to place bigger size lot trades on the interest positive direction and smaller
//          lot trades on the negative interest side of the trade.
//        2.If used for short term use, use on mutiple of major currencies. 
//          Example: GBPUSD, USDJPY, USDCHF, EURJPY, EURUSD.  Close grid once a profit is made that you decide upon.
//          Long exposure on open trades will result in loss of Equity and might not reach profit. 
//
// modified by cori. Using OrderMagicNumber to identify the trades of the grid
extern int    uniqueGridMagic = 11111; // Magic number of the trades. must be unique to identify
                                       // the trades of one grid    
extern double LotsBuy = 0.1;          // **TO USE SET LOTS YOU MUST REMOVE RISKFRACTION CODE..LINES 443 - 444
extern double LotsSell = 0.1; 
extern double Spread = 20;        // **TO USE SET LOTS YOU MUST REMOVE RISKFRACTION CODE..LINES 443 - 444
extern double GridSizeBuy = 150;        // pips between orders - grid or mesh size
extern double GridSizeSell = 150;       // pips between orders - grid or mesh size
extern double GridSteps = 14;           // total number of orders to place
extern double TakeProfitBuy = 100;      // number of ticks to take profit.
extern double TakeProfitSell = 100;     // number of ticks to take profit.
extern double StopLoss = 0;            // normal grids dont use stop losses. DO NOT USE
extern int    trailStop = 0;           // will trail if > 0 USE ONLY IF YOUR TP IS VERY HIGH
extern double RiskFractionBuy=0;      //Buy Trades: what percent of the account you want to risk Per Trade
extern double RiskFractionSell=0;     //Sell Trades: what percent of the account you want to risk Per Trade
extern int    BEPips = 0;              // will move the stoploss to BE after x pips of movement
extern int    BEx    = 0;
extern double UpdateInterval = 1;      // 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   limitEMA = false;         // do we want longs above ema only, shorts below ema only
extern int    EMAperiod = 0;          // the length of the EMA.. was previously fixed at 34
extern double GridMaxOpen = 999;       // maximum number of open positions : implemented in v1.92
extern bool   UseMACD = false;         // 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 = false;   // 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 = 0;             // parameters for MACD and OSMA
extern int    emaSlow = 0;            // parameters for MACD and OSMA
extern int    signalPeriod = 0;        // 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;     // **DO NOT ACTIVATE "GridOneShot"** Code does not work properly

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.

// Min/Max tracking
double maxOrders;
double maxEquity;
double minEquity;

// stoploss and takeprofit and close control
double SL=0;
double TP=0;
double CurrentProfit=0;
double CurrentBasket=0;

int mode=0, myOrderType=0;
int  OpenOrders=0;
double LastPrice=0;
                                       
// 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

//+------------------------------------------------------------------+
//| expert initialization function                                   |
//+------------------------------------------------------------------+
int init()
  {
//---- 
 #property show_inputs                  // shows the parameters - thanks Slawa...    
//----
   GridName = StringConcatenate( "Grid-", Symbol(),"-",uniqueGridMagic );
   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<totalorders;i++)                                // scan all orders and positions...
      {
        OrderSelect(i, SELECT_BY_POS);
// 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...
         {  int type = OrderType();
            if (MathAbs( OrderOpenPrice() - atRate ) < (inRange*0.9)) // dont look for exact price but price proximity (less than gridsize) - added 0.9 because of floating point errors
              { 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);
  }

//+------------------------------------------------------------------+
//| Delete order after x hours                                     |
//+------------------------------------------------------------------+
void DeleteAfter( double xHours )    // delete pending orders or open positions after x hours
  {
  int totalorders = OrdersTotal();
  for(int i=totalorders-1;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 Open Orders
           if ( OrderType() == OP_SELL )  result = OrderClose( OrderTicket(), OrderLots(), MarketInfo(OrderSymbol(), MODE_ASK), 5, Red );
           if ( OrderType() == OP_BUY )  result = OrderClose( OrderTicket(), OrderLots(), MarketInfo(OrderSymbol(), MODE_BID), 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);
  }


//+------------------------------------------------------------------+
//| 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)*BEx, 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)*BEx, OrderTakeProfit(), Red);
        }
    }
  } 
*/

//+------------------------------------------------------------------+
//| script program start function                                    |
//+------------------------------------------------------------------+
int start()
  {
//---- 
   int    i, j, k, k2, ticket, entermode, totalorders;
   bool   doit;
   double point, startrate, startrate2, traderate, temp;

//----
   //Basket profit or loss
   //CurrentBasket=AccountEquity()-AccountBalance();
   
   //if(CurrentBasket>maxEquity) maxEquity=CurrentBasket;
   //if(CurrentBasket<minEquity) minEquity=CurrentBasket;
   
   // actual basket closure
   //if( CurrentBasket>=BasketProfit || CurrentBasket<=(BasketLoss*(-1)) )  
     //{
      //CloseEverything();
     //}   

//---- setup parameters 

 if ( TakeProfitBuy <= 0 )                 // 
   { TakeProfitBuy = GridSizeBuy; }
 if ( TakeProfitSell <= 0 )  
   { TakeProfitSell = GridSizeSell; }

 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
   {
   

   
   
   LastUpdate = CurTime();
   //double LotsBuy=(MathCeil(AccountBalance()*RiskFractionBuy/5000.0)/100);
   //double LotsSell=(MathCeil(AccountBalance()*RiskFractionSell/5000.0)/100);
   point = MarketInfo(Symbol(),MODE_POINT);
   startrate = ( Ask + point*GridSizeBuy/2 ) / point / GridSizeBuy;    // round to a number of ticks divisible by GridSize
   startrate = ( Bid + point*GridSizeSell/2 ) / point / GridSizeSell;    // round to a number of ticks divisible by GridSize
   k = startrate ;
   k = k * GridSizeBuy ;
   k2 = startrate2 ;
   k2 = k2 * GridSizeSell ;
   startrate = k * point - GridSizeBuy*GridSteps/2*point ;          // calculate the lowest entry point
   startrate2 = k2 * point - GridSizeSell*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<myGridSteps;i++)
   {
     startrate = ( Ask + point*GridSizeBuy/2 ) / point / GridSizeBuy;    // round to a number of ticks divisible by GridSize
     startrate2 = ( Bid + point*GridSizeSell/2 ) / point / GridSizeSell;    // round to a number of ticks divisible by GridSize
     k = startrate ;
     k = k * GridSizeBuy ;
     k2 = startrate2 ;
     k2 = k2 * GridSizeSell ;
     startrate = k * point - GridSizeBuy*GridSteps/2*point ;          // calculate the lowest entry point
     startrate2 = k2 * point - GridSizeSell*GridSteps/2*point ;
     traderate = startrate + i*point*GridSizeBuy + gridOffset*point;
     traderate = startrate2 + i*point*GridSizeSell + gridOffset*point;

     if ( myWantLongs && (!limitEMA || traderate > myEMA))
       { if (longGridCenter > point) {
          temp = GridSteps / 2;
          k = temp;
          startrate = longGridCenter - k * GridSizeBuy * point;
         } else {
            startrate = ( Ask + point*GridSizeBuy/2 ) / point / GridSizeBuy;    // round to a number of ticks divisible by GridSize
            k = startrate ;
            k = k * GridSizeBuy ;
            startrate = k * point - GridSizeBuy*GridSteps/2*point ;          // calculate the lowest entry point
         }
         traderate = startrate + i*point*GridSizeBuy + 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*GridSizeBuy,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 > 500 )
               { 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,LotsBuy,traderate,0,myStopLoss,traderate+point*TakeProfitBuy,GridName,uniqueGridMagic,0,LightBlue); 
             }
          }
       }
     if ( myWantShorts && (!limitEMA || traderate < myEMA))
       { if (shortGridCenter > point) {
          temp = GridSteps / 2;
          k2 = temp;
          startrate2 = shortGridCenter - k2 * GridSizeSell * point ;
         } else {
            startrate2 = ( Bid + point*GridSizeSell/2 ) / point / GridSizeSell;    // round to a number of ticks divisible by GridSize
            k2 = startrate2 ;
            k2 = k2 * GridSizeSell ;
            startrate2 = k2 * point - GridSizeSell*GridSteps/2*point ;          // calculate the lowest entry point
         }
        traderate = startrate2 + i*point*GridSizeSell + 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*GridSizeSell,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,LotsSell,traderate-point*Spread,0,myStopLoss,traderate-point*TakeProfitSell,GridName,uniqueGridMagic,0,White); 
                }
          }
       }
    }
   }
   return(0);
  }
//+------------------------------------------------------------------+