//+------------------------------------------------------------------+
//                                         KeyToTheMint_v5_TG.mq4    |
//|                                   Copyright © 2007, Randy Knight |
//|                                           knight.randy@gmail.com |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2008, Randy Knight"
#property link      "knight.randy@gmail.com"


#define SIGNAL_NONE 0
#define SIGNAL_BUY   1
#define SIGNAL_SELL  2


extern string sec1 = "******** EA Config ************";
extern string  CommentString = "KeyToTheMint";
extern bool    SignalMail = true;
extern bool    SignalMailAllSignals = false;
extern bool    UseHourTrade = false;
extern int        FromHourTrade = 7;
extern int        ToHourTrade = 15;
extern bool    Verbose = true;
extern bool    SundayCandleExists = true;
extern int     FastTF = 60;
extern int     SlowTF = 1440;


extern string sec2 = "******** Trade Management *********";
extern bool    ATR14StopTP = true;
extern int        ATR14StopTPDivisor = 5;
extern int     TakeProfit = 30;
extern int     StopLoss = 30;
extern double  Lots = 3;
extern int     Slippage = 10;
extern int     MaxTradesDaily = 1;
extern bool    ExitOnChange = true;
extern bool    EntryOnStochExtremes = false;
extern double     StochOverSoldLevel = 10;
extern double     StochOverBoughtLevel = 80;
extern bool    AddSpreadToStopTP = true;

extern string sec3 = "**********INDICATORS *****************";
extern string ind1 = "stochastics";
extern int FastK = 8;
extern int SlowK = 3;
extern int SlowD = 3;
extern string ind2 = "rsi";
extern int RSI = 13;
extern string ind3 = "ema";
extern int EMAFast = 5;
extern int EMASlow = 8;
extern string ind4 = "atr (used for stop/tp calculation";
extern int ATR = 14;


int start() 
{   
   bool TradingHours = true;
   if (UseHourTrade == true)
   {
      if((Hour()>=FromHourTrade)&&(Hour()<=ToHourTrade))
      {
         TradingHours = true;
      }         
      else
        {
         TradingHours = false;
        }
   }

   //Calculate Indicators
   if (SundayCandleExists == true && DayOfWeek() == 1)
      int DayShift = 2;
   else  
      DayShift = 1;
      
   double EMAFastDaily = iMA(NULL, SlowTF, EMAFast, 0,MODE_EMA, PRICE_CLOSE, DayShift);
   double EMASlowDaily = iMA(NULL, SlowTF, EMASlow, 0, MODE_EMA, PRICE_OPEN, DayShift);
   double EMAFastHourly = iMA(NULL, FastTF, EMAFast, 0, MODE_EMA, PRICE_CLOSE, 0);
   double EMASlowHourly = iMA(NULL, FastTF, EMASlow, 0, MODE_EMA, PRICE_OPEN, 0);
   
   double StochHourly = iCustom(NULL, FastTF, "StochasticDiNapoli_v1", FastK, SlowK, SlowD, 0, 0);
   double StochHourly2 = iCustom(NULL, FastTF, "StochasticDiNapoli_v1", FastK, SlowK, SlowD,1, 0);
   
   double ATR14Daily = iATR(NULL,SlowTF,14,DayShift);
   int StopTPLevel = (ATR14Daily / ATR14StopTPDivisor) / Point;

   double RSIDaily = iRSI(NULL, SlowTF, RSI, 0, DayShift);
   double RSIHourly = iRSI(NULL, FastTF, RSI, 0, 0);
   double RSILine = 50;
 
   //daily direction
   string   daily_direction = "no trade";
   
   if ((EMAFastDaily > EMASlowDaily) && (RSIDaily > RSILine)) //&& (StochDaily > StochDaily2))
      daily_direction ="long";
   
   if ((EMAFastDaily < EMASlowDaily) && (RSIDaily < RSILine)) //  && (StochDaily < StochDaily2))
      daily_direction ="short";
   
   
   string   hourly_direction = "no trade";
   
   if ((EMAFastHourly > EMASlowHourly) && (RSIHourly > RSILine) && (StochHourly > StochHourly2))
   {
      hourly_direction ="long";
   
      if (EntryOnStochExtremes == false && StochHourly > StochOverBoughtLevel)
      {
         hourly_direction = "no trade";
      }
   }      
   
   if ((EMAFastHourly < EMASlowHourly) && (RSIHourly < RSILine)  && (StochHourly < StochHourly2))
   {
      hourly_direction ="short";
      if (EntryOnStochExtremes == false && StochHourly < StochOverSoldLevel)
      {
         hourly_direction = "no trade";
      }
   }
   
   //output to screen
   if (Verbose == true)
   {
      Comment("TradingHours = ", (TradingHours),
      "\n",
      "\n","     daily trend direction= ",(daily_direction),
      "\n","     hourly trend direction= ",(hourly_direction),
      "\n","     Broker time= ",TimeToStr(TimeCurrent()),
      "\n",
      "\n","     EMAFastDaily= ",DoubleToStr(EMAFastDaily,4),
      "\n","     EMASlowDaily= ",DoubleToStr(EMASlowDaily,4),
      "\n","     RSIDaily= ",DoubleToStr(RSIDaily,4),
      "\n","     ATR14Daily= ",DoubleToStr(ATR14Daily,4),
      "\n","     ATR14StopTP= ",(StopTPLevel),
      "\n",
      "\n","     EMAFastHourly= ",DoubleToStr(EMAFastHourly,4),
      "\n","     EMASlowHourly= ",DoubleToStr(EMASlowHourly,4),
      "\n","     RSIHourly= ",DoubleToStr(RSIHourly,4),
      "\n","     StochHourly= ",DoubleToStr(StochHourly,4),
      "\n","     StochHourly2= ",DoubleToStr(StochHourly2,4));
   }
   
   if (TradingHours == false)
      return (0);
      
   if (NewBar() == false)
      return (0);      
      
   //Bail if existing order
   int Order,Total;
   Total = OrdersTotal();
   Order = SIGNAL_NONE;

   bool IsTrade = False;

   for (int i = 0; i < Total; i ++) 
   {
      OrderSelect(i, SELECT_BY_POS, MODE_TRADES);
      if((OrderSymbol() == Symbol()) && ((OrderType() == OP_SELL) || (OrderType() == OP_BUY)) && (OrderComment() == CommentString))
      {
         IsTrade = True;
         
         if (ExitOnChange == true)
         {
            //make sure indicators still valid
            if ((OrderType() == OP_BUY) && ((hourly_direction != "long")  || (daily_direction != "long")))
            {
               //exit trade
               OrderClose(OrderTicket(),OrderLots(), Bid, Slippage, Red);
               Print ("Ticket: " + OrderTicket() + " closed due to indicator change.");
               return (0);
            } 
            if ((OrderType() == OP_SELL) && ((hourly_direction != "short")  || (daily_direction != "short")))
            {
               //exit trade
               OrderClose(OrderTicket(),OrderLots(), Ask, Slippage, Red);
               Print ("Ticket: " + OrderTicket() + " closed due to indicator change.");
               return (0);
            }                          
         }
         
         return (0);
      }
   }
   
   //Bail if historical trade for today exists
   int Total2;
   Total2 = OrdersHistoryTotal();
   
   IsTrade = False;
   string TodayDate = Year() + "." + Month() + "." + Day();
   datetime dtTodayDate = StrToTime(TodayDate);
   int TradesToday = 0;
   
   for (int j = 0; j < Total2; j ++) 
   {
     
      OrderSelect(j, SELECT_BY_POS, MODE_HISTORY);
      

      if((OrderSymbol() == Symbol()) && ((OrderType() == OP_SELL) || (OrderType() == OP_BUY)) && (StringSubstr(OrderComment(),0,StringLen(CommentString)) == CommentString))
      {
         if (     (TimeYear(OrderOpenTime()) == TimeYear(dtTodayDate)) 
               && (TimeMonth(OrderOpenTime()) == TimeMonth(dtTodayDate)) 
               && (TimeDay(OrderOpenTime()) == TimeDay(dtTodayDate))
            )
         TradesToday = TradesToday + 1;
      }
   }
   
   
   if (TradesToday >= MaxTradesDaily)
   {
      if (SignalMailAllSignals == true && SignalMail == true)
      {
         SendMail("[KeyToTheMint]", "[" + Symbol() + "] " + hourly_direction + " not opened due to MaxTradesDaily.");
      }
      return (0);
   }  
         

   //Signal Exists?   
   if ((daily_direction == "long") && (hourly_direction == "long"))
      Order = SIGNAL_BUY;
      
   if ((daily_direction == "short") && (hourly_direction == "short"))
      Order = SIGNAL_SELL;


   double StopLossLevel, TakeProfitLevel;
   int Ticket;
   
   //calc TP and SL based on ATR14
   if (ATR14StopTP == true)
   {
      StopLoss = StopTPLevel;
      TakeProfit = StopTPLevel;
   }
   
   double Spread;
   //Buy
   if (Order == SIGNAL_BUY) 
   {
      //Check free margin
      if (AccountFreeMargin() < (1000 * Lots))
      {
         Print("We have no money. Free Margin = ", AccountFreeMargin());
         return(0);
      }
      
      //calc spread
      if (AddSpreadToStopTP == true)
         Spread = (Ask - Bid) / Point;
      else  
         Spread = 0;        
         

      //calc stoploss
      if (StopLoss == 0) 
         StopLossLevel = 0.0;
      else
         StopLossLevel = Ask - ((StopLoss + Spread) * Point); 

      //calc takeprofit
      if (TakeProfit == 0) 
         TakeProfitLevel = 0.0;         
      else         
         TakeProfitLevel = Ask + ((TakeProfit + Spread) * Point); 
              

      Ticket = OrderSend(Symbol(), OP_BUY, Lots, Ask, Slippage, StopLossLevel, TakeProfitLevel, CommentString, 0, 0, DodgerBlue);
      if(Ticket > 0) 
      {
         if (OrderSelect(Ticket, SELECT_BY_TICKET, MODE_TRADES)) 
         {
				Print("BUY order opened : ", OrderOpenPrice());
            if (SignalMail == true) 
               SendMail("[KeyToTheMint]", "[" + Symbol() + "] " + DoubleToStr(Ask, Digits) + " Open Buy");
			} 
			else 
			{
			   Print("Error opening BUY order : ", GetLastError());
			}
         
      }
      return(0);
   }


   //Sell
   if (Order == SIGNAL_SELL) 
   {
      //Check free margin
      if (AccountFreeMargin() < (1000 * Lots)) 
      {
         Print("We have no money. Free Margin = ", AccountFreeMargin());
         return(0);
      }
      
      //calc spread
      if (AddSpreadToStopTP == true)
         Spread = (Ask - Bid) / Point;
      else  
         Spread = 0;        
         
      //calc stoploss
      if (StopLoss == 0) 
         StopLossLevel = 0.0;
      else
         StopLossLevel = Bid + ((StopLoss + Spread)* Point); 
      
      //calc takeprofit
      if (TakeProfit == 0) 
         TakeProfitLevel = 0.0;         
      else         
         TakeProfitLevel = Bid - ((TakeProfit + Spread) * Point); 
      

      Ticket = OrderSend(Symbol(), OP_SELL, Lots, Bid, Slippage, StopLossLevel, TakeProfitLevel, CommentString, 0, 0, DeepPink);
      if(Ticket > 0) 
      {
         if (OrderSelect(Ticket, SELECT_BY_TICKET, MODE_TRADES)) 
         {
			   Print("SELL order opened : ", OrderOpenPrice());
            if (SignalMail == true) 
               SendMail("[KeyToTheMintt]", "[" + Symbol() + "] " + DoubleToStr(Bid, Digits) + " Open Sell");
			} 
			else 
			{
				Print("Error opening SELL order : ", GetLastError());
			}
      }
      return(0);
   }

   return(0);
}

bool NewBar() {

	static datetime LastTime = 0;

	if (Time[0] != LastTime) {
		LastTime = Time[0];		
		return (true);
	} else
		return (false);
}


