//+------------------------------------------------------------------+
//|                                                   DayTrading.mq4 |
//|                               Copyright © 2005, NazFunds Company |
//|                                          http://www.nazfunds.com |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2005, NazFunds Company"
#property link      "http://www.nazfunds.com"
// A reliable expert, use it on 5 min charts with 20/pips profit limit. 
// Do not place any stop loss. No worries, check the results 
//
// Robert Hill modifications
// 1/19/2007
// Added MagicNumber identifier instead of nameEA
// Added setup to use nameEA and symbol and timeframe for commet in order
// Added MoneyManagement
// Added selection of mini or standard Accounts
//+---------------------------------------------------+
//|Account functions                                  |
//+---------------------------------------------------+
extern bool AccountIsMini = true;      // false for standard account. 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 int TotalLosses_Before_Decrease = 3;   // Used to set if multiple orders are placed at the same time, initial entry loss isn't used.
extern double DecreaseFactor = 4;       // Used to decrease lot size after a loss is experienced to protect equity.  Recommended not to change.
extern double Lots = 1.0;             // standard lot size. 
extern double MaxLots = 30.0;

extern double trailingStop = 15;            // trail stop in points
extern double takeProfit   = 20;            // recomended  no more than 20
extern double stopLoss     = 0;             // do not use s/l
extern double slippage     = 3;
// EA identifier. Allows for several co-existing EA with different values
extern string nameEA       = "DayTrading";  
//----
double macdHistCurrent, macdHistPrevious, macdSignalCurrent, macdSignalPrevious;
double stochHistCurrent, stochHistPrevious, stochSignalCurrent, stochSignalPrevious;
double sarCurrent, sarPrevious, momCurrent, momPrevious;
double realTP, realSL;
bool isBuying = false, isSelling = false, isClosing = false;
int cnt, ticket;
double lotMM;
int MagicNumber;
string setup;
//+------------------------------------------------------------------+
//| expert initialization function                                   |
//+------------------------------------------------------------------+
int init() 
  {
	MagicNumber = 3000 + func_Symbol2Val(Symbol())*100 + func_TimeFrame_Const2Val(Period()); 
   setup=nameEA + "_" + Symbol() + "_" + func_TimeFrame_Val2String(func_TimeFrame_Const2Val(Period()));
   return(0);
  }
//+------------------------------------------------------------------+
//| expert deinitialization function                                 |
//+------------------------------------------------------------------+
int deinit() 
  {
   return(0);
  }
//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+
int start() 
  {
// Check for invalid bars and takeprofit
   if(Bars < 200) 
     {
       Print("Not enough bars for this strategy - ", nameEA);
       return(-1);
     }
// Calculate indicators' value  
   calculateIndicators();                       
// Control open trades
   int totalOrders = OrdersTotal();
   int numPos = 0;
// scan all orders and positions...
   for(cnt = 0; cnt < totalOrders; cnt++) 
     {        
       // the next line will check for ONLY market trades, not entry orders
       OrderSelect(cnt, SELECT_BY_POS); 
       // only look for this symbol, and only orders from this EA        
       if(OrderSymbol() == Symbol() && OrderType() <= OP_SELL && OrderMagicNumber() == MagicNumber) 
         {   
           numPos++;
           // Check for close signal for bought trade
           if(OrderType() == OP_BUY)  
             {           
               if(isSelling || isClosing) 
                 {
                   // Close bought trade
                   OrderClose(OrderTicket(),OrderLots(),Bid,slippage,Violet);   
                   numPos--;
                   prtAlert("Day Trading: Closing BUY order");
                 }         
               // Check trailing stop
               if(trailingStop > 0) 
                 {             
                   if(Bid-OrderOpenPrice() > trailingStop*Point) 
                     {
                       if(OrderStopLoss() < (Bid - trailingStop*Point))
                           OrderModify(OrderTicket(), OrderOpenPrice(), 
                                       Bid-trailingStop*Point,OrderTakeProfit(),0,Blue);
                     }
                 }
             } 
           else 
             // Check sold trade for close signal
             {                              
               if(isBuying || isClosing) 
                 {
                   OrderClose(OrderTicket(), OrderLots(), Ask, slippage, Violet);
                   prtAlert("Day Trading: Closing SELL order");
                   numPos--;
                 } 
               if(trailingStop > 0) 
                 // Control trailing stop
                 {             
                   if(OrderOpenPrice() - Ask > trailingStop*Point) 
                     {
                       if(OrderStopLoss() == 0 || OrderStopLoss() > Ask + trailingStop*Point)
                           OrderModify(OrderTicket(), OrderOpenPrice(), 
                                       Ask + trailingStop*Point, OrderTakeProfit(),
                                       0, Red);
                     }           
                 } 
             }
         }
     }
   // If there is no open trade for this pair and this EA
   if(numPos < 1) 
     {
       lotMM = GetLots();   
       if(AccountFreeMargin() < 1000*lotMM) 
         {
           Print("Not enough money to trade ", lotMM, " lots. Strategy:", setup);
           return(0);
         }
       // Check for BUY entry signal
       if(isBuying && !isSelling && !isClosing) 
         {  
           if(stopLoss > 0)
               realSL = Ask - stopLoss * Point;
           if(takeProfit > 0)
               realTP = Ask + takeProfit * Point;
           // Buy
           ticket = OrderSend(Symbol(), OP_BUY, lotMM, Ask, slippage, realSL, realTP, 
                    setup, MagicNumber,0,Red);  
           if(ticket < 0)
               Print("OrderSend (",setup,") failed with error #", GetLastError());
           prtAlert("Day Trading: Buying"); 
         }
       // Check for SELL entry signal
       if(isSelling && !isBuying && !isClosing) 
         {  
           if(stopLoss > 0)
               realSL = Bid + stopLoss * Point;
           if(takeProfit > 0)
               realTP = Bid - takeProfit * Point;
           // Sell
           ticket = OrderSend(Symbol(), OP_SELL, lotMM, Bid, slippage, realSL, realTP, 
                              setup, MagicNumber, 0, Red); 
           if(ticket < 0)
               Print("OrderSend (",setup,") failed with error #", GetLastError());
           prtAlert("Day Trading: Selling"); 
         }
     }
   return(0);
  }
//+------------------------------------------------------------------+
//|  Calculate indicators' value                                     |
//+------------------------------------------------------------------+
void calculateIndicators() 
  { 
   macdHistCurrent     = iMACD(NULL, 0, 12, 26, 9, PRICE_OPEN, MODE_MAIN, 0);   
   macdHistPrevious    = iMACD(NULL, 0, 12, 26, 9, PRICE_OPEN, MODE_MAIN, 1);   
   macdSignalCurrent   = iMACD(NULL, 0, 12, 26, 9, PRICE_OPEN, MODE_SIGNAL, 0); 
   macdSignalPrevious  = iMACD(NULL, 0, 12, 26, 9, PRICE_OPEN, MODE_SIGNAL, 1); 
   stochHistCurrent    = iStochastic(NULL, 0, 5, 3, 3, MODE_SMA, 0, MODE_MAIN, 0);
   stochHistPrevious   = iStochastic(NULL, 0, 5, 3, 3, MODE_SMA, 0, MODE_MAIN, 1);
   stochSignalCurrent  = iStochastic(NULL, 0, 5, 3, 3, MODE_SMA, 0, MODE_SIGNAL, 0);
   stochSignalPrevious = iStochastic(NULL, 0, 5, 3, 3, MODE_SMA, 0, MODE_SIGNAL, 1);
   // Parabolic Sar Current
   sarCurrent          = iSAR(NULL, 0, 0.02, 0.2, 0);
   // Parabolic Sar Previuos           
   sarPrevious         = iSAR(NULL, 0, 0.02, 0.2, 1);
   // Momentum Current           
   momCurrent          = iMomentum(NULL, 0, 14, PRICE_OPEN, 0);
   // Momentum Previous 
   momPrevious         = iMomentum(NULL, 0, 14, PRICE_OPEN, 1); 
   // Check for BUY, SELL, and CLOSE signal
   isBuying  = (sarCurrent <= Ask && sarPrevious>sarCurrent && momCurrent < 100 && 
                macdHistCurrent < macdSignalCurrent && stochHistCurrent < 35);
   isSelling = (sarCurrent >= Bid && sarPrevious<sarCurrent && momCurrent > 100 && 
                macdHistCurrent > macdSignalCurrent && stochHistCurrent > 60);
   isClosing = false;
  }


//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void prtAlert(string str = "") 
  {
   Print(str);
   Alert(str);
//   SpeechText(str,SPEECH_ENGLISH);
//   SendMail("Subject EA",str);
  }

//+------------------------------------------------------------------+
//| 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;
   int    orders=HistoryTotal();     // history orders total
   int    losses=0;                  // number of losses orders without a break
//---- select lot size
   lot=NormalizeDouble(MathFloor(AccountFreeMargin()*TradeSizePercent/10000)/10,1);
   
  
//+------------------------------------------------------------------+  
//|  Calculate number of losses orders without a break               |
//+------------------------------------------------------------------+

   if(DecreaseFactor>0)
     {
      for(int i=orders-1;i>=0;i--)
        {
         if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY)==false) { Print("Error in history!"); break; }
         if(OrderSymbol()!=Symbol() || OrderType()>OP_SELL || OrderMagicNumber()!=MagicNumber) continue;
         //----
         if(OrderProfit()>0) break;
         if(OrderProfit()<0) losses++;
        }
      if(losses>TotalLosses_Before_Decrease) lot=NormalizeDouble(lot-lot*losses/DecreaseFactor,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);
}
//+------------------------------------------------------------------+