SketchyStoplossGridTrader_EA





//+------------------------------------------------------------------+
//|                                                 GridTrader_EA.mq4 |
//|                                  Copyright © 2007, Forex-Experts |
//|                                     http://www.forex-experts.com |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2007, Forex-Experts"
#property link      "http://www.forex-experts.com"

#define OrderStr "GridTrader_EA"
extern int 	  GridDirection=1;
extern int    GridSpacing=10;
extern double StopLoss=60;
extern double 	  TakeProfit=70;
extern double	  TrailingStop=60;
extern int	  DeltaPrice=7;
extern double Lots=0.1;
extern double LotIncrement=0.1;
extern bool   UseLotIncrement=false;
extern bool   NoTradeYesterdayClose=false;
int	  MaxPendingOrders=3;
extern int    MagicNumber=0;

int 	NumberOfTries=3; //Number of tries to set, close orders;
int 	RetryTime=1;
int 	Slippage=1;
extern string
			TradeLog="GridTrader_EA";
extern bool
			EnableLog=true;
extern color 
			BuyColor					= Blue,
			SellColor				= Red;
			
			
string filename="";



//---- input parameters

double BuyLot=0, SellLot=0;
bool CloseAll=false;
bool InitOrd=false;


int Spread=0;

bool stopped=false;
bool first = true;
double CloseYesterday=0;
bool Close_All=false;


int StopLevel=0;

//Events
int pre_OrdersArray[][2];

int eventBuyClosed_SL  = 0, eventBuyClosed_TP  = 0;
int eventSellClosed_SL = 0, eventSellClosed_TP = 0;
int eventBuyLimitDeleted_Exp  = 0, eventBuyStopDeleted_Exp  = 0;
int eventSellLimitDeleted_Exp = 0, eventSellStopDeleted_Exp = 0;
int eventBuyLimitOpened  = 0, eventBuyStopOpened  = 0;
int eventSellLimitOpened = 0, eventSellStopOpened = 0;

//


//+------------------------------------------------------------------+
//| expert initialization function                                   |
//+------------------------------------------------------------------+
int init()
  {
//---- 
CloseYesterday=iClose(NULL,PERIOD_D1,1);
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| expert deinitialization function                                 |
//+------------------------------------------------------------------+
int deinit()
  {
//---- 
   
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+
int start()
  {

filename=Symbol() + TradeLog + "-" + Month() + "-" + Day() + ".log";

Spread=MarketInfo(Symbol(),MODE_SPREAD);
StopLevel=MarketInfo(Symbol(),MODE_STOPLEVEL);

MaxPendingOrders=TakeProfit/GridSpacing+1;


CheckEvents( MagicNumber );



CheckClose();
if (Close_All && false) {
	CloseAll();
	Close_All=false;
	return;
}




CloseYesterday=iClose(NULL,PERIOD_D1,1);



subPrintDetails();



CheckGrid();

if (TrailingStop>0) DoTrail(Symbol(),TrailingStop);
CheckStopLoss(Symbol());





//----
   return(0);
  }
//+------------------------------------------------------------------+








int CntOrd(int Type, int Magic) {
//return number of orders with specific parameters
int _CntOrd;
_CntOrd=0;
for(int i=0;i<OrdersTotal();i++)
{
   OrderSelect(i, SELECT_BY_POS, MODE_TRADES);
  
   if (OrderSymbol()==Symbol()) {
      if ( (OrderType()==Type && (OrderMagicNumber()==Magic) || Magic==0)) _CntOrd++;
   }
}
return(_CntOrd);
}



//----------------------- PRINT COMMENT FUNCTION
void subPrintDetails()
{
//Shows all calcualted values

   string sComment   = "";
   string sp         = "----------------------------------------\n";
   string NL         = "\n";
   sComment = "GridTrader_EA v.1.02 " + NL;
   sComment = sComment + sp;   
   sComment = sComment + "GridDirection=" + DoubleToStr(GridDirection,0) + " | " + "GridSpacing=" + DoubleToStr(GridSpacing,0) + NL;      
   sComment = sComment + "StopLoss=" + DoubleToStr(StopLoss,0) + " | " + "TakeProfit=" + DoubleToStr(TakeProfit,0) + NL;      
   sComment = sComment + "TrailingStop=" + DoubleToStr(TrailingStop,0) + " | " + "DeltaPrice=" + DoubleToStr(DeltaPrice,0) + NL;      
   sComment = sComment + "Lots=" + DoubleToStr(Lots,1) + " | " + "LotIncrement=" + DoubleToStr(LotIncrement,0) + NL;
	sComment = sComment + "UseLotIncrement=" + DoubleToStr(UseLotIncrement,0) + " | " + "NoTradeYesterdayClose=" + DoubleToStr(NoTradeYesterdayClose,0) + NL;
   sComment = sComment + "MaxPendingOrders=" + DoubleToStr(MaxPendingOrders,0) + " | " + "MagicNumber=" + DoubleToStr(MagicNumber,0) + NL;         
   sComment = sComment + sp;
   Comment(sComment);
}





//+------------------------------------------------------------------+
//| return error description                                         |
//+------------------------------------------------------------------+
string ErrorDescription(int error_code)
  {
   string error_string;
//----
   switch(error_code)
     {
      //---- codes returned from trade server
      case 0:
      case 1:   error_string="no error";                                                  break;
      case 2:   error_string="common error";                                              break;
      case 3:   error_string="invalid trade parameters";                                  break;
      case 4:   error_string="trade server is busy";                                      break;
      case 5:   error_string="old version of the client terminal";                        break;
      case 6:   error_string="no connection with trade server";                           break;
      case 7:   error_string="not enough rights";                                         break;
      case 8:   error_string="too frequent requests";                                     break;
      case 9:   error_string="malfunctional trade operation";                             break;
      case 64:  error_string="account disabled";                                          break;
      case 65:  error_string="invalid account";                                           break;
      case 128: error_string="trade timeout";                                             break;
      case 129: error_string="invalid price";                                             break;
      case 130: error_string="invalid stops";                                             break;
      case 131: error_string="invalid trade volume";                                      break;
      case 132: error_string="market is closed";                                          break;
      case 133: error_string="trade is disabled";                                         break;
      case 134: error_string="not enough money";                                          break;
      case 135: error_string="price changed";                                             break;
      case 136: error_string="off quotes";                                                break;
      case 137: error_string="broker is busy";                                            break;
      case 138: error_string="requote";                                                   break;
      case 139: error_string="order is locked";                                           break;
      case 140: error_string="long positions only allowed";                               break;
      case 141: error_string="too many requests";                                         break;
      case 145: error_string="modification denied because order too close to market";     break;
      case 146: error_string="trade context is busy";                                     break;
      //---- mql4 errors
      case 4000: error_string="no error";                                                 break;
      case 4001: error_string="wrong function pointer";                                   break;
      case 4002: error_string="array index is out of range";                              break;
      case 4003: error_string="no memory for function call stack";                        break;
      case 4004: error_string="recursive stack overflow";                                 break;
      case 4005: error_string="not enough stack for parameter";                           break;
      case 4006: error_string="no memory for parameter string";                           break;
      case 4007: error_string="no memory for temp string";                                break;
      case 4008: error_string="not initialized string";                                   break;
      case 4009: error_string="not initialized string in array";                          break;
      case 4010: error_string="no memory for array\' string";                             break;
      case 4011: error_string="too long string";                                          break;
      case 4012: error_string="remainder from zero divide";                               break;
      case 4013: error_string="zero divide";                                              break;
      case 4014: error_string="unknown command";                                          break;
      case 4015: error_string="wrong jump (never generated error)";                       break;
      case 4016: error_string="not initialized array";                                    break;
      case 4017: error_string="dll calls are not allowed";                                break;
      case 4018: error_string="cannot load library";                                      break;
      case 4019: error_string="cannot call function";                                     break;
      case 4020: error_string="expert function calls are not allowed";                    break;
      case 4021: error_string="not enough memory for temp string returned from function"; break;
      case 4022: error_string="system is busy (never generated error)";                   break;
      case 4050: error_string="invalid function parameters count";                        break;
      case 4051: error_string="invalid function parameter value";                         break;
      case 4052: error_string="string function internal error";                           break;
      case 4053: error_string="some array error";                                         break;
      case 4054: error_string="incorrect series array using";                             break;
      case 4055: error_string="custom indicator error";                                   break;
      case 4056: error_string="arrays are incompatible";                                  break;
      case 4057: error_string="global variables processing error";                        break;
      case 4058: error_string="global variable not found";                                break;
      case 4059: error_string="function is not allowed in testing mode";                  break;
      case 4060: error_string="function is not confirmed";                                break;
      case 4061: error_string="send mail error";                                          break;
      case 4062: error_string="string parameter expected";                                break;
      case 4063: error_string="integer parameter expected";                               break;
      case 4064: error_string="double parameter expected";                                break;
      case 4065: error_string="array as parameter expected";                              break;
      case 4066: error_string="requested history data in update state";                   break;
      case 4099: error_string="end of file";                                              break;
      case 4100: error_string="some file error";                                          break;
      case 4101: error_string="wrong file name";                                          break;
      case 4102: error_string="too many opened files";                                    break;
      case 4103: error_string="cannot open file";                                         break;
      case 4104: error_string="incompatible access to a file";                            break;
      case 4105: error_string="no order selected";                                        break;
      case 4106: error_string="unknown symbol";                                           break;
      case 4107: error_string="invalid price parameter for trade function";               break;
      case 4108: error_string="invalid ticket";                                           break;
      case 4109: error_string="trade is not allowed";                                     break;
      case 4110: error_string="longs are not allowed";                                    break;
      case 4111: error_string="shorts are not allowed";                                   break;
      case 4200: error_string="object is already exist";                                  break;
      case 4201: error_string="unknown object property";                                  break;
      case 4202: error_string="object is not exist";                                      break;
      case 4203: error_string="unknown object type";                                      break;
      case 4204: error_string="no object name";                                           break;
      case 4205: error_string="object coordinates error";                                 break;
      case 4206: error_string="no specified subwindow";                                   break;
      default:   error_string="unknown error";
     }
//----
   return(error_string);
  }  
//+------------------------------------------------------------------+





int Write(string str)
{
if (EnableLog) {
//Write log file
   int handle; 
   handle = FileOpen(filename,FILE_READ|FILE_WRITE|FILE_CSV,"/t");
   FileSeek(handle, 0, SEEK_END);      
   FileWrite(handle," Time " + TimeToStr(CurTime(),TIME_DATE|TIME_SECONDS) + ": " + str);
   FileClose(handle);
	Print(" Time " + TimeToStr(CurTime(),TIME_DATE|TIME_SECONDS) + ": " + str);
}

}




int OrdSend(string _symbol, int _cmd, double _volume, double _price, int _slippage, double _stoploss, double _takeprofit, string _comment="", int _magic=0, datetime _expiration=0, color _arrow_color=CLR_NONE) {
//Send order with retry capabilities and log
int _stoplevel=MarketInfo(_symbol,MODE_STOPLEVEL);
double _priceop=0;
int ticket,err,tries;
tries = 0;

_stoploss = StopLoss;
_takeprofit = TakeProfit;

Print("stop loss " , _stoploss);

switch (_cmd) {
	case OP_BUY:
		while (tries < NumberOfTries) {
		//	RefreshRates();
			ticket = OrderSend(_symbol,OP_BUY,_volume,Ask,_slippage,Bid-_stoploss*Point,Ask+_takeprofit*Point,_comment,_magic,_expiration,_arrow_color);
			if(ticket<=0) {
				Write("Error Occured : "+ErrorDescription(GetLastError()));
				Write(Symbol()+" Buy @ "+Ask+" SL @ "+_stoploss+" TP @"+_takeprofit+" ticket ="+ticket);
				tries++;
			} else {
				tries = NumberOfTries;
				Write("Order opened : "+Symbol()+" Buy @ "+Ask+" SL @ "+_stoploss+" TP @"+_takeprofit+" ticket ="+ticket);
			}
			Sleep(RetryTime*1000);
		}
		err=ticket;
		break;

	case OP_SELL:
		while (tries < NumberOfTries) {
		//	RefreshRates();
			ticket = OrderSend(_symbol,OP_SELL,_volume,Bid,_slippage,Ask+_stoploss*Point,Bid-_takeprofit*Point,_comment,_magic,_expiration,_arrow_color);
			if(ticket<=0) {
				Write("Error Occured : "+ErrorDescription(GetLastError()));
				Write(Symbol()+" Sell @ "+Bid+" SL @ "+_stoploss+" TP @"+_takeprofit+" ticket ="+ticket);
				tries++;
			} else {
				tries = NumberOfTries;
				Write("Order opened : "+Symbol()+" Sell @ "+Bid+" SL @ "+_stoploss+" TP @"+_takeprofit+" ticket ="+ticket);
			}
			Sleep(RetryTime*1000);	
		}
		err=ticket;
		break;

	case OP_BUYSTOP:
		while (tries < NumberOfTries) {
		//	RefreshRates();
			if ((_price-Ask)<_stoplevel*Point) _priceop=Ask+_stoplevel*Point; else _priceop=_price;			
			ticket = OrderSend(_symbol,OP_BUYSTOP,0.1,Ask,_slippage,0,0,_comment,_magic,_expiration,_arrow_color);
			if(ticket<=0) {
				Write("Error Occured : "+ErrorDescription(GetLastError()));
				Write(Symbol()+" aaBuy Stop @ "+_priceop+" SL @ "+_stoploss+" TP @"+_takeprofit+" ticket ="+ticket);
				tries++;
			} else {
				tries = NumberOfTries;
				Write("Order opened : "+Symbol()+" Buy Stop@ "+_priceop+" SL @ "+_stoploss+" TP @"+_takeprofit+" ticket ="+ticket);
			}
			Sleep(RetryTime*1000);
		}
		err=ticket;
		break;


	case OP_SELLSTOP:
		while (tries < NumberOfTries) {
		//	RefreshRates();
			if ((Bid-_price)<_stoplevel*Point) _priceop=Bid-_stoplevel*Point; else _priceop=_price;			
			ticket = OrderSend(_symbol,OP_SELLSTOP,_volume,Bid,_slippage,Ask+_stoploss*Point,Bid-_takeprofit*Point,_comment,_magic,_expiration,_arrow_color);
			if(ticket<=0) {
				Write("Error Occured : "+ErrorDescription(GetLastError()));
				Write(Symbol()+" Sell Stop @ "+_priceop+" SL @ "+_stoploss+" TP @"+_takeprofit+" ticket ="+ticket);
				tries++;
			} else {
				tries = NumberOfTries;
				Write("Order opened : "+Symbol()+" Sell Stop @ "+_priceop+" SL @ "+_stoploss+" TP @"+_takeprofit+" ticket ="+ticket);
			}
			Sleep(RetryTime*1000);
		}
		err=ticket;
		break;


	case OP_BUYLIMIT:
		while (tries < NumberOfTries) {
		//	RefreshRates();
			if ((Ask-_price)<_stoplevel*Point) _priceop=Ask-_stoplevel*Point; else _priceop=_price;			
			ticket = OrderSend(_symbol,OP_BUYLIMIT,_volume,NormalizeDouble(_priceop,Digits),_slippage,NormalizeDouble(_stoploss,Digits),NormalizeDouble(_takeprofit,Digits),_comment,_magic,_expiration,_arrow_color);
			if(ticket<=0) {
				Write("Error Occured : "+ErrorDescription(GetLastError()));
				Write(Symbol()+" Buy Limit @ "+_priceop+" SL @ "+_stoploss+" TP @"+_takeprofit+" ticket ="+ticket);
				tries++;
			} else {
				tries = NumberOfTries;
				Write("Order opened : "+Symbol()+" Buy Limit @ "+_priceop+" SL @ "+_stoploss+" TP @"+_takeprofit+" ticket ="+ticket);
			}
			Sleep(RetryTime*1000);
		}
		err=ticket;
		break;

	case OP_SELLLIMIT:
		while (tries < NumberOfTries) {
			RefreshRates();
			if ((_price-Bid)<_stoplevel*Point) _priceop=Bid+_stoplevel*Point; else _priceop=_price;			
			ticket = OrderSend(_symbol,OP_SELLLIMIT,_volume,NormalizeDouble(_priceop,Digits),_slippage,NormalizeDouble(_stoploss,Digits),NormalizeDouble(_takeprofit,Digits),_comment,_magic,_expiration,_arrow_color);
			if(ticket<=0) {
				Write("Error Occured : "+ErrorDescription(GetLastError()));
				Write(Symbol()+" Sell Limit @ "+_priceop+" SL @ "+_stoploss+" TP @"+_takeprofit+" ticket ="+ticket);
				tries++;
			} else {
				tries = NumberOfTries;
				Write("Order opened : "+Symbol()+" Sell Limit @ "+_priceop+" SL @ "+_stoploss+" TP @"+_takeprofit+" ticket ="+ticket);
			}
			Sleep(RetryTime*1000);
		}
		err=ticket;
		break;

	default:
		Write("No valid type of order found");
		err=-1;
		break;
}
return(err);
}


int OrdClose(int _ticket, double _lots, double _price, int _slippage, color _color=CLR_NONE) {
//The function close order with log
double _priceop=0;
int ticket,err,tries;

tries = 0;
		while (tries < NumberOfTries) {
			RefreshRates();
			ticket = OrderClose(_ticket,_lots,NormalizeDouble(_price,Digits),_slippage,_color);
			if(ticket==0) {
				Write("Error Occured : "+ErrorDescription(GetLastError()));
				Write(Symbol()+" Close @ "+_price+" ticket ="+ticket);
				tries++;
			} else {
				tries = NumberOfTries;
				Write("Order closed : "+Symbol()+" Close @ "+_price+" ticket ="+ticket);
			}
			Sleep(RetryTime*1000);
		}
		err=ticket;

return(err);

}




int OrdModify(int _ticket, double _price, double _stoploss, double _takeprofit, datetime _expiration, color _color=CLR_NONE) {
//The function modify order with log
double _priceop=0;
int ticket,err,tries;

tries = 0;				
		if (!IsTradeContextBusy() && IsTradeAllowed()) {
		while (tries < NumberOfTries) {
			RefreshRates();
			ticket = OrderModify(_ticket,NormalizeDouble(_price,Digits),NormalizeDouble(_stoploss,Digits),NormalizeDouble(_takeprofit,Digits),_expiration,_color);
			if(ticket==0) {
				Write("Error Occured : "+ErrorDescription(GetLastError()));
				Write(Symbol()+" Modify @ "+_price+" SL @ "+_stoploss+" TP @"+_takeprofit+" ticket ="+_ticket);
				tries++;
			} else {
				tries = NumberOfTries;
				Write("Order modified : "+Symbol()+" Modify @ "+_price+" SL @ "+_stoploss+" TP @"+_takeprofit+" ticket ="+_ticket);
			}
			Sleep(RetryTime*1000);
		}
		}
		err=ticket;
		return(err);

}


int OrdDelete(int _ticket) {
//Delete pending order
double _priceop=0;
int ticket,err,tries;
tries = 0;
		while (tries < NumberOfTries) {
			RefreshRates();
			ticket = OrderDelete(_ticket);
			if(ticket==0) {
				Write("Error Occured : "+ErrorDescription(GetLastError()));
				Write(Symbol()+" Delete @ "+Bid+" ticket ="+ticket);
				tries++;
			} else {
				tries = NumberOfTries;
				Write("Order Deleted : "+Symbol()+" Delete @ "+Bid+" ticket ="+_ticket);
			}
			Sleep(RetryTime*1000);
		}
		err=ticket;		
		return(err);
} 






double MaxLots(int Type, int Magic) {
double _MaxLot=0;

   for(int i=0;i<OrdersTotal();i++)
   {
      OrderSelect(i, SELECT_BY_POS, MODE_TRADES);
     
      if (OrderSymbol()==Symbol()) {
         if ( (OrderType()==Type) && (OrderMagicNumber()==Magic || Magic==0)) {
            if (_MaxLot==0) _MaxLot=OrderLots();
            if (OrderLots()>_MaxLot) _MaxLot=OrderLots();		   
         }
      }
   }
return (_MaxLot);
}





bool CloseAll () {
int cnt_negative=0;
bool _closed=true;
int _total=OrdersTotal(); // number of lots  
int _ordertype;// order type   
if (_total==0) {return(true);}

int _ticket; // ticket number
double _priceClose;// price to close orders;
for(int _i=_total-1;_i>=0;_i--)
      {
      if (OrderSelect(_i,SELECT_BY_POS))
         {
         _ordertype=OrderType();
         _ticket=OrderTicket();
         if (OrderSymbol()==Symbol()) {
			_closed=false;
         switch(_ordertype)
            {
            case 0:
               Write("Close on "+_i+" position order with ticket ¹"+_ticket);
               OrdClose(_ticket,OrderLots(),Bid,Slippage);  
               break;
            case 1:
               Write("Close on "+_i+" position order with ticket ¹"+_ticket);
               OrdClose(_ticket,OrderLots(),Ask,Slippage);  
               break;
            default:
               // values from  1 to 5, deleting pending orders
               Write("Delete on "+_i+" position order with ticket ¹"+_ticket);
               OrdDelete(_ticket);  
               break;
            }    
			}
         }
}

return;
}

double MaxPrice(int Type, int Magic) {
double _MaxPrice=0;

   for(int i=0;i<OrdersTotal();i++)
   {
      OrderSelect(i, SELECT_BY_POS, MODE_TRADES);
     
      if (OrderSymbol()==Symbol()) {
         if (OrderType()==Type && (OrderMagicNumber()==Magic || Magic==0)) {
            if (_MaxPrice==0) _MaxPrice=OrderOpenPrice();
            if (OrderOpenPrice()>_MaxPrice) _MaxPrice=OrderOpenPrice();		   
         }
      }
   }
return (_MaxPrice);
}

double MinPrice(int Type, int Magic) {
double _MinPrice=0;

   for(int i=0;i<OrdersTotal();i++)
   {
      OrderSelect(i, SELECT_BY_POS, MODE_TRADES);
     
      if (OrderSymbol()==Symbol()) {
         if (OrderType()==Type && (OrderMagicNumber()==Magic || Magic==0)) {
            if (_MinPrice==0) _MinPrice=OrderOpenPrice();
            if (OrderOpenPrice()<_MinPrice) _MinPrice=OrderOpenPrice();		   
         }
      }
   }
return (_MinPrice);
}


void CheckGrid() {
//Working with grid
double TradingLot=Lots;
int ticket=0;
double PriceOp=0;
double MyTakeProfit=0;
double MyStopLoss=0;

if (GridDirection>0 || GridDirection==0) {
	double PriceMax=MaxPrice(OP_BUYSTOP,MagicNumber);
	if (CntOrd(OP_BUYSTOP,MagicNumber)==0) {
      TradingLot=Lots;
      PriceOp=Ask+DeltaPrice*Point;
      if ( ( NoTradeYesterdayClose && PriceOp<CloseYesterday ) || NoTradeYesterdayClose==false) {
      
	      if (TakeProfit==0) MyTakeProfit=0; else MyTakeProfit=PriceOp+TakeProfit*Point;
      	if (StopLoss==0) MyStopLoss=0; else MyStopLoss=PriceOp-StopLoss*Point;
      	ticket=OrdSend(Symbol(),OP_BUYSTOP,TradingLot,PriceOp,Slippage,MyStopLoss,MyTakeProfit,OrderStr,MagicNumber,0,BuyColor);					
		}
	}
	
	if (PriceMax>0) {	
		double minopenprice=MinPrice(OP_BUYSTOP,MagicNumber);
		double mintakeprofit=MinPriceProfit(OP_BUYSTOP,MagicNumber);
		

		while (CntOrd(OP_BUYSTOP,MagicNumber)<MaxPendingOrders && (MaxPriceProfit(OP_BUYSTOP,MagicNumber)-MinPriceProfit(OP_BUYSTOP,MagicNumber))<Point) {
         PriceMax=MaxPrice(OP_BUYSTOP,MagicNumber);
         if (PriceMax==0) break;
			TradingLot=Lots;        
         PriceOp=PriceMax+GridSpacing*Point;

			if ( ( NoTradeYesterdayClose && PriceOp<CloseYesterday ) || NoTradeYesterdayClose==false) {	         	         
	         if (TakeProfit==0) MyTakeProfit=0; else MyTakeProfit=PriceOp+TakeProfit*Point;
				if (PriceOp<mintakeprofit-Point) {
					MyTakeProfit=mintakeprofit;			
					if (UseLotIncrement) {
						TradingLot=MaxLots(OP_BUYSTOP,MagicNumber)+LotIncrement;	
					}
			
				}        	

				if ((mintakeprofit-PriceOp)<StopLevel*Point) {
					PriceOp=mintakeprofit+GridSpacing*Point;
					if (TakeProfit==0) MyTakeProfit=0; else MyTakeProfit=PriceOp+TakeProfit*Point;									
         		if (StopLoss==0) MyStopLoss=0; else MyStopLoss=PriceOp-StopLoss*Point;
         		TradingLot=Lots;         		
         		ticket=OrdSend(Symbol(),OP_BUYSTOP,TradingLot,PriceOp,Slippage,MyStopLoss,MyTakeProfit,OrderStr,MagicNumber,0,BuyColor);			
					break;					
				}

         	
         	if (StopLoss==0) MyStopLoss=0; else MyStopLoss=PriceOp-StopLoss*Point;
         	ticket=OrdSend(Symbol(),OP_BUYSTOP,TradingLot,PriceOp,Slippage,MyStopLoss,MyTakeProfit,OrderStr,MagicNumber,0,BuyColor);			
			}
			else break;
			

		}
	}

}


if (GridDirection<0 || GridDirection==0) {
	double PriceMin=MinPrice(OP_SELLSTOP,MagicNumber);
	if (CntOrd(OP_SELLSTOP,MagicNumber)==0) {
      TradingLot=Lots;
      PriceOp=Bid-DeltaPrice*Point;
      
      if ( ( NoTradeYesterdayClose && PriceOp>CloseYesterday ) || NoTradeYesterdayClose==false) {
	      if (TakeProfit==0) MyTakeProfit=0; else MyTakeProfit=PriceOp-TakeProfit*Point;
      	if (StopLoss==0) MyStopLoss=0; else MyStopLoss=PriceOp+StopLoss*Point;
      	ticket=OrdSend(Symbol(),OP_SELLSTOP,TradingLot,PriceOp,Slippage,MyStopLoss,MyTakeProfit,OrderStr,MagicNumber,0,SellColor);					
		}
	}
	
	if (PriceMin>0) {	
		double maxopenprice=MaxPrice(OP_SELLSTOP,MagicNumber);
		double maxtakeprofit=MaxPriceProfit(OP_SELLSTOP,MagicNumber);
		
		while (CntOrd(OP_SELLSTOP,MagicNumber)<MaxPendingOrders && (MaxPriceProfit(OP_SELLSTOP,MagicNumber)-MinPriceProfit(OP_SELLSTOP,MagicNumber))<Point) {
         PriceMin=MinPrice(OP_SELLSTOP,MagicNumber);
         if (PriceMin==0) break;
    		TradingLot=Lots; 
         PriceOp=PriceMin-GridSpacing*Point;
         if ( ( NoTradeYesterdayClose && PriceOp>CloseYesterday ) || NoTradeYesterdayClose==false) {
	         if (TakeProfit==0) MyTakeProfit=0; else MyTakeProfit=PriceOp-TakeProfit*Point;
         	if (StopLoss==0) MyStopLoss=0; else MyStopLoss=PriceOp+StopLoss*Point;

				if (PriceOp>maxtakeprofit+Point) {
					MyTakeProfit=maxtakeprofit;			
					if (UseLotIncrement) {
						TradingLot=MaxLots(OP_SELLSTOP,MagicNumber)+LotIncrement;	
					}
			
				}

				if ((PriceOp-maxtakeprofit)<StopLevel*Point) {
					PriceOp=maxtakeprofit-GridSpacing*Point;
	         	if (TakeProfit==0) MyTakeProfit=0; else MyTakeProfit=PriceOp-TakeProfit*Point;
         		if (StopLoss==0) MyStopLoss=0; else MyStopLoss=PriceOp+StopLoss*Point;
         		TradingLot=Lots;         		
         		ticket=OrdSend(Symbol(),OP_SELLSTOP,TradingLot,PriceOp,Slippage,MyStopLoss,MyTakeProfit,OrderStr,MagicNumber,0,SellColor);			
					break;					
				}


         	ticket=OrdSend(Symbol(),OP_SELLSTOP,TradingLot,PriceOp,Slippage,MyStopLoss,MyTakeProfit,OrderStr,MagicNumber,0,SellColor);
         }
         else break;			
		
		}
	}

}




return;
}




void DoTrail(string _symbol, int _trailingstop)
  {
    for (int i = 0; i < OrdersTotal(); i++) {
     OrderSelect(i, SELECT_BY_POS, MODE_TRADES);
     if ( OrderSymbol()==_symbol && ((OrderMagicNumber()==MagicNumber) || MagicNumber==0))  // only look if mygrid and symbol...
        {
          
          if (OrderType() == OP_BUY) {
             if(Bid-OrderOpenPrice()>Point*_trailingstop)
             {
                if(OrderStopLoss()<Bid-Point*_trailingstop)
                  {
                     OrdModify(OrderTicket(),OrderOpenPrice(),Bid-Point*_trailingstop,OrderTakeProfit(),0,BuyColor);
                  }
             }
          }

          if (OrderType() == OP_SELL) 
          {
             if((OrderOpenPrice()-Ask)>(Point*_trailingstop))
             {
                if((OrderStopLoss()>(Ask+Point*_trailingstop)) || (OrderStopLoss()==0))
                {
                   OrdModify(OrderTicket(),OrderOpenPrice(),Ask+Point*_trailingstop,OrderTakeProfit(),0,SellColor);
                   
                }
             }
          }
       }
    }
 }
  
  
  
void CheckEvents( int magic = 0 )
{
	static bool first = true;
	int _GetLastError = 0;
	int _OrdersTotal = OrdersTotal();
	int now_OrdersTotal = 0;
	static int pre_OrdersTotal = 0;
	int now_OrdersArray[][2];
	int now_CurOrder = 0;

	int pre_CurOrder = 0;


	int now_ClosedOrdersArray[6][3];

	int now_OpenedPendingOrders[4];

	bool OrderClosed = true, PendingOrderOpened = false;
	int ticket = 0, type = -1, close_type = -1;

	eventBuyClosed_SL  = 0; eventBuyClosed_TP  = 0;
	eventSellClosed_SL = 0; eventSellClosed_TP = 0;
	eventBuyLimitDeleted_Exp  = 0; eventBuyStopDeleted_Exp  = 0;
	eventSellLimitDeleted_Exp = 0; eventSellStopDeleted_Exp = 0;
	eventBuyLimitOpened  = 0; eventBuyStopOpened  = 0;
	eventSellLimitOpened = 0; eventSellStopOpened = 0;

	ArrayResize( now_OrdersArray, MathMax( _OrdersTotal, 1 ) );

	ArrayInitialize( now_OrdersArray, 0.0 );

	ArrayInitialize( now_ClosedOrdersArray, 0.0 );
	ArrayInitialize( now_OpenedPendingOrders, 0.0 );

	for ( int z = _OrdersTotal - 1; z >= 0; z -- )
	{
		if ( !OrderSelect( z, SELECT_BY_POS ) )
		{
			_GetLastError = GetLastError();
			Print( "OrderSelect( ", z, ", SELECT_BY_POS ) - Error #", _GetLastError );
			continue;
		}
		if ( (OrderMagicNumber()==magic || magic==0) && OrderSymbol() == Symbol() )
		{
			now_OrdersArray[now_OrdersTotal][0] = OrderTicket();
			now_OrdersArray[now_OrdersTotal][1] = OrderType();
			now_OrdersTotal ++;
		}
	}
	ArrayResize( now_OrdersArray, MathMax( now_OrdersTotal, 1 ) );

	for ( pre_CurOrder = 0; pre_CurOrder < pre_OrdersTotal; pre_CurOrder ++ )
	{
		ticket = pre_OrdersArray[pre_CurOrder][0];
		type   = pre_OrdersArray[pre_CurOrder][1];
		OrderClosed = true;
		PendingOrderOpened = false;

		for ( now_CurOrder = 0; now_CurOrder < now_OrdersTotal; now_CurOrder ++ )
		{
			if ( ticket == now_OrdersArray[now_CurOrder][0] )
			{
				OrderClosed = false;

				if ( type != now_OrdersArray[now_CurOrder][1] )
				{
					PendingOrderOpened = true;
				}
				break;
			}
		}
		if ( OrderClosed )
		{
			if ( !OrderSelect( ticket, SELECT_BY_TICKET ) )
			{
				_GetLastError = GetLastError();
				Print( "OrderSelect( ", ticket, ", SELECT_BY_TICKET ) - Error #", _GetLastError );
				continue;
			}
			if ( type < 2 )
			{
				close_type = 0;
				if ( StringFind( OrderComment(), "[sl]" ) >= 0 ) close_type = 1;
				if ( StringFind( OrderComment(), "[tp]" ) >= 0 ) close_type = 2;
			}
			else
			{
				close_type = 0;
				if ( StringFind( OrderComment(), "expiration" ) >= 0 ) close_type = 1;
			}
			
			now_ClosedOrdersArray[type][close_type] ++;
			continue;
		}
		if ( PendingOrderOpened )
		{
			now_OpenedPendingOrders[type-2] ++;
			continue;
		}
	}

	if ( !first )
	{
		for ( type = 2; type < 6; type ++ )
		{
			if ( now_OpenedPendingOrders[type-2] > 0 )
				SetOpenEvent( type );
		}

		for ( type = 0; type < 6; type ++ )
		{
			for ( close_type = 0; close_type < 3; close_type ++ )
			{
				if ( now_ClosedOrdersArray[type][close_type] > 0 )
					SetCloseEvent( type, close_type );
			}
		}
	}
	else
	{
		first = false;
	}


	ArrayResize( pre_OrdersArray, MathMax( now_OrdersTotal, 1 ) );
	for ( now_CurOrder = 0; now_CurOrder < now_OrdersTotal; now_CurOrder ++ )
	{
		pre_OrdersArray[now_CurOrder][0] = now_OrdersArray[now_CurOrder][0];
		pre_OrdersArray[now_CurOrder][1] = now_OrdersArray[now_CurOrder][1];
	}
	pre_OrdersTotal = now_OrdersTotal;
}
void SetOpenEvent( int SetOpenEvent_type )
{
	switch ( SetOpenEvent_type )
	{
		case OP_BUYLIMIT: eventBuyLimitOpened ++; return(0);
		case OP_BUYSTOP: eventBuyStopOpened ++; return(0);
		case OP_SELLLIMIT: eventSellLimitOpened ++; return(0);
		case OP_SELLSTOP: eventSellStopOpened ++; return(0);
	}
}
void SetCloseEvent( int SetCloseEvent_type, int SetCloseEvent_close_type )
{
	switch ( SetCloseEvent_type )
	{
		case OP_BUY:
		{
			if ( SetCloseEvent_close_type == 1 ) eventBuyClosed_SL ++;
			if ( SetCloseEvent_close_type == 2 ) eventBuyClosed_TP ++;
			return(0);
		}
		case OP_SELL:
		{
			if ( SetCloseEvent_close_type == 1 ) eventSellClosed_SL ++;
			if ( SetCloseEvent_close_type == 2 ) eventSellClosed_TP ++;
			return(0);
		}
		case OP_BUYLIMIT:
		{
			if ( SetCloseEvent_close_type == 1 ) eventBuyLimitDeleted_Exp ++;
			return(0);
		}
		case OP_BUYSTOP:
		{
			if ( SetCloseEvent_close_type == 1 ) eventBuyStopDeleted_Exp ++;
			return(0);
		}
		case OP_SELLLIMIT:
		{
			if ( SetCloseEvent_close_type == 1 ) eventSellLimitDeleted_Exp ++;
			return(0);
		}
		case OP_SELLSTOP:
		{
			if ( SetCloseEvent_close_type == 1 ) eventSellStopDeleted_Exp ++;
			return(0);
		}
	}
}
  
  
void CheckClose() {
	if (eventBuyClosed_TP>0 || eventSellClosed_TP>0 || eventBuyClosed_SL>0 || eventSellClosed_SL>0) {
		Close_All=true;
		eventBuyClosed_TP=0;
		eventSellClosed_TP=0;
	}
	return;
}
  


double MaxPriceProfit(int Type, int Magic) {
double _MaxPrice=0;

   for(int i=0;i<OrdersTotal();i++)
   {
      OrderSelect(i, SELECT_BY_POS, MODE_TRADES);
     
      if (OrderSymbol()==Symbol()) {
         if (OrderType()==Type && (OrderMagicNumber()==Magic || Magic==0)) {
            if (_MaxPrice==0) _MaxPrice=OrderTakeProfit();
            if (OrderTakeProfit()>_MaxPrice) _MaxPrice=OrderTakeProfit();		   
         }
      }
   }
return (_MaxPrice);
}

double MinPriceProfit(int Type, int Magic) {
double _MinPrice=0;

   for(int i=0;i<OrdersTotal();i++)
   {
      OrderSelect(i, SELECT_BY_POS, MODE_TRADES);
     
      if (OrderSymbol()==Symbol()) {
         if (OrderType()==Type && (OrderMagicNumber()==Magic || Magic==0)) {
            if (_MinPrice==0) _MinPrice=OrderTakeProfit();
            if (OrderTakeProfit()<_MinPrice) _MinPrice=OrderTakeProfit();		   
         }
      }
   }
return (_MinPrice);
}





double MaxPriceLoss(int Type, int Magic) {
double _MaxPrice=0;

   for(int i=0;i<OrdersTotal();i++)
   {
      OrderSelect(i, SELECT_BY_POS, MODE_TRADES);
     
      if (OrderSymbol()==Symbol()) {
         if (OrderType()==Type && (OrderMagicNumber()==Magic || Magic==0)) {
            if (_MaxPrice==0) _MaxPrice=OrderStopLoss();
            if (OrderTakeProfit()>_MaxPrice) _MaxPrice=OrderStopLoss();		   
         }
      }
   }
return (_MaxPrice);
}

double MinPriceLoss(int Type, int Magic) {
double _MinPrice=0;

   for(int i=0;i<OrdersTotal();i++)
   {
      OrderSelect(i, SELECT_BY_POS, MODE_TRADES);
     
      if (OrderSymbol()==Symbol()) {
         if (OrderType()==Type && (OrderMagicNumber()==Magic || Magic==0)) {
            if (_MinPrice==0) _MinPrice=OrderStopLoss();
            if (OrderTakeProfit()<_MinPrice) _MinPrice=OrderStopLoss();		   
         }
      }
   }
return (_MinPrice);
}
  
  
  
  
void CheckStopLoss(string _symbol)
  {
    for (int i = 0; i < OrdersTotal(); i++) {
     OrderSelect(i, SELECT_BY_POS, MODE_TRADES);
     if ( OrderSymbol()==_symbol && ((OrderMagicNumber()==MagicNumber) || MagicNumber==0))  // only look if mygrid and symbol...
        {
          
          if (OrderType() == OP_BUY) {
             double maxloss=MaxPriceLoss(OP_BUY,MagicNumber);
             OrderSelect(i, SELECT_BY_POS, MODE_TRADES);
             

                if(OrderStopLoss()<maxloss)
                  {
                     OrdModify(OrderTicket(),OrderOpenPrice(),maxloss,OrderTakeProfit(),0,BuyColor);
                  }
          }

          if (OrderType() == OP_SELL) 
          {
             double minloss=MinPriceLoss(OP_SELL,MagicNumber);
             OrderSelect(i, SELECT_BY_POS, MODE_TRADES);
                if(OrderStopLoss()>minloss)
                {
                   OrdModify(OrderTicket(),OrderOpenPrice(),minloss,0,SellColor);
                   
                }
          }
       }
    }
 }
  



Sample





Analysis



Market Information Used:

Series array that contains close prices for each bar


Indicator Curves created:


Indicators Used:



Custom Indicators Used:

Order Management characteristics:
Checks for the total of open orders

It automatically opens orders when conditions are reached
It Closes Orders by itself
It can change open orders parameters, due to possible stepping strategy

Other Features:

Uses files from the file system
It writes information to file

BackTest : EURUSD on H1

From 2010-04-01 to 2010-04-30 Profit Factor:0.00 Total Net Profit:0.00

BackTest : EURUSD on H1

From 2010-05-01 to 2010-05-31 Profit Factor:0.00 Total Net Profit:0.00

BackTest : EURUSD on H1

From 2010-06-01 to 2010-06-30 Profit Factor:0.00 Total Net Profit:0.00

Request Backtest for SketchyStoplossGridTrader_EA


From : (yyyy/mm/dd) To: (yyyy/mm/dd)

Pair: Period: