//+------------------------------------------------------------------+
#define SIGNAL_NONE 0
#define SIGNAL_BUY   1
#define SIGNAL_SELL  2

#property copyright "James Richards"

//Define external variables

extern string Remark1              = "== Main Settings ==";
extern int    MagicNumber          = 0;
extern string comment              = "Lock Stock & 3 smoking TFs EA";
extern bool   SignalsOnly          = False;
extern bool   Alerts               = False;
extern bool   SignalMail           = False;
extern bool   PlaySounds           = False;
extern bool   ECNBroker            = False;
extern bool   EachTickMode         = False;
extern double Lots                 = 0.01;
extern int    Slippage             = 5;
extern  bool  UseStopLoss          = False;
extern int    StopLoss             = 100;
extern bool   UseTakeProfit        = False;
extern int    TakeProfit           = 60;

extern int    high_stoch_threshold = 80;
extern int    low_stoch_threshold  = 20;
extern string Remark2              = "Lowest stochastic timeframe in minutes";
extern int    LTF                  = 5;
extern string Remark3              = "Lowest stochastic k,d & s settings";
extern int    LTF_k                = 5;
extern int    LTF_d                = 3;
extern int    LTF_s                = 3;
extern string Remark8              = "Lowest stochastic MA Method, 0 = simple ma, 1 = expo ma, 2 = smoothed ma, 3 = lwma";
extern int    LTF_ma_method        = 3;
extern string Remark11             = "Lowest stochastic Price Method, 0 = Low/High, 1 = Close/Close";
extern int    LTF_price_method     = 1;

extern string Remark4              = "Medium stochastic timeframe in minutes";
extern int    MTF                  = 60;
extern string Remark5              = "Medium stochastic k,d & s settings";
extern int    MTF_k                = 14;
extern int    MTF_d                = 3;
extern int    MTF_s                = 3;
extern string Remark9              = "Medium stochastic MA Method, 0 = simple ma, 1 = expo ma, 2 = smoothed ma, 3 = lwma";
extern int    MTF_ma_method        = 3;
extern string Remark12             = "Medium stochastic Price Method, 0 = Low/High, 1 = Close/Close";
extern int    MTF_price_method     = 1;

extern string Remark6              = "Highest stochastic timeframe in minutes";
extern int    HTF                  = 240;
extern string Remark7              = "Highest stochastic k,d & s settings";
extern int    HTF_k                = 10;
extern int    HTF_d                = 3;
extern int    HTF_s                = 3;
extern string Remark10             = "Highest stochastic MA Method, 0 = simple ma, 1 = expo ma, 2 = smoothed ma, 3 = lwma";
extern int    HTF_ma_method        = 3;
extern string Remark13             = "Highest stochastic Price Method, 0 = Low/High, 1 = Close/Close";
extern int    HTF_price_method     = 1;



string        SymbolUsed;
int           TickCount            = 0;
int           RecordDay            = -1;
string        UserName             = "";
bool          ShowDiagnostics      = False;

int           TradeBar;
int           TradesThisBar;

int           OpenBarCount;
int           CloseBarCount;

string        BrokerType           = "4-Digit Broker";
double        BrokerMultiplier     = 1;

int           Current;
bool          TickCheck            = False;

//+------------------------------------------------------------------+
//| expert initialization function                                   |
//+------------------------------------------------------------------+
int init() {
   OpenBarCount = Bars;
   CloseBarCount = Bars;
   
   TickCount = 0;
   
   SymbolUsed = StringSubstr(Symbol(), 0, 6);   
   RecordDay = TimeDayOfYear(TimeCurrent());
   
   if(!IsDllsAllowed())
      {
      Alert("ERROR: Please enable DLL calls.");
      Comment("Enable DLL Calls");
      return(0);
      }  

   
   if(Digits == 3 || Digits == 5)
      {
      BrokerType = "5-Digit Broker";
      BrokerMultiplier = 10;
      }


   if (EachTickMode) Current = 0; else Current = 1;

   return(0);
}
//+------------------------------------------------------------------+
//| expert deinitialization function                                 |
//+------------------------------------------------------------------+
int deinit() {

   return(0);
}
//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+
int start() 

//This section defines the variables//
{
   int Order                     = SIGNAL_NONE;
   int Total;
   int Ticket;
   
   double StopLossLevel; 
   double TakeProfitLevel;

   double HTF_stochastic = iStochastic(0,HTF,HTF_k,HTF_d,HTF_s,HTF_ma_method,HTF_price_method,0,1);
   double MTF_stochastic = iStochastic(0,MTF,MTF_k,MTF_d,MTF_s,MTF_ma_method,MTF_price_method,0,1);
   double LTF_stochastic = iStochastic(0,LTF,LTF_k,LTF_d,LTF_s,LTF_ma_method,LTF_price_method,0,1);
  
   bool three_tf_overbought = false;
   bool three_tf_oversold   = false;
   
   
   string TradeTrigger = "None";

   if (EachTickMode && Bars != CloseBarCount) TickCheck = False;
   Total = OrdersTotal();
   Order = SIGNAL_NONE;

//This section of code limits the trades per bar

   if(TradeBar != Bars)
   {
   TradeBar = Bars;
   TradesThisBar = 0;
   }


//This section defines the logic and the logical conditions that must be met in order to take a trade//

if(HTF_stochastic > high_stoch_threshold && MTF_stochastic > high_stoch_threshold && LTF_stochastic > high_stoch_threshold) three_tf_overbought = true;
if(HTF_stochastic < low_stoch_threshold && MTF_stochastic < low_stoch_threshold && LTF_stochastic < low_stoch_threshold) three_tf_oversold   = true;


if(three_tf_oversold)   TradeTrigger = "Open Long"; 
if(three_tf_overbought) TradeTrigger = "Open Short";



   //This section checks for open trades
   bool IsTrade = False;

   for (int i = 0; i < Total; i ++) {
      OrderSelect(i, SELECT_BY_POS, MODE_TRADES);
      if(OrderType() <= OP_SELL &&  OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber) 
         IsTrade = True;
        }
            
            
//This section defines the type of trade to be taken

if(TradeTrigger == "Open Long") Order = SIGNAL_BUY;
if(TradeTrigger == "Open Short") Order = SIGNAL_SELL;



   //Buy order
   if (Order == SIGNAL_BUY && ((EachTickMode && !TickCheck) || (!EachTickMode && (Bars != OpenBarCount)))) {
      if(SignalsOnly) {
         if (SignalMail) SendMail("Signal Alert - 3 TFs are oversold on" + Symbol(),"See subject");
         if (Alerts) Alert("[" + Symbol() + "] " + DoubleToStr(Ask, Digits) + "Buy Signal");
         if (PlaySounds) PlaySound("alert.wav");
     
      }
      
      if(!IsTrade && !SignalsOnly && TradesThisBar < 1) {
         //Check free margin
         if (AccountFreeMarginCheck(Symbol(), OP_BUY, Lots) < 0) {
            Print("We have no money. Free Margin = ", AccountFreeMargin());
            return(0);
         }

         if (UseStopLoss) StopLossLevel = Ask - StopLoss * Point; else StopLossLevel = 0;
         if (UseTakeProfit) TakeProfitLevel = Ask + TakeProfit * Point; else TakeProfitLevel = 0;
         if(ECNBroker) Ticket = OrderModify(OrderSend(Symbol(), OP_BUY, Lots, Ask, Slippage, 0, 0, "Buy(#" + MagicNumber + ")", MagicNumber, comment, DodgerBlue), OrderOpenPrice(), StopLossLevel, TakeProfitLevel, 0, CLR_NONE);
         if(!ECNBroker) Ticket = OrderSend(Symbol(), OP_BUY, Lots, Ask, Slippage, StopLossLevel, TakeProfitLevel, "Buy(#" + MagicNumber + ")", MagicNumber, comment, DodgerBlue);
            if(Ticket > 0) {
               if (OrderSelect(Ticket, SELECT_BY_TICKET, MODE_TRADES)) {
				  Print("BUY order opened : ", OrderOpenPrice());
                  if (SignalMail) SendMail("Order Alert - Lock Stock EA just bought" + Symbol() + DoubleToStr(Ask, Digits),"See subject");
			         if (Alerts) Alert("[" + Symbol() + "] " + DoubleToStr(Ask, Digits) + "Buy Signal");
                  if (PlaySounds) PlaySound("alert.wav");
                  TradesThisBar++;
			   } else {
   				Print("Error opening BUY order : ", GetLastError());
			   }
            }
            
         if (EachTickMode) TickCheck = True;
         if (!EachTickMode) OpenBarCount = Bars;
         return(0);
      }
   }

   //Sell order
   if (Order == SIGNAL_SELL && ((EachTickMode && !TickCheck) || (!EachTickMode && (Bars != OpenBarCount)))) {
      if(SignalsOnly) {
          if (SignalMail) SendMail("Signal Alert - 3 TFs are overbought on" + Symbol(),"See subject");
          if (Alerts) Alert("[" + Symbol() + "] " + DoubleToStr(Bid, Digits) + "Sell Signal");
          if (PlaySounds) PlaySound("alert.wav");
         }
      if(!IsTrade && !SignalsOnly && TradesThisBar < 1) {
         //Check free margin
         if (AccountFreeMarginCheck(Symbol(), OP_SELL, Lots) < 0) {
            Print("We have no money. Free Margin = ", AccountFreeMargin());
            return(0);
         }

         if (UseStopLoss) StopLossLevel = Bid + StopLoss * Point; else StopLossLevel = 0;
         if (UseTakeProfit) TakeProfitLevel = Bid - TakeProfit * Point; else TakeProfitLevel = 0;

         if(ECNBroker) Ticket = OrderModify(OrderSend(Symbol(), OP_SELL, Lots, Bid, Slippage, 0, 0, "Sell(#" + MagicNumber + ")", MagicNumber, comment, DeepPink), OrderOpenPrice(), StopLossLevel, TakeProfitLevel, 0, CLR_NONE);
         if(!ECNBroker) Ticket = OrderSend(Symbol(), OP_SELL, Lots, Bid, Slippage, StopLossLevel, TakeProfitLevel, "Sell(#" + MagicNumber + ")", MagicNumber, comment, DeepPink);
         if(Ticket > 0) {
            if (OrderSelect(Ticket, SELECT_BY_TICKET, MODE_TRADES)) {
				Print("SELL order opened : ", OrderOpenPrice());
                if (SignalMail) SendMail("Order Alert - Lock Stock EA just sold" + Symbol() + DoubleToStr(Ask, Digits),"See subject");
			       if (Alerts) Alert("[" + Symbol() + "] " + DoubleToStr(Bid, Digits) + "Sell Signal");
                if (PlaySounds) PlaySound("alert.wav");
                TradesThisBar++;
			} else {
				Print("Error opening SELL order : ", GetLastError());
			}
         }
         if (EachTickMode) TickCheck = True;
         if (!EachTickMode) OpenBarCount = Bars;
         return(0);
      }
   }

   if (!EachTickMode) CloseBarCount = Bars;
   
   return(0);
}

//END