//+------------------------------------------------------------------+
//|                                                      Smart S.mq4 |
//|                                        Copyright © 2007, LEGRUPO |
//|                                           http://www.legrupo.com |
//|                                                     Version: 1.0 |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2007, LEGRUPO"
#property link      "http://www.legrupo.com"

extern bool UseStopLoss = true;
extern double TakeProfit = 200.0;
extern double StopLoss = 150.0;
extern double LotSize = 0.1;

extern int ShortMA = 6; 
extern int LongMA  = 36;
extern bool   UseCompletedBars = true;

extern double Slippage = 4;
extern string BuyComment = "Smart S BUY";
extern string SellComment = "Smart S SELL";
extern int ExpertID = 334488;

datetime timeprev=0;
bool EnterLong = false;
bool ExitLong  = false;
bool EnterShort = false;
bool ExitShort = false;
static color   EnterLongColor = Green;
static color  EnterShortColor = Red;
static color    ExitLongColor = Blue;
static color   ExitShortColor = Pink;
//---- If using pending orders and if you need an expiration enter the value here
static int     EXPIRATION     = 0;
//+------------------------------------------------------------------+
//| expert initialization function                                   |
//+------------------------------------------------------------------+
int init()
  {
//----
   
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| expert deinitialization function                                 |
//+------------------------------------------------------------------+
int deinit()
  {
//----
   
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+
int start()
  {
//----
   int RealTime = 0;
     if( UseCompletedBars )
     {
      if(timeprev==Time[0]){return(0);} timeprev = Time[0];
      RealTime = 1;
     }
   double MA11 = iMA(NULL,0,ShortMA,0,MODE_LWMA, PRICE_TYPICAL,0+RealTime);
   double MA12 = iMA(NULL,0,ShortMA,0,MODE_LWMA, PRICE_TYPICAL,1+RealTime);
   double MA21 = iMA(NULL,0,LongMA,0,MODE_LWMA, PRICE_TYPICAL,0+RealTime);
   double MA22 = iMA(NULL,0,LongMA,0,MODE_LWMA, PRICE_TYPICAL,1+RealTime);
   
   EnterLong = false;
   ExitLong  = false;
   EnterShort = false;
   ExitShort = false;

   if( MA11 > MA21 && MA12 < MA22 ) { EnterLong = True; }
   if( MA11 < MA21 && MA12 > MA22 ) { EnterShort = True; }
   
   int MagicNumber = 0;
   MagicNumber = MakeMagicNumber( ExpertID, false );
   // ENTER LONG CONDITION
   if(EnterLong == true && CountLongs(MagicNumber)== 0 && ParabolicSAR() == "underneath_the_candles" && MACD() == "buy")
   {
      //CLOSE OPEN ORDER
      CloseShorts(MagicNumber);
      // PLACE THE ORDER
      OrderSend(Symbol(),OP_BUY,LotSize,Ask,Slippage,StopLong(Bid,StopLoss),TakeLong(Ask,TakeProfit),BuyComment,MagicNumber,EXPIRATION,EnterLongColor);
   } 
   // ENTER SHORT CONDITION
   if(EnterShort == true && CountShorts(MagicNumber)== 0 && ParabolicSAR() == "above_the_candles" && MACD() == "sell")
   {
      //CLOSE OPEN ORDER
      CloseLongs(MagicNumber);
      // PLACE THE ORDER
      OrderSend(Symbol(),OP_SELL,LotSize,Bid,Slippage,StopShort(Ask,StopLoss),TakeShort(Bid,TakeProfit),SellComment,MagicNumber,EXPIRATION,EnterShortColor);
   }
   Print(MACD());
//----
   return(0);
  }
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
//|                     EXTERNAL FUNCTIONS                           |
//|     YOU SHOULD NOT HAVE TO MODIFY ANYTHING BELOW THIS BOX        |
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
//| Check to see if MACD confirms the trade                          |
//+------------------------------------------------------------------+
string MACD() {
   double MacdCurrent, MacdPrevious, SignalCurrent;
   double SignalPrevious, MaCurrent, MaPrevious;
   double MACDOpenLevel=3;
   double MACDCloseLevel=2;
   double MATrendPeriod=26;
   MacdCurrent=iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_MAIN,0);
   MacdPrevious=iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_MAIN,1);
   SignalCurrent=iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_SIGNAL,0);
   SignalPrevious=iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_SIGNAL,1);
   MaCurrent=iMA(NULL,0,MATrendPeriod,0,MODE_EMA,PRICE_CLOSE,0);
   MaPrevious=iMA(NULL,0,MATrendPeriod,0,MODE_EMA,PRICE_CLOSE,1);
   // check for long position (BUY) possibility
      if(MacdCurrent<0 && MacdCurrent>SignalCurrent && MacdPrevious<SignalPrevious &&
         MathAbs(MacdCurrent)>(MACDOpenLevel*Point) && MaCurrent>MaPrevious)
        {
            return("buy");
        }
      // check for short position (SELL) possibility
      if(MacdCurrent>0 && MacdCurrent<SignalCurrent && MacdPrevious>SignalPrevious && 
         MacdCurrent>(MACDOpenLevel*Point) && MaCurrent<MaPrevious)
        {
            return("sell");
        }
   
   return("sorry_no_good_trade");
}

//+------------------------------------------------------------------+
//| Check to see where is parabolic SAR                              |
//+------------------------------------------------------------------+
string ParabolicSAR()
{
   double PSarPrevious, PSARCurrent;
   
   PSarPrevious = iSAR(NULL,0,0.0072,0.5,1);
   PSARCurrent = iSAR(NULL,0,0.0072,0.5,0);
   
   //Sell Signal
   if (PSARCurrent > iOpen(NULL,0,0)) {
      return("above_the_candles");
   } else {
      return("underneath_the_candles");
   }
   return("nothing?");
}

//+------------------------------------------------------------------+
//| Make Magic Number                                                |
//+------------------------------------------------------------------+
int MakeMagicNumber( int ExpertID, bool TimeSpecific )
{
   int SymbolCode  = 0;
   int PeriodCode  = 0;
   int MagicNumber = 0; 
   
   //---- Symbol Code
        if( Symbol() == "AUDCAD" || Symbol() == "AUDCADm" ) { SymbolCode = 1000; }
   else if( Symbol() == "AUDJPY" || Symbol() == "AUDJPYm" ) { SymbolCode = 2000; }
   else if( Symbol() == "AUDNZD" || Symbol() == "AUDNZDm" ) { SymbolCode = 3000; }
   else if( Symbol() == "AUDUSD" || Symbol() == "AUDUSDm" ) { SymbolCode = 4000; }
   else if( Symbol() == "CHFJPY" || Symbol() == "CHFJPYm" ) { SymbolCode = 5000; }
   else if( Symbol() == "EURAUD" || Symbol() == "EURAUDm" ) { SymbolCode = 6000; }
   else if( Symbol() == "EURCAD" || Symbol() == "EURCADm" ) { SymbolCode = 7000; }
   else if( Symbol() == "EURCHF" || Symbol() == "EURCHFm" ) { SymbolCode = 8000; }
   else if( Symbol() == "EURGBP" || Symbol() == "EURGBPm" ) { SymbolCode = 9000; }
   else if( Symbol() == "EURJPY" || Symbol() == "EURJPYm" ) { SymbolCode = 1000; }
   else if( Symbol() == "EURUSD" || Symbol() == "EURUSDm" ) { SymbolCode = 1100; }
   else if( Symbol() == "GBPCHF" || Symbol() == "GBPCHFm" ) { SymbolCode = 1200; }
   else if( Symbol() == "GBPJPY" || Symbol() == "GBPJPYm" ) { SymbolCode = 1300; }
   else if( Symbol() == "GBPUSD" || Symbol() == "GBPUSDm" ) { SymbolCode = 1400; }
   else if( Symbol() == "NZDJPY" || Symbol() == "NZDJPYm" ) { SymbolCode = 1500; }
   else if( Symbol() == "NZDUSD" || Symbol() == "NZDUSDm" ) { SymbolCode = 1600; }
   else if( Symbol() == "USDCAD" || Symbol() == "USDCADm" ) { SymbolCode = 1700; }
   else if( Symbol() == "USDCHF" || Symbol() == "USDCHFm" ) { SymbolCode = 1800; }
   else if( Symbol() == "USDJPY" || Symbol() == "USDJPYm" ) { SymbolCode = 1900; }
                     
   
   //---- Period Code
   if( TimeSpecific )
   {
              if( Period() == 1 )    { PeriodCode = 10; }
         else if( Period() == 5 )    { PeriodCode = 20; }
         else if( Period() == 15 )   { PeriodCode = 30; }
         else if( Period() == 30 )   { PeriodCode = 40; }
         else if( Period() == 60 )   { PeriodCode = 50; }
         else if( Period() == 240 )  { PeriodCode = 60; }
         else if( Period() == 1440 ) { PeriodCode = 70; }
         else if( Period() == 10080 ){ PeriodCode = 80; }
   }
   else
   {
      PeriodCode = 0;
   }
   //---- Calculate MagicNumber
   MagicNumber = ExpertID+SymbolCode+PeriodCode;
   return(MagicNumber);
}
//+------------------------------------------------------------------+
//| Calculate concurrent Long position                               |
//+------------------------------------------------------------------+
int CountLongs(int MagicNumber)
{
 int count=0;
 int trade;
 int trades=OrdersTotal();
 for(trade=0;trade<trades;trade++)
 {
  OrderSelect(trade,SELECT_BY_POS,MODE_TRADES);
  
  if( OrderSymbol()!=Symbol() || OrderMagicNumber() != MagicNumber )
   continue;
   
  if(OrderType()==OP_BUY)
   count++;
 }//for
 return(count);
}
//+------------------------------------------------------------------+
//| Calculate concurrent short position                              |
//+------------------------------------------------------------------+
int CountShorts(int MagicNumber)
{
 int count=0;
 int trade;
 int trades=OrdersTotal();
 for(trade=0;trade<trades;trade++)
 {
  OrderSelect(trade,SELECT_BY_POS,MODE_TRADES);
  
  if(OrderSymbol()!=Symbol() || OrderMagicNumber() != MagicNumber )
   continue;
   
  if(OrderType()==OP_SELL)
  count++;
 }//for
 return(count);
}
//+------------------------------------------------------------------+
//| Close Long Position                                              |
//+------------------------------------------------------------------+
void CloseLongs(int MagicNumber)
{
 int i = OrdersTotal();
 
 while( CountLongs(MagicNumber) != 0 && i >= 0 )
 {  
   OrderSelect(i,SELECT_BY_POS,MODE_TRADES);
   
   if( OrderSymbol() != Symbol() || OrderMagicNumber() != MagicNumber )
   {
     i--;
     continue;
   }
   else if(OrderType()==OP_BUY || OrderType()== OP_BUYLIMIT)
   {
     OrderClose(OrderTicket(),OrderLots(),Bid,Slippage,ExitLongColor);
     i--;
   }
 }
}
//+------------------------------------------------------------------+
//| Close Short Position                                             |
//+------------------------------------------------------------------+
void CloseShorts(int MagicNumber)
{
 int i = OrdersTotal();
 
 while( CountShorts(MagicNumber) != 0 && i >= 0 )
 {  
   OrderSelect(i,SELECT_BY_POS,MODE_TRADES);
   
   if( OrderSymbol() != Symbol() || OrderMagicNumber() != MagicNumber)
   {
     i--;
     continue;
   }
   else if(OrderType()== OP_SELL || OrderType()==OP_SELLLIMIT )
  {
   OrderClose(OrderTicket(),OrderLots(),Ask,Slippage,ExitShortColor);
  }
 }
}

//+------------------------------------------------------------------+
//| Calculate Stop Long                                              |
//+------------------------------------------------------------------+
double StopLong(double price,int stop)
{
 if(stop==0)
 {
  return(0);
 }
 else
 {
  return(price-(stop*Point));
 }
}
//+------------------------------------------------------------------+
//| Calculate Stop Short                                             |
//+------------------------------------------------------------------+
double StopShort(double price,int stop)
{
 if(stop==0)
 {
  return(0);
 }
 else
 {
  return(price+(stop*Point));
 }
}
//+------------------------------------------------------------------+
//| Calculate Profit Target Long                                     |
//+------------------------------------------------------------------+
double TakeLong(double price,int take)
{
 if(take==0) {  return(0);}
 else        {  return(price+(take*Point));}
}
//+------------------------------------------------------------------+
//| Calculate Profit Target Short                                     |
//+------------------------------------------------------------------+
double TakeShort(double price,int take)
{
 if(take==0) {  return(0);}
 else        {  return(price-(take*Point));}
}