TriplePlayTesting





//+------------------------------------------------------------------+
//|                                            TriplePlay.mq4        |
//|                                              Copyright © 2006    |
//|    Written by Robert Hill                                        |
//| Based on idea posted by Ignace BIENVILLE                         |
//| Uses entry rule from MACD Sample to place triple trades          |
//| Added many ideas for entering, filtering and exiting trades      |
//| Default values worked best on backtest from Aug 20, 2006         |
//| Includes string prompts to better understand inputs              |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2006, Robert Hill"
#include <stdlib.mqh>
#include <stderror.mqh> 

#define NO 0
#define YES 1
// Additional modes for Moving average
#define MODE_LSMA 4
#define MODE_ITREND 5
#define MODE_HMA 6

// Entry methods
// MACD as supplied by MT4 using SMA for signal line smoothing
// MACD_EMA uses EMA for signal line smoothing
// MACD_LSMA uses LSMA instead of EMA and EMA for smoothing
#define MACD 0
#define MACD_EMA 1
#define MACD_LSMA 2
// MACD crosses use histogram crossing zero line
#define MACD_CROSS 3
#define MACD_EMA_CROSS 4
#define MACD_LSMA_CROSS 5
// Moving averages used for trend
#define SMA 6
#define EMA 7
#define SMMA 8
#define LWMA 9
#define LSMA 10
#define ITREND 11
#define HMA 12

// MACD trend Filters
#define NO_FILTER 0
#define SMA_FILTER 1
#define EMA_FILTER 2
#define SMMA_FILTER 3
#define LWMA_FILTER 4
#define LSMA_FILTER 5
#define ITREND_FILTER 6
#define HMA_FILTER 7

//exit methods
#define MACD_EXIT 0
#define MACD_EMA_EXIT 1
#define MACD_LSMA_EXIT 2
#define MACD_CROSS_EXIT 3
#define MACD_EMACROSS_EXIT 4
#define MACD_LSMACROSS_EXIT 5
#define SMA_EXIT 6
#define EMA_EXIT 7
#define SMMA_EXIT 8
#define LWMA_EXIT 9
#define LSMA_EXIT 10
#define ITREND_EXIT 11
#define HMA_EXIT 12


//+---------------------------------------------------+
//|Account functions                                  |
//+---------------------------------------------------+
extern bool AccountIsMini = true;      // Change to true if trading mini account
//+---------------------------------------------------+
//|Money Management                                   |
//+---------------------------------------------------+
extern bool MoneyManagement = true; // Change to false to shutdown money management controls.
extern string str1 = " TradeSizePersent <= 5";
extern double TradeSizePercent = 5;      // Change to whatever percent of equity you wish to risk.
extern double Lots = 0.1;             // standard lot size. 
 double MaxLots = 100;

//+---------------------------------------------------+
//|Profit controls                                    |
//+---------------------------------------------------+
extern double StopLoss = 70;        // Maximum pips willing to lose per position.
extern int FirstLevel = 10;
extern int SecondLevel = 20;
extern double TakeProfit1 = 30;
extern double TakeProfit2 = 20;
extern double TakeProfit3 = 10;

extern string str2 = " TrailingStopType";
extern string str3 = " 1 - Trail immediately";
extern string str4 = " 2 - Wait til TrailingStop";
extern string str5 = "     is reached to trail";
extern bool UseTrailingStop = false;
extern int		TrailingStopType 	= 2;
extern double	TrailingStop		= 5;

 double Margincutoff = 800;   // Expert will stop trading if equity level decreases to that level.
 int Slippage = 10;           // Possible fix for not getting filled or closed    

//+---------------------------------------------------+
//|Indicator Variables                                |
//| Change these to try your own system               |
//| or add more if you like                           |
//+---------------------------------------------------+

extern string  estr1 = "Entry Methods";
extern string  estr2 = "   0 = MACD";
extern string  estr3 = "   1 = MACD-EMA";
extern string  estr4 = "   2 = MACD-LSMA";
extern string  estr5 = "   3 = MACD Cross";
extern string  estr6 = "   4 = MACD EMA Cross";
extern string  estr7 = "   5 = MACD LSMA Cross";
extern string  estr8 = "   6 = SMA";
extern string  estr9 = "   7 = EMA";
extern string  estr10 = "   8 = SMMA";
extern string  estr11 = "   9 = LWMA";
extern string  estr12 = "  10 = LSMA";
extern string  estr13 = "  11 = ITREND";
extern string  estr14 = "  12 = HMA";
extern int     EntryMethod = 1;
extern string  estr15 = " MACD_LSMA - FastEMA = 20, slowEMA = 38";
extern int     FastEMA=12;
extern int     SlowEMA=26;
extern int     SignalEMA=9;
extern double  MACD_OpenLevel=5;
extern double  MACD_CloseLevel=1;
extern int     MACD_TimeFrame = 0;

extern int     MA_EntryPeriod=14;
extern int     LSMA_EntryPeriod=18;
extern int     iTrend_EntryPeriod=26;
extern int     HMA_EntryPeriod = 16;
extern int     TrendEntry_TimeFrame = 0;

extern string  fstr1 = "MACD Filter Methods";
extern string  fstr2 = " 0 = No Filter";
extern string  fstr3 = " 1 = SMA";
extern string  fstr4 = " 2 = EMA";
extern string  fstr5 = " 3 = SMMA";
extern string  fstr6 = " 4 = LWMA";
extern string  fstr7 = " 5 = LSMA";
extern string  fstr8 = " 6 = iTrend";
extern string  fstr9 = " 7 = HMA";
extern int     FilterMethod = 2;

extern int     MA_FilterPeriod=21;
extern int     LSMA_FilterPeriod=18;
extern int     iTrend_FilterPeriod=26;
extern int     HMA_FilterPeriod = 16;
extern int     TrendFilter_TimeFrame = 0;
 
extern int SignalCandle = 1;
 
extern bool UseDST = false;
extern int StartHour = 1;            // Start trades after time
extern  int StopHour = 13;              // Stop trading after time

extern string  xstr1 = "Exit Methods";
extern string  xstr2 = "  0 = MACD";
extern string  xstr3 = "  1 = MACD EMA";
extern string  xstr4 = "  2 = MACD LSMA";
extern string  xstr5 = "  3 = MACD Cross";
extern string  xstr6 = "  4 = MACD EMA Cross";
extern string  xstr7 = "  5 = MACD LSMA Cross";
extern string  xstr8 = "  6 = SMA";
extern string  xstr9 = "  7 = EMA";
extern string  xstr10 = "  8 = SMMA";
extern string  xstr11 = "  9 = LWMA";
extern string  xstr12 = " 10 = LSMA";
extern string  xstr13 = " 11 = iTrend";
extern string  xstr14 = " 12 = HMA";
extern int     ExitMethod = 4;
extern int     MA_ExitPeriod=14;
extern int     LSMA_ExitPeriod=18;
extern int     iTrend_ExitPeriod=26;
extern int     HMA_ExitPeriod = 16;
extern int     TrendExit_TimeFrame = 0;

bool Debug = false;
int StartTime2;        // Start trades after time
int StopTime2;         // Stop trading after time
double MacdCurrent, MacdPrevious;
double SignalCurrent, SignalPrevious;
double MACurrent, MAPrevious;

//+---------------------------------------------------+
//|General controls                                   |
//+---------------------------------------------------+
string setup;
double lotMM;
int TradesInThisSymbol;
int MagicNumber;
bool YesStop;

//+------------------------------------------------------------------+
//| expert initialization function                                   |
//+------------------------------------------------------------------+
int init()
  {
   
	MagicNumber = 4000 + func_Symbol2Val(Symbol())*100 + func_TimeFrame_Const2Val(Period()); 

   setup="TriplePlay" + Symbol() + "_" + func_TimeFrame_Val2String(func_TimeFrame_Const2Val(Period()));
//----
   return(0);
  }
  
//+------------------------------------------------------------------+
//| expert deinitialization function                                 |
//+------------------------------------------------------------------+
int deinit()
  {
   return(0);
  }

//+------------------------------------------------------------------+
//| Custom Indicators                                                |
//+------------------------------------------------------------------+


//+------------------------------------------------------------------------+
//| LSMA - Least Squares Moving Average function calculation               |
//| LSMA_In_Color Indicator plots the end of the linear regression line    |
//+------------------------------------------------------------------------+

double fLSMA(int LSMA_TimeFrame, int myRperiod, int shift)
{
   int i;
   double sum;
   int length;
   double lengthvar;
   double tmp;
   double wt;

   length = myRperiod;
 
   sum = 0;
   for(i = length; i >= 1  ; i--)
   {
     lengthvar = length + 1;
     lengthvar /= 3;
     tmp = 0;
     tmp = ( i - lengthvar)*iClose(Symbol(),LSMA_TimeFrame, length-i+shift);
     sum+=tmp;
    }
    wt = sum*6/(length*(length+1));
//    wt = MathFloor(sum*6/(length*(length+1))/Point)*Point;
    
    return(wt);
}


//+------------------------------------------------------------------------+
//| MACD Exits                                                             |
//| Get the MACD values from different MACD indicators                     |
//| Test for exit code from MACD_Sample                                    |
//+------------------------------------------------------------------------+
bool MACD_Exits(int method, int cmd)
{
   switch (method)
   {
    case MACD_EXIT :      GetMACD(TrendExit_TimeFrame,MODE_SMA);
                          break;
 
    case MACD_EMA_EXIT :  GetMACD(TrendExit_TimeFrame,MODE_EMA);
                          break;
   
    case MACD_LSMA_EXIT : GetMACD(TrendExit_TimeFrame,MODE_LSMA);
   }
   
   switch (cmd)
   {
     case OP_BUY : if(MacdCurrent>0 && MacdCurrent<SignalCurrent &&
                      MacdPrevious>SignalPrevious &&
                      MacdCurrent>(MACD_CloseLevel*Point))
                   {
                      return(true);
                   }
                   return(false);
                   break;
    case OP_SELL : if(MacdCurrent<0 && MacdCurrent>SignalCurrent &&
                      MacdPrevious<SignalPrevious &&
                      MathAbs(MacdCurrent)>(MACD_CloseLevel*Point))
                   {
                      return(true);
                   }
                   return(false);
    }
    return(false);
   
}

//+------------------------------------------------------------------------+
//| MACD Cross Exits                                                       |
//| Get the MACD values from different MACD indicators                     |
//| Test for exit uses check for histogram cross of zero line              |
//+------------------------------------------------------------------------+
bool MACD_CrossExits(int method, int cmd)
{
   switch (method)
   {
    case MACD_CROSS_EXIT :       GetMACD(TrendExit_TimeFrame,MODE_SMA);
                                break;

    case MACD_EMACROSS_EXIT :   GetMACD(TrendExit_TimeFrame,MODE_EMA);
                                break;
   
    case MACD_LSMACROSS_EXIT :  GetMACD(TrendExit_TimeFrame,MODE_LSMA);
                                break;
   }
   switch (cmd)
   {
     case OP_BUY : if( SignalCurrent - MacdCurrent > MACD_CloseLevel*Point)
                   {
                      return(true);
                   }
                   return(false);
                   break;
    case OP_SELL : if(MacdCurrent - SignalCurrent > MACD_CloseLevel * Point)
                   {
                      return(true);
                   }
                   return(false);
   }
   return(false);
}
   
//+------------------------------------------------------------------------+
//| Trend Exits                                                            |
//| Get the Moving average values using different MA indicators            |
//| Test for exit using change of direction                                |
//+------------------------------------------------------------------------+
bool Trend_Exits(int method, int cmd)
{
   switch (method)
   {
   case SMA_EXIT :    GetMA(TrendExit_TimeFrame,MA_ExitPeriod,MODE_SMA);
                      break;
   case EMA_EXIT :    GetMA(TrendExit_TimeFrame,MA_ExitPeriod,MODE_EMA);
                      break;
   case SMMA_EXIT :   GetMA(TrendExit_TimeFrame,MA_ExitPeriod,MODE_SMMA);
                      break;
   case LWMA_EXIT :   GetMA(TrendExit_TimeFrame,MA_ExitPeriod,MODE_LWMA);
                      break;
   case LSMA_EXIT :   GetMA(TrendExit_TimeFrame,LSMA_ExitPeriod,MODE_LSMA);
                      break;
   case ITREND_EXIT : GetMA(TrendExit_TimeFrame,iTrend_ExitPeriod,MODE_ITREND);
                      break;
    case HMA_EXIT :   GetMA(TrendExit_TimeFrame,HMA_ExitPeriod,MODE_HMA);
   }
   switch (cmd)
   {
      case OP_BUY :  if (MACurrent  < MAPrevious) return(true);
                     return (false);
                     break;
     case OP_SELL : if(MACurrent  > MAPrevious)  return(true);
                    return (false);
    }
    return(false);
}


//+------------------------------------------------------------------+
//| CheckExitCondition                                               |
//| Check which exit method to test                                  |
//+------------------------------------------------------------------+
bool CheckExitCondition(int cmd)
{
   bool ExitTrade;
   
   ExitTrade = false;
   
   if (ExitMethod < MACD_CROSS_EXIT)
   {
      ExitTrade = MACD_Exits(ExitMethod, cmd);
      return(ExitTrade);
   }
   if (ExitMethod < SMA_EXIT)
   {
      ExitTrade = MACD_CrossExits(ExitMethod, cmd);
      return(ExitTrade);
   }
   
   ExitTrade = Trend_Exits(ExitMethod, cmd);
   return (ExitTrade);
}

//+------------------------------------------------------------------------+
//| MACD Entries                                                           |
//| Get the MACD values from different MACD indicators                     |
//| Test for entry code from MACD_Sample                                   |
//+------------------------------------------------------------------------+
bool MACD_Entries(int method, int cmd)
{
   bool filter;
   
   switch (method)
   {
    case MACD :      GetMACD(MACD_TimeFrame,MODE_SMA);
                     break;
 
    case MACD_EMA :  GetMACD(MACD_TimeFrame,MODE_EMA);
                     break;
   
    case MACD_LSMA : GetMACD(MACD_TimeFrame,MODE_LSMA);
   }
   
   filter = CheckFilter(cmd);
	
   switch (cmd)
   {
    case OP_BUY :  if(MacdCurrent<0 && MacdCurrent>SignalCurrent &&
                    MacdPrevious<SignalPrevious &&
                    MathAbs(MacdCurrent)>(MACD_OpenLevel*Point))
                   {
                     return(filter);
                   }
                   break;
    case OP_SELL : if(MacdCurrent>0 && MacdCurrent<SignalCurrent &&
                      MacdPrevious>SignalPrevious && 
                      MacdCurrent>(MACD_OpenLevel*Point))
                   {
                     return(filter);
                   }
   }
   return(false);
   
}

//+------------------------------------------------------------------------+
//| MACD Cross Entries                                                     |
//| Get the MACD values from different MACD indicators                     |
//| Test for entry uses check for histogram cross of zero line             |
//+------------------------------------------------------------------------+
bool MACD_CrossEntries(int method, int cmd)
{
   int filter;
   
   switch (method)
   {
    case MACD_CROSS :       GetMACD(MACD_TimeFrame,MODE_SMA);
                                break;

    case MACD_EMA_CROSS :   GetMACD(MACD_TimeFrame,MODE_EMA);
                                break;
   
    case MACD_LSMA_CROSS :  GetMACD(MACD_TimeFrame,MODE_LSMA);
                                break;
   }
  filter = CheckFilter(cmd);
  switch (cmd)
   {
     case OP_BUY : if( MacdCurrent - SignalCurrent > MACD_OpenLevel*Point)
                   {
                      return(filter);
                   }
                   break;
    case OP_SELL : if(SignalCurrent - MacdCurrent > MACD_OpenLevel * Point)
                   {
                      return(filter);
                   }
   }
   return(false);
}
   
//+------------------------------------------------------------------------+
//| Trend Entries                                                          |
//| Get the Moving average values using different MA indicators            |
//| Test for entry using direction of MA                                   |
//+------------------------------------------------------------------------+
bool Trend_Entries(int method, int cmd)
{
   switch (method)
   {
   case SMA :    GetMA(TrendEntry_TimeFrame,MA_EntryPeriod,MODE_SMA);
                      break;
   case EMA :    GetMA(TrendEntry_TimeFrame,MA_EntryPeriod,MODE_EMA);
                      break;
   case SMMA :   GetMA(TrendEntry_TimeFrame,MA_EntryPeriod,MODE_SMMA);
                      break;
   case LWMA :   GetMA(TrendEntry_TimeFrame,MA_EntryPeriod,MODE_LWMA);
                      break;
   case LSMA :   GetMA(TrendEntry_TimeFrame,LSMA_EntryPeriod,MODE_LSMA);
                      break;
   case ITREND : GetMA(TrendEntry_TimeFrame,iTrend_EntryPeriod,MODE_ITREND);
                      break;
    case HMA :   GetMA(TrendEntry_TimeFrame,HMA_EntryPeriod,MODE_HMA);
   }
   switch (cmd)
   {
      case OP_BUY :  if (MACurrent  > MAPrevious) return(true);
                     return (false);
                     break;
     case OP_SELL : if(MACurrent  < MAPrevious)  return(true);
                    return (false);
    }
    return(false);
}

//+------------------------------------------------------------------+
//| CheckEntryCondition                                              |
//| Check which entry method to test                                 |
//+------------------------------------------------------------------+
bool CheckEntryCondition(int cmd)
{
	bool EnterTrade;
   
	EnterTrade = false;
	if (EntryMethod < MACD_CROSS)
	{
	   EnterTrade = MACD_Entries(EntryMethod, cmd);
	   return(EnterTrade);
	}
	
	if (EntryMethod < SMA)
	{
	   EnterTrade = MACD_CrossEntries(EntryMethod, cmd);
	   return(EnterTrade);
	}
   
   EnterTrade = Trend_Entries(EntryMethod, cmd);
   return (EnterTrade);
}

//+------------------------------------------------------------------+
//| Get MACD using one of 3 different MACD indicators                |
//| Places values in global variable                                 |
//+------------------------------------------------------------------+
void GetMACD(int TimeFrame, int MACD_Method)
{
   switch (MACD_Method)
   {
   case MACD_EMA  : MacdCurrent=iCustom(NULL,TimeFrame,"MACD_EMA",FastEMA,SlowEMA,SignalEMA,MODE_MAIN,1);
                    MacdPrevious=iCustom(NULL,TimeFrame,"MACD_EMA",FastEMA,SlowEMA,SignalEMA,MODE_MAIN,2);
                    SignalCurrent=iCustom(NULL,TimeFrame,"MACD_EMA",FastEMA,SlowEMA,SignalEMA,MODE_SIGNAL,1);
                    SignalPrevious=iCustom(NULL,TimeFrame,"MACD_EMA",FastEMA,SlowEMA,SignalEMA,MODE_SIGNAL,2);
                    break;
   case MACD_LSMA : MacdCurrent=iCustom(NULL,MACD_TimeFrame,"MACD_LSMA",FastEMA,SlowEMA,SignalEMA,MODE_MAIN,1);
                    MacdPrevious=iCustom(NULL,MACD_TimeFrame,"MACD_LSMA",FastEMA,SlowEMA,SignalEMA,MODE_MAIN,2);
                    SignalCurrent=iCustom(NULL,MACD_TimeFrame,"MACD_LSMA",FastEMA,SlowEMA,SignalEMA,MODE_SIGNAL,1);
                    SignalPrevious=iCustom(NULL,MACD_TimeFrame,"MACD_LSMA",FastEMA,SlowEMA,SignalEMA,MODE_SIGNAL,2);
                    break;
   default :        MacdCurrent=iMACD(NULL,MACD_TimeFrame,FastEMA,SlowEMA,SignalEMA,PRICE_CLOSE,MODE_MAIN,1);
                    MacdPrevious=iMACD(NULL,MACD_TimeFrame,FastEMA,SlowEMA,SignalEMA,PRICE_CLOSE,MODE_MAIN,2);
                    SignalCurrent=iMACD(NULL,MACD_TimeFrame,FastEMA,SlowEMA,SignalEMA,PRICE_CLOSE,MODE_SIGNAL,1);
                    SignalPrevious=iMACD(NULL,MACD_TimeFrame,FastEMA,SlowEMA,SignalEMA,PRICE_CLOSE,MODE_SIGNAL,2);
                    break;
   }
}

//+------------------------------------------------------------------+
//| Get Moving Average using one of 7 different MA indicators        |
//| Places values in global variable                                 |
//+------------------------------------------------------------------+
void GetMA(int TimeFrame, int MAPeriod, int mode)
{
   
   if (mode < MODE_LSMA)
   {
      MACurrent=iMA(NULL,TimeFrame,MAPeriod,0,mode,PRICE_CLOSE,1);
      MAPrevious=iMA(NULL,TimeFrame,MAPeriod,0,mode,PRICE_CLOSE,2);
   }
   else
   {
     switch (mode)
     {
     case MODE_LSMA   : MACurrent=fLSMA(TimeFrame,MAPeriod,1);
                        MAPrevious=fLSMA(TimeFrame,MAPeriod,2);
                        break;
     case MODE_ITREND : MACurrent=iCustom(NULL,TimeFrame,"Ehlers_iTrend",MAPeriod,0,1);
                        MAPrevious=iCustom(NULL,TimeFrame,"Ehlers_iTrend",MAPeriod,0,2);
                        break;
     case MODE_HMA    : MACurrent=iCustom(NULL,TimeFrame,"HMA2",MAPeriod,0,1);
                        MAPrevious=iCustom(NULL,TimeFrame,"HMA2",MAPeriod,0,2);
     }
   }
}


//+------------------------------------------------------------------+
//| Check Filter                                                     |
//| Uses the filter idea from MACD_Sample                            |
//| Get Moving Average using one of 7 different MA indicators        |
//| Returns true if filter allows trade                              |
//+------------------------------------------------------------------+
bool CheckFilter (int cmd)
{
   bool filter = false;
   int myFilterMAPeriod, myFilterMode;
   
   
   filter = false;
   if (FilterMethod == NO_FILTER)
       filter = true;
   else
   {
      if (FilterMethod < LSMA_FILTER)
      {
         myFilterMAPeriod = MA_FilterPeriod;
         myFilterMode = FilterMethod - 1;
      }
      else
      {
         switch(FilterMethod)
         {
            case LSMA_FILTER   : myFilterMAPeriod = LSMA_FilterPeriod;
                                 myFilterMode = MODE_LSMA;
                                 break;
            case ITREND_FILTER : myFilterMAPeriod = iTrend_FilterPeriod;
                                 myFilterMode = MODE_ITREND;
                                 break;
            case HMA_FILTER    : myFilterMAPeriod = HMA_FilterPeriod;
                                 myFilterMode = MODE_HMA;
                                 break;
                               
         }
         
      }
      GetMA(TrendFilter_TimeFrame, myFilterMAPeriod, myFilterMode);
   
      filter = false;
      switch (cmd)
      {
      case OP_BUY : if (MACurrent > MAPrevious) filter = true;
                    break;
      case OP_SELL : if (MACurrent < MAPrevious) filter = true;
      }
   }
   return (filter);
}


//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+
int start()
  {
//---- 

/*
   if (Period() != 60)
   {
    Alert("60 Minute Chart Only.");
    return(0);
   }
*/

   
//+------------------------------------------------------------------+
//| Check for Open Position                                          |
//+------------------------------------------------------------------+

     HandleOpenPositions();
     
// Check if any open positions were not closed

     TradesInThisSymbol = CheckOpenPositions();
     
//+------------------------------------------------------------------+
//| Check if OK to make new trades                                   |
//+------------------------------------------------------------------+


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

// Only allow 1 trade per Symbol

     if(TradesInThisSymbol > 0) {
       return(0);}
   
// setup times to trade based on Day Light Savings Time
   if (UseDST)
   {
     StartTime2 = StartHour - 1;
     if (StartTime2 < 0) StartTime2 = 0;
     StopTime2 = StopHour - 1;
   }
   else
   {
     StartTime2 = StartHour;
     StopTime2 = StopHour;
   }

   if (Hour() > StopTime2) return(0);
   if (Hour() < StartTime2) return(0);

   lotMM = GetLots();
   
      
//	if(CheckEntryConditionBUY() && !CheckExitConditionBUY())
	if(CheckEntryCondition(OP_BUY) )
	{
	      CloseOpenOrders(OP_SELL); // This also deletes pending orders
		   OpenBuyOrders();
		   return(0);
	}

   
//	if(CheckEntryConditionSELL() && !CheckExitConditionSELL())
	if(CheckEntryCondition(OP_SELL) )
	{
         CloseOpenOrders(OP_BUY); // This also deletes pending orders
         OpenSellOrders();
	}
//----
   return(0);
  }

  
//+------------------------------------------------------------------+
//| OpenBuyOrder                                                     |
//| If Stop Loss or TakeProfit are used the values are calculated    |
//| for each trade                                                   |
//| place 3 orders :
//| - 1 st order , 1 lot TARGET 30 pips
//| - 2 nd order , 2 lot placed first order price +10 pips TARGET 20 pips
//| - 3 nd order , 3 lot placed first order price +20 pips TARGET 10 pips
//+------------------------------------------------------------------+
void OpenBuyOrders( )
{
   int ticket, digits, err;
   double myPrice, myStopLoss, myTakeProfit;
   
   myPrice = MarketInfo(Symbol( ), MODE_ASK);
   myStopLoss = 0;
   if ( StopLoss > 0 ) myStopLoss = myPrice - StopLoss * Point ;
   myTakeProfit = myPrice + TakeProfit1 * Point;
      
 // Normalize all price / stoploss / takeprofit to the proper # of digits.
   digits = MarketInfo(Symbol( ), MODE_DIGITS) ;
   if (digits > 0) 
   {
     myPrice = NormalizeDouble( myPrice, digits);
     myStopLoss = NormalizeDouble( myStopLoss, digits);
     myTakeProfit = NormalizeDouble( myTakeProfit, digits); 
   }
 
   ticket=OrderSend( Symbol(), OP_BUY, lotMM, myPrice, Slippage, myStopLoss, myTakeProfit, "FirstBuy", MagicNumber, 0, Green); 
   if (ticket > 0)
   {
    if (OrderSelect( ticket,SELECT_BY_TICKET, MODE_TRADES) ) 
     {
      if (Debug) Print("BUY order opened : ", OrderOpenPrice( ));
      myPrice = OrderOpenPrice() + FirstLevel*Point;
      myStopLoss = 0;
      if ( StopLoss > 0 ) myStopLoss = myPrice - StopLoss * Point ;
      myTakeProfit = myPrice + TakeProfit2*Point;
      if (digits > 0) 
      {
        myPrice = NormalizeDouble( myPrice, digits);
        myStopLoss = NormalizeDouble( myStopLoss, digits);
        myTakeProfit = NormalizeDouble( myTakeProfit, digits); 
      }
      ticket=OrderSend( Symbol(), OP_BUYSTOP, 2*lotMM, myPrice, Slippage, myStopLoss, myTakeProfit, "Second Buy", MagicNumber, 0, Green); 
      myPrice = OrderOpenPrice() + SecondLevel*Point;
      myStopLoss = 0;
      if ( StopLoss > 0 ) myStopLoss = myPrice - StopLoss * Point ;
      myTakeProfit = myPrice + TakeProfit3*Point;
      if (digits > 0) 
      {
        myPrice = NormalizeDouble( myPrice, digits);
        myStopLoss = NormalizeDouble( myStopLoss, digits);
        myTakeProfit = NormalizeDouble( myTakeProfit, digits); 
      }
      ticket=OrderSend( Symbol(), OP_BUYSTOP, 3*lotMM, myPrice, Slippage, myStopLoss, myTakeProfit, "Third Buy", MagicNumber, 0 ,Green); 
    }
   }
   else
   {
		   err = GetLastError();
         Print("Error opening BUY order : (" + err + ") " + ErrorDescription( err) );
   }
}
 
//+------------------------------------------------------------------+
//| OpenSellOrder                                                    |
//| If Stop Loss or TakeProfit are used the values are calculated    |
//| for each trade                                                   |
//| - 1 st order , 1 lot TARGET 30 pips
//| - 2 nd order , 2 lot placed first order price +10 pips TARGET 20 pips
//| - 3 nd order , 3 lot placed first order price +20 pips TARGET 10 pips
//+------------------------------------------------------------------+
void OpenSellOrders( )
{
   int ticket, digits, err;
   double myPrice, myStopLoss, myTakeProfit;
   
   myPrice = MarketInfo(Symbol( ), MODE_BID);
   myStopLoss = 0;
   if ( StopLoss > 0 ) myStopLoss = myPrice + StopLoss * Point ;
   myTakeProfit = myPrice - TakeProfit1 * Point;
      
 // Normalize all price / stoploss / takeprofit to the proper # of digits.
   digits = MarketInfo(Symbol( ), MODE_DIGITS) ;
   if (digits > 0) 
   {
     myPrice = NormalizeDouble( myPrice, digits);
     myStopLoss = NormalizeDouble( myStopLoss, digits);
     myTakeProfit = NormalizeDouble( myTakeProfit, digits); 
   }
 
   ticket=OrderSend( Symbol(), OP_SELL, lotMM, myPrice, Slippage, myStopLoss ,myTakeProfit, "First Sell", MagicNumber, 0, Red); 
   if (ticket > 0)
   {
     if (OrderSelect( ticket,SELECT_BY_TICKET, MODE_TRADES) ) 
     {
      if (Debug) Print("Sell order opened : ", OrderOpenPrice());
      myPrice = OrderOpenPrice() - FirstLevel*Point;
      myStopLoss = 0;
      if ( StopLoss > 0 ) myStopLoss = myPrice + StopLoss * Point ;
      myTakeProfit = myPrice - TakeProfit2*Point;
      if (digits > 0) 
      {
        myPrice = NormalizeDouble( myPrice, digits);
        myStopLoss = NormalizeDouble( myStopLoss, digits);
        myTakeProfit = NormalizeDouble( myTakeProfit, digits); 
      }
      ticket=OrderSend( Symbol(), OP_SELLSTOP, 2*lotMM, myPrice, Slippage, myStopLoss, myTakeProfit, "Second Sell", MagicNumber, 0, Red); 
      myPrice = OrderOpenPrice() - SecondLevel*Point;
      myStopLoss = 0;
      if ( StopLoss > 0 ) myStopLoss = myPrice + StopLoss * Point ;
      myTakeProfit = myPrice - TakeProfit3*Point;
      if (digits > 0) 
      {
        myPrice = NormalizeDouble( myPrice, digits);
        myStopLoss = NormalizeDouble( myStopLoss, digits);
        myTakeProfit = NormalizeDouble( myTakeProfit, digits); 
      }
      ticket=OrderSend( Symbol(), OP_SELLSTOP, 3*lotMM, myPrice, Slippage, myStopLoss, myTakeProfit, "Third Sell", MagicNumber, 0, Red); 
     }
   }
   else
   { 
		   err = GetLastError();
         Print("Error opening Sell order : (" + err + ") " + ErrorDescription( err) );
   }
}
 
//+------------------------------------------------------------------+
//| Check Open Position Controls                                     |
//+------------------------------------------------------------------+
  
int CheckOpenPositions()
{
   int cnt, total, NumPositions;
   
   NumPositions = 0;
   total=OrdersTotal();
   for(cnt=OrdersTotal()-1;cnt>=0;cnt--)
     {
      OrderSelect (cnt, SELECT_BY_POS, MODE_TRADES);
      if ( OrderSymbol() != Symbol()) continue;
      if ( OrderMagicNumber() != MagicNumber)  continue;
      
      if(OrderType() == OP_BUY )  NumPositions++;
      if(OrderType() == OP_SELL ) NumPositions++;
             
     }
     return (NumPositions);
  }

//+------------------------------------------------------------------+
//| Close Open Position Controls                                     |
//|  Try to close position 3 times                                   |
//+------------------------------------------------------------------+
int CloseOrder(int ticket,double numLots,int type)
{
   int CloseCnt, err;
   double close_price;
   
   // try to close 3 Times
      
    CloseCnt = 0;
    while (CloseCnt < 3)
    {
       switch (type)
       {
         case OP_BUY : close_price = MarketInfo(Symbol(),MODE_BID);
                       break;
         case OP_SELL : close_price = MarketInfo(Symbol(),MODE_ASK);
       }
       
       if (!OrderClose(ticket,numLots,close_price,Slippage,Violet))
       {
         err=GetLastError();
         Print(CloseCnt," Error closing order : (", err , ") " + ErrorDescription(err));
         if (err > 0) CloseCnt++;
       }
       else
       {
         CloseCnt = 3;
       }
    }
}

int ModifyStopLoss(int ticket, double stoploss)
{
    int Cnt, digits, err;
    string symbol;
    double myStopLoss;
    
    OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES);
    symbol = OrderSymbol();
    digits = MarketInfo(symbol,MODE_DIGITS);
    if (digits > 0)
    {
			 myStopLoss = NormalizeDouble(stoploss,digits);
    }
    Cnt=0;
    while (Cnt < 3)
    {
       if (OrderModify(ticket,OrderOpenPrice(),myStopLoss,OrderTakeProfit(),0,Aqua))
       {
         Cnt = 3;
       }
       else
       {
          err=GetLastError();
          Print(Cnt," Error modifying order : (", err , ") " + ErrorDescription(err));
         if (err>0) Cnt++;
       }
    }
}


//+------------------------------------------------------------------+
//| Handle Open Positions                                            |
//| Check if any open positions need to be closed or modified        |
//+------------------------------------------------------------------+
int HandleOpenPositions()
{
   int cnt;
   bool YesClose;
   double pt;
   
   for(cnt=OrdersTotal()-1;cnt>=0;cnt--)
   {
      OrderSelect (cnt, SELECT_BY_POS, MODE_TRADES);
      if ( OrderSymbol() != Symbol()) continue;
      if ( OrderMagicNumber() != MagicNumber)  continue;
      
      if(OrderType() == OP_BUY)
      {
            
         if (CheckExitCondition(OP_BUY))
          {
               CloseOrder(OrderTicket(),OrderLots(),OP_BUY);
               DeletePendingOrders();
               return(0);
          }
		   if (UseTrailingStop)	// Handle mods to trailing stop
			    HandleTrailingStop(OrderType(), OrderTicket(), OrderOpenPrice(), OrderStopLoss());
      }

      if(OrderType() == OP_SELL)
      {
          if (CheckExitCondition(OP_SELL))
          {
             CloseOrder(OrderTicket(),OrderLots(),OP_SELL);
             DeletePendingOrders();
             return(0);
          }
		    if (UseTrailingStop)	// Handle mods to trailing stop
			    HandleTrailingStop(OrderType(), OrderTicket(), OrderOpenPrice(), OrderStopLoss());
       }
   }
   return(0);
}

//=============================================================================
//
// 							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
//
//
//	PARAMETERS:
//
//		type:		OP_BUY or OP_SELL
//		ticket:		the ticket number
//		open_price:	the order's open price
//		cur_sl:		the order's current StopLoss value
//
//	RETURN VALUE:
//		zero for now
//
//  Calling example 
//	HandleTrailingStop(OP_BUY,OrderTicket(),OrderOpenPrice(),OrderStopLoss());
//
//=============================================================================
int HandleTrailingStop(int type, int ticket, double open_price, double cur_sl)
{
	double pt, TS = 0, myAsk, myBid;

	if (type == OP_BUY)
	{
		myBid = MarketInfo(Symbol(),MODE_BID);
		switch (TrailingStopType)
		{
			case 1: 
				pt = Point * StopLoss;
				if (myBid - cur_sl > pt) 
					ModifyStopLoss(ticket, myBid - pt);
				break;
				
			case 2: 
				pt = Point * TrailingStop;
				if (myBid - open_price > pt && (cur_sl < myBid - pt || cur_sl == 0))
					ModifyStopLoss(ticket, myBid - pt);
				break;

		}
		return(0);
	}


	else if (type ==  OP_SELL)
	{
		myAsk = MarketInfo(Symbol(),MODE_ASK);
		switch (TrailingStopType)
		{
			case 1: 
				pt = Point * StopLoss;
				if (cur_sl - myAsk > pt) 
					ModifyStopLoss(ticket, myAsk+pt);
				break;
				
			case 2: 
				pt = Point * TrailingStop;
				if (open_price - myAsk > pt && (cur_sl > myAsk + pt || cur_sl == 0))
					ModifyStopLoss(ticket, myAsk+pt);
				break;
				
		 }
	 }
	 return(0);
}

//+------------------------------------------------------------------+
//| Close Open Orders                                            |
//| Check if any open positions need to be closed or modified        |
//+------------------------------------------------------------------+
int CloseOpenOrders(int cmd)
{
   int cnt;
   bool YesClose;
   double pt;
   
   for(cnt=OrdersTotal()-1;cnt>=0;cnt--)
   {
      OrderSelect (cnt, SELECT_BY_POS, MODE_TRADES);
      if ( OrderSymbol() != Symbol()) continue;
      if ( OrderMagicNumber() != MagicNumber)  continue;
      
      if(OrderType() == OP_BUY)
      {
            
         if (cmd == OP_BUY)
          {
               CloseOrder(OrderTicket(),OrderLots(),Bid);
               DeletePendingOrders();
          }
      }

      if(OrderType() == OP_SELL)
      {
          if (cmd == OP_SELL)
          {
             CloseOrder(OrderTicket(),OrderLots(),Ask);
             DeletePendingOrders();
          }
       }
   }
}

//+------------------------------------------------------------------+
int DeletePendingOrders() {
   int i, ticket;

   //Check Orders
   for (i=OrdersTotal()-1;i>0;i--){
      OrderSelect(i,SELECT_BY_POS,MODE_TRADES);
      if(OrderSymbol()!=Symbol()) continue;
      if (OrderMagicNumber() != MagicNumber) continue;
      if( OrderType()==OP_BUYSTOP)  OrderDelete(OrderTicket());
      if( OrderType()==OP_SELLSTOP) OrderDelete(OrderTicket());
    }
 }
     
//+------------------------------------------------------------------+
//| Get number of lots for this trade                                |
//+------------------------------------------------------------------+
double GetLots()
{
   double lot;
   
   if(MoneyManagement)
   {
     lot = LotsOptimized();
   }
   else
   {
     lot = Lots;
   }
   
   if(AccountIsMini)
   {
     if (lot < 0.1) lot = 0.1;
   }
   else
   {
     if (lot >= 1.0) lot = MathFloor(lot); else lot = 1.0;
   }
   if (lot > MaxLots) lot = MaxLots;
   
   return(lot);
}

//+------------------------------------------------------------------+
//| Calculate optimal lot size                                       |
//+------------------------------------------------------------------+

double LotsOptimized()
  {
   double lot=Lots;
   int TradePercent;
   
   TradePercent = TradeSizePercent;
   if (TradeSizePercent > 5) TradePercent = 5;
   
//---- select lot size
   lot=NormalizeDouble(MathFloor(AccountFreeMargin()*TradePercent/10000)/10,1);
   
  
  // lot at this point is number of standard lots
  
//  if (Debug) Print ("Lots in LotsOptimized : ",lot);
  
  // Check if mini or standard Account
  
  if(AccountIsMini)
  {
    lot = MathFloor(lot*10)/10;
    
   }
   return(lot);
  }

//+------------------------------------------------------------------+
//| Time frame interval appropriation  function                      |
//+------------------------------------------------------------------+

int func_TimeFrame_Const2Val(int Constant ) {
   switch(Constant) {
      case 1:  // M1
         return(1);
      case 5:  // M5
         return(2);
      case 15:
         return(3);
      case 30:
         return(4);
      case 60:
         return(5);
      case 240:
         return(6);
      case 1440:
         return(7);
      case 10080:
         return(8);
      case 43200:
         return(9);
   }
}

//+------------------------------------------------------------------+
//| Time frame string appropriation  function                               |
//+------------------------------------------------------------------+

string func_TimeFrame_Val2String(int Value ) {
   switch(Value) {
      case 1:  // M1
         return("PERIOD_M1");
      case 2:  // M1
         return("PERIOD_M5");
      case 3:
         return("PERIOD_M15");
      case 4:
         return("PERIOD_M30");
      case 5:
         return("PERIOD_H1");
      case 6:
         return("PERIOD_H4");
      case 7:
         return("PERIOD_D1");
      case 8:
         return("PERIOD_W1");
      case 9:
         return("PERIOD_MN1");
   	default: 
   		return("undefined " + Value);
   }
}

int func_Symbol2Val(string symbol) {
	if(symbol=="AUDCAD") {
		return(1);
	} else if(symbol=="AUDJPY") {
		return(2);
	} else if(symbol=="AUDNZD") {
		return(3);
	} else if(symbol=="AUDUSD") {
		return(4);
	} else if(symbol=="CHFJPY") {
		return(5);
	} else if(symbol=="EURAUD") {
		return(6);
	} else if(symbol=="EURCAD") {
		return(7);
	} else if(symbol=="EURCHF") {
		return(8);
	} else if(symbol=="EURGBP") {
		return(9);
	} else if(symbol=="EURJPY") {
		return(10);
	} else if(symbol=="EURUSD") {
		return(11);
	} else if(symbol=="GBPCHF") {
		return(12);
	} else if(symbol=="GBPJPY") {
		return(13);
	} else if(symbol=="GBPUSD") {
		return(14);
	} else if(symbol=="NZDUSD") {
		return(15);
	} else if(symbol=="USDCAD") {
		return(16);
	} else if(symbol=="USDCHF") {
		return(17);
	} else if(symbol=="USDJPY") {
		return(18);
	} else {
		Comment("unexpected Symbol");
		return(0);
	}
}

 





Sample





Analysis



Market Information Used:

Series array that contains close prices for each bar


Indicator Curves created:


Indicators Used:


MACD Histogram
Moving average indicator


Custom Indicators Used:
Ehlers_iTrend
HMA2
MACD_EMA
MACD_LSMA

Order Management characteristics:
It automatically opens orders when conditions are reached
Checks for the total of open orders
It Closes Orders by itself
It can change open orders parameters, due to possible stepping strategy

Other Features:

It issuies visual alerts to the screen

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

BackTest : GBPUSD on H1

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

Request Backtest for TriplePlayTesting


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

Pair: Period: