//+------------------------------------------------------------------+
//| 
//+------------------------------------------------------------------+
#property copyright "RK"
#property link      "None"
#include <stdlib.mqh>
#include <stderror.mqh> 

extern string  EA_Name        = " RK-ZeroLag-Macd_EA ";
extern string  Indic_Name     = " RK-ZeroLag-MACD & RSI";
extern bool    Debug          = false;
//|Account functions                                  |
extern bool    AccountIsMini  = true;     // Change to true if trading mini account
//|Money Management                                   |
extern bool   MoneyManagement = false;    // Change to false to shutdown money management controls.
                                    // Lots = 1 will be in effect and only 1 lot will be open regardless of equity.
extern double TradeSizePercent= 10;       // Change to whatever percent of equity you wish to risk.
extern double Lots            = 0.01;      // standard lot size. 
double        MaxLots         = 1;

extern double  StopLoss       = 0;        // Maximum pips willing to lose per position.
extern int     TakeProfit     = 0;        // 0= Off, Maximum profit level achieved.
extern int     Slippage       = 5;        // Possible fix for not getting filled or closed    

extern string ____ExitMode___ = "Use MMs: 0=off/Signal exits, 1= MM ONLY: SL-TP Exits ONLY" ;
extern int        ExitMode    = 0;        // 0-off/Signal exits, 1= MM: SL-TP Exits" ;

extern string  Time_Inputs    = " Timing parameters ";
extern int     StartHour      = 0;        // Start Hour of Trade Session 
extern int     StartMinute    = 0;        // Start Minute of Trade Session 
extern int     EndHour        =23;        // End Hour of Trade Session
extern int     EndMinute      = 0;        // End Hour of Trade Session

extern string  Indicator_ZeroLag = " RK-ZeroLag-MACD parameters--";
extern int     FastEMA        = 10;
extern int     SlowEMA        = 20;
extern int     SignalEMA      = 5;
extern int     ShiftM         =0;
extern int     ShiftMx        =0;

extern string  Indicator_rsi  = " RSI parameters--";
extern int     RSIPd          = 14;

extern bool   UseTrailingStop = FALSE;

extern string  tsp0           = "--Trailing Stop Types--";
extern string  tsp1           = " 1 = Trail immediately";
extern string  tsp2           = " 2 = Wait to trail";
extern string  tsp3           = " 3 = Uses 3 levels before trail";
extern string  tsp4           = " 4 = Breakeven + Lockin";
extern string  tsp5           = " 5 = Step trail";
extern string  tsp6           = " 6 = MA trail";
extern string  tsp7           = " 7 = pSAR trail";
extern string  tsp8           = " 8 = HiLo trail";
extern int   TrailingStopType = 5;         //Type 1 moves stop immediately,
extern string  ts2 = "Settings for Type 2";  //Type 2 waits til value of TrlStop is reached
extern double  TrailingStop   = 15;            // Change to whatever number of pips you wish to trail your position with.

extern string  ts3            = "Settings for Type 3";
extern double  FirstMove      = 20;               // Type 3  first level pip gain
extern double  FirstStopLoss  = 50;           // Move Stop to Breakeven
extern double  SecondMove     = 30;              // Type 3 second level pip gain
extern double  SecondStopLoss = 30;   // Move stop to lock is profit
extern double  ThirdMove      = 40;        // type 3 third level pip gain
extern double  TrailingStop3  = 20;    // Move stop and trail from there

extern string  ts4            = "Settings for Type 4";
extern double  BreakEven      = 15;
extern int     LockInPips     = 1;        // Profit Lock in pips

extern string  ts5            = "Settings for Type 5";
extern int     eTrailingStop  = 15;
extern int     eTrailingStep  = 2;

extern string  ts6 = "Settings for Type 6";
extern int     TrailMA_TimeFrame    =  15;
extern int     TrailMA_Period       = 10;
extern int     TrailMA_Shift        =  0;    
extern string  t3="--Moving Average settings--";
extern string  tm = "--Moving Average Types--";
extern string  tm0 = " 0 = SMA";
extern string  tm1 = " 1 = EMA";
extern string  tm2 = " 2 = SMMA";
extern string  tm3 = " 3 = LWMA";
extern int     TrailMA_Type = 1;
extern string  tp = "--Applied Price Types--";
extern string  tp0 = " 0 = close";
extern string  tp1 = " 1 = open";
extern string  tp2 = " 2 = high";
extern string  tp3 = " 3 = low";
extern string  tp4 = " 4 = median(high+low)/2";
extern string  tp5 = " 5 = typical(high+low+close)/3";
extern string  tp6 = " 6 = weighted(high+low+close+close)/4";
extern int     TrailMA_AppliedPrice = 0;
extern int     InitialStop     =  0;
 
extern string  ts7 = "Settings for Type 7";
extern double  StepParabolic = 0.02;
extern double  MaxParabolic  = 0.2;
extern int     Interval      = 5;

extern string  ts8 = "Settings for Type 8";
extern int     BarsBack = 5;

datetime       timeprev = 0;
double   myStopLoss;   
double   lotMM;
int      MagicNumber;
string   setup = "";
int      totalTries = 5; 
int      retryDelay = 1000;
double pointvalue;
int myTradeErr;
int init() 
{
	MagicNumber = 5000 + func_Symbol2Val(Symbol())*100 + func_TimeFrame_Const2Val(Period()); 
   setup = EA_Name + Symbol() + "_" + func_TimeFrame_Val2String(func_TimeFrame_Const2Val(Period()));

    //Convert to 3 & 5 diget broker
    if (Digits == 4 || Digits == 2) pointvalue = Point;
      else if (Digits == 5 || Digits == 3) pointvalue = 10.0 * Point;
}

bool TimeCondition()
{
   bool result = false;
   
   datetime SessionStart = StrToTime(StartHour+":"+StartMinute);
   datetime SessionEnd   = StrToTime(EndHour+":"+EndMinute);
   
   if (StartHour < EndHour)
   result = TimeCurrent() >= SessionStart && TimeCurrent() < SessionEnd;
   else
   if (StartHour > EndHour)
   result = (TimeCurrent() > SessionStart && TimeHour(TimeCurrent()) < 24)||
                              (TimeHour(TimeCurrent()) >= 0 && TimeCurrent() < SessionEnd);
   return(result);
}   

bool BuySignal() 
{
   double Macd   = iCustom(NULL,0,"RK-ZeroLag-MACD",FastEMA,SlowEMA,SignalEMA,0,ShiftM+0);
   double Macdp  = iCustom(NULL,0,"RK-ZeroLag-MACD",FastEMA,SlowEMA,SignalEMA,0,ShiftM+1);
   double Signal = iCustom(NULL,0,"RK-ZeroLag-MACD",FastEMA,SlowEMA,SignalEMA,1,ShiftM+0);
   double rsi =iCustom(NULL,0,"RSI",RSIPd,0,0); //opt#   tnp   pf    tt    Win  %
   if ( //Macd > 0                   //  1              
   //&& Macdp < 0                    //  2            
     Macd > Macdp                    //  3          
    //&& Macd > Signal               //  4
    && rsi > 50                      //  5
    && TimeCondition())  return(true);  return(false);
}
bool SellSignal() 
{
   double Macd   = iCustom(NULL,0,"RK-ZeroLag-MACD",FastEMA,SlowEMA,SignalEMA,0,ShiftM+0);
   double Macdp  = iCustom(NULL,0,"RK-ZeroLag-MACD",FastEMA,SlowEMA,SignalEMA,0,ShiftM+1);
   double Signal = iCustom(NULL,0,"RK-ZeroLag-MACD",FastEMA,SlowEMA,SignalEMA,1,ShiftM+0);
   double rsi =iCustom(NULL,0,"RSI",RSIPd,0,0);
   if (// Macd < 0 
   //&& Macdp > 0
     Macd < Macdp
    //&& Macd < Signal
    && rsi < 50 
    && TimeCondition()) return(true); return (false);
}
bool BuyExitSignal()
{
   double Macd   = iCustom(NULL,0,"RK-ZeroLag-MACD",FastEMA,SlowEMA,SignalEMA,0,ShiftMx+0);
   double Macdp  = iCustom(NULL,0,"RK-ZeroLag-MACD",FastEMA,SlowEMA,SignalEMA,0,ShiftMx+1);
   double Signal = iCustom(NULL,0,"RK-ZeroLag-MACD",FastEMA,SlowEMA,SignalEMA,1,ShiftMx+0);
   
  if (ExitMode ==0 && Macd < Macdp
   || !TimeCondition()) return(true); return(false); 
}
bool SellExitSignal()
{
   double Macd   = iCustom(NULL,0,"RK-ZeroLag-MACD",FastEMA,SlowEMA,SignalEMA,0,ShiftMx+0);
   double Macdp  = iCustom(NULL,0,"RK-ZeroLag-MACD",FastEMA,SlowEMA,SignalEMA,0,ShiftMx+1);
   double Signal = iCustom(NULL,0,"RK-ZeroLag-MACD",FastEMA,SlowEMA,SignalEMA,1,ShiftMx+0);
   
  if (ExitMode ==0 && Macd > Macdp
   || !TimeCondition()) return(true);  return(false); 
}

int start()
{
  
    // Only run once per completed bar L-118
     if(timeprev==Time[0]) return(0);
     timeprev = Time[0];
   
//+------------------------------------------------------------------+
//| Check for Open Position                                          |
//+------------------------------------------------------------------+
   
  HandleOpenPositions();
  
//+------------------------------------------------------------------+
//| Check if OK to make new trades                                   |
//+------------------------------------------------------------------+
    
if (TimeCondition())
   { 

// Only allow 1 trade per Symbol
     
  if (CheckOpenPositions() > 0) return(0);
   
   lotMM = GetLots();
  
   if( BuySignal()) //&& Close[1] > upper)  
      {
	     OpenBuyOrder();
         return(0);
      }
     
      if(SellSignal()) //&& Close[1] < lower) 
      {
      OpenSellOrder();
      }
      return(0);
  }
}
//+------------------------------------------------------------------+187
//| OpenBuyOrder                                                     |
//| If Stop Loss or TakeProfit are used the values are calculated    |
//| for each trade                                                   |
//+------------------------------------------------------------------+ 
void OpenBuyOrder()
{
   int ticket;
   int cnt, err, digits;
   double myStopLoss = 0, myTakeProfit = 0, myPrice = 0 ;
   double modifyDone;
   myPrice = MarketInfo(Symbol(), MODE_ASK);
   myStopLoss = 0;
   if ( StopLoss > 0 ) myStopLoss = myPrice - StopLoss * pointvalue ;
	if (myStopLoss != 0) ValidStopLoss(OP_BUY,myPrice, myStopLoss); 
   myTakeProfit = 0;
   if (TakeProfit > 0) myTakeProfit = myPrice + TakeProfit * pointvalue;
   // Normalize all price / stoploss / takeprofit to the proper # of digits.
   digits = MarketInfo(Symbol(), MODE_DIGITS);
	if (digits > 0) 
	{
		myPrice = NormalizeDouble(myPrice, digits);
	   myStopLoss = NormalizeDouble(myStopLoss, digits);
	   myTakeProfit = NormalizeDouble(myTakeProfit, digits); 
	}
  ticket = OrderSend(Symbol(), OP_BUY, lotMM, myPrice, Slippage, 0, 0, setup, MagicNumber, 0, DodgerBlue);
     //Print("BUY order opened : ------------------------------------ticket #  " , ticket ,"   ", OrderOpenPrice());
     if(ticket > 0)
     {
         if (OrderSelect(ticket, SELECT_BY_TICKET, MODE_TRADES))
          {
                  OrderModify(ticket,OrderOpenPrice(),myStopLoss, myTakeProfit,0,DarkRed);
                  Print("BUY order Modified : ticket #  " , ticket ,"--MYSL--",myStopLoss,"--MyTP--", myTakeProfit,"   " , OrderOpenPrice());
          }                     
     }
     else Print("Error opening BUY order : ", GetLastError());
            
 }
//+------------------------------------------------------------------+
//| OpenSellOrder                                                    |
//| If Stop Loss or TakeProfit are used the values are calculated    |
//| for each trade                                                   |
//+------------------------------------------------------------------+ 251
void OpenSellOrder()
{
   int ticket;
   int cnt, err, digits;
   double myStopLoss = 0, myTakeProfit = 0, myPrice = 0;
   double modifyDone;
   myPrice = MarketInfo(Symbol(), MODE_BID);
   myStopLoss = 0;
   if ( StopLoss > 0 ) myStopLoss = myPrice + StopLoss * pointvalue ;
	if (myStopLoss != 0) ValidStopLoss(OP_SELL,myPrice, myStopLoss); //261
   myTakeProfit = 0;
   if (TakeProfit > 0) myTakeProfit = myPrice - TakeProfit * pointvalue;
   // Normalize all price / stoploss / takeprofit to the proper # of digits.
	digits = MarketInfo(Symbol(), MODE_DIGITS);
	if (digits > 0) 
	{
	   myPrice = NormalizeDouble(myPrice, digits);
	   myStopLoss = NormalizeDouble(myStopLoss, digits);
	   myTakeProfit = NormalizeDouble(myTakeProfit, digits); 
	}
  ticket = OrderSend(Symbol(), OP_SELL, lotMM, myPrice, Slippage, 0, 0, setup, MagicNumber, 0, Red);
     //Print("Sell order opened : ------------------------------------ticket #  " , ticket ,"   ", OrderOpenPrice());
     if(ticket > 0)
     {
         if (OrderSelect(ticket, SELECT_BY_TICKET, MODE_TRADES))
          {
                  OrderModify(ticket,OrderOpenPrice(),myStopLoss, myTakeProfit,0,DarkRed);
                  Print("Sell order Nodified : ticket #  " , ticket,"--MYSL--",myStopLoss,"--MyTP--", myTakeProfit,"   " , OrderOpenPrice());
          }                     
     }
     else Print("Error opening Sell order : ", GetLastError());
  return(0);
}
//+------------------------------------------------------------------+
//| Check Open Position Controls                                     |
//+------------------------------------------------------------------+276 
int CheckOpenPositions()
{
   int cnt, total, NumPositions;
   int NumBuyTrades, NumSellTrades;   // Number of buy and sell trades in this symbol
   
   NumBuyTrades = 0;
   NumSellTrades = 0;
   total=OrdersTotal();
   for(cnt=OrdersTotal()-1;cnt>=0;cnt--)
     {
      OrderSelect (cnt, SELECT_BY_POS, MODE_TRADES);
      if ( OrderSymbol() != Symbol()) continue;
      if ( OrderMagicNumber() != MagicNumber)  continue;
      
      if(OrderType() == OP_BUY )  NumBuyTrades++;
      if(OrderType() == OP_SELL ) NumSellTrades++;
             
     }
     NumPositions = NumBuyTrades + NumSellTrades;
     return (NumPositions);
}

bool myOrderModify(int myOrderType, int ord_ticket, double op, double oSL, double oTP, color mColor = CLR_NONE) 
{

   int err;
   bool result;
   
      
	if (!IsConnected()) 
	{
		myTradeErr = ERR_NO_CONNECTION; 
      Print(" Error modifying order : (", myTradeErr , ") " + ErrorDescription(myTradeErr));
		return(false);
	}
	
	if (IsStopped()) 
	{
		return(false);
	}
	
	int cnt = 0;
	while(!IsTradeAllowed() && cnt < totalTries) 
	{
		Sleep(retryDelay);
		cnt++;
	}
	if (!IsTradeAllowed()) 
	{
		myTradeErr = ERR_TRADE_CONTEXT_BUSY; 
      Print(" Error modifying order : (", myTradeErr , ") " + ErrorDescription(myTradeErr));
		return(false);  
	}

	err = GetLastError(); // so we clear the global variable.  
	err = 0; 
	myTradeErr = 0; 
	bool exit_loop = false;
	cnt = 0;
	result = false;

	while (!exit_loop) 
	{
		if (IsTradeAllowed()) 
		{
			result = OrderModify(ord_ticket, op, oSL, oTP, 0, mColor);

		if (result == true) 
			exit_loop = true;
	   else
	   {
			err = GetLastError();
			myTradeErr = err; 

		switch (err) 
		{
			case ERR_NO_ERROR:
				exit_loop = true;
				break;
				
			case ERR_NO_RESULT:
				// modification without changing a parameter. 
				// if you get this then you may want to change the code.
				exit_loop = true;
				break;
				
			case ERR_SERVER_BUSY:
			case ERR_NO_CONNECTION:
			case ERR_INVALID_PRICE:
			case ERR_OFF_QUOTES:
			case ERR_BROKER_BUSY:
			case ERR_TRADE_CONTEXT_BUSY: 
			case ERR_TRADE_TIMEOUT:		// for modify this is a retryable error, I hope. 
				cnt++; 	// a retryable error
				break;
				
			case ERR_PRICE_CHANGED:
			case ERR_REQUOTE:
				RefreshRates();
				continue; 	// we can apparently retry immediately according to MT docs.
				
			default:
				// an apparently serious, unretryable error.
				exit_loop = true;
				break; 
				
		}  // end switch 
	   }

		} 
		else 
			cnt++;
		if (cnt > totalTries) 
			exit_loop = true; 
			
		if (!exit_loop) 
		{
			Sleep (retryDelay); 
			RefreshRates(); 
		}
		
	}  
	
	// we have now exited from loop. 
	if ((result == true) || (err == ERR_NO_ERROR)) 
	{
		OrderSelect(ord_ticket, SELECT_BY_TICKET, MODE_TRADES); 
		OrderPrint(); 
		return(true); // SUCCESS! 
	} 
	
	if (err == ERR_NO_RESULT) 
	{
      Print(" No Result - Error modifying order : (", err , ") " + ErrorDescription(err));
		return(true);
	}
   Print(" Error modifying order : (", err , ") " + ErrorDescription(err));
	
	return(false);  
}


double ValidStopLoss(int type, double price, double SL)
{

   double mySL;
   double minstop;
   
   minstop = MarketInfo(Symbol(),MODE_STOPLEVEL);
   if (Digits == 3 || Digits == 5) minstop = minstop / 10;
   
   mySL = SL;
   if (type == OP_BUY)
   {
		 if((price - mySL) < minstop*pointvalue) mySL = price - minstop*pointvalue;
   }
   if (type == OP_SELL)
   {
       if((mySL-price) < minstop*pointvalue)  mySL = price + minstop*pointvalue;  
   }

   return(NormalizeDouble(mySL,MarketInfo(Symbol(), MODE_DIGITS)));   
}
//+------------------------------------------------------------------+
//| Modify Open Position Controls                                    |
//|  Try to modify position 3 times                                  |
//+------------------------------------------------------------------+ 
/*bool ModifyOrder(int nOrderType, int ord_ticket,double op, double price,double tp, color mColor = CLR_NONE)
{
    int cnt, err;
    double myStop;
    
    myStop = ValidStopLoss (nOrderType, price);
    cnt=0;
    while (cnt < totalTries)
    {
       if (OrderModify(ord_ticket,op,myStop,tp,0,mColor))
       {
         return(true);
       }
       else
       {
          err=GetLastError();
          if (err > 1) Print(cnt," Error modifying order : (", ord_ticket , ") " 
                                   + ErrorDescription(err), " err ",err);
          
          if (err>0) cnt++;
          Sleep(retryDelay);
       }
    }
    return(false);
}

// 	Adjust stop loss so that it is legal.
double ValidStopLoss(int cmd, double sl)
{
   
   if (sl == 0) return(0.0);
   
   double mySL, myPrice;
   double dblMinStopDistance = MarketInfo(Symbol(),MODE_STOPLEVEL)*MarketInfo(Symbol(), MODE_POINT);
   
   mySL = sl;
   
// Check if SlopLoss needs to be modified

   switch(cmd)
   {
   case OP_BUY:
      myPrice = MarketInfo(Symbol(), MODE_BID);
	   if (myPrice - sl < dblMinStopDistance) 
		mySL = myPrice - dblMinStopDistance;	// we are long
		break;
      
   case OP_SELL:
      myPrice = MarketInfo(Symbol(), MODE_ASK);
	   if (sl - myPrice < dblMinStopDistance) 
		mySL = myPrice + dblMinStopDistance;	// we are long

   }
   return(NormalizeDouble(mySL,MarketInfo(Symbol(), MODE_DIGITS)));
}
*/

//+------------------------------------------------------------------+
//| HandleTrailingStop                                               |
//| Type 1 moves the stoploss without delay.                         |
//| Type 2 waits for price to move the amount of the trailStop       |
//| before moving stop loss then moves like type 1                   |
//| Type 3 uses up to 3 levels for trailing stop       |
//|      Level 1 Move stop to 1st level                              |
//|      Level 2 Move stop to 2nd level                              |
//|      Level 3 Trail like type 1 by fixed amount other than 1      |
//| Type 4 Move stop to breakeven + Lockin, no trail                                               |
//| Type 4 uses 2 for 1, every 2 pip move moves stop 1 pip           |
//| Type 5 uses steps for 1, every step pip move moves stop 1 pip    |
//| Type 6 Uses EMA to set trailing stop  
//| Type 7 Uses pSar to set trailing stop 
//| Type 8 Uses HiLO to set trailing stop 
//+------------------------------------------------------------------+ 371
int HandleTrailingStop(int type, int ticket, double op, double os, double tp)
{
    switch (TrailingStopType)
   {
     case 1 : Immediate_TrailingStop (type, ticket, op, os, tp);
              break;
     case 2 : Delayed_TrailingStop (type, ticket, op, os, tp);
              break;
     case 3 : ThreeLevel_TrailingStop (type, ticket, op, os, tp);
              break;
     case 4 : BreakEven_TrailingStop (type, ticket, op, os, tp);
              break;
	  case 5 : eTrailingStop (type, ticket, op, os, tp);
              break;
     case 6 : MA_TrailingStop (type, ticket, op, os, tp);
              break;
	  case 7 : pSAR_TrailingStop (type, ticket, op, os, tp);
              break;
	  case 8 : HiLo_TrailingStop (type, ticket, op, os, tp);
              break;
    	}
   return(0);
}
    
//+------------------------------------------------------------------+
//|                                       Immediate_TrailingStop.mq4 |
//|                                  Copyright © 2006, Forex-TSD.com |
//|                         Written by MrPip,robydoby314@yahoo.com   |
//|                                                                  |   
//| Moves the stoploss without delay.                                |
//+------------------------------------------------------------------+
void Immediate_TrailingStop(int type, int ticket, double op, double os, double tp)
{

   int digits;
   double pt, pBid, pAsk, BuyStop, SellStop;

   digits = MarketInfo(Symbol( ), MODE_DIGITS);
   
   if (type==OP_BUY)
   {
     pBid = MarketInfo(Symbol(), MODE_BID);
     pt = StopLoss * pointvalue;
     Print("os------",os);
     if(pBid-os > pt)
     {
       BuyStop = pBid - pt;
       if (digits > 0) BuyStop = NormalizeDouble( BuyStop, digits);
		 BuyStop = ValidStopLoss(OP_BUY,pBid, BuyStop);   
       if (os < BuyStop) myOrderModify(type, ticket,op,BuyStop,tp,LightGreen);
		 return;
	  }
   }
   if (type==OP_SELL)
   {
     pAsk = MarketInfo(Symbol(), MODE_ASK);
     pt = StopLoss * pointvalue;
     if(os - pAsk > pt)
     {
       SellStop = pAsk + pt;
       if (digits > 0) SellStop = NormalizeDouble( SellStop, digits);
       SellStop = ValidStopLoss(OP_SELL, pAsk, SellStop);  
       if (os > SellStop) myOrderModify(type, ticket,op,SellStop,tp,DarkOrange);
		 return;
     }
   }   
}
//+------------------------------------------------------------------+
//|                                         Delayed_TrailingStop.mq4 |
//|                                  Copyright © 2006, Forex-TSD.com |
//|                         Written by MrPip,robydoby314@yahoo.com   |
//|                                                                  |   
//| Waits for price to move the amount of the TrailingStop           |
//| Moves the stoploss pip for pip after delay.                      |
//+------------------------------------------------------------------+
void Delayed_TrailingStop(int type, int ticket, double op, double os, double tp)
{
   int digits;
   double pt, pBid, pAsk, BuyStop, SellStop;

   pt = TrailingStop * pointvalue;
   digits = MarketInfo(Symbol(), MODE_DIGITS);
   
   if (type==OP_BUY)
   {
     pBid = MarketInfo(Symbol(), MODE_BID);
     BuyStop = pBid - pt;
     if (digits > 0) BuyStop = NormalizeDouble( BuyStop, digits);
	  BuyStop = ValidStopLoss(OP_BUY,pBid, BuyStop);   
     if (pBid-op > pt && os < BuyStop) myOrderModify(type, ticket,op,BuyStop,tp,LightGreen);
	  return;
   }
   if (type==OP_SELL)
   {
     pAsk = MarketInfo(Symbol(), MODE_ASK);
     pt = TrailingStop * pointvalue;
     SellStop = pAsk + pt;
     if (digits > 0) SellStop = NormalizeDouble( SellStop, digits);
     SellStop = ValidStopLoss(OP_SELL, pAsk, SellStop);  
     if (op - pAsk > pt && os > SellStop) myOrderModify(type, ticket,op,SellStop,tp,DarkOrange);
	  return;
   }   
}    
    
//+------------------------------------------------------------------+
//|                                      ThreeLevel_TrailingStop.mq4 |
//|                                  Copyright © 2006, Forex-TSD.com |
//|                         Written by MrPip,robydoby314@yahoo.com   |   
//|                                                                  |
//| Uses up to 3 levels for trailing stop                            |
//|      Level 1 Move stop to 1st level                              |
//|      Level 2 Move stop to 2nd level                              |
//|      Level 3 Trail like type 1 by fixed amount other than 1      |
//+------------------------------------------------------------------+
void ThreeLevel_TrailingStop(int type, int ticket, double op, double os, double tp)
{

   int digits;
   double pBid, pAsk, BuyStop, SellStop;

   digits = MarketInfo(Symbol(), MODE_DIGITS) ;

   if (type == OP_BUY)
   {
      pBid = MarketInfo(Symbol(), MODE_BID);
      if (pBid - op > FirstMove * pointvalue)
      {
         BuyStop = op + FirstMove*pointvalue - FirstStopLoss * pointvalue;
         if (digits > 0) BuyStop = NormalizeDouble(BuyStop, digits); 
		   BuyStop = ValidStopLoss(OP_BUY, pBid, BuyStop);   
         if (os < BuyStop) myOrderModify(type, ticket,op,BuyStop,tp,LightGreen);
      }
              
      if (pBid - op > SecondMove * pointvalue)
      {
         BuyStop = op + SecondMove*pointvalue - SecondStopLoss * pointvalue;
         if (digits > 0) BuyStop = NormalizeDouble(BuyStop, digits); 
		   BuyStop = ValidStopLoss(OP_BUY, pBid, BuyStop);   
         if (os < BuyStop) myOrderModify(type, ticket,op,BuyStop,tp,LightGreen);
      }
                
      if (pBid - op > ThirdMove * pointvalue)
      {
         BuyStop = pBid  - TrailingStop3*pointvalue;
         if (digits > 0) BuyStop = NormalizeDouble(BuyStop, digits); 
		   BuyStop = ValidStopLoss(OP_BUY, pBid, BuyStop);   
         if (os < BuyStop) myOrderModify(type, ticket,op,BuyStop,tp,LightGreen);
      }
   }
       
    if (type ==  OP_SELL)
    {
        pAsk = MarketInfo(Symbol(), MODE_ASK);
        if (op - pAsk > FirstMove * pointvalue)
        {
           SellStop = op - FirstMove * pointvalue + FirstStopLoss * pointvalue;
           if (digits > 0) SellStop = NormalizeDouble(SellStop, digits); 
		     SellStop = ValidStopLoss(OP_SELL, pAsk, SellStop);   
           if (os > SellStop) myOrderModify(type, ticket,op,SellStop,tp,DarkOrange);
        }
        if (op - pAsk > SecondMove * pointvalue)
        {
           SellStop = op - SecondMove * pointvalue + SecondStopLoss * pointvalue;
           if (digits > 0) SellStop = NormalizeDouble(SellStop, digits); 
		     SellStop = ValidStopLoss(OP_SELL, pAsk, SellStop);   
           if (os > SellStop) myOrderModify(type, ticket,op,SellStop,tp,DarkOrange);
        }
        if (op - pAsk > ThirdMove * pointvalue)
        {
           SellStop = pAsk + TrailingStop3 * pointvalue;               
           if (digits > 0) SellStop = NormalizeDouble(SellStop, digits); 
		     SellStop = ValidStopLoss(OP_SELL, pAsk, SellStop);   
           if (os > SellStop) myOrderModify(type, ticket,op,SellStop,tp,DarkOrange);
        }
    }

}
    
//+------------------------------------------------------------------+
//|                                           BreakEvenExpert_v1.mq4 |
//|                                  Copyright © 2006, Forex-TSD.com |
//|                         Written by IgorAD,igorad2003@yahoo.co.uk |   
//|            http://finance.groups.yahoo.com/group/TrendLaboratory |                                      
//+------------------------------------------------------------------+
void BreakEven_TrailingStop(int type, int ticket, double op, double os, double tp)
{

   int digits;
   double pBid, pAsk, BuyStop, SellStop;

   digits = MarketInfo(Symbol(), MODE_DIGITS);
   
  if (type==OP_BUY)
  {
    pBid = MarketInfo(Symbol(), MODE_BID);
    if ( pBid-op > pointvalue*BreakEven ) 
    {
       BuyStop = op + LockInPips * pointvalue;
       if (digits > 0) BuyStop = NormalizeDouble( BuyStop, digits);
		 BuyStop = ValidStopLoss(OP_BUY,pBid, BuyStop);   
       if (os < BuyStop) myOrderModify(type, ticket,op,BuyStop,tp,LightGreen);
		 return;
	 }
  }
  if (type==OP_SELL)
  {
    pAsk = MarketInfo(Symbol(), MODE_ASK);
    if ( op - pAsk > pointvalue*BreakEven ) 
    {
       SellStop = op - LockInPips * pointvalue;
       if (digits > 0) SellStop = NormalizeDouble( SellStop, digits);
       SellStop = ValidStopLoss(OP_SELL, pAsk, SellStop);  
       if (os > SellStop) myOrderModify(type, ticket,op,SellStop,tp,DarkOrange);
		 return;
    }
  }   

}

//+------------------------------------------------------------------+
//|                                                   e-Trailing.mq4 |
//|                                           Ким Игорь В. aka KimIV |
//|                                              http://www.kimiv.ru |
//|                                                                  |
//| 12.09.2005 Автоматический Trailing Stop всех открытых позиций    |
//|            Вешать только на один график                          |
//+------------------------------------------------------------------+
void eTrailingStop(int type, int ticket, double op, double os, double tp)
{

  int digits;
  double pBid, pAsk, BuyStop, SellStop;

  digits = MarketInfo(Symbol(), MODE_DIGITS) ;
  if (type==OP_BUY)
  {
    pBid = MarketInfo(Symbol(), MODE_BID);
    if ((pBid-op)>eTrailingStop*pointvalue)
    {
      if (os<pBid-(eTrailingStop+eTrailingStep-1)*pointvalue)
      {
        BuyStop = pBid-eTrailingStop*pointvalue;
        if (digits > 0) BuyStop = NormalizeDouble( BuyStop, digits);
		  BuyStop = ValidStopLoss(OP_BUY, pBid, BuyStop);   
        myOrderModify(type,ticket,op,BuyStop,tp,LightGreen);
        return;
      }
    }
  }
  if (type==OP_SELL)
  {
    pAsk = MarketInfo(Symbol(), MODE_ASK);
    if (op - pAsk > eTrailingStop*pointvalue)
    {
      if (os > pAsk + (eTrailingStop + eTrailingStep-1)*pointvalue || os==0)
      {
        SellStop = pAsk + eTrailingStop * pointvalue;
        if (digits > 0) SellStop = NormalizeDouble( SellStop, digits);
        SellStop = ValidStopLoss(OP_SELL, pAsk, SellStop);  
        myOrderModify(type, ticket,op,SellStop,tp,DarkOrange);
        return;
      }
    }
  }

}
//+------------------------------------------------------------------+
//|                                           EMATrailingStop_v1.mq4 |
//|                                  Copyright © 2006, Forex-TSD.com |
//|                         Written by IgorAD,igorad2003@yahoo.co.uk |   
//|            http://finance.groups.yahoo.com/group/TrendLaboratory |
//|                                                                  |
//|  Modified to use any MA                                          |                                      
//+------------------------------------------------------------------+
void MA_TrailingStop(int type, int ticket, double op, double os, double tp)
{
   int digits;
   double pBid, pAsk, BuyStop, SellStop, ema;

   digits = MarketInfo(Symbol(), MODE_DIGITS) ;
   ema = iMA(Symbol(),TrailMA_TimeFrame,TrailMA_Period,0,TrailMA_Type,TrailMA_AppliedPrice,TrailMA_Shift);
   
   if (type==OP_BUY) 
   {
	   BuyStop = ema;
      pBid = MarketInfo(Symbol(),MODE_BID);
		if(os == 0 && InitialStop>0 ) BuyStop = pBid-InitialStop*pointvalue;
		if (digits > 0) BuyStop = NormalizeDouble(BuyStop, digits); 
		BuyStop = ValidStopLoss(OP_BUY, pBid, BuyStop);   
		if ((op <= BuyStop && BuyStop > os) || os==0) 
		{
          myOrderModify(type,ticket,op,BuyStop,tp,LightGreen);
			 return;
      }
   }   

   if (type==OP_SELL)
   {
	   SellStop = ema;
      pAsk = MarketInfo(Symbol(),MODE_ASK);
      if (os==0 && InitialStop > 0) SellStop = pAsk+InitialStop*pointvalue;
		if (digits > 0) SellStop = NormalizeDouble(SellStop, digits); 
		SellStop = ValidStopLoss(OP_SELL, pAsk, SellStop);
      if( (op >= SellStop && os > SellStop) || os==0) 
      {
          myOrderModify(type,ticket,op,SellStop,tp,DarkOrange);
			 return;
      }
   }
}

//+------------------------------------------------------------------+
//|                                                b-TrailingSAR.mqh |
//|                                           Ким Игорь В. aka KimIV |
//|                                              http://www.kimiv.ru |
//|                                                                  |
//|    21.11.2005  Библиотека функций трала по параболику.           |
//|  Для использования добавить строку в модуле start                |
//|  if (UseTrailing) TrailingPositions();                           |
//+------------------------------------------------------------------+
void pSAR_TrailingStop(int type, int ticket, double op, double os, double tp)
{
   int digits;
   double pBid, pAsk, BuyStop, SellStop, spr;
   double sar1, sar2;
  
   digits = MarketInfo(Symbol(), MODE_DIGITS) ;
   pBid = MarketInfo(Symbol(), MODE_BID);
   pAsk = MarketInfo(Symbol(), MODE_ASK);
   sar1=iSAR(NULL, 0, StepParabolic, MaxParabolic, 1);
   sar2=iSAR(NULL, 0, StepParabolic, MaxParabolic, 2);
   spr = pAsk - pBid;
   if (digits > 0) spr = NormalizeDouble(spr, digits); 
   
   if (type==OP_BUY)
   {
     pBid = MarketInfo(Symbol(), MODE_BID);
     if (sar2 < sar1)
     {
        BuyStop = sar1-Interval*pointvalue;
        if (digits > 0) BuyStop = NormalizeDouble(BuyStop, digits); 
	     BuyStop = ValidStopLoss(OP_BUY, pBid, BuyStop);   
        if (os<BuyStop) myOrderModify(type,ticket,op,BuyStop,tp,LightGreen);
     }
   }
   if (type==OP_SELL)
   {
     if (sar2 > sar1)
     {
        SellStop = sar1 + Interval * pointvalue + spr;
        if (digits > 0) SellStop = NormalizeDouble(SellStop, digits); 
	     SellStop = ValidStopLoss(OP_SELL, pAsk, SellStop);   
        if (os>SellStop || os==0) myOrderModify(type,ticket,op,SellStop,tp,DarkOrange);
     }
   }
}
//+------------------------------------------------------------------+
//|                                            HiLo_TrailingStop.mq4 |
//|                                    Copyright © 2010, Robert Hill |
//|         Written by Robert Hill aka MrPip,robydoby314@yahoo.com   |
//|                                                                  |   
//| Moves the stoploss to the Highest High X Bars back for Sell      |
//| and the Lowest Low X Bars Back for Buy.                          |
//+------------------------------------------------------------------+
void HiLo_TrailingStop(int type, int ticket, double op, double os, double tp)
{
   int digits;
   double pBid, pAsk, BuyStop, SellStop;

   digits = MarketInfo(Symbol(), MODE_DIGITS) ;
   
   if (type==OP_BUY) 
   {
	   BuyStop = Low[iLowest(NULL, 0, MODE_LOW, BarsBack, 0)];
      pBid = MarketInfo(Symbol(),MODE_BID);
		if (digits > 0) BuyStop = NormalizeDouble(BuyStop, digits); 
		BuyStop = ValidStopLoss(OP_BUY, pBid, BuyStop);   
		if ((op <= BuyStop && BuyStop > os) || os==0) 
		{
          myOrderModify(type,ticket,op,BuyStop,tp,LightGreen);
			 return;
      }
   }   

   if (type==OP_SELL)
   {
	   SellStop = High[iHighest(NULL, 0, MODE_HIGH, BarsBack, 0)];
      pAsk = MarketInfo(Symbol(),MODE_ASK);
		if (digits > 0) SellStop = NormalizeDouble(SellStop, digits); 
		SellStop = ValidStopLoss(OP_SELL, pAsk, SellStop);
      if( (op >= SellStop && os > SellStop) || os==0) 
      {
          myOrderModify(type,ticket,op,SellStop,tp,DarkOrange);
			 return;
      }
   }
}
//+------------------------------------------------------------------+
//| Handle Open Positions                                            |
//| Check if any open positions need to be closed or modified        |
//+------------------------------------------------------------------+
int HandleOpenPositions()
{
   int cnt;
   
   for(cnt=OrdersTotal()-1;cnt>=0;cnt--)
   {
      OrderSelect (cnt, SELECT_BY_POS, MODE_TRADES);
      if ( OrderSymbol() != Symbol()) continue;
      if ( OrderMagicNumber() != MagicNumber)  continue;
      
      if(OrderType() == OP_BUY)
      {
         //if ( !TimeCondition()) 
         // {
         //      OrderClose(OrderTicket(),OrderLots(),Bid, Slippage, Violet);
         // }
          
         if ( BuyExitSignal()) // && Close[0] < upper)
          {
               OrderClose(OrderTicket(),OrderLots(),Bid, Slippage, Violet);
          }
          else
          {
            if (UseTrailingStop)
            {
               HandleTrailingStop(OP_BUY,OrderTicket(),OrderOpenPrice(),OrderStopLoss(),OrderTakeProfit());
            }
          }
      }

      if(OrderType() == OP_SELL)
      {
         // if ( !TimeCondition())
         // {
         //    OrderClose(OrderTicket(),OrderLots(),Ask, Slippage, Violet);
         // }
          if (SellExitSignal()) //&& Close[0] > lower)
          {
             OrderClose(OrderTicket(),OrderLots(),Ask, Slippage, Violet);
          }
          else
          {
             if(UseTrailingStop)  
             {                
               HandleTrailingStop(OP_SELL,OrderTicket(),OrderOpenPrice(),OrderStopLoss(),OrderTakeProfit());
             }
          }
       }
   }
}

     
//+------------------------------------------------------------------+
//| Get number of lots for this trade                                |
//+------------------------------------------------------------------+ 465
double GetLots()
{
   double lot;
   
   if(MoneyManagement)
   {
     lot = LotsOptimized();
   }
   else
   {
     lot = Lots;
   }
   
   if(AccountIsMini)
   {
     if (lot < 0.1) lot = 0.1;
   }
   else
   {
     if (lot >= 1.0) lot = MathFloor(lot); else lot = 1.0;
   }
   if (lot > MaxLots) lot = MaxLots;
   
   return(lot);
}

//+------------------------------------------------------------------+
//| Calculate optimal lot size                                       |
//+------------------------------------------------------------------+ 494

double LotsOptimized()
  {
   double lot=Lots;
//---- select lot size
   lot=NormalizeDouble(MathFloor(AccountFreeMargin()*TradeSizePercent/10000)/10,1);
   
  
  // lot at this pointvalue is number of standard lots
  
//  if (Debug) Print ("Lots in LotsOptimized : ",lot);
  
  // Check if mini or standard Account
  
  if(AccountIsMini)
  {
    lot = MathFloor(lot*10)/10;
    
   }
   return(lot);
  }

//+------------------------------------------------------------------+
//| Time frame interval appropriation  function                      |
//+------------------------------------------------------------------+ 519

int func_TimeFrame_Const2Val(int Constant ) {
   switch(Constant) {
      case 1:  // M1
         return(1);
      case 5:  // M5
         return(2);
      case 15:
         return(3);
      case 30:
         return(4);
      case 60:
         return(5);
      case 240:
         return(6);
      case 1440:
         return(7);
      case 10080:
         return(8);
      case 43200:
         return(9);
   }
}

//+------------------------------------------------------------------+
//| Time frame string appropriation  function                        |
//+------------------------------------------------------------------+546

string func_TimeFrame_Val2String(int Value ) {
   switch(Value) {
      case 1:  // M1
         return("PERIOD_M1");
      case 2:  // M1
         return("PERIOD_M5");
      case 3:
         return("PERIOD_M15");
      case 4:
         return("PERIOD_M30");
      case 5:
         return("PERIOD_H1");
      case 6:
         return("PERIOD_H4");
      case 7:
         return("PERIOD_D1");
      case 8:
         return("PERIOD_W1");
      case 9:
         return("PERIOD_MN1");
   	default: 
   		return("undefined " + Value);
   }
}

int func_Symbol2Val(string symbol) {
   string mySymbol = StringSubstr(symbol,0,6);
	if(mySymbol=="AUDCAD") return(1);
	if(mySymbol=="AUDJPY") return(2);
	if(mySymbol=="AUDNZD") return(3);
	if(mySymbol=="AUDUSD") return(4);
	if(mySymbol=="CHFJPY") return(5);
	if(mySymbol=="EURAUD") return(6);
	if(mySymbol=="EURCAD") return(7);
	if(mySymbol=="EURCHF") return(8);
	if(mySymbol=="EURGBP") return(9);
	if(mySymbol=="EURJPY") return(10);
	if(mySymbol=="EURUSD") return(11);
	if(mySymbol=="GBPCHF") return(12);
	if(mySymbol=="GBPJPY") return(13);
	if(mySymbol=="GBPUSD") return(14);
	if(mySymbol=="NZDUSD") return(15);
	if(mySymbol=="USDCAD") return(16);
	if(mySymbol=="USDCHF") return(17);
	if(mySymbol=="USDJPY") return(18);
	return(19);
}

//+------------------------------------------------------------------+ 596