//+------------------------------------------------------------------+
//|                                         The Dragon EA testv2.mq4 |
//|                                                jiva34, Taiyakixz |
//|                                               thanks to geoffb65 |
//+------------------------------------------------------------------+
#property copyright "jiva34, Taiyakixz"
#property link      ""

extern int iMagicNumber = 628527;
extern double Lots = 0.1;
extern int StopLoss = 40;
extern int TakeProfit = 80;
extern int TrailingStopStart = 30;
extern int TrailingStopWidth = 20;
extern int GMTOffset = 2;
extern int LookBackBars = 1;
extern int SMA_Period = 10;
extern int MACD_fast_ema_period = 12;
extern int MACD_slow_ema_period = 26;
extern int MACD_signal_period = 9;
extern bool ShowSettings = true;

int startTime = 13; //9:00EST = 13:00GMT

int tradeHour;
int err;
double macdMain, macdSignal, checkBarShift;
double LastUpFractal,LastDownFractal,TimeOfLastDownFractal,TimeOfLastUpFractal;
double Poin;
int trend;
int buyOrder, sellOrder;
int Time0, currentTime;

//+------------------------------------------------------------------+
//| expert initialization function                                   |
//+------------------------------------------------------------------+
int init()
  {
//----
   //Checking for unconventional Point digits number
   if (Point == 0.00001) Poin = 0.0001; //6 digits
   else if (Point == 0.001) Poin = 0.01; //3 digits (for Yen based pairs)
   else Poin = Point; //Normal
   
   tradeHour = startTime + GMTOffset;
   if(tradeHour >= 24) tradeHour = tradeHour - 24;

//----
   return(0);
  }
//+------------------------------------------------------------------+
//| expert deinitialization function                                 |
//+------------------------------------------------------------------+
int deinit()
  {
//----
   
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+
int start()
  {
//----
   int retries;

   //if( prevTime != Time[0] && TimeHour(Time[0]) == tradeHour && TimeMinute(Time[0]) == 0)
   FractalTrend();
   currentTime = TimeYear(Time[0]) * 1000000 + TimeMonth(Time[0]) * 10000 + TimeDay(Time[0]) * 100 + TimeHour(Time[0]);
   if( Hour() == tradeHour )
   {
     CountOrders();
     checkBarShift = MathFloor(TimeMinute(Time[0])) / 15 + LookBackBars;
     macdMain = iMACD(NULL,0,MACD_fast_ema_period,MACD_slow_ema_period,MACD_signal_period,PRICE_CLOSE,MODE_MAIN,checkBarShift);
     macdSignal = iMACD(NULL,0,MACD_fast_ema_period,MACD_slow_ema_period,MACD_signal_period,PRICE_CLOSE,MODE_SIGNAL,checkBarShift);

     if( macdMain > macdSignal
         && iMA(NULL,0,SMA_Period,0,MODE_SMA,PRICE_CLOSE,checkBarShift) > iMA(NULL,0,SMA_Period,0,MODE_SMA,PRICE_CLOSE,checkBarShift+1)
         && iFractals(NULL, PERIOD_M1, MODE_LOWER,3)!=0
         && trend==1 )
     {
       if( buyOrder==0 && Time0 != currentTime )
       {
         retries =10;
         while(retries > 0)
         {
           RefreshRates();
           OrderSend(Symbol(), OP_BUY, Lots, Ask, 3*Poin/Point, Ask-StopLoss*Poin, Ask+TakeProfit*Poin, "", iMagicNumber, 0, Blue);
           err = GetLastError();
           if(err != 0)
           {
             Print("Buy OrderSend failed with error #", err);
             Sleep(1000);
           }
           else                 
           break;
           retries--;
         }//end while
         Time0 = TimeYear(Time[0]) * 1000000 + TimeMonth(Time[0]) * 10000 + TimeDay(Time[0]) * 100 + TimeHour(Time[0]);
       }//end if
     }//end if

     if( macdMain < macdSignal
         && iMA(NULL,0,SMA_Period,0,MODE_SMA,PRICE_CLOSE,checkBarShift) < iMA(NULL,0,SMA_Period,0,MODE_SMA,PRICE_CLOSE,checkBarShift+1)
         && iFractals(NULL, PERIOD_M1, MODE_UPPER,3)!=0
         && trend==2 )
     {
       if( sellOrder==0 && Time0 != currentTime )
       {
         retries =10;
         while(retries > 0)
         {
           RefreshRates();
           OrderSend(Symbol(), OP_SELL, Lots, Bid, 3*Poin/Point, Bid+StopLoss*Poin, Bid-TakeProfit*Poin, "",iMagicNumber, 0, Red);
           err = GetLastError();
           if(err != 0)
           {
             Print("Sell OrderSend failed with error #", err);
             Sleep(1000);
           }
           else                 
           break;
           retries--;
         }//end while
         Time0 = TimeYear(Time[0]) * 1000000 + TimeMonth(Time[0]) * 10000 + TimeDay(Time[0]) * 100 + TimeHour(Time[0]);
       }//end if
     }//end if

   }//end if  
   
//----
   CountOrders();
   if( buyOrder > 0 || sellOrder > 0 ) TrailingStop();
   
   if( ShowSettings ) DisplayStatus();
   
   return(0);
  }
//+------------------------------------------------------------------+

void TrailingStop()
  {
   int iCount, iTotal;
   iTotal = OrdersTotal();
   
   for(iCount=0;iCount<iTotal;iCount++)
   {
     OrderSelect(iCount, SELECT_BY_POS, MODE_TRADES);
     if( OrderSymbol()==Symbol() && OrderMagicNumber() == iMagicNumber)
       switch(OrderType()){
         case OP_BUY:
           if(Bid-OrderOpenPrice() > Poin*TrailingStopStart){
             if((OrderStopLoss()<(Bid-Poin*TrailingStopWidth)) || OrderStopLoss()==0){
               OrderModify(OrderTicket(),OrderOpenPrice(),Bid-Poin*(TrailingStopWidth-2),OrderTakeProfit(),0,Aqua);
             }
           }
           break;
         case OP_SELL:
           if(OrderOpenPrice()-Ask > Poin*TrailingStopStart){
              if((OrderStopLoss()>(Ask+Poin*TrailingStopWidth)) || OrderStopLoss()==0){
                 OrderModify(OrderTicket(),OrderOpenPrice(),Ask+Poin*(TrailingStopWidth-2),OrderTakeProfit(),0,Orange);
              }
           }
           break;
       }
   }
  }

void CountOrders()
  {
   int total = OrdersTotal();
   int i;
   
   buyOrder = 0; sellOrder = 0;

   for(i = 0; i < total; i++) 
   {
     OrderSelect(i, SELECT_BY_POS, MODE_TRADES);
     if(OrderSymbol() == Symbol() && OrderMagicNumber() == iMagicNumber)
     {
       if (OrderType()==OP_BUY) {buyOrder = buyOrder + 1;}
       else if (OrderType()==OP_SELL) {sellOrder = sellOrder + 1;}
     } //end if
   } //end for
  }

void FractalTrend()
  {
   for(int v=1;v<Bars;v++){
     if(iFractals(NULL,PERIOD_M5, MODE_UPPER,v)!=0){
       LastUpFractal=iFractals(NULL,PERIOD_M5, MODE_UPPER,v);
       TimeOfLastUpFractal=Time[v];
       break;
     }//end if
   }//end for
   for(int w=1;w<Bars;w++){
     if(iFractals(NULL,PERIOD_M5, MODE_LOWER,w)!=0){
       LastDownFractal=iFractals(NULL,PERIOD_M5, MODE_LOWER,w);
       TimeOfLastDownFractal=Time[w];
       break;
     }//end if
   }//end for
    
   if(TimeOfLastUpFractal > TimeOfLastDownFractal) trend=1;
   else trend=2;
  }

void DisplayStatus()
  {
   string sComment;
   sComment = "Buy Order="+buyOrder+"; Sell Order="+sellOrder+";\n";
   sComment = sComment + "Lots= "+DoubleToStr(Lots,2)+"; StopLoss= "+StopLoss+"; TakeProfit="+TakeProfit+";\n";
   sComment = sComment + "TrailingStopStart="+TrailingStopStart+"; TrailingStopWidth="+TrailingStopWidth+";\n";
   sComment = sComment + "GMTOffset="+GMTOffset+";\n";
   sComment = sComment + "Trade Hour="+tradeHour+";\n";
   
   if( Hour() == tradeHour )
   {
     sComment = sComment + "***** Trade Hour *****\n";
     if( macdMain > macdSignal ) sComment = sComment + "MACD BUY;\n";
     if( macdMain < macdSignal ) sComment = sComment + "MACD SELL;\n";
     if( iMA(NULL,0,SMA_Period,0,MODE_SMA,PRICE_CLOSE,checkBarShift) > iMA(NULL,0,SMA_Period,0,MODE_SMA,PRICE_CLOSE,checkBarShift+1))
       sComment = sComment + "SMA BUY;\n";
     if( iMA(NULL,0,SMA_Period,0,MODE_SMA,PRICE_CLOSE,checkBarShift) < iMA(NULL,0,SMA_Period,0,MODE_SMA,PRICE_CLOSE,checkBarShift+1))
       sComment = sComment + "SMA SELL;\n";
   }
   if( trend == 1 ) sComment = sComment + "Fractal 5m BUY;\n";
   if( trend == 2 ) sComment = sComment + "Fractal 5m SELL;\n";

   Comment(sComment); 
  }

