
// coded by Ronald Reygun
//+------------------------------------------------------------------+
#define           SIGNAL_NONE             0
#define           SIGNAL_BUY              1
#define           SIGNAL_SELL             2
#define           SIGNAL_CLOSEBUY         3
#define           SIGNAL_CLOSESELL        4

#property copyright  "Copyright@2009, Chistabo"
#property link       "chistabo@gmail.com"

extern string     Remark1                 = "== Main Settings ==";
extern int        MagicNumber             = 131313;
extern bool       SignalsOnly             = False;                      // this does not work on Strategy tester
extern bool       Alerts                  = False;
extern bool       SignalMail              = False;
extern bool       PlaySounds              = False;
extern bool       EachTickMode            = True;
extern bool       CloseOnOppositeSignal   = True;
extern double     Lots                    = 0.01;
extern bool       MoneyManagement         = False;
extern int        Risk                    = 1;
extern int        Slippage                = 50;

extern int        LookBack                = 2;                          // Bars back from current open to look for a Fractal

extern  bool      UseStopLoss             = True;
extern int        StopLoss                = 1500;
extern bool       UseTakeProfit           = true;
extern int        TakeProfit              = 1200;
extern bool       UseTrailingStop         = true;
extern int        TrailingStop            = 420;
extern bool       MoveStopOnce            = true;
extern int        MoveStopWhenPrice       = 3600;
extern int        MoveStopTo              = 100;

extern string     Remark2                 = "== Fast MA Settings ==";
extern int        MA1Period               = 3;
extern int        MA1Shift                = 0;
extern int        MA1Method               = 3;
extern int        MA1Price                = 0;

extern string     Remark3                 = "== Slow MA Settings ==";
extern int        MA2Period               = 46;
extern int        MA2Shift                = 0;
extern int        MA2Method               = 3;
extern int        MA2Price                = 0;

extern string     Remark4                 = "Trading hours are Broker time";
extern int        StartTrading            = 0;                          // Start of trading session
extern int        StopTrading             = 24;                         // end of trading session

datetime          timenowup               = 0,                          // fractals
                  timenowdn               = 0;                          // fractals

int               BarCount;
int               Current;
bool              TickCheck               = False;
//+------------------------------------------------------------------+
//| expert initialization function                                   |
//+------------------------------------------------------------------+
int init() 
   {
   BarCount = Bars;

   if (EachTickMode) Current = 0; else Current = 1;

   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;
//Money Management sequence
   if (MoneyManagement)
      {
      if (Risk < 1 || Risk > 100)
         {
         Comment ("Invalid Risk Value");
         return(0);
         }
      else
         {
         Lots = MathFloor ((AccountFreeMargin() * AccountLeverage() * Risk * Point * 100) / (Ask * MarketInfo (Symbol(), 
         MODE_LOTSIZE) * MarketInfo (Symbol(), MODE_MINLOT))) * MarketInfo (Symbol(), MODE_MINLOT);
         }
      }
//+------------------------------------------------------------------+
//| Variable Begin                                                   |
//+------------------------------------------------------------------+
/*
   double MA1A = iMA(NULL, 0, MA1Period, MA1Shift, MA1Method, MA1Price, Current + 0);
   double MA1B = iMA(NULL, 0, MA1Period, MA1Shift, MA1Method, MA1Price, Current + 1);

   double MA2A = iMA(NULL, 0, MA2Period, MA2Shift, MA2Method, MA2Price, Current + 0);
   double MA2B = iMA(NULL, 0, MA2Period, MA2Shift, MA2Method, MA2Price, Current + 1);
*/
   double   upfractal = GetFractal (MODE_UPPER),
            dnfractal = GetFractal (MODE_LOWER);
// get value for Fast Simple Moving Average 
   double   FMAPrev  = iMA (NULL, 0, MA1Period, MA1Shift, MA1Method, MA1Price, Current + 1);
   double   FMACurr  = iMA (NULL, 0, MA1Period, MA1Shift, MA1Method, MA1Price, Current);

// get value for Slow Simple Moving Average
   double   SMAPrev  = iMA (NULL, 0, MA2Period, MA2Shift, MA2Method, MA2Price, Current + 1);
   double   SMACurr  = iMA (NULL, 0, MA2Period, MA2Shift, MA2Method, MA2Price, Current);   
//+------------------------------------------------------------------+
//| Variable End                                                     |
//+------------------------------------------------------------------+
//Check position
   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;
         if (OrderType() == OP_BUY) 
            {
//Close
//+------------------------------------------------------------------+
//| Signal Begin (Exit Buy)                                           |
//+------------------------------------------------------------------+
            if (CloseOnOppositeSignal && 
               upfractal != 0
               &&
               (FMAPrev > FMACurr)
               &&
               (SMAPrev > SMACurr)) 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;
               }
//MoveOnce
            if (MoveStopOnce && MoveStopWhenPrice > 0) 
               {
               if (Bid - OrderOpenPrice() >= Point * MoveStopWhenPrice)
                  {
                  if (OrderStopLoss() < OrderOpenPrice() + Point * MoveStopTo)
                     {
                     OrderModify (OrderTicket(), OrderOpenPrice(), OrderOpenPrice() + Point * MoveStopTo, OrderTakeProfit(), 0, Red);
                     if (!EachTickMode) BarCount = Bars;
                     continue;
                     }
                  }
               }
//Trailing stop
            if (UseTrailingStop && 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 (CloseOnOppositeSignal && 
               dnfractal != 0
               &&
               (FMAPrev < FMACurr)
               &&
               (SMAPrev < SMACurr)) 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;
               }
//MoveOnce
            if (MoveStopOnce && MoveStopWhenPrice > 0)
               {
               if (OrderOpenPrice() - Ask >= Point * MoveStopWhenPrice)
                  {
                  if (OrderStopLoss() > OrderOpenPrice() - Point * MoveStopTo)
                     {
                     OrderModify (OrderTicket(), OrderOpenPrice(), OrderOpenPrice() - Point * MoveStopTo, OrderTakeProfit(), 0, Red);
                     if (!EachTickMode) BarCount = Bars;
                     continue;
                     }
                  }
               }
//Trailing stop
            if (UseTrailingStop && TrailingStop > 0)
               {
               if (OrderOpenPrice() - Ask > Point * TrailingStop)
                  {
                  if (OrderStopLoss() > Ask + Point * TrailingStop)
                     {
                     OrderModify (OrderTicket(), OrderOpenPrice(), Ask + Point * TrailingStop, OrderTakeProfit(), 0, DarkOrange);
                     if (!EachTickMode) BarCount = Bars;
                     continue;
                     }
                  }
               }
            }
         }
      }
//+------------------------------------------------------------------+
//| Signal Begin(Entry)                                              |
//+------------------------------------------------------------------+
      if (
         (dnfractal != 0 && timenowdn != Time[0] && Hour() >= StartTrading && Hour() < StopTrading)
         &&
         (FMAPrev < FMACurr)
         &&
      (  SMAPrev < SMACurr)) Order = SIGNAL_BUY;
      
      if (
         (upfractal != 0 && timenowup != Time[0] && Hour() >= StartTrading && Hour() < StopTrading)
         &&
         (FMAPrev > FMACurr)
         &&
         (SMAPrev > SMACurr)) Order = SIGNAL_SELL;
//+------------------------------------------------------------------+
//| Signal End                                                       |
//+------------------------------------------------------------------+
//Buy
      if (Order == SIGNAL_BUY && ((EachTickMode && !TickCheck) || (!EachTickMode && (Bars != BarCount))))
         {
         if (SignalsOnly)
            {
            if (SignalMail) SendMail ("[Signal Alert]", "[" + Symbol() + "] " + DoubleToStr (Ask, Digits) + "Buy Signal");
            if (Alerts) Alert ("[" + Symbol() + "] " + DoubleToStr (Ask, Digits) + "Buy Signal");
            if (PlaySounds) PlaySound ("alert.wav");
            }
      
         if (!IsTrade && !SignalsOnly)
            {
//Check free margin
         if (AccountFreeMargin() < (1000 * Lots))
            {
            Print ("We have no money. Free Margin = ", AccountFreeMargin());
            return(0);
            }

         if (UseStopLoss) StopLossLevel = Ask - StopLoss * Point; else StopLossLevel = 0.0;
         if (UseTakeProfit) 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) + "Buy Signal");
			      if (Alerts) Alert ("[" + Symbol() + "] " + DoubleToStr (Ask, Digits) + "Buy Signal");
               if (PlaySounds) PlaySound ("alert.wav");
			      }
			   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 (SignalsOnly)
            {
            if (SignalMail) SendMail ("[Signal Alert]", "[" + Symbol() + "] " + DoubleToStr (Bid, Digits) + "Sell Signal");
            if (Alerts) Alert ("[" + Symbol() + "] " + DoubleToStr (Bid, Digits) + "Sell Signal");
            if (PlaySounds) PlaySound ("alert.wav");
            }
         if (!IsTrade && !SignalsOnly)
            {
//Check free margin
         if (AccountFreeMargin() < (1000 * Lots))
            {
            Print ("We have no money. Free Margin = ", AccountFreeMargin());
            return(0);
            }

         if (UseStopLoss) StopLossLevel = Bid + StopLoss * Point; else StopLossLevel = 0.0;
         if (UseTakeProfit) 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) + "Sell Signal");
			      if (Alerts) Alert ("[" + Symbol() + "] " + DoubleToStr (Bid, Digits) + "Sell Signal");
               if (PlaySounds) PlaySound ("alert.wav");
			      }
			   else
			      {
               Print ("Error opening SELL order: ", GetLastError());
               }
            }
         if (EachTickMode) TickCheck = True;
         if (!EachTickMode) BarCount = Bars;
         return(0);
         }
      }
   if (!EachTickMode) BarCount = Bars;
   return(0);
   }
//------------------------------------------------------------------
double GetFractal (int mode)
   {
   double tempup = 0, tempdn = 0, fup = 0, fdn = 0;
   tempup = iFractals (Symbol(), 0, MODE_UPPER, LookBack);
   tempdn = iFractals (Symbol(), 0, MODE_LOWER, LookBack);
   
   if (tempup != 0) fup = tempup;
   if (tempdn != 0) fdn = tempdn;
   
   if (fup != 0 && fdn == 0 && mode == MODE_UPPER ) return (fup);
   if (fdn != 0 && fup == 0 && mode == MODE_LOWER ) return (fdn);
   return(0);
   }
//------------------------------------------------------------------