//+------------------------------------------------------------------+
//|                                                Ovenstone_EA.mq4  |
//|                                       EA Based Ovenstone System  |
//|                                                 Rodrigo Brayner  |
//|                                                            2006  |
//|                                     http://rbrayner.blogspot.com |
//+------------------------------------------------------------------+

#property copyright "Rodrigo Brayner"
#property link      "http://rbrayner.blogspot.com"

/* Input Parameters */ 
extern double    takeProfit=0.0; // Maximum profit
extern double    stopLoss=0.0; // Maximum stop loss
extern double    lots=0.1;
extern double    trailingStop=0.0;
extern int       signalBar = 1; // Buy how many bars after cross? 1 means 1 bar after cross, 0 means the current bar etc
extern int       barsAfterCross = 1;
extern int       myPlaySound = 0;
extern int       maxActiveOrders = 5;
int              lastDirection = 0;
int              currentDirection = 0;
int              tradeDirectionCross_m30 = 0;
int              tradeDirectionCross_h1 = 0;
int              tradeDirectionCross_h4 = 0;
int              tradeDirectionColor_m30 = 0;
int              tradeDirectionColor_h1 = 0;
int              tradeDirectionColor_h4 = 0;
int              executeOperation = 0;
int              isCrossed = 0;
string           name;
datetime         bartime=0;
string           comments = "";

int init()
{
   // Apply to bartime the open time of the current bar.
   bartime = Time[0];
   return(0);
}

int deinit()
{
   return(0);
}


/***********************************************************/
/************************ FUNCTIONS ************************/
/***********************************************************/

// Verify if the green line (uptrend) and red line (downtrent) cross each other. If crossed, a trend will be defined. 
// I'm not using this cross to place a trade for a while.
int verifyTRexCrossDirection (int _signalBar,int timeFrame)
{
   bool direction = 0; // No direction
   double redLine = iCustom(NULL,timeFrame,"T_REX","",0,48,1,1,3,2,3,_signalBar); // Downtrend line
   double greenLine = iCustom(NULL,timeFrame,"T_REX","",0,48,1,1,3,2,2,_signalBar); // Uptrend line
   if(redLine>greenLine) direction = -1; // Direction DOWN
   if(greenLine>redLine) direction = 1; // Direction UP
   return (direction);
}

// Verify if the two past bars have different colors (if signalBar = 1). If so, a trend is defined or is continued.
int verifyTRexColor (int _signalBar,int timeFrame)
{
   bool direction = 0; // No direction
   double redBar = iCustom(NULL,timeFrame,"T_REX","",0,48,1,1,3,2,1,_signalBar); // Downtrend color
   double greenBar = iCustom(NULL,timeFrame,"T_REX","",0,48,1,1,3,2,0,_signalBar); // Uptrend color
   if(redBar>greenBar) direction = -1; // Direction DOWN
   if(greenBar>redBar) direction = 1; // Direction UP
   return (direction);
}

string trendToString(int trendNumber)
{
   string directionString = "Trend not changed...";
   if(trendNumber == 1)
      directionString = "Uptrend";
   else if(trendNumber == -1)
      directionString = "Downtrend";
   return (directionString);   
}

void comments()
{  
   string remaining = Time[0]+Period()*60-TimeCurrent();
   comments = 
   "\nRemaining: " + remaining + " seconds"
   + "\nTime: " + TimeToStr(TimeCurrent()) + "" 
   + "\nDirection Lines M30: " + trendToString(verifyTRexCrossDirection(signalBar,30)) + "" 
   + "\nDirection Lines H1: " + trendToString(verifyTRexCrossDirection(signalBar,60)) + "" 
   + "\nDirection Lines H4: " + trendToString( crossed (verifyTRexCrossDirection(signalBar,240),verifyTRexCrossDirection(signalBar+barsAfterCross,240))) + "" 
   + "\nDirection Color M30: " + trendToString(verifyTRexColor(signalBar,30)) + "" 
   + "\nDirection Color H1: " + trendToString(verifyTRexColor(signalBar,60)) + "" 
   + "\nDirection Color H4: " + trendToString( crossed (verifyTRexColor(signalBar,240),verifyTRexColor(signalBar+barsAfterCross,240))) + "" 
   ;
   Comment(comments);
}

// Verify if the lines or the colors have crossed each other. If so, then a new trend is defined.
int crossed (int _currentDirection, int _lastDirection)
{
   if(_currentDirection != _lastDirection) // Crossed/Changed 
   {
      return (_currentDirection);
   }
   else
   {
      return (0); // No changing
   }
} 


/***********************************************************/
/******************** END FUNCTIONS ************************/
/***********************************************************/

/***********************************************************/
/************************** START **************************/
/***********************************************************/

int start()
{
   int cnt, ticket, total;
   
   if(Bars<100) { Print("[ERROR] Bars less than 100!"); return(0); }

   // Only execute the script when a new bar is opened.   
   if(bartime!=Time[0])
   {
      // Change bartime variable to execute the script only in a new bar.   
      bartime = Time[0];   
      
      // Verify directions of the lines in different timeframes.
      tradeDirectionCross_m30 = verifyTRexCrossDirection(signalBar,30);
      tradeDirectionCross_h1 = verifyTRexCrossDirection(signalBar,60);
      
      // Verify if the lines have crossed on H4 timeframe.
      lastDirection = verifyTRexCrossDirection(signalBar+barsAfterCross,240); // barsAfterCross means the cross can be considered if a cross have been defined within for example 5 bars (if barsAfterCross = 5)
      currentDirection = verifyTRexCrossDirection(signalBar,240);
      tradeDirectionCross_h4 = crossed (currentDirection,lastDirection);

      // Verify directions of the colors in different timeframes.
      tradeDirectionColor_m30 = verifyTRexColor(signalBar,30);
      tradeDirectionColor_h1 = verifyTRexColor(signalBar,60);
   
      // Verify if the colors have changed.
      lastDirection = verifyTRexColor(signalBar+barsAfterCross,240); // barsAfterCross the same as the comment above.
      currentDirection = verifyTRexColor(signalBar,240);
      tradeDirectionColor_h4 = crossed (currentDirection,lastDirection);

      // Trade if m30 color is red, h1 color is red and h4 color have changed color within barsAfterCross bars.
      if(tradeDirectionColor_h4 == 1)
         executeOperation = 1;
      else if (tradeDirectionColor_h4 == -1)
         executeOperation = -1;
      else
         executeOperation = 0;
      
      // Verify if the symbol is already traded.
      total  = OrdersTotal(); 
      int alreadyTraded = 0;
      for(cnt=0;cnt<total;cnt++)
      {
         OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);
         if(OrderSymbol()==Symbol())
            alreadyTraded = 1;
      }
      
      // If it is not already traded, then open position. If many pairs is being traded, only maxActiveOrders trades is allowable.
      if (alreadyTraded == 0 && total < maxActiveOrders)
      {
          if( executeOperation == 1 ) // Goind up
          {
               if(stopLoss == 0.0 && takeProfit == 0.0)
                  ticket=OrderSend(Symbol(),OP_BUY,lots,Ask,3,0,0,"[BUY] T-Rex EA",12345,0,Blue);
               else if (stopLoss != 0.0 && takeProfit == 0.0)
                  ticket=OrderSend(Symbol(),OP_BUY,lots,Ask,3,Ask-stopLoss*Point,0,"[BUY] T-Rex EA",12345,0,Blue);
               else if (stopLoss == 0.0 && takeProfit != 0.0)
                  ticket=OrderSend(Symbol(),OP_BUY,lots,Ask,3,0,Ask+takeProfit*0,"[BUY] T-Rex EA",12345,0,Blue);
               else
                  ticket=OrderSend(Symbol(),OP_BUY,lots,Ask,3,Ask-stopLoss*Point,Ask+takeProfit*0,"[BUY] T-Rex EA",12345,0,Blue);
               
               if(ticket>0)
               {
                  if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES)) Print("[BUY] Order opened : ",OrderOpenPrice());
                  name = "[BUY] " + Hour() + Minute();
                  ObjectCreate(name, OBJ_ARROW, 0, CurTime(), Ask);
                  ObjectSet(name, OBJPROP_ARROWCODE, SYMBOL_ARROWUP);
                  if (myPlaySound == 1) PlaySound("alert.wav");
               }
               else Print("Error opening BUY order : ",GetLastError()); 
               return(0);
          }
       
          if( executeOperation == -1 ) // Goind down
          {
             
             if (stopLoss == 0.0 && takeProfit == 0.0)
               ticket=OrderSend(Symbol(),OP_SELL,lots,Bid,3,0,0,"[SELL] Ovenstone_EA",12345,0,Red);
             else if (stopLoss != 0.0 && takeProfit == 0.0)
               ticket=OrderSend(Symbol(),OP_SELL,lots,Bid,3,Bid+stopLoss*Point,0,"[SELL] Ovenstone_EA",12345,0,Red);
             else if (stopLoss == 0.0 && takeProfit != 0.0)
               ticket=OrderSend(Symbol(),OP_SELL,lots,Bid,3,0,Bid-takeProfit*Point,"[SELL] Ovenstone_EA",12345,0,Red);
             else
               ticket=OrderSend(Symbol(),OP_SELL,lots,Bid,3,Bid+stopLoss*Point,Bid-takeProfit*Point,"[SELL] Ovenstone_EA",12345,0,Red);
                          
             if(ticket>0)
             {
                if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES)) Print("[SELL] Order opened : ",OrderOpenPrice());
                name = "[SELL] " + Hour() + Minute();
                ObjectCreate(name, OBJ_ARROW, 0, CurTime(), CurTime(), Bid);
                ObjectSet(name, OBJPROP_ARROWCODE, SYMBOL_ARROWDOWN);
                if (myPlaySound == 1) PlaySound("alert.wav");
             }
             else Print("Error opening SELL order : ",GetLastError()); 
             return(0);
          }
          return(0);
      }
   
   
      for(cnt=0;cnt<total;cnt++)
        {
         OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);
         if(OrderType()<=OP_SELL && OrderSymbol()==Symbol())
           {
            if(OrderType()==OP_BUY)   // long position is opened
              {
               // should it be closed?
              if( ((verifyTRexColor(signalBar,240) == -1)) )
                   {
                    OrderClose(OrderTicket(),OrderLots(),Bid,3,White); // close position
                    return(0); // exit
                   }
               // check for trailing stop
               if(trailingStop>0)  
                 {                 
                  if(Bid-OrderOpenPrice()>Point*trailingStop)
                    {
                     if(OrderStopLoss()<Bid-Point*trailingStop)
                       {
                        OrderModify(OrderTicket(),OrderOpenPrice(),Bid-Point*trailingStop,OrderTakeProfit(),0,Blue);
                        return(0);
                       }
                    }
                 }
              }
            else // go to short position
              {
               // should it be closed?
                 if( ((verifyTRexColor(signalBar,240) == 1)) )
                 {
                  OrderClose(OrderTicket(),OrderLots(),Ask,3,Violet); // close position
                  return(0); // exit
                 }
               // check for trailing stop
               if(trailingStop>0)  
                 {                 
                  if((OrderOpenPrice()-Ask)>(Point*trailingStop))
                    {
                     if((OrderStopLoss()>(Ask+Point*trailingStop)) || (OrderStopLoss()==0))
                       {
                        OrderModify(OrderTicket(),OrderOpenPrice(),Ask+Point*trailingStop,OrderTakeProfit(),0,Red);
                        return(0);
                       }
                    }
                 }
              }
           }
        }

   }
   
   comments();
   return(0);
  }

