//+------------------------------------------------------------------+
//|                                                   SuperStochs EA |
//|                                                      version 3.0 |
//|                                       http://www.forexforums.org |
//|Check EA Main thread at:                                          |
//|http://www.forexforums.org/showthread.php?t=1888                  |
//+------------------------------------------------------------------+
 
extern int        Magic              = 42008;                       // 
extern double     LotSize            = 0.1;                         // 
extern int        TP                 = 400;                         // 
extern int        SL                 = 1800;                        // 
extern string     LongComment        = "SSL";                       // 
extern string     ShortComment       = "SSS";                       //  
extern double     BreakEven          = 100;                         // Profit Lock in pips
extern double     BEOffset           = 10;                          // BreakEven profit capture
extern double     TrailStop          = 400;                         // 
extern bool       MoneyManagement    = true;                        // Set to true to use Money Management 
extern double     MaxLotSize         = 1.5;                         // Max Lot size when using Money Management
extern double     Risk               = 15;                          // Risk factor when using MM
extern int        PreventPos         = 1;                           // Prevent the opening of a new position if there are other near
extern int        MaxOpenTrades      = 20; 
extern string     EMA                = "EMA FILTER SETTINGS";
extern bool       UseEMAFilter       = true;                        // Set true to use EMA filter to enter positions
extern int        ShortEma           = 19;
extern int        LongEma            = 110;                         // Minimum diference between EMA's that allow opening
extern int        MinEmaDiverg       = 10;
// extern bool       CloseOnEmaCross    = false;                        // Close all orders if EMA's reverse

double S1M, S1S, S2M, S2S, S3M, S3S, S4M, S4S;
string Signal;
string Status;
bool AccountIsMicro;
double ticket, AccountSize;
double slippage=5;
double EMA1,EMA2;
double LWMA1,LWMA2,SEma, LEma;
bool   Sell=0, Buy=0;
int init()
{
   if (MarketInfo(Symbol(),MODE_LOTSTEP) == 0.01)
   {
     AccountIsMicro = true;
   }
   else
   {
     AccountIsMicro = false;
   }

   return(0);
}

int start()
{
  
  
  SEma = iMA(Symbol(),PERIOD_H1,ShortEma,0,MODE_EMA,PRICE_CLOSE,0);
  LEma = iMA(Symbol(),PERIOD_H1,LongEma,0,MODE_EMA,PRICE_CLOSE,0);
  
  EMA1  = iMA(0,PERIOD_H1,ShortEma,0,MODE_EMA,PRICE_CLOSE,1);
  EMA2  = iMA(0,PERIOD_H1,ShortEma,0,MODE_EMA,PRICE_CLOSE,2);
  LWMA1 = iMA(0,PERIOD_H1,ShortEma,0,MODE_LWMA,PRICE_CLOSE,1);
  LWMA2 = iMA(0,PERIOD_H1,ShortEma,0,MODE_LWMA,PRICE_CLOSE,2); 

  Sell=   LWMA1 < EMA1 && LWMA1 < LWMA2 && EMA1 < EMA2 ; 
  Buy=    LWMA1 > EMA1 && LWMA1 > LWMA2 && EMA1 > EMA2 ;

  if (!UseEMAFilter) {
    
   Buy = true;
   Sell = true;
   
   }
  
  
   S1M=iStochastic(NULL,PERIOD_M5,5,3,3,MODE_SMA,0,MODE_MAIN,0);
   S1S=iStochastic(NULL,PERIOD_M5,5,3,3,MODE_SMA,0,MODE_SIGNAL,0);
   S2M=iStochastic(NULL,PERIOD_M30,5,3,3,MODE_SMA,0,MODE_MAIN,0);
   S2S=iStochastic(NULL,PERIOD_M30,5,3,3,MODE_SMA,0,MODE_SIGNAL,0);
   S3M=iStochastic(NULL,PERIOD_H1,5,3,3,MODE_SMA,0,MODE_MAIN,0);
   S3S=iStochastic(NULL,PERIOD_H1,5,3,3,MODE_SMA,0,MODE_SIGNAL,0);
   S4M=iStochastic(NULL,PERIOD_H1,14,3,3,MODE_SMA,0,MODE_MAIN,0);
   S4S=iStochastic(NULL,PERIOD_H1,14,3,3,MODE_SMA,0,MODE_SIGNAL,0);
   
   if (MoneyManagement) LotSize = LotSize();
   
   if (ScanOpenTrades() == 0) Status = "READY";
      
   Signal="NONE";
   if(S1M>S1S && S2M>S2S && S3M>S3S && S4M>S4S && Buy)
   {
      Signal="LONG";
   }
   if(S1M<S1S && S2M<S2S && S3M<S3S && S4M<S4S && Sell)
   {
      Signal="SHORT";
   }
   
   
   if(Status=="READY" && Signal=="LONG" &&  !IsPosition(PreventPos) && ScanOpenTrades() < MaxOpenTrades)
   {
      ticket=OrderSend(Symbol(),OP_BUY,LotSize,Ask,slippage,Ask-SL*Point,Ask+TP*Point,LongComment,Magic,0,Blue);
      if(ticket>-1)
      {
         Status="LONG ACTIVE";
      }
   }
   
   if(Status=="READY" && Signal=="SHORT" &&  !IsPosition(PreventPos) && ScanOpenTrades() < MaxOpenTrades)
   {
      ticket=OrderSend(Symbol(),OP_SELL,LotSize,Bid,slippage,Bid+SL*Point,Bid-TP*Point,ShortComment,Magic,0,Red);
      if(ticket>-1)
      {
         Status="SHORT ACTIVE";
      }
   }
   
   if(Status=="LONG ACTIVE" && (Signal=="NONE" || Signal=="SHORT"))
   {
      if (Signal=="SHORT") OpenOrdClose();
      Status="READY";
   }
   
   if(Status=="SHORT ACTIVE" && (Signal=="NONE" || Signal=="LONG"))
   {
      if (Signal=="LONG") OpenOrdClose();
      Status="READY";
   }
   
    
    
    
    if (TrailStop > 0) 
    {
      TrailIt(TrailStop);
    }
   
    if (BreakEven > 0)
    {
      DoBE(BreakEven);
    }
   
   
   
   
   
   
   return(0);
}
   
int ScanOpenTrades()
{   
   int total = OrdersTotal();
   int numords = 0;
    
   for(int cnt=0; cnt<=total-1; cnt++) 
   {        
   OrderSelect(cnt, SELECT_BY_POS);
      if(OrderType()<=OP_SELL)
      {
      if(Magic > 0) if(OrderMagicNumber() == Magic) numords++;
      if(Magic == 0) numords++;
      }
   }   
   return(numords);
}  

void DoBE(int byPips)
  {
    for (int i = 0; i < OrdersTotal(); i++) {
     OrderSelect(i, SELECT_BY_POS, MODE_TRADES);
     if ( OrderSymbol()==Symbol() && ( (OrderMagicNumber() == Magic) ) )  

        {
            if (OrderType() == OP_BUY && (OrderStopLoss() < (OrderOpenPrice() +  MarketInfo(OrderSymbol(), MODE_POINT)*BEOffset))) if ((Bid - OrderOpenPrice() > byPips * MarketInfo(OrderSymbol(), MODE_POINT)) && (OrderOpenPrice()-OrderStopLoss() > 0)) if (OrderStopLoss() != (OrderOpenPrice() +  MarketInfo(OrderSymbol(), MODE_POINT))) OrderModify(OrderTicket(), OrderOpenPrice(), OrderOpenPrice() +  MarketInfo(OrderSymbol(), MODE_POINT)*BEOffset, OrderTakeProfit(), Red);
            if (OrderType() == OP_SELL && (OrderStopLoss() > (OrderOpenPrice() +  MarketInfo(OrderSymbol(), MODE_POINT)*BEOffset))) if ((OrderOpenPrice() - Ask > byPips * MarketInfo(OrderSymbol(), MODE_POINT)) && (OrderOpenPrice()-OrderStopLoss() > 0)) if (OrderStopLoss() != (OrderOpenPrice() -  MarketInfo(OrderSymbol(), MODE_POINT))) OrderModify(OrderTicket(), OrderOpenPrice(), OrderOpenPrice() -  MarketInfo(OrderSymbol(), MODE_POINT)*BEOffset, OrderTakeProfit(), Red);
        }
    }
  }

 void TrailIt( int byPips )                   // based on trailing stop code from MT site... thanks MT!
  {
  if (byPips >=5)
  {
  for (int i = 0; i < OrdersTotal(); i++) {
     OrderSelect(i, SELECT_BY_POS, MODE_TRADES);
     if ( OrderSymbol()==Symbol() && ( (OrderMagicNumber() == Magic)) ) 
        {
            if (OrderType() == OP_BUY) {

               if (Bid - OrderOpenPrice() > byPips * MarketInfo(OrderSymbol(), MODE_POINT)) {
                  if (OrderStopLoss() < Bid - byPips * MarketInfo(OrderSymbol(), MODE_POINT)) {
                     OrderModify(OrderTicket(), OrderOpenPrice(), Bid - byPips * MarketInfo(OrderSymbol(), MODE_POINT), OrderTakeProfit(), Red);
                  }
               }
            } else if (OrderType() == OP_SELL) {
               if (OrderOpenPrice() - Ask > byPips * MarketInfo(OrderSymbol(), MODE_POINT)) {
                  if ((OrderStopLoss() > Ask + byPips * MarketInfo(OrderSymbol(), MODE_POINT)) || 
                        (OrderStopLoss() == 0)) {
                     OrderModify(OrderTicket(), OrderOpenPrice(),
                        Ask + byPips * MarketInfo(OrderSymbol(), MODE_POINT), OrderTakeProfit(), Red);
                  }
               }
            }
        }
	  }
	  }

  } // proc TrailIt()


double LotSize()
{

     double Account = 0;
  
     double lotMM = MathCeil(AccountFreeMargin() *  Risk / 1000) / 1000;
     
     if(AccountIsMicro)  {
     
     if(lotMM < 0.01) lotMM = 0.01;
     if(lotMM >= MaxLotSize) lotMM = MaxLotSize;
     
     AccountSize=2;
     
     } else {
     
     if(lotMM < 0.1) lotMM = 0.1;
     if(lotMM >= MaxLotSize) lotMM = MaxLotSize;
     
     AccountSize=1;
     
     }
     
     lotMM = NormalizeDouble(lotMM,AccountSize);
     
	  return (lotMM);
}


// Closing of Open Orders      
void OpenOrdClose()
{
    int total=OrdersTotal();
    
    for (int cnt=0;cnt<total;cnt++)
    { 
    OrderSelect(total-cnt-1, SELECT_BY_POS);
    int mode=OrderType();
    bool res = false; 
    bool condition = false;
    if (OrderMagicNumber()==Magic ) condition = true;
      if (condition && ( mode==OP_BUY || mode==OP_SELL ))
      { 
       
// - BUY Orders         
         if(mode==OP_BUY)
         {  
         res = OrderClose(OrderTicket(),OrderLots(),MarketInfo(OrderSymbol(),MODE_BID),3,Yellow);
               
            if( !res )
            {
            Print(" BUY: OrderClose failed with error #",GetLastError());
            Print(" Ticket=",OrderTicket());
            Sleep(3000);
            }
         }
         else     
// - SELL Orders          
         if( mode == OP_SELL)
         {
         res = OrderClose(OrderTicket(),OrderLots(),MarketInfo(OrderSymbol(),MODE_ASK),3,White);
                 
            if( !res )
            {
            Print(" SELL: OrderClose failed with error #",GetLastError());
            Print(" Ticket=",OrderTicket());
            Sleep(3000);
            } 
         }  
      }                  
   }
}


bool IsPosition(double inRange)
{
  int totalorders = OrdersTotal();
  for(int i = 0;i < totalorders;i++)
  {
    OrderSelect(i, SELECT_BY_POS);
    if ((OrderSymbol() == Symbol()) && (OrderMagicNumber() == Magic)) 
    {  
      int type = OrderType();
      
      if ((MathAbs(OrderOpenPrice() - MarketInfo(Symbol(),MODE_ASK))*90) < (inRange))
      {        
        if (type == OP_BUY || type == OP_SELL)
        { 
          return(true); 
        }
      }
     }
   } 
   return(false);
 }