//+------------------------------------------------------------------+
//| Collaboration: Dolly + Isakas + Nina System (DIN)                |
//|                                         DIN_KusKus_EA.mq4        |
//|                                              Copyright © 2007    |
//|                                                                  |
//|    Written by Robert Hill aka MrPip for Forex-tsd group          |
//|                                                                  |
//| Version 1.0                                                      |
//|  Indicators                                                      |
//|     Heiken_Ashi_Ma, Fisher_m11, BBands_Stop_v2                   |
//|                                                                  |
//|  Includes 6 different types of trailing stops                    |
//|  Code from IgorAD, KimIV and MrPip modified to be functions      |
//|                                                                  |
//| Version 1.1                                                      |
//|   Added pSAR trailing stop                                       |
//|                                                                  |
//| Version 2.0                                                      |
//|  Added check for trend on daily and 4 hr timeframe using         |
//|  code from GMACD and HMA3 indicator                              |
//|  Added Hist_StepMA_Stoch_KV1_Ex_03 indicator                     |
//|  Added Nina EMA check for entry                                  |
//|                                                                  |
//| Version 2.1                                                      |
//|   Added FlatTrend_w_MACD+ indicator                              |
//|                                                                  |
//| Version 2.2                                                      |
//|   Added inputs for Hist_StepMA_Stoch_KV1_Ex_03                   |
//|   Default values 7, 0.7                                          |
//|                                                                  |
//| Version 2.3                                                      |
//|   Added Stocastic Momentum indicator(SMI)                        |
//|   for use as signal or trend                                     |
//|   Added selection of Entry and Exit trends                       |
//|                                                                  |
//| Version 2.4                                                      |
//|   added Lookback check                                           |
//|   Added check for current candle direction                       |
//|   Removed unused functions                                       |
//|                                                                  |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2007, Robert Hill"
#property link      "http://www.forex-tsd.com/"
#include <stdlib.mqh>

#define UP 1
#define DOWN 2

// Trend indicators
#define NO_FILTER 0
#define MACD_FILTER 1
#define HMA_FILTER 2

//+---------------------------------------------------+
//|Account functions                                  |
//+---------------------------------------------------+
extern bool AccountIsMini = true;      // Change to true if trading mini account
//+---------------------------------------------------+
//|Money Management                                   |
//+---------------------------------------------------+
extern bool    MoneyManagement = true; // 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.1;             // standard lot size. 
extern double  MaxLots = 100;

//+---------------------------------------------------+
//|Indicator Variables                                |
//| Change these to try your own system               |
//| or add more if you like                           |
//+---------------------------------------------------+

extern string  Expert_Name    = "---- DIN_KusKus_EA_v2.6 ----";

extern string  sw="--Switches--";
extern string  sw1=" 0 = OFF, 1 = ON";

// Kuskus Indicators
extern int     useHeikenAshi = 1;
extern int     useBBStop = 1;
extern int     useFish = 1;
extern int     useCurrentCandle = 1;
extern int     useDamianiFilter = 1;

// DIN Indicators
extern int     useTrendEntry = 0;
extern int     useNinaEMA = 1;
extern int     useStepMA = 1;

extern int     useHeikenAshiExit = 0;
extern int     useBBStopExit = 0;
extern int     useFishExit = 1;

extern int     useTrendExit = 1;
extern int     useStepMAExit = 0;

extern string  bb="--BBandsStop settings--";
extern int     Length=20;      // Bollinger Bands Period
extern int     Deviation=2;    // Deviation
extern double  MoneyRisk=1.00; // Offset Factor

extern string  fi="--Fisher settings--";
extern int     RangePeriods=35;
extern double  PriceSmoothing=0.3;    // =0.67 bei Fisher_m10 
extern double  IndexSmoothing=0.3;    // =0.50 bei Fisher_m10

extern string  ha="--Heiken_Ashi_Ma settings--";
extern int     MaMethod  = 1;
extern int     MaPeriod = 15;

extern string  s5="--Damiani Filter settings--";
extern int     Viscosity=10;
extern int     Sedimentation=60;
extern double  Threshold_level=1.4;
extern bool    lag_supressor=true;

extern string  stm="--StepMA_Stoch settings--";
extern int     PeriodWATR=7;
extern double  Kwatr=0.7000;

extern string  em="--EMA setting for entry--";
extern int     EntryMA_Period = 50;

extern string  scc="--CurrentCandle settings--";
extern int     Breakout = 2;

extern string  st1="--Signal_TimeFrame--";
extern string  st2=" 30 or 60 minute";
extern int     Signal_TimeFrame = 30;


extern string  dstr0 = "--Trend Method--";
extern string  dstr1 = " 0 = None";
extern string  dstr2 = " 1 = MACD";
extern string  dstr3 = " 2 = HMA";
extern int     T4_EntryMethod = 2;
extern int     T1_EntryMethod = 2;
extern int     T4_ExitMethod = 2;
extern int     T1_ExitMethod = 2;

extern string  ss="--HMA settings--";
extern int     T4_Period=12;
extern double  T4_Threshold=20;
extern int     T4_PrevShift=3;
extern int     T4_CurShift=1;
extern int     T1_Period=12;
extern double  T1_Threshold=10;
extern int     T1_PrevShift=3;
extern int     T1_CurShift=1;
extern int     HMA_method = 0;
extern int     HMA_price = 0;

extern string  sD="--GMACD settings--";
extern int     FastEMA = 8;
extern int     SlowEMA = 17;
extern int     SignalSMA = 9;
extern int     GMACD_SignalCandle = 0;

extern int     T4_TimeFrame = 240;
extern int     T1_TimeFrame = 1440;

extern string  sm="--Trading Hours--";
extern bool    UseTradingHours = true;
extern bool    TradeAsianMarket = true;
extern int     StartHour1 = 0;       // Start trades after time
extern int     StopHour1 = 3;      // Stop trading after time
extern bool    TradeEuropeanMarket = true;
extern int     StartHour2 = 9;       // Start trades after time
extern int     StopHour2 = 11;      // Stop trading after time
extern bool    TradeNewYorkMarket = false;
extern int     StartHour3 = 15;       // Start trades after time
extern int     StopHour3 = 17;      // Stop trading after time

extern string  hd = " --Delay time--";
extern int     useDelay = 1;
extern int     useDelayAfterWin = 1;
extern int     MinutesToDelay = 180;

//+---------------------------------------------------+
//|Profit controls                                    |
//+---------------------------------------------------+
extern string  st6 = "--Profit Controls--";
extern double  StopLoss = 100;          // Maximum pips willing to lose per position.

extern double  Margincutoff = 500;     // Expert will stop trading if equity level decreases to that level.
extern int     TakeProfit = 50;        // Maximum profit level achieved.
extern int     Slippage = 10;          // Possible fix for not getting filled or closed    
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 = EMA trail";
extern string  tsp7 = " 7 = pSAR trail";
extern bool    UseTrailingStop = false;
extern int     TrailingStopType = 4;

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 = 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 = 30;
extern int     LockInPips = 1;        // Profit Lock in pips

extern string  ts5 = "Settings for Type 5";
extern int     eTrailingStop   = 10;
extern int     eTrailingStep   = 2;

extern string  ts6 = "Settings for Type 6";
extern int     EMATimeFrame    =  30;
extern int     Price           =  0;
extern int     EMAPeriod       = 13;
extern int     EMAShift        =  2;    
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;

//+---------------------------------------------------+
//|General controls                                   |
//+---------------------------------------------------+
string setup;
double lotMM;
int TradesInThisSymbol;
int MagicNumber;
bool YesStop;
datetime StopTime;                 // Time to wait after a trade is stopped out
bool StoppedOut=false;

//+---------------------------------------------------+
//|  Indicator values for signals and filters         |
//|  Add or Change to test your system                |
//+---------------------------------------------------+
// variables used for trend
double  macd_H4, macd_HH4;
double macd_D1, macd_DD1;
double MACurrent, MAPrevious;

 int SignalCandle = 1;
//+------------------------------------------------------------------+
//| expert initialization function                                   |
//+------------------------------------------------------------------+
int init()
  {
   
	MagicNumber = 3000 + func_Symbol2Val(Symbol())*100 + func_TimeFrame_Const2Val(Period()); 

   setup=Expert_Name + Symbol() + "_" + func_TimeFrame_Val2String(func_TimeFrame_Const2Val(Period()));
   
//----
   return(0);
  }
  
//+------------------------------------------------------------------+
//| expert deinitialization function                                 |
//+------------------------------------------------------------------+
int deinit()
  {
   return(0);
  }

//+------------------------------------------------------------------+
//| The functions from this point to the start function are where    |
//| changes are made to test other systems or strategies.            |
//|+-----------------------------------------------------------------+

//+------------------------------------------------------------------+
//| Custom Indicators                                                |
//+------------------------------------------------------------------+


bool CheckHeikenAshi(int cmd)
{
   double haOpen, haClose;
   double haOpenPrev, haClosePrev;

   haOpen = iCustom(NULL, Signal_TimeFrame, "Heiken_Ashi_Ma",MaMethod,MaPeriod,2,SignalCandle);
   haClose = iCustom(NULL, Signal_TimeFrame, "Heiken_Ashi_Ma",MaMethod,MaPeriod,3,SignalCandle);
   switch (cmd)
   {
     case OP_BUY : if (haOpen < haClose)
                   {
                         return (true);
                   }
                   break;
     case OP_SELL : if (haOpen > haClose)
                    {
                         return (true);
                   }
   }
   
   return(false);
}


bool CheckFish(int cmd)
{
   double Fish, FishPrev;
   
   Fish = iCustom(NULL, Signal_TimeFrame, "Fisher_m11",RangePeriods,PriceSmoothing, IndexSmoothing,0,SignalCandle);
   switch (cmd)
   {
     case OP_BUY : if (Fish > 0)
                   {
                         return (true);
                   }
                   break;
     case OP_SELL : if (Fish < 0)
                    {
                         return (true);
                    }
   }
   
   return(false);
}

bool CheckBBStop(int cmd)
{
   double BBStopUp, BBStopDown;
   double BBStopUpPrev, BBStopDownPrev;

   BBStopUp = iCustom(NULL, Signal_TimeFrame, "BBands_Stop_v2", Length, Deviation, MoneyRisk, 0, SignalCandle);
   BBStopDown = iCustom(NULL, Signal_TimeFrame, "BBands_Stop_v2", Length, Deviation, MoneyRisk, 1, SignalCandle);
   switch (cmd)
   {
     case OP_BUY : if (BBStopUp > 0 )
                   {
                         return (true);
                   }
                   break;
     case OP_SELL : if (BBStopDown > 0)
                    {
                         return (true);
                    }
   }
   
   return(false);
}

bool CheckDamianiFilter()
{
   double DamianiGreen, DamianiGray;

   DamianiGray = iCustom(NULL, Signal_TimeFrame, "Damiani_volatmeter", Viscosity, Sedimentation, Threshold_level,lag_supressor, 0, SignalCandle);
   DamianiGreen = iCustom(NULL, Signal_TimeFrame, "Damiani_volatmeter", Viscosity, Sedimentation, Threshold_level,lag_supressor, 2, SignalCandle);
   if (DamianiGreen > DamianiGray)
   {
     return (true);
   }
   
   return(false);
}

bool CheckNinaEMA(int cmd)
{
    double ma;
    
    ma=iMA(NULL,Signal_TimeFrame,EntryMA_Period,0,MODE_EMA,PRICE_CLOSE,SignalCandle);
    switch (cmd)
    {
       case OP_BUY : if (Close[1] > ma) return(true);
                     break;
       case OP_SELL : if (Close[1] < ma) return(true);
     }
     return(false);
}

bool CheckStepMA(int cmd)
{
   double LineMin, LineMid;

   LineMin = iCustom(NULL, Signal_TimeFrame, "Hist_StepMA_Stoch_KV1_Ex_03",PeriodWATR,Kwatr,0,SignalCandle);
   LineMid = iCustom(NULL, Signal_TimeFrame, "Hist_StepMA_Stoch_KV1_Ex_03",PeriodWATR,Kwatr,1,SignalCandle);
   switch (cmd)
   {
     case OP_BUY : if (LineMid > 0) return(true);
                   break;
     case OP_SELL : if (LineMin < 0) return(true);
   }
   
   return(false);
}

bool CheckCurrentCandle(int cmd)
{
   double myBid;
   
   myBid = MarketInfo(Symbol(), MODE_BID);
   switch (cmd)
   {
     case OP_BUY : 
                   if (myBid - iClose(Symbol(), Signal_TimeFrame ,1) >= Breakout*Point) return(true);
                   break;
     case OP_SELL : if (iClose(Symbol(), Signal_TimeFrame ,1) - myBid >= Breakout*Point) return(true);
   }
   
   return(false);
}

//===================================================================
//                                                    EMA_Angle.mq4 
//                                                          jpkfox
//
// You can use this indicator to measure when the EMA angle is
// "near zero". AngleTreshold determines when the angle for the
// EMA is "about zero": This is when the value is between
// [-AngleTreshold, AngleTreshold] (or when the histogram is red).
//   EMAPeriod: EMA period 
//   AngleTreshold: The angle value is "about zero" when it is
//     between the values [-AngleTreshold, AngleTreshold].
//   StartEMAShift: The starting point to calculate the 
//     angle. This is a shift value to the left from the
//     observation point. Should be StartEMAShift > EndEMAShift.
//   StartEMAShift: The ending point to calculate the
//     angle. This is a shift value to the left from the
//     observation point. Should be StartEMAShift > EndEMAShift.
//
//  Return 1 for up OK
//  Return -1 for down OK
//  Return 0 for too flat
//===================================================================
double MA_Angle( int PrevShift, int CurShift, double fPrevMA, double fCurMA)
{
   double fAngle, mFactor;
   string Sym;
   int ShiftDif;
   
   mFactor = 100000.0;
   Sym = StringSubstr(Symbol(),3,3);
   if (Sym == "JPY") mFactor = 1000.0;
   ShiftDif = PrevShift-CurShift;
   mFactor /= ShiftDif; 

    fAngle = mFactor * (fCurMA - fPrevMA)/2.0;

    return(fAngle);
}

void GetHMA(int TimeFrame, int MAPeriod, int Prev, int Cur)
{
   MACurrent=iCustom(NULL,TimeFrame,"HMA3",MAPeriod,HMA_method,HMA_price,0,Cur);
   MAPrevious=iCustom(NULL,TimeFrame,"HMA3",MAPeriod,HMA_method,HMA_price,0,Prev);
}

void GetMA_Trend (int myTimeFrame, int myPeriod, int PrevShift, int CurShift)
{
   GetHMA(myTimeFrame,  myPeriod, PrevShift, CurShift);
}

void GetMACD_H4()
{
   macd_H4=iMACD(NULL,T4_TimeFrame,FastEMA,SlowEMA,SignalSMA,PRICE_CLOSE,MODE_MAIN,GMACD_SignalCandle); 
   macd_HH4=iMACD(NULL,T4_TimeFrame,FastEMA,SlowEMA,SignalSMA,PRICE_CLOSE,MODE_SIGNAL,GMACD_SignalCandle); 
}

void GetMACD_D1()
{
   macd_D1=iMACD(NULL,T1_TimeFrame,FastEMA,SlowEMA,SignalSMA,PRICE_CLOSE,MODE_MAIN,GMACD_SignalCandle); 
   macd_DD1=iMACD(NULL,T1_TimeFrame,FastEMA,SlowEMA,SignalSMA,PRICE_CLOSE,MODE_SIGNAL,GMACD_SignalCandle); 
}

int Get_Daily_Trend(int cmd, int T1_Method)
{
	bool TrendUP, TrendDOWN;
	double maAngle;
	
   TrendUP = false;
   TrendDOWN = false;
   switch(T1_Method)
   {
      case NO_FILTER :
          TrendUP = true;
          TrendDOWN = true;
          break;
      case MACD_FILTER :
          GetMACD_D1();
          if (macd_D1 > macd_DD1) TrendUP = true;
          if (macd_D1 < macd_DD1) TrendDOWN = true;
          break;
      case HMA_FILTER :
          GetMA_Trend( T1_TimeFrame, T1_Period, T1_PrevShift, T1_CurShift );
	       maAngle = MA_Angle(T1_PrevShift, T1_CurShift, MAPrevious, MACurrent);
          switch (cmd)
          {
             case OP_BUY : if (maAngle > T1_Threshold) TrendUP = true;
                           break;
             case OP_SELL : if (maAngle < -T1_Threshold) TrendDOWN = true;
          }
          break;
   }
   
   switch (cmd)
   {
      case OP_BUY : if (TrendUP) return(UP); else return(DOWN);
                    break;
      case OP_SELL : if (TrendDOWN) return(DOWN); else return (UP);

   }
}

int Get_4Hr_Trend (int cmd, int T4_Method)
{
	bool TrendUP, TrendDOWN;
	double maAngle;
	
   TrendUP = false;
   TrendDOWN = false;
   switch(T4_Method)
   {
      case NO_FILTER :
          TrendUP = true;
          TrendDOWN = true;
          break;
      case MACD_FILTER :
          GetMACD_H4();
          if (macd_H4 > macd_HH4) TrendUP = true;
          if (macd_H4 < macd_HH4) TrendDOWN = true;
          break;
      case HMA_FILTER :
          GetMA_Trend(T4_TimeFrame, T4_Period , T4_PrevShift, T4_CurShift);
	       maAngle = MA_Angle(T4_PrevShift, T4_CurShift, MAPrevious, MACurrent);
          switch (cmd)
          {
             case OP_BUY : if (maAngle > T4_Threshold) TrendUP = true;
                           break;
             case OP_SELL : if (maAngle < -T4_Threshold) TrendDOWN = true;
          }
          break;
   }
      
   switch (cmd)
   {
      case OP_BUY : if (TrendUP) return(UP); else return(DOWN);
                    break;
      case OP_SELL : if (TrendDOWN) return(DOWN); else return (UP);
   }
 }
 
 bool CheckEntryTrend(int cmd)
{
	int trend1, trend4;
   
   switch (cmd)
   {
     case OP_BUY : trend1 = Get_Daily_Trend(OP_BUY, T1_EntryMethod);
                   if (trend1 == UP)
                   {
                       trend4 = Get_4Hr_Trend(OP_BUY, T4_EntryMethod);
                       if (trend4 == UP) return(true);
                   }
                   return(false);
                   break;
     case OP_SELL : trend1 = Get_Daily_Trend(OP_SELL, T1_EntryMethod);
                   if (trend1 == DOWN)
                   {
                       trend4 = Get_4Hr_Trend(OP_SELL, T4_EntryMethod);
                       if (trend4 == DOWN) return(true);
                   }
                   return(false);
    }
    return(false);
}

 bool CheckExitTrend(int cmd)
{
	int trend1, trend4;
   
   switch (cmd)
   {
     case OP_BUY : trend1 = Get_Daily_Trend(OP_BUY, T1_ExitMethod);
                   if (trend1 == UP)
                   {
                       trend4 = Get_4Hr_Trend(OP_BUY, T4_ExitMethod);
                       if (trend4 == UP) return(true);
                   }
                   return(false);
                   break;
     case OP_SELL : trend1 = Get_Daily_Trend(OP_SELL, T1_ExitMethod);
                   if (trend1 == DOWN)
                   {
                       trend4 = Get_4Hr_Trend(OP_SELL, T4_ExitMethod);
                       if (trend4 == DOWN) return(true);
                   }
                   return(false);
    }
    return(false);
}

//+------------------------------------------------------------------+
//| CheckExitCondition                                               |
//| Uses OP_BUY as cmd to check exit sell                            |
//| Uses OP_SELL as cmd to check exit buy                            |
//+------------------------------------------------------------------+
bool CheckExitCondition(int cmd)
{
   bool rule1, rule2, rule3, rule4, rule5, rule6;
   
   rule1 = true;
   rule2 = true;
   rule3 = true;
   rule4 = true;
   rule5 = true;
   rule6 = true;
   
// The rules are checked this way for speed

   if (useHeikenAshiExit == 1) rule1 = CheckHeikenAshi(cmd);
   if (rule1)
   {
       if (useFishExit == 1) rule2 = CheckFish(cmd);
       if (rule2)
       {
         if (useBBStopExit == 1) rule3 = CheckBBStop(cmd);
         if (rule3)
         {
            
               if (useTrendExit == 1) rule5 = CheckExitTrend(cmd);
               if (rule5)
               {
                 if (useStepMAExit == 1) rule6 = CheckStepMA(cmd);
                 if (rule6) return (true);
               }
         }
       }
   }
   
   return (false);
}

//+------------------------------------------------------------------+
//| CheckEntryCondition                                              |
//+------------------------------------------------------------------+
bool CheckEntryCondition(int cmd)
{
   bool rule1, rule2, rule3, rule4, rule5, rule6, rule7, rule8, rule9;
   
   rule1 = true;
   rule2 = true;
   rule3 = true;
   rule4 = true;
   rule5 = true;
   rule6 = true;
   rule7 = true;
   rule8 = true;
   rule9 = true;
   
// The rules are checked this way for speed
  
   if (useHeikenAshi == 1) rule1 = CheckHeikenAshi(cmd);
   if (rule1)
   {
      if (useFish == 1) rule3 = CheckFish(cmd);
      if (rule3)
      {
         if (useCurrentCandle == 1) rule6 = CheckCurrentCandle(cmd);
         if (rule6)
         {
             if (useNinaEMA == 1) rule7 = CheckNinaEMA(cmd);
             if (rule7)
             {
                if (useBBStop == 1) rule2 = CheckBBStop(cmd);
                if (rule2)
                {
                   if (useTrendEntry == 1) rule8 = CheckEntryTrend(cmd);
                   if (rule8)
                   {
                      if (useStepMA == 1) rule9 = CheckStepMA(cmd);
                      if (rule9)
                      {
                        if (useDamianiFilter == 1) rule5 = CheckDamianiFilter();
                        if (rule5) return(true);
                      }
                   }
                }
             }
         }
      }
   }
   return (false);
}
  
//+------------------------------------------------------------------+
//| LastTradeStoppedOut                                              |
//| Check History to see if last trade stopped out                   |
//| Return Time for next trade                                       |
//+------------------------------------------------------------------+
  
datetime LastTradeStoppedOut()
{
   int cnt, total;
   datetime NextTime;
   bool Stopped;
   
   NextTime = 0;
   
   total = HistoryTotal();
   for (cnt = total - 1; cnt >= 0; cnt--)
   {
      OrderSelect (cnt, SELECT_BY_POS, MODE_HISTORY);
      
      if(OrderSymbol()==Symbol() && OrderMagicNumber() == MagicNumber)
      {
        Stopped = false;
        if (OrderType() == OP_BUY)
        {
          if (OrderClosePrice() - OrderOpenPrice() < 0)
          {
             Stopped = true;
          }
          if(useDelayAfterWin == 1) Stopped = true;
          cnt = 0;
        }
        if (OrderType() == OP_SELL)
        {
          if (OrderOpenPrice() - OrderClosePrice() < 0)
          {
             Stopped = true;
          }
          if(useDelayAfterWin == 1) Stopped = true;
          cnt = 0;
        }
      }
   }
   
   if (Stopped)
   {
      StopTime = OrderCloseTime() + MinutesToDelay*60;
   }
   
   return (Stopped);
}

bool CheckTradingTimes()
{
   bool StopTrading;
   
     StopTrading = true;
// Check trading Asian Market
     if (TradeAsianMarket)
     {
        if (StartHour1 > 18)
        {
// Check broker that uses Asian open before 0:00

          if (Hour() >= StartHour1) StopTrading = false;
          if (!StopTrading)
          {
            if (StopHour1 < 24)
            {
              if ( Hour() <= StopHour1) StopTrading = false;
            }
// These cannot be combined even though the code looks the same
            if (StopHour1 >=0)
            {
              if ( Hour() <= StopHour1) StopTrading = false;
            }
          }
        }
        else
        {
          if (Hour() >= StartHour1 && Hour() <= StopHour1) StopTrading = false;
        }
     }
     if (StopTrading)
     {
// Check trading European Market
       if (TradeEuropeanMarket)
       {
         if (Hour() >= StartHour2 && Hour() <= StopHour2) StopTrading = false;
       }
     }
     if (StopTrading)
     {
// Check trading European Market
       if (TradeNewYorkMarket)
       {
         if (Hour() >= StartHour3 && Hour() <= StopHour3) StopTrading = false;
       }
     }
     
     return(StopTrading);
}

//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+
int start()
  {
//---- 
   
//+------------------------------------------------------------------+
//| Check for Open Position                                          |
//+------------------------------------------------------------------+

     HandleOpenPositions();
     
// Check if any open positions were not closed

     TradesInThisSymbol = CheckOpenPositions();
     
//+------------------------------------------------------------------+
//| Check if OK to make new trades                                   |
//+------------------------------------------------------------------+

// Check if last trade stopped out

   if (useDelay == 1)
   {
     StoppedOut = LastTradeStoppedOut();
     if  (CurTime() < StopTime)
     {
//    Comment("No Trades Until : " + TimeToStr(StopTime,TIME_DATE|TIME_MINUTES));
      return(0);
     }
   }

   if(AccountFreeMargin() < Margincutoff) {
     return(0);}

   YesStop = false;
   if (UseTradingHours) YesStop = CheckTradingTimes();
   
   if (YesStop)
   {
//      Comment ("Trading has been stopped as requested - wrong time of day");
       return (0);
   }
     
// Only allow 1 trade per Symbol

     if(TradesInThisSymbol > 0) {
       return(0);}
   

   lotMM = GetLots();
   
      
	if(CheckEntryCondition(OP_BUY))
	{
		   OpenBuyOrder();
		   return(0);
	}

   
	if(CheckEntryCondition(OP_SELL))
	{
         OpenSellOrder();
	}
//----
   return(0);
  }

//+------------------------------------------------------------------+
//| Functions beyond this point should not need to be modified       |
//| Eventually will be placed in include file                        |
//+------------------------------------------------------------------+



//+------------------------------------------------------------------+
//| OpenBuyOrder                                                     |
//| If Stop Loss or TakeProfit are used the values are calculated    |
//| for each trade                                                   |
//+------------------------------------------------------------------+
void OpenBuyOrder()
{
   int err,ticket, digits;
   double myPrice, myStopLoss = 0, myTakeProfit = 0;
   
   myPrice = MarketInfo(Symbol(), MODE_ASK);
   myStopLoss = 0;
   if ( StopLoss > 0 ) myStopLoss = myPrice - StopLoss * Point ;
   myTakeProfit = 0;
   if (TakeProfit>0) myTakeProfit = myPrice + TakeProfit * Point;
 // 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,myStopLoss,myTakeProfit,setup,MagicNumber,0,Green); 
   if (ticket > 0)
   {
    if (OrderSelect( ticket,SELECT_BY_TICKET, MODE_TRADES) ) 
     {
      Print("BUY order opened : ", OrderOpenPrice( ));
//      ModifyOrder(ticket,OrderOpenPrice( ), OrderStopLoss(), myTakeProfit);
    }
   }
   else
   {
      err = GetLastError();
      Print("Error opening BUY order [" + setup + "]: (" + err + ") " + ErrorDescription(err)); 
   }
}

//+------------------------------------------------------------------+
//| OpenSellOrder                                                    |
//| If Stop Loss or TakeProfit are used the values are calculated    |
//| for each trade                                                   |
//+------------------------------------------------------------------+
void OpenSellOrder()
{
   int err, ticket, digits;
   double myPrice, myStopLoss = 0, myTakeProfit = 0;
   
   myPrice = MarketInfo(Symbol( ), MODE_BID);
   myStopLoss = 0;
   if ( StopLoss > 0 ) myStopLoss = myPrice + StopLoss * Point;
   myTakeProfit = 0;
   if (TakeProfit > 0) myTakeProfit = myPrice - TakeProfit * Point;
 // 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,myStopLoss,myTakeProfit,setup,MagicNumber,0,Red); 
   if (ticket > 0)
   {
     if (OrderSelect( ticket,SELECT_BY_TICKET, MODE_TRADES) ) 
     {
      Print("Sell order opened : ", OrderOpenPrice());
//      ModifyOrder(ticket,OrderOpenPrice( ), OrderStopLoss(), myTakeProfit);
     }
   }
   else
   {
      err = GetLastError();
      Print("Error opening Sell order [" + setup + "]: (" + err + ") " + ErrorDescription(err)); 
   }
}

//+------------------------------------------------------------------+
//| Check Open Position Controls                                     |
//+------------------------------------------------------------------+
  
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);
  }

int CloseOrder(int ticket,double numLots,int cmd)
{
   int CloseCnt, err, digits;
   double myPrice;
   
   if (cmd == OP_BUY) myPrice = MarketInfo(Symbol( ), MODE_BID);
   if (cmd == OP_SELL) myPrice = MarketInfo(Symbol( ), MODE_ASK);
   digits = MarketInfo(Symbol( ), MODE_DIGITS) ;
   if (digits > 0)  myPrice = NormalizeDouble( myPrice, digits);
   // try to close 3 Times
      
    CloseCnt = 0;
    while (CloseCnt < 3)
    {
       if (!OrderClose(ticket,numLots,myPrice,Slippage,Violet))
       {
         err=GetLastError();
         Print(CloseCnt," Error closing order : (", err , ") " + ErrorDescription(err));
         if (err > 0) CloseCnt++;
       }
       else
       {
         CloseCnt = 3;
       }
    }
}

int ModifyOrder(int ord_ticket,double op, double price,double tp, color mColor)
{
    int CloseCnt, err;
    
    CloseCnt=0;
    while (CloseCnt < 3)
    {
       if (OrderModify(ord_ticket,op,price,tp,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 minstop, pp;
   
   pp = MarketInfo(Symbol(), MODE_POINT);
   minstop = MarketInfo(Symbol(),MODE_STOPLEVEL);
   if (type == OP_BUY)
   {
		 if((price - SL) < minstop*pp) SL = price - minstop*pp;
   }
   if (type == OP_SELL)
   {
       if((SL-price) < minstop*pp)  SL = price + minstop*pp;  
   }

   return(SL);   
}
//+------------------------------------------------------------------+
//|                                           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, pp, BuyStop, SellStop;

   pp = MarketInfo(Symbol(), MODE_POINT);
   digits = MarketInfo(Symbol(), MODE_DIGITS);
   
  if (type==OP_BUY)
  {
    pBid = MarketInfo(Symbol(), MODE_BID);
    if ( pBid-op > pp*BreakEven ) 
    {
       BuyStop = op + LockInPips * pp;
       if (digits > 0) BuyStop = NormalizeDouble( BuyStop, digits);
		 BuyStop = ValidStopLoss(OP_BUY,pBid, BuyStop);   
       if (digits > 0) BuyStop = NormalizeDouble( BuyStop, digits);
       if (os < BuyStop) ModifyOrder(ticket,op,BuyStop,tp,LightGreen);
		 return;
	 }
  }
  if (type==OP_SELL)
  {
    pAsk = MarketInfo(Symbol(), MODE_ASK);
    if ( op - pAsk > pp*BreakEven ) 
    {
       SellStop = op - LockInPips * pp;
       if (digits > 0) SellStop = NormalizeDouble( SellStop, digits);
       SellStop = ValidStopLoss(OP_SELL, pAsk, SellStop);  
       if (digits > 0) SellStop = NormalizeDouble( SellStop, digits);
       if (os > SellStop) ModifyOrder(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, pp, BuyStop, SellStop;

  pp = MarketInfo(Symbol(), MODE_POINT);
  digits = MarketInfo(Symbol(), MODE_DIGITS) ;
  if (type==OP_BUY)
  {
    pBid = MarketInfo(Symbol(), MODE_BID);
    if ((pBid-op)>eTrailingStop*pp)
    {
      if (os<pBid-(eTrailingStop+eTrailingStep-1)*pp)
      {
        BuyStop = pBid-eTrailingStop*pp;
        if (digits > 0) BuyStop = NormalizeDouble( BuyStop, digits);
		  BuyStop = ValidStopLoss(OP_BUY, pBid, BuyStop);   
        if (digits > 0) BuyStop = NormalizeDouble( BuyStop, digits);
        ModifyOrder(ticket,op,BuyStop,tp,LightGreen);
        return;
      }
    }
  }
  if (type==OP_SELL)
  {
    pAsk = MarketInfo(Symbol(), MODE_ASK);
    if (op - pAsk > eTrailingStop*pp)
    {
      if (os > pAsk + (eTrailingStop + eTrailingStep-1)*pp || os==0)
      {
        SellStop = pAsk + eTrailingStop * pp;
        if (digits > 0) SellStop = NormalizeDouble( SellStop, digits);
        SellStop = ValidStopLoss(OP_SELL, pAsk, SellStop);  
        if (digits > 0) SellStop = NormalizeDouble( SellStop, digits);
        ModifyOrder(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 |                                      
//+------------------------------------------------------------------+
void EMA_TrailingStop(int type, int ticket, double op, double os, double tp)
{
   int digits;
   double pBid, pAsk, pp, BuyStop, SellStop, ema;

   pp = MarketInfo(Symbol(), MODE_POINT);
   digits = MarketInfo(Symbol(), MODE_DIGITS) ;
   ema = iMA(Symbol(),EMATimeFrame,EMAPeriod,0,MODE_EMA,Price,EMAShift);
   
   if (type==OP_BUY) 
   {
	   BuyStop = ema;
      pBid = MarketInfo(Symbol(),MODE_BID);
		if(os == 0 && InitialStop>0 ) BuyStop = pBid-InitialStop*pp;
		if (digits > 0) BuyStop = NormalizeDouble(SellStop, digits); 
		BuyStop = ValidStopLoss(OP_BUY, pBid, BuyStop);   
		if (digits > 0) BuyStop = NormalizeDouble(BuyStop, digits);
		Print("MA=",ema," BuyStop=",BuyStop);
		if ((op <= BuyStop && BuyStop > os) || os==0) 
		{
          ModifyOrder(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*pp;
		if (digits > 0) SellStop = NormalizeDouble(SellStop, digits); 
		SellStop = ValidStopLoss(OP_SELL, pAsk, SellStop);
		if (digits > 0) SellStop = NormalizeDouble(SellStop, digits);
      Print("MA=",ema," SellStop=",SellStop);   
      if( (op >= SellStop && os > SellStop) || os==0) 
      {
          ModifyOrder(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, pp, BuyStop, SellStop, spr;
   double sar1, sar2;
  
   pp = MarketInfo(Symbol(), MODE_POINT);
   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*pp;
        if (digits > 0) BuyStop = NormalizeDouble(BuyStop, digits); 
	     BuyStop = ValidStopLoss(OP_BUY, pBid, BuyStop);   
        if (digits > 0) BuyStop = NormalizeDouble(BuyStop, digits); 
        if (os<BuyStop) ModifyOrder(ticket,op,BuyStop,tp,LightGreen);
     }
   }
   if (type==OP_SELL)
   {
     if (sar2 > sar1)
     {
        SellStop = sar1 + Interval * pp + spr;
        if (digits > 0) SellStop = NormalizeDouble(SellStop, digits); 
	     SellStop = ValidStopLoss(OP_SELL, pAsk, SellStop);   
        if (digits > 0) SellStop = NormalizeDouble(SellStop, digits); 
        if (os>SellStop || os==0) ModifyOrder(ticket,op,SellStop,tp,DarkOrange);
     }
   }
}

//+------------------------------------------------------------------+
//|                                      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, pp, BuyStop, SellStop;

   pp = MarketInfo(Symbol(), MODE_POINT);
   digits = MarketInfo(Symbol(), MODE_DIGITS) ;

   if (type == OP_BUY)
   {
      pBid = MarketInfo(Symbol(), MODE_BID);
      if (pBid - op > FirstMove * pp)
      {
         BuyStop = op + FirstMove*pp - FirstStopLoss * pp;
         if (digits > 0) BuyStop = NormalizeDouble(BuyStop, digits); 
		   BuyStop = ValidStopLoss(OP_BUY, pBid, BuyStop);   
         if (digits > 0) BuyStop = NormalizeDouble(BuyStop, digits); 
         if (os < BuyStop) ModifyOrder(ticket,op,BuyStop,tp,LightGreen);
      }
              
      if (pBid - op > SecondMove * pp)
      {
         BuyStop = op + SecondMove*pp - SecondStopLoss * pp;
         if (digits > 0) BuyStop = NormalizeDouble(BuyStop, digits); 
		   BuyStop = ValidStopLoss(OP_BUY, pBid, BuyStop);   
         if (digits > 0) BuyStop = NormalizeDouble(BuyStop, digits); 
         if (os < BuyStop) ModifyOrder(ticket,op,BuyStop,tp,LightGreen);
      }
                
      if (pBid - op > ThirdMove * pp)
      {
         BuyStop = pBid  - ThirdMove*pp;
         if (digits > 0) BuyStop = NormalizeDouble(BuyStop, digits); 
		   BuyStop = ValidStopLoss(OP_BUY, pBid, BuyStop);   
         if (digits > 0) BuyStop = NormalizeDouble(BuyStop, digits); 
         if (os < BuyStop) ModifyOrder(ticket,op,BuyStop,tp,LightGreen);
      }
   }
       
    if (type ==  OP_SELL)
    {
        pAsk = MarketInfo(Symbol(), MODE_ASK);
        if (op - pAsk > FirstMove * pp)
        {
           SellStop = op - FirstMove * pp + FirstStopLoss * pp;
           if (digits > 0) SellStop = NormalizeDouble(SellStop, digits); 
		     SellStop = ValidStopLoss(OP_SELL, pAsk, SellStop);   
           if (digits > 0) SellStop = NormalizeDouble(SellStop, digits); 
           if (os > SellStop) ModifyOrder(ticket,op,SellStop,tp,DarkOrange);
        }
        if (op - pAsk > SecondMove * pp)
        {
           SellStop = op - SecondMove * pp + SecondStopLoss * pp;
           if (digits > 0) SellStop = NormalizeDouble(SellStop, digits); 
		     SellStop = ValidStopLoss(OP_SELL, pAsk, SellStop);   
           if (digits > 0) SellStop = NormalizeDouble(SellStop, digits); 
           if (os > SellStop) ModifyOrder(ticket,op,SellStop,tp,DarkOrange);
        }
        if (op - pAsk > ThirdMove * pp)
        {
           SellStop = pAsk + ThirdMove * pp;               
           if (digits > 0) SellStop = NormalizeDouble(SellStop, digits); 
		     SellStop = ValidStopLoss(OP_SELL, pAsk, SellStop);   
           if (digits > 0) SellStop = NormalizeDouble(SellStop, digits); 
           if (os > SellStop) ModifyOrder(ticket,op,SellStop,tp,DarkOrange);
        }
    }

}

//+------------------------------------------------------------------+
//|                                       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, pp, BuyStop, SellStop;

   pp = MarketInfo(Symbol(), MODE_POINT);
   digits = MarketInfo(Symbol( ), MODE_DIGITS);
   
   if (type==OP_BUY)
   {
     pBid = MarketInfo(Symbol(), MODE_BID);
     pt = StopLoss * pp;
     if(pBid-os > pt)
     {
       BuyStop = pBid - pt;
       if (digits > 0) BuyStop = NormalizeDouble( BuyStop, digits);
		 BuyStop = ValidStopLoss(OP_BUY,pBid, BuyStop);   
       if (digits > 0) BuyStop = NormalizeDouble( BuyStop, digits);
       if (os < BuyStop) ModifyOrder(ticket,op,BuyStop,tp,LightGreen);
		 return;
	  }
   }
   if (type==OP_SELL)
   {
     pAsk = MarketInfo(Symbol(), MODE_ASK);
     pt = StopLoss * pp;
     if(os - pAsk > pt)
     {
       SellStop = pAsk + pt;
       if (digits > 0) SellStop = NormalizeDouble( SellStop, digits);
       SellStop = ValidStopLoss(OP_SELL, pAsk, SellStop);  
       if (digits > 0) SellStop = NormalizeDouble( SellStop, digits);
       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, pp, BuyStop, SellStop;

   pp = MarketInfo(Symbol(), MODE_POINT);
   pt = TrailingStop * pp;
   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 (digits > 0) BuyStop = NormalizeDouble( BuyStop, digits);
     if (pBid-op > pt && os < BuyStop) ModifyOrder(ticket,op,BuyStop,tp,LightGreen);
	  return;
   }
   if (type==OP_SELL)
   {
     pAsk = MarketInfo(Symbol(), MODE_ASK);
     pt = TrailingStop * pp;
     SellStop = pAsk + pt;
     if (digits > 0) SellStop = NormalizeDouble( SellStop, digits);
     SellStop = ValidStopLoss(OP_SELL, pAsk, SellStop);  
     if (digits > 0) SellStop = NormalizeDouble( SellStop, digits);
     if (op - pAsk > pt && os > SellStop) ModifyOrder(ticket,op,SellStop,tp,DarkOrange);
	  return;
   }   
}
//+------------------------------------------------------------------+
//| 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;
	  case 5 : eTrailingStop (type, ticket, op, os, tp);
              break;
	  case 6 : EMA_TrailingStop (type, ticket, op, os, tp);
              break;
	  case 7 : pSAR_TrailingStop (type, ticket, op, os, tp);
              break;
	}
   return(0);
}

//+------------------------------------------------------------------+
//| 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 (CheckExitCondition(OP_SELL))
          {
              CloseOrder(OrderTicket(),OrderLots(),OP_BUY);
          }
          else
          {
            if (UseTrailingStop)
            {
               HandleTrailingStop(OP_BUY,OrderTicket(),OrderOpenPrice(),OrderStopLoss(),OrderTakeProfit());
            }
          }
      }

      if(OrderType() == OP_SELL)
      {
          if (CheckExitCondition(OP_BUY))
          {
             CloseOrder(OrderTicket(),OrderLots(),OP_SELL);
          }
          else
          {
            if (UseTrailingStop)
            {
               HandleTrailingStop(OP_SELL,OrderTicket(),OrderOpenPrice(),OrderStopLoss(),OrderTakeProfit());
            }
          }
      }
   }
}

     
//+------------------------------------------------------------------+
//| Get number of lots for this trade                                |
//+------------------------------------------------------------------+
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                                       |
//+------------------------------------------------------------------+

double LotsOptimized()
  {
   double lot=Lots;
//---- select lot size
   lot=NormalizeDouble(MathFloor(AccountFreeMargin()*TradeSizePercent/10000)/10,1);
   
  
  // lot at this point 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                      |
//+------------------------------------------------------------------+

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                               |
//+------------------------------------------------------------------+

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);
   Comment("unexpected Symbol");
	return(19);
}

