//+-----------------------------------------------------------+
//| HA Breakout strategy, from ForexFactory                   |
//|     http://www.forexfactory.com/showthread.php?t=255038   |
//+-----------------------------------------------------------+

#define SIGNAL_NONE 0
#define SIGNAL_BUY   1
#define SIGNAL_SELL  2
#define SIGNAL_CLOSEBUY 3
#define SIGNAL_CLOSESELL 4

#property copyright "Alexander C. Boyd"

extern int MagicNumber = 44;
extern double RiskPercent = 1;
extern int Slippage = 3;
extern int Offset = 10;
extern int MAPeriod = 14;
extern bool UseStopLoss = false;
extern int StopLoss = 100;
extern bool UseTakeProfit = false;
extern int TakeProfit = 200;
extern bool UseTrailingStop = false;
extern int TrailingStop = 1500;
extern bool SignalMail = False;
extern bool EachTickMode = True;

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() {

if(CheckTodaysOrders() >= 1){
return(0); // abort
}

   int Order = SIGNAL_NONE;
   int Total, Ticket;
   double StopLossLevel, TakeProfitLevel;



   if (EachTickMode && Bars != BarCount) TickCheck = False;
   Total = OrdersTotal();
   Order = SIGNAL_NONE;
   
/*
Money Management
*/

double Lots = NormalizeDouble(AccountEquity()*(0.00001*RiskPercent), 2);
if (Lots < 0.01) Lots = MODE_MINLOT;


   //+------------------------------------------------------------------+
   //| Variable Begin                                                   |
   //+------------------------------------------------------------------+

double MA = iMA(NULL, PERIOD_D1, MAPeriod, 0, MODE_EMA, PRICE_CLOSE, 0);
double MAPrev = iMA(NULL, PERIOD_D1, MAPeriod, 0, MODE_EMA, PRICE_CLOSE, 1);

double D1HAOpen = iCustom(NULL, PERIOD_D1, "Heiken Ashi", 2, 1);
double D1HAClose = iCustom(NULL, PERIOD_D1, "Heiken Ashi", 3, 1);

double D2HAOpen = iCustom(NULL, PERIOD_D1, "Heiken Ashi", 2, 2);
double D2HAClose = iCustom(NULL, PERIOD_D1, "Heiken Ashi", 3, 2);

double D1Low = iMA(NULL, PERIOD_D1, 1, 0, MODE_SMA, PRICE_LOW, 1) - (Offset*Point);
double D1High = iMA(NULL, PERIOD_D1, 1, 0, MODE_SMA, PRICE_HIGH, 1) + (Offset*Point);

double TodayLow = iMA(NULL, PERIOD_M1, 1, 0, MODE_SMA, PRICE_LOW, 0);
double TodayHigh = iMA(NULL, PERIOD_M1, 1, 0, MODE_SMA, PRICE_HIGH, 0);

bool D2White, D2Red, D1White, D1Red, LongCondition, ShortCondition, MovingAverageIsRising, MovingAverageIsFalling;

if (D2HAClose > D2HAOpen)       {D2White = true;}   else    {D2Red = true;}
if (D1HAClose > D1HAOpen)       {D1White = true;}   else    {D1Red = true;}

if (D1HAClose > MAPrev)   {LongCondition = true;}   else    {ShortCondition = true;}

if (MA > MAPrev) {MovingAverageIsRising  = true;}   else    {MovingAverageIsFalling = true;}

   int TotalOrders = 0;

   //+------------------------------------------------------------------+
   //| Signal Begin(Entry)                                              |
   //+------------------------------------------------------------------+

   if (D2White && D1White && LongCondition && MovingAverageIsRising && TodayHigh > D1High) Order = SIGNAL_BUY;
   if (D2Red && D1Red && ShortCondition && MovingAverageIsFalling && TodayLow < D1Low) Order = SIGNAL_SELL;


   //+------------------------------------------------------------------+
   //| Signal End                                                       |
   //+------------------------------------------------------------------+

   //Buy
   if (Order == SIGNAL_BUY && ((EachTickMode && !TickCheck) || (!EachTickMode && (Bars != BarCount)))) {
      if(OrdersTotal() == 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)) {
				TotalOrders++;
				Print("BUY order opened : ", OrderOpenPrice());
                if (SignalMail) SendMail("[Signal Alert]", "[" + Symbol() + "] " + DoubleToStr(Ask, Digits) + " Open Buy");
			} 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(OrdersTotal() == 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)) {
                TotalOrders++;
				Print("SELL order opened : ", OrderOpenPrice());
                if (SignalMail) SendMail("[Signal Alert]", "[" + Symbol() + "] " + DoubleToStr(Bid, Digits) + " Open Sell");
			} else {
				Print("Error opening SELL order : ", GetLastError());
			}
         }
         if (EachTickMode) TickCheck = True;
         if (!EachTickMode) BarCount = Bars;
         return(0);
      }
   }

   if (!EachTickMode) BarCount = Bars;

   return(0);
}

// function

int CheckTodaysOrders(){
int TodaysOrders = 0;
for(int i = OrdersTotal()-1; i >=0; i--){
OrderSelect(i, SELECT_BY_POS,MODE_TRADES);
if(TimeDayOfYear(OrderOpenTime()) == TimeDayOfYear(TimeCurrent())){
TodaysOrders += 1;

}

}

for(i = OrdersHistoryTotal()-1; i >=0; i--){
OrderSelect(i, SELECT_BY_POS,MODE_HISTORY);
if(TimeDayOfYear(OrderOpenTime()) == TimeDayOfYear(TimeCurrent())){
TodaysOrders += 1;

}

}

return(TodaysOrders);

}
//+------------------------------------------------------------------+

