//+------------------------------------------------------------------+
//|                                                    RobinHood.mq4 |
//|                                    Copyright © 2009, Robert Hill |
//|                                                                  |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2009, Robert Hill"
#property link      ""
#include <stdlib.mqh>
#include <stderror.mqh> 

// Define signal types
#define NONE 0
#define LONG 1
#define SHORT 2
#define CLOSEBUY 3
#define CLOSESELL 4

//---- input parameters
extern int       MagicBase=10000;
extern string    myComment = "Robin Hood";
extern int       Slippage = 3;
 
extern int ShowText = 1;

extern int     StochK1=120;
extern string  p1 = "PriceField";
extern string  p2 = " Use 0 for Low/High";
extern string  p3 = " Use 1 for Close/Close";
extern int     StochPrice1 = 0;
extern int     ovrbotlevel1=85;
extern int     ovrsoldlevel1=10;
extern int     UseCancelRule = 1;
extern int     CancelBuyLevel = 70;
extern int     CancelSellLevel = 25;
extern int     StochK2 = 15;
extern int     StochPrice2 = 0;
extern int     ovrbotlevel2=40;
extern int     TargetBotLevel2 = 95;
extern int     ovrsoldlevel2=70;
extern int     TargetSoldLevel2 = 5;

extern int     StopLoss = 35;
extern int     TakeProfit = 50;

extern string  tsp = "--Trailing Stop Types--";
extern string  tsp0 = " 0 = Do not trail";
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 int     TrailingStopType = 2;

extern string  ts2 = "Settings for Type 2";
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 = 10;        // Type 3  first level pip gain
extern double  FirstStopLoss = 30;    // Move Stop to Breakeven
extern double  SecondMove = 25;       // Type 3 second level pip gain
extern double  SecondStopLoss = 20;   // Move stop to lock is profit
extern double  ThirdMove = 35;        // type 3 third level pip gain
extern double  TrailingStop3 = 15;    // Move stop and trail from there

extern string  ts4 = "Settings for Type 4";
extern double  BreakEven = 25;
extern int     LockInPips = 10;        // Profit Lock in pips

//+---------------------------------------------------+
//|Money Management                                   |
//+---------------------------------------------------+
extern string  mm = "---Money Management---";
extern double  Lots=0.01;
extern bool    UseMoneyManagement = false; // Change to false to shutdown money management controls.
extern bool    BrokerIsIBFX = true;
extern bool    BrokerIsCrownForex = false;
extern string  m1="Set mini and micro to false for standard account";
extern bool    AccountIsMini = false;
extern bool    AccountIsMicro = true;
extern double  TradeSizePercent = 1;  // Change to whatever percent of equity you wish to risk.
extern bool    BrokerPermitsFractionalLots = true;

extern string  ef3="Friday No Trade - Enter 0 for false, 1 for true";
extern int    UseFridayNoTradeTime = 0;
extern int     FridayFinalHour = 20;   // No trades to start after time
int            FridayFinalTime;              // No trades to start after time

extern string  sm0="--Trading Hours Filter--";
extern string  sm2="UseTradingHours - Enter 0 for false, 1 for true";
extern int    UseTradingHours = 0;
extern string  sm4="TradeAsian - Enter 0 for false, 1 for true";
extern int    TradeAsianMarket = 1;
extern int     AsianStart = 100;       // Start trades after time
extern int     AsianStop = 400;      // Stop trading after time
extern string  sm5="Trade Europe - Enter 0 for false, 1 for true";
extern int    TradeEuropeanMarket = 1;
extern int     EurStart = 1000;       // Start trades after time
extern int     EurStop = 1200;      // Stop trading after time
extern string  sm6="Trade NY - Enter 0 for false, 1 for true";
extern int    TradeNewYorkMarket = 1;
extern int     NYStart = 1600;       // Start trades after time
extern int     NYStop = 1800;      // Stop trading after time

extern string  to="---Text Object Settings---";
extern int 		StatusTxtSize = 10;
extern color 	StatusColor  = White;
extern int 		CommentTxtSize = 10;
extern color 	CommentColor   = White;
extern int 		TrendTxtSize = 10;
extern color 	TrendColor   = White;
extern int 		LookingTxtSize = 10;
extern color 	LookingColor = White;
extern int 		FoundTxtSize = 10;
extern color 	FoundColor   = White;
extern int 		WaitingTxtSize = 10;
extern color 	WaitingColor = White;
extern int 		ConditionTxtSize = 10;
extern color 	ConditionColor  = White;
extern int 		TradeTxtSize = 10;
extern color   TradeColor  = White;
extern int 		DrawDownTxtSize = 10;
extern color 	DrawDownColor = White;
extern color   MarkColor = Red;
int            StatusY, Comment1Y, TrendY;
int            LookingY, FoundY, ConditionY;
int            Trade1Y, Trade2Y, Trade3Y, Trade4Y;
string         StatusLabel, Comment1Label,  TrendLabel;
string         LookingLabel, FoundLabel, ConditionLabel;
string         Trade1Label, Trade2Label, Trade3Label, Trade4Label, MarkLabel;

string StatusStr = "Robin Hood";
double myPoint;

int MagicNumber;
bool rule1;
double mLots; 
int LastTrade = NONE;

//+------------------------------------------------------------------+
//| expert initialization function                                   |
//+------------------------------------------------------------------+
int init()
  {

	  MagicNumber = MagicBase + func_Symbol2Val(Symbol())*100 + Period();

     if (ShowText == 1)
     {
       DeleteExistingLabels();
       SetupLabels();
       ClearLabels();
       OutputStatusToChart(StatusStr + " INITIALIZED SUCCESSFULLY");
     }
     myPoint = SetPoint();
     rule1 = NONE;
   
   return(0);
  }

//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+
int start()
  {
  //***********ADDED FOR ACCOUNT SENTRY ***************

    if (GlobalVariableGet("GV_CloseAllAndHalt") > 0) {
        return (0);
    } else

  //***********END ACCOUNTSENTRY HOOK ***************

  bool YesStop;
  
   int NumOrders = 0,  signal = 0;

   if (ShowText == 1)
   {
   if (Comment1Y < 10)
   {
     SetupLabels();
     ClearLabels();
     DeleteExistingLabels();
     SetupLabels();// Make sure label settings are OK
   }
   }
   if (IsTesting() == false)
   {
     if (IsExpertEnabled() == false)
     {
     if (ShowText == 1)
     {
      OutputComment1ToChart("Expert is not enabled");
      }
      return(0);
     }
   }
   if (IsTradeAllowed()==false ) return(0);
   

  NumOrders = CalculateCurrentOrders();
  if (NumOrders == 0)
  {
     if (ShowText == 1)
     {
     ClearWorkingLabels();
     }
     YesStop = CheckTradeFilters();
     if (YesStop == false)
     {
       if (!NewBar()) return(0); // wait until first tick after bar close to take any action; 
       signal = GetEntrySignal();
       if (signal != NONE)
       {
        mLots = GetLots();
        if (LastTrade == NONE) OpenNewTrades(signal, mLots);
        if (LastTrade == LONG && signal == SHORT) OpenNewTrades(signal, mLots);
        if (LastTrade == SHORT && signal == LONG) OpenNewTrades(signal, mLots);
       }
     }
     else
        rule1 = NONE;
  }
  else
  {
     RefreshRates();
     CheckForClose();
  }
  return(0);
}

int CheckStochRule1()
{
  // Indicator values
   double StochMain1, StochMain2;

   StochMain1 = iStochastic(NULL, 0, StochK1, 3, 3, MODE_SMA, StochPrice1, MODE_MAIN, 1);
//   StochSignal11 = iStochastic(NULL, 0, StochK1, 3, 3, MODE_SMA, StochPrice1, MODE_SIGNAL, 1);
   StochMain2 = iStochastic(NULL, 0, StochK2, 3, 3, MODE_SMA, StochPrice2, MODE_MAIN, 1);
//   StochSignal21 = iStochastic(NULL, 0, StochK2, 3, 3, MODE_SMA, StochPrice2, MODE_SIGNAL, 1);
   
   if (StochMain1 > ovrbotlevel1)
   {
      if (StochMain2 > ovrbotlevel2) return(LONG);
   }
   if (StochMain1 < ovrsoldlevel1)
   {
       if (StochMain2 < ovrsoldlevel2) return(SHORT);
   }
   return(NONE);
   
}

bool CheckStochRule2(int cmd)
{
   double StochMain;

   StochMain = iStochastic(NULL, 0, StochK2, 3, 3, MODE_SMA, StochPrice2, MODE_MAIN, 1);
//   StochSignal21 = iStochastic(NULL, 0, StochK2, 3, 3, MODE_SMA, StochPrice2, MODE_SIGNAL, 1);
   
   if (cmd == LONG)
   {
      if (StochMain > ovrbotlevel2)
      {
         if (ShowText == 1)
         {
            OutputFoundToChart("Stoch 2 Still above target");
         }
         return(false);
      }
      return(true);
   }
   
   if (cmd == SHORT)
   {
      if (StochMain < ovrsoldlevel2)
      {
          if (ShowText == 1)
          {
            OutputFoundToChart("Stoch 2 Still below target");
          }
          return(false);
      }
      return(true);
   }
   return(false);
}

bool CheckStochRuleC(int cmd)
{
   double StochMain;

   StochMain = iStochastic(NULL, 0, StochK1, 3, 3, MODE_SMA, StochPrice1, MODE_MAIN, 1);
//   StochSignal11 = iStochastic(NULL, 0, StochK1, 3, 3, MODE_SMA, StochPrice1, MODE_SIGNAL, 1);
   
   if (cmd == LONG)
   {
      if (StochMain < CancelBuyLevel) return(true);
   }
   if (cmd == SHORT)
   {
      if (StochMain > CancelSellLevel) return(true);
   }
   return(false);
   
}

int GetEntrySignal()
{
   bool rule2 = false, rulec;

   if (rule1 == NONE) rule1 = CheckStochRule1();

    if (rule1 == NONE)
    {
      if (ShowText == 1)
      {
        ClearWorkingLabels();
        OutputTrendToChart("Stoch 1 is neutral");
      }
      return(NONE);
    }

  
  if (rule1 == LONG)
  {
     if (ShowText == 1)
     {
       OutputTrendToChart("Stoch 1 overbought");
       OutputLookingToChart( "Looking for Stoch 2 peak" );
     }
     
     if (UseCancelRule == 1)
     {
        rulec = CheckStochRuleC(LONG);
        if (rulec == true)
        {
          OutputTrendToChart("Stoch 1 below cancel");
          rule1 = NONE;
          return(NONE);
        }
     }
     
     rule2 = CheckStochRule2(LONG);
     if (rule2 == false) return(NONE);
     if (ShowText == 1)
     {
       OutputFoundToChart("Stoch 2 Peak found");
     }
     
     rule1 = NONE;
     if (ShowText == 1)
     {
       OutputConditionToChart("All conditions met, entering " + isUpOrDown(LONG) + " trade");
     }
     return(LONG);
  }
  
  if (rule1 == SHORT)
  {
     if (ShowText == 1)
     {
       OutputTrendToChart("Stoch 1 oversold");
       OutputLookingToChart( "Looking for Stoch 2 trough" );
     }
     
     if (UseCancelRule == 1)
     {
        rulec = CheckStochRuleC(SHORT);
        if (rulec == true)
        {
          OutputTrendToChart("Stoch 1 below cancel");
          rule1 = NONE;
          return(NONE);
        }
     }

     rule2 = CheckStochRule2(SHORT);
     if (rule2 == false) return(NONE);
     if (ShowText == 1)
     {
       OutputFoundToChart("Stoch 2 Trough found");
     }
     
     rule1 = NONE;
     if (ShowText == 1)
     {
       OutputConditionToChart("All conditions met, entering " + isUpOrDown(SHORT) + " trade");
     }

     return (SHORT);
  }
  return(NONE);
}

int GetExitSignal(int cmd)
{
   double StochMain;
   
   StochMain = iStochastic(NULL, 0, StochK2, 3, 3, MODE_SMA, StochPrice2, MODE_MAIN, 1);
//   StochSignal = iStochastic(NULL, 0, StochK2, 3, 3, MODE_SMA, StochPrice2, MODE_SIGNAL, 1);
   
   if (cmd == OP_BUY)
   {
     if (StochMain >= TargetBotLevel2) return(CLOSEBUY); //red HA candle
   }
   
   if (cmd == OP_SELL)
   {
     if (StochMain <= TargetSoldLevel2) return(CLOSESELL); //green HA candle
   }
    
   return(NONE);
   
}


void OpenNewTrades(int mSignal, double mLots)
{
  int ticket, err;
  double TPprice,STprice;
  double OrderOP;
      
   RefreshRates();
   
// Place new trades

   
    if (mSignal == SHORT)
    { 
    
      ticket=OrderSend(Symbol(),OP_SELL,mLots,Bid,Slippage * myPoint,0,0,
                  myComment,MagicNumber,0,Red); //Sell at Market price
      if (ticket > 0)
      {
         LastTrade = SHORT;
         OrderSelect(ticket, SELECT_BY_TICKET, MODE_TRADES);
         OrderOP = OrderOpenPrice();
         if (StopLoss != 0 || TakeProfit != 0)
	      {
            TPprice = 0;
            if (TakeProfit > 0)
            {
               TPprice=TakeShort(OrderOP, TakeProfit);
            }
            STprice = 0;
            if (StopLoss > 0)
            {
              STprice=StopShort(OrderOP, StopLoss);
		        STprice = ValidStopLoss(OP_SELL,Ask, STprice);
		      }   
 // Normalize stoploss / takeprofit to the proper # of digits.
            if (Digits > 0) 
            {
              STprice = NormalizeDouble( STprice, Digits);
              TPprice = NormalizeDouble( TPprice, Digits); 
            }
		      ModifyOrder(ticket, OrderOP, STprice, TPprice, LightGreen);
         } 
         if (ShowText == 1)
         {
         OutputTrade1ToChart("Ticket : " + ticket);
         OutputTrade2ToChart(" SELL : " + DoubleToStr(mLots, 2) + " Lots at " + DoubleToStr(OrderOpenPrice(), Digits));
         }
      }
    }
    
    if (mSignal == LONG)   
    {
      ticket=OrderSend(Symbol(),OP_BUY,mLots,Ask,Slippage * myPoint,0,0,
                   myComment,MagicNumber,0,Lime); //Buy at Market price
      if (ticket > 0)
      {
         LastTrade = LONG;
         OrderSelect(ticket, SELECT_BY_TICKET, MODE_TRADES);
         OrderOP = OrderOpenPrice();
         if (StopLoss != 0 || TakeProfit != 0)
	      {
            TPprice = 0;
            if (TakeProfit > 0)
            {
              TPprice=TakeLong(OrderOP,TakeProfit);
            }
            STprice = 0;
            if (StopLoss > 0)
            {
              STprice=StopLong(OrderOP ,StopLoss);
		        STprice = ValidStopLoss(OP_BUY,Bid, STprice); 
		      }  
 // Normalize stoploss / takeprofit to the proper # of digits.
            if (Digits > 0) 
            {
              STprice = NormalizeDouble( STprice, Digits);
              TPprice = NormalizeDouble( TPprice, Digits); 
            }
		      ModifyOrder(ticket, OrderOP, STprice, TPprice, Red);
         }
         if (ShowText == 1)
         {
         OutputTrade1ToChart("Ticket : " + ticket);
         OutputTrade2ToChart(" BUY : " + DoubleToStr(mLots, 2) + " Lots at " + DoubleToStr(OrderOpenPrice(), Digits));
         }
      }
    }
   if(ticket<0)
   {
     err = GetLastError();
     if (ShowText == 1)
     {
     OutputTrade1ToChart("OrderSend failed : (" +  err + ")");
     OutputTrade2ToChart(ErrorDescription(err));
     }
   }
}


void CheckForClose()
{
   int Signal, result, err;
   
// Check for open trades to close or modify

    for(int cnt=OrdersTotal()-1;cnt>=0;cnt--)
    {
      OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);
      if (OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber)
      {
        Signal = GetExitSignal(OrderType());
        result = true;
        if(OrderType() == OP_BUY)
        {
           if (Signal == CLOSEBUY)
           {
              result = OrderClose(OrderTicket(), OrderLots(), Bid, 3, Red);
           }
           else
              if (TrailingStopType > 0) HandleTrailingStop(OP_BUY,OrderTicket(),OrderOpenPrice(),OrderStopLoss(),OrderTakeProfit());
 
        }
        if(OrderType() == OP_SELL)
        {
           if (Signal == CLOSESELL)
           {
             result = OrderClose(OrderTicket(), OrderLots(), Ask, 3, Lime);
           }
           else
             if (TrailingStopType > 0) HandleTrailingStop(OP_SELL,OrderTicket(),OrderOpenPrice(),OrderStopLoss(),OrderTakeProfit());
 
        }
        if (result == false)
        {
		     err = GetLastError();
           if (ShowText == 1)
           {
             OutputTrade3ToChart(" Error closing order : (" +  err + ")");
             OutputTrade4ToChart(ErrorDescription(err));
           }
        }
        
      }
    }
 }
//----

//+------------------------------------------------------------------+
//| 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 5 uses steps for 1, every step pip move moves stop 1 pip    |
//| Type 6 Uses EMA to set trailing stop                             |
//+------------------------------------------------------------------+
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;
	}
   return(0);
}

int ModifyOrder(int ord_ticket,double op, double oSL, double oTP, color mColor)
{
    int CloseCnt, err;
    double myStop, myTake;
    
/*
    if (Digits > 0)
    {
       myStop = NormalizeDouble( oSL, Digits);
       myTake = NormalizeDouble( oTP, Digits);
    }
*/
    CloseCnt=0;
    while (CloseCnt < 3)
    {
       if (OrderModify(ord_ticket,op,oSL,oTP,0,mColor))
       {
         CloseCnt = 3;
       }
       else
       {
          err=GetLastError();
          Print(CloseCnt," Error modifying order : (", err , ") " + ErrorDescription(err));
         if (err>0) CloseCnt++;
       }
    }
}

double ValidStopLoss(int type, double price, double SL)
{

   double mySL;
   double minstop;
   
   if (SL < 0.1) return(SL);
   
   mySL = SL;
   minstop = MarketInfo(Symbol(),MODE_STOPLEVEL);
   if (Digits == 3 || Digits == 5) minstop = minstop / 10;
   if (type == OP_BUY)
   {
		 if((price - SL) < minstop*myPoint) mySL = price - minstop*myPoint;
   }
   if (type == OP_SELL)
   {
       if((SL-price) < minstop*myPoint)  mySL = price + minstop*myPoint;  
   }

   return(NormalizeDouble(mySL,MarketInfo(Symbol(), MODE_DIGITS)));   
}

//+------------------------------------------------------------------+
//|                                       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 * myPoint;
     if(pBid-os > pt)
     {
       BuyStop = pBid - pt;
       if (digits > 0) BuyStop = NormalizeDouble( BuyStop, digits);
		 BuyStop = ValidStopLoss(OP_BUY,pBid, BuyStop);   
       if (os < BuyStop) ModifyOrder(ticket,op,BuyStop,tp,LightGreen);
		 return;
	  }
   }
   if (type==OP_SELL)
   {
     pAsk = MarketInfo(Symbol(), MODE_ASK);
     pt = StopLoss * myPoint;
     if(os - pAsk > pt)
     {
       SellStop = pAsk + pt;
       if (digits > 0) SellStop = NormalizeDouble( SellStop, digits);
       SellStop = ValidStopLoss(OP_SELL, pAsk, SellStop);  
       if (os > SellStop) ModifyOrder(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 * myPoint;
   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) ModifyOrder(ticket,op,BuyStop,tp,LightGreen);
	  return;
   }
   if (type==OP_SELL)
   {
     pAsk = MarketInfo(Symbol(), MODE_ASK);
     pt = TrailingStop * myPoint;
     SellStop = pAsk + pt;
     if (digits > 0) SellStop = NormalizeDouble( SellStop, digits);
     SellStop = ValidStopLoss(OP_SELL, pAsk, SellStop);  
     if (op - pAsk > pt && os > SellStop) ModifyOrder(ticket,op,SellStop,tp,DarkOrange);
	  return;
   }   
}
 
//+------------------------------------------------------------------+
//|                                           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 > myPoint*BreakEven ) 
    {
       BuyStop = op + LockInPips * myPoint;
       if (digits > 0) BuyStop = NormalizeDouble( BuyStop, digits);
		 BuyStop = ValidStopLoss(OP_BUY,pBid, BuyStop);   
       if (os < BuyStop) ModifyOrder(ticket,op,BuyStop,tp,LightGreen);
		 return;
	 }
  }
  if (type==OP_SELL)
  {
    pAsk = MarketInfo(Symbol(), MODE_ASK);
    if ( op - pAsk > myPoint*BreakEven ) 
    {
       SellStop = op - LockInPips * myPoint;
       if (digits > 0) SellStop = NormalizeDouble( SellStop, digits);
       SellStop = ValidStopLoss(OP_SELL, pAsk, SellStop);  
       if (os > SellStop) ModifyOrder(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 * myPoint)
      {
         BuyStop = op + FirstMove*myPoint - FirstStopLoss * myPoint;
         if (digits > 0) BuyStop = NormalizeDouble(BuyStop, digits); 
		   BuyStop = ValidStopLoss(OP_BUY, pBid, BuyStop);   
         if (os < BuyStop) ModifyOrder(ticket,op,BuyStop,tp,LightGreen);
      }
              
      if (pBid - op > SecondMove * myPoint)
      {
         BuyStop = op + SecondMove*myPoint - SecondStopLoss * myPoint;
         if (digits > 0) BuyStop = NormalizeDouble(BuyStop, digits); 
		   BuyStop = ValidStopLoss(OP_BUY, pBid, BuyStop);   
         if (os < BuyStop) ModifyOrder(ticket,op,BuyStop,tp,LightGreen);
      }
                
      if (pBid - op > ThirdMove * myPoint)
      {
         BuyStop = pBid  - ThirdMove*myPoint;
         if (digits > 0) BuyStop = NormalizeDouble(BuyStop, digits); 
		   BuyStop = ValidStopLoss(OP_BUY, pBid, BuyStop);   
         if (os < BuyStop) ModifyOrder(ticket,op,BuyStop,tp,LightGreen);
      }
   }
       
    if (type ==  OP_SELL)
    {
        pAsk = MarketInfo(Symbol(), MODE_ASK);
        if (op - pAsk > FirstMove * myPoint)
        {
           SellStop = op - FirstMove * myPoint + FirstStopLoss * myPoint;
           if (digits > 0) SellStop = NormalizeDouble(SellStop, digits); 
		     SellStop = ValidStopLoss(OP_SELL, pAsk, SellStop);   
           if (os > SellStop) ModifyOrder(ticket,op,SellStop,tp,DarkOrange);
        }
        if (op - pAsk > SecondMove * myPoint)
        {
           SellStop = op - SecondMove * myPoint + SecondStopLoss * myPoint;
           if (digits > 0) SellStop = NormalizeDouble(SellStop, digits); 
		     SellStop = ValidStopLoss(OP_SELL, pAsk, SellStop);   
           if (os > SellStop) ModifyOrder(ticket,op,SellStop,tp,DarkOrange);
        }
        if (op - pAsk > ThirdMove * myPoint)
        {
           SellStop = pAsk + ThirdMove * myPoint;               
           if (digits > 0) SellStop = NormalizeDouble(SellStop, digits); 
		     SellStop = ValidStopLoss(OP_SELL, pAsk, SellStop);   
           if (os > SellStop) ModifyOrder(ticket,op,SellStop,tp,DarkOrange);
        }
    }

}


//-- Check for Start of a new Bar
bool NewBar()
{
   static datetime dt = 0;
   
   if (Time[0] != dt)
   {
      dt = Time[0];
      return(true);
   }
   return(false);
}

double StopLong(double price,int stop)
{
 if(stop==0)
  return(0);
 else
  return(price-(stop*myPoint));
}

double StopShort(double price,int stop)
{
 if(stop==0)
  return(0);
 else
  return(price+(stop*myPoint));
}

double TakeLong(double price,int take)
{
 if(take==0)
  return(0);
 else
  return(price+(take*myPoint));
}

double TakeShort(double price,int take)
{
 if(take==0)
  return(0);
 else
  return(price-(take*myPoint));
}

int CalculateCurrentOrders()
{
   int buys = 0, sells = 0, num = 0;
   for(int i=OrdersTotal()-1;i>=0;i--)
   {
      OrderSelect(i,SELECT_BY_POS,MODE_TRADES);
      if(OrderSymbol()== Symbol() && OrderMagicNumber()== MagicNumber)
      {
        if(OrderType() == OP_BUY)  buys++;
        if(OrderType() == OP_SELL) sells++;
      }
   }
     
   num = buys + sells;
   return(num);
}

//+------------------------------------------------------------------+
//| expert deinitialization function                                 |
//+------------------------------------------------------------------+
int deinit()
  {
   if (ShowText == 1)
   {
     ClearLabels();
     DeleteExistingLabels();
   }
  return(0);
  }  

//+------------------------------------------------------------------+
//| Get number of lots for this trade                                |
//+------------------------------------------------------------------+
double GetLots()
{
   double lot;
   double myMaxLot = MarketInfo(Symbol(), MODE_MAXLOT);
   
   if(UseMoneyManagement == false) return(Lots);

   if (BrokerIsIBFX == true)
   {
     lot = Calc_IBFX_Money_Management();
     return(lot);
   }
   
   if (BrokerIsCrownForex == true)
   {
     lot = Calc_CrownMoney_Management();
     return(lot);
   }
//   lot = LotsOptimized();
   lot=NormalizeDouble((AccountEquity()*TradeSizePercent/10000)/10,2);

//   lot = MathRound( lot/myStep ) * myStep;

// Use at least 1 micro lot
   if (AccountIsMicro == true)
   {
      lot = MathFloor(lot*100)/100;
      if (lot < 0.01) lot = 0.01;
      if (lot > myMaxLot) lot = myMaxLot;
      return(lot);
   }

// Use at least 1 mini lot
   if(AccountIsMini == true)
   {
      lot = MathFloor(lot*10)/10;
      if (lot < 0.1) lot = 0.1;
      if (lot > myMaxLot) lot = myMaxLot;
      return(lot);
   }
   
// Standard account   
   if( BrokerPermitsFractionalLots == false)
   {
      if (lot >= 1.0) lot = MathFloor(lot); else lot = 1.0;
   }
   
   if (lot < 1.0) lot = 1.0;
   if (lot > myMaxLot) lot = myMaxLot;

   return(lot);
}

double Calc_CrownMoney_Management()
{
   double lot;

   lot=NormalizeDouble((AccountEquity()*TradeSizePercent/10000)/10,1);

//   lot = MathRound( lot/myStep ) * myStep;

// Use at least 1 mini lot
   if(AccountIsMini == true)
   {
      lot = MathFloor(lot*10)/10 * 10000;
      if (lot < 10000) lot = 10000;
//      if (lot > myMaxLot) lot = myMaxLot;
      return(lot);
   }
   
// Standard account   
   
   lot = lot * 100000;
   if (lot < 100000) lot = 100000;
//   if (lot > myMaxLot) lot = myMaxLot;

   return(lot);
}

double Calc_IBFX_Money_Management()
{
// variables used for money management
   double lot;
   double myMaxLot = MarketInfo(Symbol(), MODE_MAXLOT);

   lot=NormalizeDouble((AccountEquity()*TradeSizePercent/10000)/10,2);
   
// Use at least 1 micro lot
   if (AccountIsMicro == true)
   {
      lot = lot * 10;
      lot = MathFloor(lot*100)/100;
      if (lot < 0.1) lot = 0.1;
      if (lot > myMaxLot) lot = myMaxLot;
      return(lot);
   }

// Use at least 1 mini lot
   if(AccountIsMini == true)
   {
      lot = lot * 10;
      lot = MathFloor(lot*10)/10;
      if (lot < 1) lot = 1;
      if (lot > myMaxLot) lot = myMaxLot;
      return(lot);
   }
   
   // Standard Account
   
   if(BrokerPermitsFractionalLots == true)
        lot = StrToDouble(DoubleToStr(lot, 2));
   else
        lot = MathFloor(lot);
   
   if (lot > myMaxLot) lot = myMaxLot;

   return(lot); 
}

double SetPoint()
{
   double mPoint;
   
   if (Digits < 4)
      mPoint = 0.01;
   else
      mPoint = 0.0001;
   
   return(mPoint);
}

string isUpOrDown(int i)
{
   if(i==LONG) return ("LONG"); else if (i==SHORT) return("SHORT");
}

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=="NZDJPY") return(15);
	if(mySymbol=="NZDUSD") return(16);
	if(mySymbol=="USDCAD") return(17);
	if(mySymbol=="USDCHF") return(18);
	if(mySymbol=="USDJPY") return(19);
   Comment("unexpected Symbol");
	return(999);
}

string tf2txt(int tf)
{
   switch(tf)
   {
      case PERIOD_M1: return("M1");
      case PERIOD_M5: return("M5");
      case PERIOD_M15: return("M15");
      case PERIOD_M30: return("M30");
      case PERIOD_H1: return("H1");
      case PERIOD_H4: return("H4");
      case PERIOD_D1: return("D1");
      case PERIOD_W1: return("W1");
      case PERIOD_MN1: return("MN");
   
   }
   return("??");
}

//+------------------------------------------------------------------+
//|                                                   Labels_inc.mqh |
//|                                                 Copyright © 2007 |
//|                                                                  |
//+------------------------------------------------------------------+

void OutputMarkToChart(int yPos, int TxtSize, string myMark)
{
  	if(ObjectFind(MarkLabel) != 0)
   {
   ObjectCreate(MarkLabel, OBJ_LABEL, 0, 0, 0);
   }
	ObjectSet(MarkLabel, OBJPROP_CORNER, 0);
	ObjectSet(MarkLabel, OBJPROP_XDISTANCE, 10);
	ObjectSet(MarkLabel, OBJPROP_YDISTANCE, yPos);
	ObjectSetText(MarkLabel,myMark, TxtSize*2, "Arial Bold", MarkColor);
}

void ClearLabels()
{
   string mComment = " ";
   
   OutputStatusToChart( mComment);
   OutputComment1ToChart( mComment);
   OutputTrendToChart( mComment);
   OutputLookingToChart( mComment);
   OutputFoundToChart( mComment);
   OutputConditionToChart( mComment);
   OutputTrade1ToChart( mComment);
   OutputTrade2ToChart( mComment);
   OutputTrade3ToChart( mComment);
   OutputTrade4ToChart( mComment);
}

void ClearWorkingLabels()
{
   string mComment = " ";
   
//   OutputTrendToChart( mComment);
//   OutputLookingToChart( mComment);
//   OutputFoundToChart( mComment);
   OutputConditionToChart( mComment);
   OutputTrade1ToChart( mComment);
   OutputTrade2ToChart( mComment);
   OutputTrade3ToChart( mComment);
   OutputTrade4ToChart( mComment);
}

void DeleteExistingLabels()
{
   int objLabels = ObjectsTotal(OBJ_LABEL);
   string objName;
   string  prefix;

   prefix = "RH_" + Symbol() +  tf2txt(Period());
   
   if (objLabels > 0)
   {
      for (int i = objLabels; i >= 0;i--)
      {
         objName = ObjectName(i);
         if (StringFind(objName,prefix + "Status", 0) >= 0) { ObjectDelete(objName); continue; }  
         if (StringFind(objName,prefix + "Comment1", 0) >= 0) { ObjectDelete(objName); continue; } 
         if (StringFind(objName,prefix + "Trend", 0) >= 0) { ObjectDelete(objName); continue; }
         if (StringFind(objName,prefix + "Looking", 0) >= 0) { ObjectDelete(objName); continue; }
         if (StringFind(objName,prefix + "Found", 0) >= 0) { ObjectDelete(objName); continue; }
         if (StringFind(objName,prefix + "Condition", 0) >= 0) { ObjectDelete(objName); continue; }
         if (StringFind(objName,prefix + "Trade", 0) >= 0) { ObjectDelete(objName); continue; }
         if (StringFind(objName,prefix + "Mark", 0) >= 0)  ObjectDelete(objName);  
      }
   }
}

void SetupLabels()
{
   string  prefix;

   prefix = "HH_" + Symbol() +  tf2txt(Period());
     StatusY = 12;
     Comment1Y = StatusY + StatusTxtSize + 4;
     TrendY = Comment1Y + CommentTxtSize + 4;
     LookingY = TrendY + TrendTxtSize + 4;
     FoundY = LookingY + LookingTxtSize + 4;
     ConditionY = FoundY + FoundTxtSize + 4;
     Trade1Y = ConditionY + ConditionTxtSize + 4;
     Trade2Y = Trade1Y + TradeTxtSize + 4;
     Trade3Y = Trade2Y + TradeTxtSize + 4;
     Trade4Y = Trade3Y + TradeTxtSize + 4;
	  StatusLabel = prefix + "Status";
	  Comment1Label = prefix + "Comment1";
	  TrendLabel = prefix + "Trend"; 
	  LookingLabel = prefix + "Looking";
	  FoundLabel = prefix + "Found";
	  ConditionLabel = prefix + "Condition";
	  Trade1Label = prefix + "Trade1";
	  Trade2Label = prefix + "Trade2";
	  Trade3Label = prefix + "Trade3";
	  Trade4Label = prefix + "Trade4";
	  MarkLabel = prefix + "Mark";
}

void OutputLabelToChart(string LabelName, int LabelY, int LabelTxtSize, color LabelColor, string LabelStr, string MarkString)
{
//  string mtime=Month()+"/"+Day()+" "+Hour()+":"+Minute()+":"+Seconds()+"  ";

  	if(ObjectFind(LabelName) != 0)
   {
   ObjectCreate(LabelName, OBJ_LABEL, 0, 0, 0);
	ObjectSet(LabelName, OBJPROP_CORNER, 0);
	ObjectSet(LabelName, OBJPROP_XDISTANCE, 20);
	ObjectSet(LabelName, OBJPROP_YDISTANCE, LabelY);
	}
	ObjectSetText(LabelName, LabelStr, LabelTxtSize, "Arial Bold", LabelColor);
	OutputMarkToChart(LabelY, LabelTxtSize, MarkString);
}

void OutputStatusToChart(string mComment)
{
   OutputLabelToChart(StatusLabel, StatusY, StatusTxtSize, StatusColor, mComment, "*");
}

void OutputComment1ToChart(string mComment)
{
   OutputLabelToChart(Comment1Label, Comment1Y, CommentTxtSize, CommentColor, mComment, "*");
}

void OutputTrendToChart(string mComment)
{
   OutputLabelToChart(TrendLabel, TrendY, TrendTxtSize, TrendColor, mComment, "*");
}

void OutputLookingToChart(string mComment)
{
   OutputLabelToChart(LookingLabel, LookingY, LookingTxtSize, LookingColor, mComment, "*");
}

void OutputFoundToChart(string mComment)
{
   OutputLabelToChart(FoundLabel, FoundY, FoundTxtSize, FoundColor, mComment, "*");
}

void OutputConditionToChart(string mComment)
{
   OutputLabelToChart(ConditionLabel, ConditionY, ConditionTxtSize, ConditionColor, mComment, "*");
}

void OutputTrade1ToChart(string mComment)
{
   OutputLabelToChart(Trade1Label, Trade1Y, TradeTxtSize, TradeColor, mComment, "*");
}

void OutputTrade2ToChart(string mComment)
{
   OutputLabelToChart(Trade2Label, Trade2Y, TradeTxtSize, TradeColor, mComment, "*");
}

void OutputTrade3ToChart(string mComment)
{
   OutputLabelToChart(Trade3Label, Trade3Y, TradeTxtSize, TradeColor, mComment, "*");
}

void OutputTrade4ToChart(string mComment)
{
   OutputLabelToChart(Trade4Label, Trade4Y, TradeTxtSize, TradeColor, mComment, "*");
}

bool CheckTradeFilters()
{
   bool myStop, Expired;
   
   myStop = false;
   
      
      if (UseTradingHours == 1)
      {
        myStop = CheckTradingTimes();
   
        if (ShowText == 1)
        {
        if (myStop == true)
        {
          OutputComment1ToChart ("Trading has been stopped - wrong time of day");
        }
        else
        {
          OutputComment1ToChart ("Trading has resumed - time is OK");
        }
        }
      }
      else
        if (ShowText == 1)
        {
          OutputComment1ToChart("Trading Time filter not in use");
        }

   
//+------------------------------------------------------------------+
//| Friday No trade zone                                             |
//+------------------------------------------------------------------+
   if (myStop == false)
   {
      if (UseFridayNoTradeTime == 1)
      {
         if(DayOfWeek()==5 && Hour() >= FridayFinalHour)
         {
            myStop = true;
            if (ShowText == 1)
            {
            OutputComment1ToChart ("Trading has been stopped - Friday");
            }
         }
      }
   }

   
   return(myStop);
}


bool IsNotValidTradingTime( int StartHour, int EndHour)
{
  int lHour=Hour() *100+Minute( );
  if(StartHour<=EndHour)
  {
    if(lHour<StartHour || lHour>EndHour) return(true) ;
  }
  else if(lHour>EndHour && lHour<StartHour) return(true) ;
  return(false) ;
}

bool CheckTradingTimes()
{
   bool StopTrading;
   int ct;
   ct = Hour() * 100 + Minute();
   
     StopTrading = true;
// Check trading Asian Market
     if (TradeAsianMarket == 1)
     {
        StopTrading = IsNotValidTradingTime(AsianStart, AsianStop);
     }
     if (StopTrading == true)
     {
// Check trading European Market
       if (TradeEuropeanMarket == 1)
       {
         StopTrading = IsNotValidTradingTime(EurStart, EurStop);
       }
     }
     if (StopTrading == true)
     {
// Check trading New York Market
       if (TradeNewYorkMarket == 1)
       {
         StopTrading = IsNotValidTradingTime(NYStart, NYStop);
       }
     }
     
     return(StopTrading);
}
//----




