UniversalMACrossEA1





//+------------------------------------------------------------------+
//|                                           UniversalMACrossEA.mq4 |
//|                                  Copyright © 2006-2007, firedave | 
//|               Partial Function Copyright © 2006-2007, codersguru | 
//|                   Partial Function Copyright © 2006-2007, pengie |
//|                                        http://www.fx-review.com/ | 
//|                                        http://www.forex-tsd.com/ |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2006-2007, firedave"
#property link      "http://www.fx-review.com"

// Discussion at Forex-TSD
// http://www.forex-tsd.com/expert-advisors-metatrader-4/1933-universal-ma-cross-ea.html 

//----------------------- INCLUDES
#include <stdlib.mqh>

//----------------------- EA PARAMETER
extern string           Expert_Name          = "---------- Universal MA Cross EA v8.0";
extern int              MagicNumber          = 1234;
extern double           StopLoss             = 15,
                        TakeProfit           = 50;
                        
extern string           TrailingStop_Setting = "---------- Trailing Stop Setting";
extern int              TrailingStopType     = 1,
                        TrailingStop         = 15;
                        
extern string           Indicator_Setting    = "---------- Indicator Setting";
extern int              FastMAPeriod         = 5,
                        FastMAType           = 3,    //0:SMA 1:EMA 2:SMMA 3:LWMA
                        FastMAPrice          = 0,    //0:Close 1:Open 2:High 3:Low 4:Median 5:Typical 6:Weighted
                        FastMAshift          = 0,
                        SlowMAPeriod         = 12,
                        SlowMAType           = 1,    //0:SMA 1:EMA 2:SMMA 3:LWMA
                        SlowMAPrice          = 0,    //0:Close 1:Open 2:High 3:Low 4:Median 5:Typical 6:Weighted
                        SlowMAshift          = 0;
                        
extern string           CossDistance_Setting = "---------- Min Cross Distance Setting";
extern int              MinCrossDistance     = 1,    //Always positive, 0:disable
                        MaxLookUp            = 5;    //Number of bar to keep checking for the entry condition
                        
extern string           Exit_Setting         = "---------- Exit Setting";
extern bool             StopAndReverse       = false,  // TURE:if signal change, exit and reverse order
                        PureSAR              = false,  // TRUE:no SL, no TP, no TS
                        ExitOnCross          = false;
                        
extern string           ThirdEMA_Setting     = "---------- Third MA Setting";
extern bool             UseThirdMA           = false,
                        UseCounterTrend      = false,
                        OnlyCounterTrend     = true;
                        
extern int              ThirdMAPeriod        = 45,
                        ThirdMAType          = 1,    //0:SMA 1:EMA 2:SMMA 3:LWMA
                        ThirdMAPrice         = 0,    //0:Close 1:Open 2:High 3:Low 4:Median 5:Typical 6:Weighted
                        ThirdMAshift         = 0,
                        CTStopLoss           = 150,
                        CTTakeProfit         = 20;
                        
extern string           Pivot.Setting        = "---------- Pivot Filter Setting";
extern bool             Use.Pivot.Filter     = false;


/* reserve for future development
extern string           BGFilter_Setting     = "---------- BG Cross Filter Setting";
extern bool             UseBGFilter          = false;
extern int              BGFilter             = 20;                  
*/
extern string         
                        RSI_Settings         = "---------- RSI Filter Settings";
extern bool
                        UseRSIfilter         = true;
extern int         
                        RSIPeriod            = 14,   
                        RSIPrice             = 1;       
extern string  
                        EMA_Angle_Setting     = "---------- EMA Angle Setting";
extern bool
                        UseEMAAngle          = false,
                        ExitOnAngle          = false;
extern int 
                        EMAPeriod            = 10,
                        StartEMAShift        = 6,
                        EndEMAShift          = 0;                 
extern double 
                        AngleTreshold        = 0.2;
                                  
extern string           Order_Setting        = "---------- Order Setting";

extern bool             ReverseCondition     = false, // TRUE:buy-sell , sell-buy
                        ConfirmedOnEntry     = false,  // TRUE:entry on the next signal bar
                        OneEntryPerBar       = true;
                        
extern int              NumberOfTries        = 10,
                        Slippage             = 5;
                        
extern string           OpenOrder_Setting    = "---------- Multiple Open Trade Setting";
extern int              MaxOpenTrade         = 10,
                        MinPriceDistance     = 30;
                        
extern string           Time_Parameters      = "---------- EA Active Time";
extern bool             UseHourTrade         = false;         
extern int              StartHour            = 00,
                        EndHour              = 24;
                        
extern string           MM_Parameters        = "---------- Money Management";
extern double           Lots                 = 0.1;

extern bool             MM                   = true, //Use Money Management or not
                        AccountIsMicro       = false; //Use Micro-Account or not
                        
extern int              Risk                 = 02; //02%

extern string           Alert_Setting        = "---------- Alert Setting";
extern bool             EnableAlert          = true;

extern string           SoundFilename        = "alert.wav";
extern string           Testing_Parameters= "---------- Back Test Parameter";
extern bool             PrintControl         = true,
                        Show_Settings        = true;
//+---------------------------------------------------+
//|Money Management                                   |
//+---------------------------------------------------+

extern bool UseTrailingStop = true;


extern double TRStopLevel_1 = 10;       // Type 3  first level pip gain
extern double TrailingStop1 = 10;       // Move Stop to Breakeven
extern double TRStopLevel_2 = 10;       // Type 3 second level pip gain
extern double TrailingStop2 = 10;       // Move stop to lock is profit
extern double TRStopLevel_3 = 10;       // type 3 third level pip gain
extern double TrailingStop3 = 10;       // Move stop and trail from there

extern double Margincutoff = 50;       // Expert will stop trading if equity level decreases to that level.

//----------------------- GLOBAL VARIABLE
static int              TimeFrame            = 15;
string                  TicketComment        = "UniversalMA v8.0",
                        LastTrade,
                        LastAlert,
                        TradeDirection       = "NONE",
                        PreviousDirection    = "NONE",
                        CurrentDirection     = "NONE";
datetime                CheckTime,
                        CheckEntryTime,
                        CrossTime;

//+------------------------------------------------------------------+
//| expert initialization function                                   |
//+------------------------------------------------------------------+
int init()
{

//----------------------- GENERATE MAGIC NUMBER AND TICKET COMMENT
//----------------------- SOURCE : PENGIE
   MagicNumber    = subGenerateMagicNumber(MagicNumber, Symbol(), Period());
	TicketComment  = StringConcatenate(TicketComment, "-", Symbol(), "-", Period());

//----------------------- SET MinCrossDistance ALWAYS POSITIVE
   MinCrossDistance = MathAbs(MinCrossDistance);

//----------------------- SHOW EA SETTING ON THE CHART
//----------------------- SOURCE : CODERSGURU
   if(Show_Settings) subPrintDetails();
   else Comment("");
   
//----------------------- INITIALIZE PURE Stop And Reverse
//----------------------- NO STOP LOSS, NO TAKE PROFIT, NO TRAILING STOP
   if(PureSAR)
   {
      StopLoss       = 0;
      TakeProfit     = 0;
      TrailingStop   = 0;
      StopAndReverse = true;
   }

//----------------------- MaxTrade ALWAYS >= 1
   if(MaxOpenTrade<=0) MaxOpenTrade = 1;
   
//+------------------------------------------------------------------+
//| CHECK LAST OPEN TRADE                                            |
//+------------------------------------------------------------------+
   LastTrade = subCheckOpenTrade();
   Print("Last Trade : ",LastTrade);
}

//+------------------------------------------------------------------+
//| expert deinitialization function                                 |
//+------------------------------------------------------------------+
int deinit()
{
 
//----------------------- PREVENT RE-COUNTING WHILE USER CHANGING TIME FRAME
//----------------------- SOURCE : CODERSGURU
   TimeFrame=Period(); 
   return(0);
}


//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int start()
{
   double 
         FastMACurrent,
         SlowMACurrent,
         ThirdMAValue,
         LastHigh,
         LastLow,
         LastClose,
         P,
         S1,
         R1,
         S2,
         R2;
                   
   int   
         cnt,
         ticket,
         total,
         shiftCROSS,
         Distance;
         
   bool
         BuyCondition,
         SellCondition,
         CounterTrend;

   string
         CrossDirection;         
         
//----------------------- TIME FILTER
   if (UseHourTrade)
   {
      if(!(Hour()>=StartHour && Hour()<=EndHour))
      {
         Comment("Non-Trading Hours!");
         return(0);
      }
      else{
         if(Show_Settings) subPrintDetails();
            else Comment("");

      }
   }

//----------------------- CHECK CHART NEED MORE THAN 100 BARS
   if(Bars<100)
   {
      Print("bars less than 100");
      return(0);  
   }

//----------------------- TRAILING STOP SECTION
   if(TrailingStop>0 && subTotalTrade()>0)
   {
      total = OrdersTotal();
      for(cnt=0;cnt<total;cnt++)
      {
         OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);

         if(OrderType()<=OP_SELL &&
            OrderSymbol()==Symbol() &&
            OrderMagicNumber()==MagicNumber)
         {
            subTrailingStop(OrderType());
         }
      }
   }            

//----------------------- ADJUST LOTS IF USING MONEY MANAGEMENT
   if(MM) Lots = subLotSize();

//----------------------- SET VALUE FOR VARIABLE
   if(ConfirmedOnEntry)
   {
      if(CheckTime==iTime(NULL,TimeFrame,0)) return(0); else CheckTime = iTime(NULL,TimeFrame,0);
   
      FastMACurrent    = iMA(NULL,TimeFrame,FastMAPeriod,FastMAshift,FastMAType,FastMAPrice,1);
      SlowMACurrent    = iMA(NULL,TimeFrame,SlowMAPeriod,SlowMAshift,SlowMAType,SlowMAPrice,1);
   }
   else
   {
      FastMACurrent    = iMA(NULL,TimeFrame,FastMAPeriod,FastMAshift,FastMAType,FastMAPrice,0);
      SlowMACurrent    = iMA(NULL,TimeFrame,SlowMAPeriod,SlowMAshift,SlowMAType,SlowMAPrice,0);
   }
   
   CrossDirection = subCrossDirection(FastMACurrent,SlowMACurrent);
 
//----------------------- CONDITION CHECK
   if(!ReverseCondition)
   {
//----------------------- BUY CONDITION   
      if(CrossDirection=="UP")
      {
         BuyCondition   = true;
         TradeDirection = "UP";
         CrossTime      = iTime(NULL,TimeFrame,0);
      }                       

//----------------------- SELL CONDITION   
      if(CrossDirection=="DOWN")
      {
         SellCondition  = true;
         TradeDirection = "DOWN";
         CrossTime      = iTime(NULL,TimeFrame,0);
      }
   }
   else
   {
//----------------------- SELL CONDITION   
      if(CrossDirection=="UP")
      {
         SellCondition  = true;
         TradeDirection = "UP";
         CrossTime      = iTime(NULL,TimeFrame,0);
      }                       

//----------------------- BUY CONDITION   
      if(CrossDirection=="DOWN")
      {
         BuyCondition   = true;
         TradeDirection = "DOWN";
         CrossTime      = iTime(NULL,TimeFrame,0);
      }
   }                        

   if(PrintControl)
   {
      if(BuyCondition)  Print("MA Cross BUY");
      if(SellCondition) Print("MA Cross SELL");
   }      

//----------------------- ALERT ON CROSS
   if(EnableAlert && ConfirmedOnEntry)
   {
      if(TradeDirection=="UP" && LastAlert!="UP")
      {
         subCrossAlert("UP");
         LastAlert = "UP";
      }            
      if(TradeDirection=="DOWN" && LastAlert!="DOWN")
      {
         subCrossAlert("DOWN");
         LastAlert ="DOWN";
      }
   }                        

//+------------------------------------------------------------------+
//| EXIT BASE ONLY ON MOVING AVERAGE CROSS                           |
//+------------------------------------------------------------------+
if(ExitOnCross && subTotalTrade()>0)
   {
      if((LastTrade=="BUY" && SellCondition) || (LastTrade=="SELL" && BuyCondition))
      {
         subCloseOrder();
         if(subTotalTrade()>0) subCloseOrder();
         if(subTotalTrade()>0) subCloseOrder();
         
         if(IsTesting() && PrintControl) Print("EXIT ON CROSS !");
      }
   }

//+------------------------------------------------------------------+
//| CHECKING FOR MIN CROSS DISTANCE SEVERAL BAR AFTER THE CROSS      |
//+------------------------------------------------------------------+
   if(MaxLookUp>0 && MinCrossDistance>0)
   {
      BuyCondition  = false;
      SellCondition = false;
      shiftCROSS    = iBarShift(NULL,TimeFrame,CrossTime);
      Distance      = MathFloor(MathAbs((FastMACurrent-SlowMACurrent)/Point));
   
      if(shiftCROSS<=MaxLookUp && Distance>=MinCrossDistance)
      {
         if(!ReverseCondition)
         {
            BuyCondition  = TradeDirection=="UP";
            SellCondition = TradeDirection=="DOWN";
         }
         else
         {
            SellCondition = TradeDirection=="UP";
            BuyCondition  = TradeDirection=="DOWN";
         }
      }
      
      if(PrintControl)
      {
         Print(TimeToStr(CrossTime,TIME_MINUTES)," - ",shiftCROSS," - ",Distance," - ",MinCrossDistance," - ",TradeDirection);
         if(BuyCondition ) Print("MinCrosDistance BUY");
         if(SellCondition) Print("MinCrosDistance SELL");
      }
   }

//+------------------------------------------------------------------+
//| ADDITIONAL FILTER                                                |
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| THIRD MOVING AVERAGE                                             |
//+------------------------------------------------------------------+
   if(UseThirdMA)
   {
      ThirdMAValue = iMA(NULL,TimeFrame,ThirdMAPeriod,ThirdMAshift,ThirdMAType,ThirdMAPrice,0);

      if(!UseCounterTrend)
      {      
         BuyCondition  = (BuyCondition  && SlowMACurrent>ThirdMAValue);
         SellCondition = (SellCondition && SlowMACurrent<ThirdMAValue);
      }
      else
      {
         CounterTrend = ((BuyCondition && FastMACurrent<ThirdMAValue) ||
                        (SellCondition && FastMACurrent>ThirdMAValue));

//+------------------------------------------------------------------+
//| DON'T ALLOW ANY TREND FOLLOWING ENTRY / ONLY COUNTER TREND       |
//+------------------------------------------------------------------+
         if(OnlyCounterTrend && !CounterTrend)
         {
            BuyCondition  = true;
            SellCondition = true;
         }
      }
   }
   
   //+------------------------------------------------------------------+
//| RSI FILTER SETTINGS                                              |
//+------------------------------------------------------------------+
   if (UseRSIfilter)
   {
         double RSI    = iRSI(NULL,0,RSIPeriod,RSIPrice,0);
         BuyCondition  = (BuyCondition  && RSI>55.0000);
         SellCondition = (SellCondition && RSI<45.0000);
      
   }
//+------------------------------------------------------------------+
//| START OF EMA ANGLE                                               +
//+------------------------------------------------------------------+
  /*if (UseEMAAngle)
   {
   double fEndMA, fStartMA;
   
   
   double fAngle, mFactor, dFactor;
   int nLimit, i;
   int nCountedBars;
   bool angle;
   int ShiftDif;
   string Sym;

   if(EndEMAShift >= StartEMAShift)
   {
   bool ReverseCondition;
      Print("Error: EndEMAShift >= StartEMAShift");
      StartEMAShift = 6;
      EndEMAShift = 0;      
   }  
   nLimit = Bars-nCountedBars;
   dFactor = 2*3.14159/180.0;
   mFactor = 10000.0;
   Sym = StringSubstr(Symbol(),3,3);
   if (Sym == "JPY") mFactor = 100.0;
   ShiftDif = StartEMAShift-EndEMAShift;
   mFactor /= ShiftDif;      
   string Angle,XAngle;
      fEndMA=iMA(NULL,0,EMAPeriod,0,MODE_EMA,PRICE_MEDIAN,i+EndEMAShift);
      fStartMA=iMA(NULL,0,EMAPeriod,0,MODE_EMA,PRICE_MEDIAN,i+StartEMAShift);
      // 10000.0 : Multiply by 10000 so that the fAngle is not too small
      // for the indicator Window.
      fAngle = mFactor * (fEndMA - fStartMA)/2.0;
//      fAngle = MathArctan(fAngle)/dFactor;
      
      //market is in an uptrend
      if(fAngle > AngleTreshold)
      {
         Print("market is an uptrend");
        Angle = "UPAngle";
      }

      //market is in a downtrend
      else if (fAngle < -AngleTreshold)
      {  Print("market is a downtrend");
         Angle = "DOWNAngle";
      }

      // Ema ANgle near zero, market is ranging
      else if (fAngle < AngleTreshold && fAngle > -AngleTreshold){
        Print("market is near zero"); 
        UseCounterTrend      = true;
        Angle = "ZEROAngle";
      }
      
            //market is in a downtrend
      if (fAngle > 0.0)
      {  Print("market is a downtrend");
         XAngle = "UPAngle";
      }
      //market is in a downtrend
      if (fAngle < 0.0)
      {  Print("market is a downtrend");
         XAngle = "DOWNAngle";
      } 
      }*/
//-----------------------END ANGLE

//+------------------------------------------------------------------+
//| EXIT BASE ONLY ON EMA ANGLE                          |
//+------------------------------------------------------------------+
if(ExitOnAngle && subTotalTrade()>0)
   {
      if((LastTrade=="BUY" && SellCondition) || (LastTrade=="SELL" && BuyCondition))
      {
         subCloseOrder();
         if(subTotalTrade()>0) subCloseOrder();
         if(subTotalTrade()>0) subCloseOrder();
         
         if(IsTesting() && PrintControl) Print("EXIT ON EMA ANGLE !");
      }
   }
 
//+------------------------------------------------------------------+
//| PIVOT FILTER                                                     |
//+------------------------------------------------------------------+
   if(Use.Pivot.Filter)
   {
      LastHigh  = iHigh (NULL,PERIOD_D1,1);
      LastLow   = iLow  (NULL,PERIOD_D1,1);
      LastClose = iClose(NULL,PERIOD_D1,1);
      P         = (LastHigh + LastLow+ LastClose)/3;
      R1        = (2*P)-LastLow;
      S1        = (2*P)-LastHigh;
      R2        = P+(LastHigh - LastLow);
      S2        = P-(LastHigh - LastLow);
      
      BuyCondition  = (BuyCondition  && SlowMACurrent<=S1 && SlowMACurrent>=S2);
      SellCondition = (SellCondition && SlowMACurrent>=R1 && SlowMACurrent<=R2);
   }

//+------------------------------------------------------------------+
//| STOP AND REVERSE                                                 |
//+------------------------------------------------------------------+
if(StopAndReverse && subTotalTrade()>0)
   {
      if((LastTrade=="BUY" && SellCondition) || (LastTrade=="SELL" && BuyCondition))
      {
         subCloseOrder();
         if(subTotalTrade()>0) subCloseOrder();
         if(subTotalTrade()>0) subCloseOrder();

         if(IsTesting() && PrintControl) Print("STOP AND REVERSE !");
      }
   }
//+------------------------------------------------------------------+
//| Check if OK to make new trades                                   |
//+------------------------------------------------------------------+


   if(AccountFreeMargin() < Margincutoff) {
     return(0);}

//----------------------- ENTRY
//----------------------- TOTAL ORDER BASE ON MAGICNUMBER AND SYMBOL
   total = subTotalTrade();

//----------------------- IF NUMBER TRADE LESS THAN MaxTrade
   if(total<MaxOpenTrade && (BuyCondition || SellCondition)) 
   {

//----------------------- ONE ENTRY PER BAR
      if(OneEntryPerBar)
      {
         if(CheckEntryTime==iTime(NULL,TimeFrame,0)) return(0); else CheckEntryTime = iTime(NULL,TimeFrame,0);
      }         

//----------------------- BUY CONDITION   
      if(BuyCondition)
      {
         if(MaxOpenTrade>1 && !subHighestLowest("BUY")) return(0);
      
         if(!CounterTrend)
         {
            ticket = subOpenOrder(OP_BUY,StopLoss,TakeProfit);
            if(ticket<=0) ticket = subOpenOrder(OP_BUY,StopLoss,TakeProfit);
            if(ticket<=0) ticket = subOpenOrder(OP_BUY,StopLoss,TakeProfit);
         }
         else
         {
            ticket = subOpenOrder(OP_BUY,CTStopLoss,CTTakeProfit);
            if(ticket<=0) ticket = subOpenOrder(OP_BUY,CTStopLoss,CTTakeProfit);
            if(ticket<=0) ticket = subOpenOrder(OP_BUY,CTStopLoss,CTTakeProfit);
         }
         subCheckError(ticket,"BUY");
         LastTrade = "BUY";
         return(0);
      }

//----------------------- SELL CONDITION   
      if(SellCondition)
      {
         if(MaxOpenTrade>1 && !subHighestLowest("SELL")) return(0);
         
         if(!CounterTrend)
         {
            ticket = subOpenOrder(OP_SELL,StopLoss,TakeProfit);
            if(ticket<=0) ticket = subOpenOrder(OP_SELL,StopLoss,TakeProfit);
            if(ticket<=0) ticket = subOpenOrder(OP_SELL,StopLoss,TakeProfit);
         }
         else
         {
            ticket = subOpenOrder(OP_SELL,CTStopLoss,CTTakeProfit);
            if(ticket<=0) ticket = subOpenOrder(OP_SELL,CTStopLoss,CTTakeProfit);
            if(ticket<=0) ticket = subOpenOrder(OP_SELL,CTStopLoss,CTTakeProfit);
         }
         subCheckError(ticket,"SELL");
         LastTrade = "SELL";
         return(0);
      }
      return(0);
   }
   
   return(0);
}

//----------------------- END PROGRAM

//+------------------------------------------------------------------+
//| FUNCTION DEFINITIONS
//+------------------------------------------------------------------+

//----------------------- MONEY MANAGEMENT FUNCTION  
//----------------------- SOURCE : CODERSGURU
double subLotSize()
{
     double lotMM = MathCeil(AccountFreeMargin() *  Risk / 1000) / 100;
	  
	  if(AccountIsMicro==false) //normal account
	  {
	     if(lotMM < 0.1)                  lotMM = Lots;
	     if((lotMM > 0.5) && (lotMM < 1)) lotMM = 0.5;
	     if(lotMM > 1.0)                  lotMM = MathCeil(lotMM);
	     if(lotMM > 100)                  lotMM = 100;
	  }
	  else //micro account
	  {
	     if(lotMM < 0.01)                 lotMM = Lots;
	     if(lotMM > 1.0)                  lotMM = MathCeil(lotMM);
	     if(lotMM > 100)                  lotMM = 100;
	  }
	  
	  return (lotMM);
}
//+------------------------------------------------------------------+
//| Modify Open Position Controls                                    |
//|  Try to modify position 3 times                                  |
//+------------------------------------------------------------------+
void ModifyOrder(int ord_ticket,double op, double price,double tp)
{
    int CloseCnt, err;
    
    CloseCnt=0;
    while (CloseCnt < 3)
    {
       if (OrderModify(ord_ticket,op,price,tp,0,Aqua))
       {
         CloseCnt = 3;
       }
       else
       {
          err=GetLastError();
          Print(CloseCnt," Error modifying order : (", err , ") " + ErrorDescription(err));
         if (err>0) CloseCnt++;
       }
    }
}
//+------------------------------------------------------------------+
//| HandleTrailingStop                                               |
//| Type 1 moves the stoploss without delay.                         |
//| Type 2 waits for price to move the amount of the trailStop       |
//| before moving stop loss then moves like type 1                   |
//| Type 3 uses up to 3 levels for trailing stop                     |
//|      Level 1 Move stop to 1st level                              |
//|      Level 2 Move stop to 2nd level                              |
//|      Level 3 Trail like type 1 by fixed amount other than 1      |
//| Possible future types                                            |
//| Type 4 uses 2 for 1, every 2 pip move moves stop 1 pip           |
//| Type 5 uses 3 for 1, every 3 pip move moves stop 1 pip           |
//+------------------------------------------------------------------+
int HandleTrailingStop(string type, int ticket, double op, double os, double tp)
{
    double pt, TS=0;
    double bos,bop,opa,osa;
    
    if (type == "BUY")
    {
       switch(TrailingStopType)
       {
        case 1: pt = Point*StopLoss;
                if(Bid-os > pt) ModifyOrder(ticket,op,Bid-pt,tp);
                break;
        case 2: pt = Point*TrailingStop;
                if(Bid-op > pt && os < Bid - pt) ModifyOrder(ticket,op,Bid - pt,tp);
                break;
        case 3: if (Bid - op > TRStopLevel_1 * Point)
                {
                   TS = op + TRStopLevel_1*Point - TrailingStop1 * Point;
                   if (os < TS)
                   {
                    ModifyOrder(ticket,op,TS,tp);
                   }
                }
                 
                if (Bid - op > TRStopLevel_2 * Point)
                {
                   TS = op + TRStopLevel_2*Point - TrailingStop2 * Point;
                   if (os < TS)
                   {
                    ModifyOrder(ticket,op,TS,tp);
                   }
                }
                 
                if (Bid - op > TRStopLevel_3 * Point)
                {
//                   TS = op + TRStopLevel_3 * Point - TrailingStop3*Point;
                   TS = Bid  - TrailingStop3*Point;
                   if (os < TS)
                   {
                     ModifyOrder(ticket,op,TS,tp);
                   }
                }
                break;
       }
       return(0);
    }
       
    if (type ==  "SELL")
    {
       switch(TrailingStopType)
       {
        case 1: pt = Point*StopLoss;
                if(os - Ask > pt) ModifyOrder(ticket,op,Ask+pt,tp);
                break;
        case 2: pt = Point*TrailingStop;
                if(op - Ask > pt && os > Ask+pt) ModifyOrder(ticket,op,Ask+pt,tp);
                break;
        case 3: if (op - Ask > TRStopLevel_1 * Point)
                {
                   TS = op - TRStopLevel_1 * Point + TrailingStop1 * Point;
                   if (os > TS)
                   {
                    ModifyOrder(ticket,op,TS,tp);
                   }
                }
                if (op - Ask > TRStopLevel_2 * Point)
                {
                   TS = op - TRStopLevel_2 * Point + TrailingStop2 * Point;
                   if (os > TS)
                   {
                    ModifyOrder(ticket,op,TS,tp);
                   }
                }
                if (op - Ask > TRStopLevel_3 * Point)
                {
//                  TS = op - TRStopLevel_3 * Point + TrailingStop3 * Point;               
                  TS = op + TrailingStop3 * Point;               
                  if (os > TS)
                  {
                    ModifyOrder(ticket,op,TS,tp);
                  }
                }
                break;
       }
    }
    return(0);
}

//----------------------- NUMBER OF ORDER BASE ON SYMBOL AND MAGICNUMBER FUNCTION
int subTotalTrade()
{
   int
      cnt, 
      total = 0;

   for(cnt=0;cnt<OrdersTotal();cnt++)
   {
      OrderSelect(cnt,SELECT_BY_POS,MODE_TRADES);
      if(OrderType()<=OP_SELL &&
         OrderSymbol()==Symbol() &&
         OrderMagicNumber()==MagicNumber) total++;
   }
   return(total);
}

//+------------------------------------------------------------------+
//| FUNCTION : CHECK OPEN ORDER BASE ON SYMBOL AND MAGIC NUMBER      |
//| SOURCE   : n/a                                                   |
//| MODIFIED : FIREDAVE                                              |
//+------------------------------------------------------------------+
string subCheckOpenTrade()
{
   int
      cnt         = 0;
   string
      lasttrade   = "None";      

   for(cnt=0;cnt<OrdersTotal();cnt++)
   {
      OrderSelect(cnt,SELECT_BY_POS,MODE_TRADES);
      if(OrderType()<=OP_SELL &&
         OrderSymbol()==Symbol() &&
         OrderMagicNumber()==MagicNumber)
      {
         if(OrderType()==OP_BUY ) lasttrade = "BUY";
         if(OrderType()==OP_SELL) lasttrade = "SELL";
      }         
   }
   return(lasttrade);
}

//----------------------- FIND LOWEST/HIGHEST BUY-SELL FUNCTION
bool subHighestLowest(string type)
{
   int
      cnt, 
      total = 0;
      
   double
      HighestBuy  = 0,
      LowestBuy   = 10000,
      HighestSell = 0,
      LowestSell  = 10000;

   for(cnt=0;cnt<OrdersTotal();cnt++)
   {
      OrderSelect(cnt,SELECT_BY_POS,MODE_TRADES);
      if(OrderType()<=OP_SELL &&
         OrderSymbol()==Symbol() &&
         OrderMagicNumber()==MagicNumber)
      {
         if(OrderType()==OP_BUY)
         {
            if(OrderOpenPrice()<LowestBuy ) LowestBuy  = OrderOpenPrice();
            if(OrderOpenPrice()>HighestBuy) HighestBuy = OrderOpenPrice();
         }

         if(OrderType()==OP_SELL)
         {
            if(OrderOpenPrice()<LowestSell ) LowestSell  = OrderOpenPrice();
            if(OrderOpenPrice()>HighestSell) HighestSell = OrderOpenPrice();
         }

      }
   }
   
   if     (type=="BUY"  && (Ask<=LowestBuy -MinPriceDistance*Point || Ask>=HighestBuy +MinPriceDistance*Point)) return(true);
   else if(type=="SELL" && (Bid<=LowestSell-MinPriceDistance*Point || Bid>=HighestSell+MinPriceDistance*Point)) return(true);
   else return(false);
}

//+------------------------------------------------------------------+
//| FUNCTION : CHECK IS CROSS OR NOT                                 |
//| SOURCE   : CODERSGURU                                            |
//| MODIFIED : FIREDAVE                                              |
//+------------------------------------------------------------------+
string subCrossDirection(double fastMA, double slowMA)
{
        if(fastMA>slowMA) CurrentDirection = "UP";
   else if(fastMA<slowMA) CurrentDirection = "DOWN";
   
   if(PreviousDirection=="NONE")
   {
      PreviousDirection = CurrentDirection;
      return("NONE");
   }

   if(PrintControl) Print("Prev : ",PreviousDirection," - Curr : ",CurrentDirection);
   
   if(PreviousDirection!=CurrentDirection)
   {
      PreviousDirection = CurrentDirection;
      return(CurrentDirection);
   }
   else return("NONE");
}

//----------------------- OPEN ORDER FUNCTION
//----------------------- SOURCE   : CODERSGURU
//----------------------- SOURCE   : PENGIE
//----------------------- MODIFIED : FIREDAVE
int subOpenOrder(int type, int stoploss, int takeprofit)
{
   int
         ticket      = 0,
         err         = 0,
         c           = 0;
         
   double         
         aStopLoss   = 0,
         aTakeProfit = 0,
         bStopLoss   = 0,
         bTakeProfit = 0;

   if(stoploss!=0)
   {
      aStopLoss   = NormalizeDouble(Ask-stoploss*Point,4);
      bStopLoss   = NormalizeDouble(Bid+stoploss*Point,4);
   }
   
   if(takeprofit!=0)
   {
      aTakeProfit = NormalizeDouble(Ask+takeprofit*Point,4);
      bTakeProfit = NormalizeDouble(Bid-takeprofit*Point,4);
   }
   
   if(type==OP_BUY)
   {
      for(c=0;c<NumberOfTries;c++)
      {
         ticket=OrderSend(Symbol(),OP_BUY,Lots,Ask,Slippage,aStopLoss,aTakeProfit,TicketComment,MagicNumber,0,Green);
         err=GetLastError();
         if(err==0)
         { 
            if(ticket>0) break;
         }
         else
         {
            if(err==0 || err==4 || err==136 || err==137 || err==138 || err==146) //Busy errors
            {
               Sleep(5000);
               continue;
            }
            else //normal error
            {
               if(ticket>0) break;
            }  
         }
      }   
   }
   if(type==OP_SELL)
   {   
      for(c=0;c<NumberOfTries;c++)
      {
         ticket=OrderSend(Symbol(),OP_SELL,Lots,Bid,Slippage,bStopLoss,bTakeProfit,TicketComment,MagicNumber,0,Red);
         err=GetLastError();
         if(err==0)
         { 
            if(ticket>0) break;
         }
         else
         {
            if(err==0 || err==4 || err==136 || err==137 || err==138 || err==146) //Busy errors
            {
               Sleep(5000);
               continue;
            }
            else //normal error
            {
               if(ticket>0) break;
            }  
         }
      }   
   }  
   return(ticket);
}


//----------------------- CLOSE ORDER FUNCTION
void subCloseOrder()
{
   int
         cnt, 
         total       = 0,
         ticket      = 0,
         err         = 0,
         c           = 0;

   total = OrdersTotal();
   for(cnt=total-1;cnt>=0;cnt--)
   {
      OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);

      if(OrderSymbol()==Symbol() &&
         OrderMagicNumber()==MagicNumber)
      {
         switch(OrderType())
         {
            case OP_BUY      :
               for(c=0;c<NumberOfTries;c++)
               {
                  ticket=OrderClose(OrderTicket(),OrderLots(),Bid,Slippage,Violet);
                  err=GetLastError();
                  if(err==0)
                  { 
                     if(ticket>0) break;
                  }
                  else
                  {
                     if(err==0 || err==4 || err==136 || err==137 || err==138 || err==146) //Busy errors
                     {
                        Sleep(5000);
                        continue;
                     }
                     else //normal error
                     {
                        if(ticket>0) break;
                     }  
                  }
               }   
               break;
               
            case OP_SELL     :
               for(c=0;c<NumberOfTries;c++)
               {
                  ticket=OrderClose(OrderTicket(),OrderLots(),Ask,Slippage,Violet);
                  err=GetLastError();
                  if(err==0)
                  { 
                     if(ticket>0) break;
                  }
                  else
                  {
                     if(err==0 || err==4 || err==136 || err==137 || err==138 || err==146) //Busy errors
                     {
                        Sleep(5000);
                        continue;
                     }
                     else //normal error
                     {
                        if(ticket>0) break;
                     }  
                  }
               }   
               break;
               
            case OP_BUYLIMIT :
            case OP_BUYSTOP  :
            case OP_SELLLIMIT:
            case OP_SELLSTOP :
               OrderDelete(OrderTicket());
         }
      }
   }      
}


//----------------------- TRAILING STOP FUNCTION
//----------------------- SOURCE   : CODERSGURU
//----------------------- MODIFIED : FIREDAVE
void subTrailingStop(int Type)
{
   if(Type==OP_BUY)   // buy position is opened   
   {
      switch(TrailingStopType)
      {
//----------------------- AFTER PROFIT TRAILING STOP      
         case 1:
            if(Bid-OrderOpenPrice()>Point*TrailingStop &&
              OrderStopLoss()<Bid-Point*TrailingStop)
            {
               OrderModify(OrderTicket(),OrderOpenPrice(),Bid-Point*TrailingStop,OrderTakeProfit(),0,Green);
               return(0);
            }
            break;
            
//----------------------- TRAILING STOP
         case 2:
            if(Bid>OrderOpenPrice() &&
              OrderStopLoss()<Bid-Point*TrailingStop)
            {
               OrderModify(OrderTicket(),OrderOpenPrice(),Bid-Point*TrailingStop,OrderTakeProfit(),0,Green);
               return(0);
            }
            break;

//----------------------- DEFAULT : AFTER PROFIT TRAILING STOP      
         default:
            if(Bid-OrderOpenPrice()>Point*TrailingStop &&
              OrderStopLoss()<Bid-Point*TrailingStop)
            {
               OrderModify(OrderTicket(),OrderOpenPrice(),Bid-Point*TrailingStop,OrderTakeProfit(),0,Green);
               return(0);
            }  
      }
   }

   if(Type==OP_SELL)   // sell position is opened   
   {
      switch(TrailingStopType)
      {
//----------------------- AFTER PROFIT TRAILING STOP      
         case 1:
            if(OrderOpenPrice()-Ask>Point*TrailingStop)
            {
            if(OrderStopLoss()>Ask+Point*TrailingStop || OrderStopLoss()==0)
            {
               OrderModify(OrderTicket(),OrderOpenPrice(),Ask+Point*TrailingStop,OrderTakeProfit(),0,Red);
               return(0);
            }
            }
            break;
            
//----------------------- TRAILING STOP
         case 2:
            if(OrderOpenPrice()>Ask)
            {
            if(OrderStopLoss()>Ask+Point*TrailingStop || OrderStopLoss()==0)
            {
               OrderModify(OrderTicket(),OrderOpenPrice(),Ask+Point*TrailingStop,OrderTakeProfit(),0,Red);
               return(0);
            }
            }
            break;

//----------------------- DEFAULT : AFTER PROFIT TRAILING STOP      
         default:
            if(OrderOpenPrice()-Ask>Point*TrailingStop)
            {
            if(OrderStopLoss()>Ask+Point*TrailingStop || OrderStopLoss()==0)
            {
               OrderModify(OrderTicket(),OrderOpenPrice(),Ask+Point*TrailingStop,OrderTakeProfit(),0,Red);
               return(0);
            }
            }
      }
   }
}



//----------------------- CHECK ERROR CODE FUNCTION
//----------------------- SOURCE : CODERSGURU
void subCheckError(int ticket, string Type)
{
    if(ticket>0) 
    {
      if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES)) Print(Type + " order opened : ",OrderOpenPrice());
    }
    else Print("Error opening " + Type + " order : (",GetLastError(),") ", ErrorDescription(GetLastError()));
}

//----------------------- GENERATE MAGIC NUMBER BASE ON SYMBOL AND TIME FRAME FUNCTION
//----------------------- SOURCE   : PENGIE
//----------------------- MODIFIED : FIREDAVE
int subGenerateMagicNumber(int MagicNumber, string symbol, int timeFrame)
{
   int isymbol = 0;
   if (symbol == "EURUSD")       isymbol = 1;
   else if (symbol == "GBPUSD")  isymbol = 2;
   else if (symbol == "USDJPY")  isymbol = 3;
   else if (symbol == "USDCHF")  isymbol = 4;
   else if (symbol == "AUDUSD")  isymbol = 5;
   else if (symbol == "USDCAD")  isymbol = 6;
   else if (symbol == "EURGBP")  isymbol = 7;
   else if (symbol == "EURJPY")  isymbol = 8;
   else if (symbol == "EURCHF")  isymbol = 9;
   else if (symbol == "EURAUD")  isymbol = 10;
   else if (symbol == "EURCAD")  isymbol = 11;
   else if (symbol == "GBPUSD")  isymbol = 12;
   else if (symbol == "GBPJPY")  isymbol = 13;
   else if (symbol == "GBPCHF")  isymbol = 14;
   else if (symbol == "GBPAUD")  isymbol = 15;
   else if (symbol == "GBPCAD")  isymbol = 16;
   else                          isymbol = 17;
   if(isymbol<10) MagicNumber = MagicNumber * 10;
   return (StrToInteger(StringConcatenate(MagicNumber, isymbol, timeFrame)));
}


//----------------------- PRINT COMMENT FUNCTION
//----------------------- SOURCE : CODERSGURU
void subPrintDetails()
{
   string sComment   = "";
   string sp         = "----------------------------------------\n";
   string NL         = "\n";

   sComment = sp;
   sComment = sComment + "TakeProfit=" + DoubleToStr(TakeProfit,0) + " | ";
   sComment = sComment + "TrailingStop=" + DoubleToStr(TrailingStop,0) + " | ";
   sComment = sComment + "StopLoss=" + DoubleToStr(StopLoss,0) + NL; 
   sComment = sComment + sp;
   sComment = sComment + "Reverse Entry Condition=" + subBoolToStr(ReverseCondition) + NL;
   sComment = sComment + "Confirmed On Entry=" + subBoolToStr(ConfirmedOnEntry) + NL;
   sComment = sComment + "Stop And Reverse=" + subBoolToStr(StopAndReverse) + NL;
   sComment = sComment + "Pure SAR=" + subBoolToStr(PureSAR) + NL;
   sComment = sComment + sp;
   sComment = sComment + "Lots=" + DoubleToStr(Lots,2) + " | ";
   sComment = sComment + "MM=" + subBoolToStr(MM) + " | ";
   sComment = sComment + "Risk=" + DoubleToStr(Risk,0) + "%" + NL;
   sComment = sComment + sp;
  
   Comment(sComment);
}


//----------------------- BOOLEN VARIABLE TO STRING FUNCTION
//----------------------- SOURCE : CODERSGURU
string subBoolToStr ( bool value)
{
   if(value) return ("True");
   else return ("False");
}

//----------------------- ALERT ON MA CROSS
//----------------------- SOURCE : FIREDAVE
void subCrossAlert(string type)
{
   string AlertComment;
   
   if(type=="UP")   AlertComment = "Moving Average Cross UP !";
   if(type=="DOWN") AlertComment = "Moving Average Cross DOWN !";
   
   Alert(AlertComment);
   PlaySound(SoundFilename);
}

//----------------------- END FUNCTION

//+------------------------------------------------+
//| Check for valid TrailingStopType               |
//|  |
//|  return true if invalid, false if OK           |
//+------------------------------------------------+
bool CheckTrailingStopType(int stop_type)
{
   if (stop_type < 0 ) return(true);
   if (stop_type > 3) return(true);
     return(false);
}



Sample





Analysis



Market Information Used:

Series array that contains close prices for each bar


Indicator Curves created:


Indicators Used:

Moving average indicator
Relative strength index


Custom Indicators Used:

Order Management characteristics:
Checks for the total of open orders

It can change open orders parameters, due to possible stepping strategy
It automatically opens orders when conditions are reached
It Closes Orders by itself

Other Features:

It issuies visual alerts to the screen
It plays sound alerts

BackTest : EURUSD on H1

From 2009-11-01 to 2009-11-30 Profit Factor:0.00 Total Net Profit:0.00

BackTest : USDJPY on H1

From 2009-11-01 to 2009-11-30 Profit Factor:0.00 Total Net Profit:0.00

BackTest : USDCHF on H1

From 2009-12-01 to 2010-01-01 Profit Factor:0.00 Total Net Profit:0.00

BackTest : EURUSD on H1

From 2009-12-01 to 2010-01-17 Profit Factor:0.00 Total Net Profit:0.00

BackTest : USDCAD on H1

From 2009-12-01 to 2010-01-01 Profit Factor:0.00 Total Net Profit:0.00

BackTest : EURUSD on H1

From 2009-08-01 to 2009-10-01 Profit Factor:0.00 Total Net Profit:0.00

BackTest : GBPUSD on H1

From 2010-01-01 to 2010-02-27 Profit Factor:0.00 Total Net Profit:0.00

BackTest : EURUSD on H1

From 2010-04-01 to 2010-04-30 Profit Factor:0.00 Total Net Profit:0.00

BackTest : EURUSD on H1

From 2010-05-01 to 2010-05-31 Profit Factor:0.00 Total Net Profit:0.00

BackTest : EURUSD on H1

From 2010-06-01 to 2010-06-30 Profit Factor:0.00 Total Net Profit:0.00

Request Backtest for UniversalMACrossEA1


From : (yyyy/mm/dd) To: (yyyy/mm/dd)

Pair: Period: