//+------------------------------------------------------------------+
//|                                                     nkSAR EA.mq4 |
//+------------------------------------------------------------------+
#property copyright ""
#property link      ""
#include <stdlib.mqh>
#include <stderror.mqh>
extern double LotSize=2;
extern int    Slippage=3;
extern double StopLoss=15;
extern double TakeProfit=100;
extern int    TrailingStop=15;
extern int    OpenPosHandler=0; 
extern bool   TestMode=true;
int     ticket;
int     maxloop=25; // maximum number of attempts to handle errors
int     MagicNumber=123;
string  EAName="nkSAR EA 0.1";
double  aSAR[3,3];
double  tfSAR[]={PERIOD_M1, PERIOD_M15, PERIOD_H1};
int OrderBar=0;
int OrderTime=0;
double OpenBuy=0;
double OpenSell=0;
//+------------------------------------------------------------------+
//| expert initialization function                                   |
//+------------------------------------------------------------------+
int init()
{
  return(0);
}
//+------------------------------------------------------------------+
//| expert deinitialization function                                 |
//+------------------------------------------------------------------+
int deinit()
{
  return(0);
}
//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+
int start()
{
  HandleOpenPositions(0);
  CheckEntry();
  CheckExit();
  return(0);
}
//+------------------------------------------------------------------+
int HandleOpenPositions(int id)
{
   int cnt, OrderMN;
   double lotsi;
   
   OpenBuy=0;
   OpenSell=0;
   
   for(cnt=OrdersTotal()-1;cnt>=0;cnt--)
   {
      OrderSelect (cnt, SELECT_BY_POS, MODE_TRADES);
      lotsi=OrderLots();
      OrderMN=OrderMagicNumber();
      if( !(OrderSymbol() == Symbol()) ) continue;
      if( OrderMN != MagicNumber)  continue;
      
      if(OrderType()==OP_BUY) OpenBuy = OpenBuy+OrderLots();
      if(OrderType()==OP_SELL) OpenSell = OpenSell+OrderLots();
      
      HandleTrailingStop(OrderType(), OrderTicket(), OrderOpenPrice(), OrderStopLoss(), 1, TrailingStop);
   }
   return(0);
}
void CheckEntry()
{
  for(int i=0; i<3; i++)
  for(int j=0; j<3; j++)
  {
    aSAR[j,i]=iSAR(NULL,tfSAR[j],0.01,0.1,i);
  }
  
  if(IsLong(2) && IsLong(1) && IsNewLong(0) && OrderBar !=Bars)
  {
    OrderBar=Bars;
    OpenOrder(Symbol(),OP_BUY,LotSize,Ask,Slippage,StopLoss,TakeProfit,EAName,MagicNumber,0,Blue);
  }
  if(IsShort(2) && IsShort(1) && IsNewShort(0) && OrderBar !=Bars)
  {
    OrderBar=Bars;
    OpenOrder(Symbol(),OP_SELL,LotSize,Bid,Slippage,StopLoss,TakeProfit,EAName,MagicNumber,0,Red);
  }
}
bool IsLong(int aTF)
{
  return(aSAR[aTF,1]<Bid);
}
bool IsShort(int aTF)
{
  return(aSAR[aTF,2]>Bid);
}
bool IsNewLong(int aTF)
{
  return(aSAR[aTF,2]>Bid && aSAR[aTF,1]<Bid);
}
bool IsNewShort(int aTF)
{
  return(aSAR[aTF,2]<Bid && aSAR[aTF,1]>Bid);
}
void CheckExit()
{
}
int OpenOrder(string aSymbol, int pType,double pLots,double pLevel,int sp, int sl, int tp,string pComment,int pMagic,datetime pExpiration,color pColor)
{
  int ticket=0;
  int err=0;
  int c = 0;
  int NumberOfTries = 10;
  switch (pType)
  {
      case OP_BUY:
         for(c = 0 ; c < NumberOfTries ; c++)
         {  
            RefreshRates();
            ticket=OrderSend(aSymbol,OP_BUY,pLots,Ask,sp,StopLong(Bid,sl),TakeLong(Bid,tp),pComment,pMagic,pExpiration,pColor);
            if (ticket > 0) break;
            err=GetLastError();
            if(err==0)
            { 
               break;
            }
            else
            {
               if(err==4 || err==137 ||err==146 || err==136) //Busy errors
               {
                  Sleep(5000);
                  continue;
               }
               else //normal error
               {
                  Print("Error Code= ", err);
                  break;
               }  
            }
         } 
         break;
      case OP_SELL:
         for(c = 0 ; c < NumberOfTries ; c++)
         {
            RefreshRates();
            ticket=OrderSend(aSymbol,OP_SELL,pLots,Bid,sp,StopShort(Ask,sl),TakeShort(Ask,tp),pComment,pMagic,pExpiration,pColor);
            if (ticket > 0) break;
            err=GetLastError();
            if(err==0)
            { 
               break;
            }
            else
            {
               if(err==4 || err==137 ||err==146 || err==136) //Busy errors
               {
                  Sleep(5000);
                  continue;
               }
               else //normal error
               {
                  Print("Error Code= ", err);
                  break;
               }  
            }
         } 
         break;
  } 
  
  return(ticket);
}  
void CloseLongs(string aSymbol, int MagicNumber, double clots=0)
{
 int trade;
 double olots;
 
 for(trade=OrdersTotal()-1;trade>=0;trade--)
 {
  if(OrderSelect(trade,SELECT_BY_POS,MODE_TRADES)==false) continue;
  if(OrderSymbol()!=aSymbol||OrderMagicNumber()!=MagicNumber) continue;
  if(OrderType()!=OP_BUY) continue;
   
  olots=OrderLots();
  if (clots==0) clots=olots;
  OrderClose(OrderTicket(),clots,Bid,Slippage,Blue);
  if(olots!=clots && StopLoss !=0)
  ModifyStopLoss(OrderTicket(),StopLong(Bid,StopLoss));
 }//for
}
void CloseShorts(string aSymbol, int MagicNumber, double clots=0)
{
 int trade;
 double olots;
 for(trade=OrdersTotal()-1;trade>=0;trade--)
 {
  if(OrderSelect(trade,SELECT_BY_POS,MODE_TRADES)==false) continue;
  if(OrderSymbol()!=aSymbol||OrderMagicNumber()!=MagicNumber) continue;
  if(OrderType()!=OP_SELL) continue;
  
  olots=OrderLots();
  if (clots==0) clots=olots; 
  OrderClose(OrderTicket(),clots,Ask,Slippage,Red);
  if(olots!=clots && StopLoss !=0)
  ModifyStopLoss(OrderTicket(),StopShort(Ask,StopLoss));
 }//for
}
double StopLong(double price,int stop)
{
 if(stop==0)
  return(0);
 else
  return(price-(stop*Point));
}
double StopShort(double price,int stop)
{
 if(stop==0)
  return(0);
 else
  return(price+(stop*Point));
}
double TakeLong(double price,int take)
{
 if(take==0)
  return(0);
 else
  return(price+(take*Point));
}
double TakeShort(double price,int take)
{
 if(take==0)
  return(0);
 else
  return(price-(take*Point));
}
int HandleTrailingStop(int type, int ticket, double open_price, double cur_sl, int TrailingStopType, int TrailingStop)
{
	double pt, TS = 0, myAsk, myBid;
	if (type == OP_BUY)
	{
		myBid = MarketInfo(Symbol(),MODE_BID);
		switch (TrailingStopType)
		{
			case 1: 
				pt = Point * StopLoss;
				if (myBid - cur_sl > pt) 
					ModifyStopLoss(ticket, myBid - pt);
				break;
				
			case 2: 
				pt = Point * TrailingStop;
				if (myBid - open_price > pt && (cur_sl < myBid - pt || cur_sl == 0))
					ModifyStopLoss(ticket, myBid - pt);
				break;
		}
		return(0);
	}
	else if (type ==  OP_SELL)
	{
		myAsk = MarketInfo(Symbol(),MODE_ASK);
		switch (TrailingStopType)
		{
			case 1: 
				pt = Point * StopLoss;
				if (cur_sl - myAsk > pt) 
					ModifyStopLoss(ticket, myAsk+pt);
				break;
				
			case 2: 
				pt = Point * TrailingStop;
				if (open_price - myAsk > pt && (cur_sl > myAsk + pt || cur_sl == 0))
					ModifyStopLoss(ticket, myAsk+pt);
				break;
				
		 }
	 }
	 return(0);
}
int ModifyStopLoss(int ticket, double stoploss)
{
    int Cnt, digits, err;
    string symbol;
    double myStopLoss;
    
    OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES);
    symbol = OrderSymbol();
    digits = MarketInfo(symbol,MODE_DIGITS);
    if (digits > 0)
    {
			 myStopLoss = NormalizeDouble(stoploss,digits);
    }
    Cnt=0;
    while (Cnt < 3)
    {
       if (OrderModify(ticket,OrderOpenPrice(),myStopLoss,OrderTakeProfit(),0,Aqua))
       {
         Cnt = 3;
       }
       else
       {
          err=GetLastError();
          Print(Cnt," Error modifying order : (", err , ") " + ErrorDescription(err));
         if (err>0) Cnt++;
       }
    }
}
void logwrite (string filename, string mydata)
  {
   int myhandle;
   string gregorian=TimeToStr(CurTime(),TIME_DATE|TIME_SECONDS);
   Print(mydata+", "+gregorian);
   
   // don't log anything if testing or if user doesn't want it
   //if(IsTesting()) return(0);
   if(TestMode==FALSE) return(0);
   myhandle=FileOpen(Symbol()+"_"+filename, FILE_CSV|FILE_WRITE|FILE_READ, ";");
   if(myhandle>0)
     {
      FileSeek(myhandle,0,SEEK_END);
      FileWrite(myhandle, mydata+", "+gregorian);
      FileClose(myhandle);
     }
  } 
             
            
Comments