//+------------------------------------------------------------------+
//|       This MQL is generated by Expert Advisor Builder            |
//|     http://sufx.core.t3-ism.net/ExpertAdvisorBuilder/            |
//|      
//|     
//|               
//|               
//|                                                                  |
//|  In no event will author be liable for any damages whatsoever.   |
//|                      Use at your own risk.                       |
//|                                                                  |
//+------------------- DO NOT REMOVE THIS HEADER --------------------+

#define SIGNAL_NONE 0
#define SIGNAL_BUY   1
#define SIGNAL_SELL  2
#define SIGNAL_CLOSEBUY 3
#define SIGNAL_CLOSESELL 4

#property copyright "Copyright © 2007, AKA TradeForexFX"
#property link      "http://www./"

extern string  Expert_Name    = "----  by TF ----";


//***********************
// Modified to use base for calculation of MagicNumber
extern int MagicNumberBase = 10000;
int MagicNumber;  // This is now calculated based on Symbol and Period

extern bool SignalMail = False;
extern bool EachTickMode = True;
extern double Lots = 1.00;

extern int Slippage = 3;
extern bool StopLossMode = True;
extern int StopLoss = 30;
extern bool TakeProfitMode = True;
extern int TakeProfit = 150;
extern bool TrailingStopMode = True;
extern int TrailingStop = 30;

//******************************************
// Inputs for trading hours
extern string  sm0="--Trading Hours Filter--";
extern string  sm2="UseTradingHours - Enter 0 for false, 1 for true";
extern int    UseTradingHours = 1;
extern string  sm3="Trade Session 1 - Enter 0 for false, 1 for true";
extern int    TradeSession1 = 1;
extern int     Session1Start = 300;       // Start trades after time
extern int     Session1Stop = 500;      // Stop trading after time
extern string  sm4="Trade Session 2 - Enter 0 for false, 1 for true";
extern int    TradeSession2 = 1;
extern int     Session2Start = 800;       // Start trades after time
extern int     Session2Stop = 1300;      // Stop trading after time
extern string  sm5="Trade Session 3 - Enter 0 for false, 1 for true";
extern int    TradeSession3 = 1;
extern int     Session3Start = 1400;       // Start trades after time
extern int     Session3Stop = 1915;      // Stop trading after time
extern string  sm6="Trade Session 4 - Enter 0 for false, 1 for true";
extern int    TradeSession4 = 0;
extern int     Session4Start = 1330;       // Start trades after time
extern int     Session4Stop = 1500;      // Stop trading after time
extern string  sm7="Trade Session 5 - Enter 0 for false, 1 for true";
extern int    TradeSession5 = 0;
extern int     Session5Start = 1700;       // Start trades after time
extern int     Session5Stop = 1900;      // Stop trading after time

bool     YesStop;

// Trading Hours variables end here
//************************************

int BarCount;
int Current;
bool TickCheck = False;


//+------------------------------------------------------------------+
//| expert initialization function                                   |
//+------------------------------------------------------------------+
int init() {
   BarCount = Bars;

   if (EachTickMode) Current = 0; else Current = 1;
   
//*******************************
// Calculate MagicNumber
	MagicNumber = MagicNumberBase + func_Symbol2Val(Symbol())*100 + func_TimeFrame_Const2Val(Period()); 

   return(0);
}
//+------------------------------------------------------------------+
//| expert deinitialization function                                 |
//+------------------------------------------------------------------+
int deinit() {
   return(0);
}
//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+
int start() {
   int Order = SIGNAL_NONE;
   int Total, Ticket;
   double StopLossLevel, TakeProfitLevel;



   if (EachTickMode && Bars != BarCount) TickCheck = False;
   Total = OrdersTotal();
   Order = SIGNAL_NONE;
   
   
   
   

   //+------------------------------------------------------------------+
   //| Variable Begin                                                   |
   //+------------------------------------------------------------------+


// double Var0 = iAO(NULL, 0, Current + 0);



// double HA0, HA1, HA2, HA3;
   
double HA0 = iCustom(NULL,0,"Heiken_Ashi_Smoothed",0,0);
double   HA1 = iCustom(NULL,0,"Heiken_Ashi_Smoothed",1,0);
double   HA2 = iCustom(NULL,0,"Heiken_Ashi_Smoothed",2,0);
double   HA3 = iCustom(NULL,0,"Heiken_Ashi_Smoothed",3,0);

 
double   HA50 = iCustom(NULL,PERIOD_M5,"Heiken_Ashi_Smoothed",0,1);
double   HA51 = iCustom(NULL,PERIOD_M5,"Heiken_Ashi_Smoothed",1,1);
double   HA52 = iCustom(NULL,PERIOD_M5,"Heiken_Ashi_Smoothed",2,1);
double   HA53 = iCustom(NULL,PERIOD_M5,"Heiken_Ashi_Smoothed",3,1);



double Var10 = iStochastic(NULL, 0, 5, 3, 3, MODE_SMA, 0, MODE_MAIN, Current + 0);
double Var11 = iStochastic(NULL, 0, 5, 3, 3, MODE_SMA, 0, MODE_SIGNAL, Current + 0);
double Var12 = iStochastic(NULL, 0, 5, 3, 3, MODE_SMA, 0, MODE_MAIN, Current + 1);


double Var13 = iRSI(NULL, 0, 6, PRICE_CLOSE, Current + 0);
double Var14 = iRSI(NULL, 0, 6, PRICE_CLOSE, Current + 1);

   
double Var1 = HA3 - HA2;
double Var2 = HA1 - HA0;


double Var111 = HA53 - HA52;
double Var112 = HA51 - HA50;



double Var3 = Var10 - Var11;
double Var4 = Var10 - Var12;
double Var5 = Var13 - Var14;





double Buy1_1 =  Var1 ;
double Buy1_2 = 0;
double Buy2_1 =  Var2 ;
double Buy2_2 = 0;
double Buy3_1 =  Var3 ;
double Buy3_2 = 0;
double Buy4_1 =  Var4 ;
double Buy4_2 = 0;
double Buy5_1 =  Var5 ;
double Buy5_2 = 0;
double Buy6_1 =  Var13 ;
double Buy6_2 = 60;
double Buy7_1 =  Var111 ;
double Buy7_2 = 0;
double Buy8_1 =  Var112 ;
double Buy8_2 = 0;



double Sell1_1 =  Var1 ;
double Sell1_2 = 0;
double Sell2_1 =  Var2 ;
double Sell2_2 = 0;



double Sell3_1 =  Var3 ;
double Sell3_2 = 0;
double Sell4_1 =  Var4 ;
double Sell4_2 = 0;
double Sell5_1 =  Var5 ;
double Sell5_2 = 0;
double Sell6_1 =  Var13 ;
double Sell6_2 = 40;
double Sell7_1 =  Var111 ;
double Sell7_2 = 0;
double Sell8_1 =  Var112 ;
double Sell8_2 = 0;


// double Sell6_1 =  Var14 ;
// double Sell6_2 = 0;


double CloseBuy1_1 =  Var1 ;
double CloseBuy1_2 = 0;
double CloseBuy2_1 =  Var2 ;
double CloseBuy2_2 = 0;
double CloseBuy3_1 =  Var5 ;
double CloseBuy3_2 = 0;
double CloseBuy4_1 =  Var13 ;
double CloseBuy4_2 = 55;



double CloseSell1_1 =  Var1 ;
double CloseSell1_2 = 0;
double CloseSell2_1 =  Var2 ;
double CloseSell2_2 = 0;
double CloseSell3_1 =  Var5 ;
double CloseSell3_2 = 0;
double CloseSell4_1 =  Var13 ;
double CloseSell4_2 = 45;

   
   //+------------------------------------------------------------------+
   //| Variable End                                                     |
   //+------------------------------------------------------------------+

     
   //Check position
   bool IsTrade = False;

   for (int i = 0; i < Total; i ++) {
      OrderSelect(i, SELECT_BY_POS, MODE_TRADES);
//*******************************************
// Important to have code check MagicNumber and Symbol

      if (OrderSymbol() != Symbol()) continue;
      if (OrderMagicNumber() != MagicNumber) continue;
//*******************************************
      
      if(OrderType() <= OP_SELL) {
         IsTrade = True;
         if(OrderType() == OP_BUY) {
            //Close

            //+------------------------------------------------------------------+
            //| Signal Begin(Exit Buy)                                           |
            //+------------------------------------------------------------------+

                     if (CloseBuy1_1 < CloseBuy1_2 && CloseBuy2_1 < CloseBuy2_2 && CloseBuy3_1 < CloseBuy3_2 && CloseBuy4_1 < CloseBuy4_2 ) Order = SIGNAL_CLOSEBUY;


            //+------------------------------------------------------------------+
            //| Signal End(Exit Buy)                                             |
            //+------------------------------------------------------------------+

            if (Order == SIGNAL_CLOSEBUY && ((EachTickMode && !TickCheck) || (!EachTickMode && (Bars != BarCount)))) {
               OrderClose(OrderTicket(), OrderLots(), Bid, Slippage, MediumSeaGreen);
               if (SignalMail) SendMail("[Signal Alert]", "[" + Symbol() + "] " + DoubleToStr(Bid, Digits) + " Close Buy");
               if (!EachTickMode) BarCount = Bars;
               IsTrade = False;
               continue;
            }
            //Trailing stop
            if(TrailingStopMode && TrailingStop > 0) {                 
               if(Bid - OrderOpenPrice() > Point * TrailingStop) {
                  if(OrderStopLoss() < Bid - Point * TrailingStop) {
                     OrderModify(OrderTicket(), OrderOpenPrice(), Bid - Point * TrailingStop, OrderTakeProfit(), 0, MediumSeaGreen);
                     if (!EachTickMode) BarCount = Bars;
                     continue;
                  }
               }
            }
         } else {
            //Close

            //+------------------------------------------------------------------+
            //| Signal Begin(Exit Sell)                                          |
            //+------------------------------------------------------------------+

                     if (CloseSell1_1 > CloseSell1_2 && CloseSell2_1 > CloseSell2_2 && CloseSell4_1 > CloseSell4_2 ) Order = SIGNAL_CLOSESELL;


            //+------------------------------------------------------------------+
            //| Signal End(Exit Sell)                                            |
            //+------------------------------------------------------------------+

            if (Order == SIGNAL_CLOSESELL && ((EachTickMode && !TickCheck) || (!EachTickMode && (Bars != BarCount)))) {
               OrderClose(OrderTicket(), OrderLots(), Ask, Slippage, DarkOrange);
               if (SignalMail) SendMail("[Signal Alert]", "[" + Symbol() + "] " + DoubleToStr(Ask, Digits) + " Close Sell");
               if (!EachTickMode) BarCount = Bars;
               IsTrade = False;
               continue;
            }
            //Trailing stop
            if(TrailingStopMode && TrailingStop > 0) {                 
               if((OrderOpenPrice() - Ask) > (Point * TrailingStop)) {
                  if((OrderStopLoss() > (Ask + Point * TrailingStop)) || (OrderStopLoss() == 0)) {
                     OrderModify(OrderTicket(), OrderOpenPrice(), Ask + Point * TrailingStop, OrderTakeProfit(), 0, DarkOrange);
                     if (!EachTickMode) BarCount = Bars;
                     continue;
                  }
               }
            } // Trailing Stop
         } // Close
      } // OrderType
   }// for

//*******************************************
// Check trading sessions

   int NumOrders = 0;
   
   NumOrders = CalculateCurrentOrders();
   if(NumOrders == 0) {
     YesStop = false;
      
     if (UseTradingHours == 1) {
        YesStop = CheckTradingTimes();
   
        if (YesStop == true) {
          Comment ("Trading has been stopped");
        }
       
    //     - wrong time of day
        else {
          Comment ("Trading has resumed ");
   //    - time is OK   
          
        }
     }

     if (YesStop == false) {

   //+------------------------------------------------------------------+
   //| Signal Begin(Entry)                                              |
   //+------------------------------------------------------------------+

 //  if (Buy1_1 > Buy1_2 && Buy2_1 > Buy2_2 && Buy3_1 > Buy3_2 && Buy4_1 > Buy4_2 && Buy5_1 < Buy5_2) Order = SIGNAL_BUY;

//   if (Sell1_1 < Sell1_2 && Sell2_1 < Sell2_2 && Sell3_1 < Sell3_2 && Sell4_1 < Sell4_2 && Sell5_1 > Sell5_2) Order = SIGNAL_SELL;

       if (Buy1_1 > Buy1_2 && Buy2_1 > Buy2_2 && Buy3_1 > Buy3_2 && Buy4_1 > Buy4_2 && Buy5_1 > Buy5_2 && Buy6_1 > Buy6_2&& Buy7_1 > Buy7_2 && Buy8_1 > Buy8_2  ) Order = SIGNAL_BUY;
 
       if (Sell1_1 < Sell1_2 && Sell2_1 < Sell2_2 && Sell3_1 < Sell3_2 && Sell4_1 < Sell4_2 && Sell5_1 > Sell5_2 && Sell6_1 < Sell6_2  && Sell7_1 < Sell7_2 && Sell8_1 < Sell8_2 ) Order = SIGNAL_SELL;



   //+------------------------------------------------------------------+
   //| Signal End                                                       |
   //+------------------------------------------------------------------+


   //Buy
       if (Order == SIGNAL_BUY && ((EachTickMode && !TickCheck) || (!EachTickMode && (Bars != BarCount)))) {
          if(!IsTrade) {
         //Check free margin
            if (AccountFreeMargin() < (500 * Lots)) {
              Print("We have no money. Free Margin = ", AccountFreeMargin());
              return(0);
            }

            if (StopLossMode) StopLossLevel = Ask - StopLoss * Point; else StopLossLevel = 0.0;
            if (TakeProfitMode) TakeProfitLevel = Ask + TakeProfit * Point; else TakeProfitLevel = 0.0;

            Ticket = OrderSend(Symbol(), OP_BUY, Lots, Ask, Slippage, StopLossLevel, TakeProfitLevel, "Buy(#" + MagicNumber + ")", MagicNumber, 0, DodgerBlue);
            if(Ticket > 0) {
             if (OrderSelect(Ticket, SELECT_BY_TICKET, MODE_TRADES)) {
				    Print("BUY order opened : ", OrderOpenPrice());
                if (SignalMail) SendMail("[Signal Alert]", "[" + Symbol() + "] " + DoubleToStr(Ask, Digits) + " Open Buy");
	  		    } else {
				    Print("Error opening BUY order : ", GetLastError());
			    }
            }
            if (EachTickMode) TickCheck = True;
            if (!EachTickMode) BarCount = Bars;
            return(0);
          }
       }
  







 //Sell


  
       if (Order == SIGNAL_SELL && ((EachTickMode && !TickCheck) || (!EachTickMode && (Bars != BarCount)))) {
          if(!IsTrade) {
         //Check free margin
             if (AccountFreeMargin() < (500 * Lots)) {
                Print("We have no money. Free Margin = ", AccountFreeMargin());
                return(0);
             }

             if (StopLossMode) StopLossLevel = Bid + StopLoss * Point; else StopLossLevel = 0.0;
             if (TakeProfitMode) TakeProfitLevel = Bid - TakeProfit * Point; else TakeProfitLevel = 0.0;

             Ticket = OrderSend(Symbol(), OP_SELL, Lots, Bid, Slippage, StopLossLevel, TakeProfitLevel, "Sell(#" + MagicNumber + ")", MagicNumber, 0, DeepPink);
             if(Ticket > 0) {
                if (OrderSelect(Ticket, SELECT_BY_TICKET, MODE_TRADES)) {
				      Print("SELL order opened : ", OrderOpenPrice());
                  if (SignalMail) SendMail("[Signal Alert]", "[" + Symbol() + "] " + DoubleToStr(Bid, Digits) + " Open Sell");
			       } else {
				      Print("Error opening SELL order : ", GetLastError());
			       }
             }
             if (EachTickMode) TickCheck = True;
             if (!EachTickMode) BarCount = Bars;
             return(0);
          }
       }

     } // YesStop
   } // NumOrders

   if (!EachTickMode) BarCount = Bars;

   return(0);
}

//+------------------------------------------------------------------+
// Return true if time is not in session for trading
bool CheckOutsideSession(int SessionStart, int SessionStop, int ct)
{

   if (SessionStart < SessionStop)
   {
     if (ct >= SessionStart && ct <= SessionStop) return (false); else return(true);
   }
   else
   {
      if (ct > SessionStop && ct < SessionStart) return (true); else return(false);
   }
}

bool CheckTradingTimes()
{
   bool StopTrading;
   int ct;
   ct = Hour() * 100 + Minute();
   
     StopTrading = true;

     if (TradeSession1 == 1)
     {
        StopTrading = CheckOutsideSession(Session1Start, Session1Stop, ct);
     }
     if (StopTrading == true)
     {

       if (TradeSession2 == 1)
       {
         StopTrading = CheckOutsideSession(Session2Start, Session2Stop, ct);
       }
     }
     if (StopTrading == true)
     {

       if (TradeSession3 == 1)
       {
         StopTrading = CheckOutsideSession(Session3Start, Session3Stop, ct);
       }
     }
     if (StopTrading == true)
     {

       if (TradeSession4 == 1)
       {
         StopTrading = CheckOutsideSession(Session4Start, Session4Stop, ct);
       }
     }
     if (StopTrading == true)
     {

       if (TradeSession5 == 1)
       {
         StopTrading = CheckOutsideSession(Session5Start, Session5Stop, ct);
       }
     }
     
     return(StopTrading);
}

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


// Functions for MagicNumber Calculations
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);
}

//+------------------------------------------------------------------+
//| 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);
   }
}


