bouncingPipEA_mpowerV41





//+------------------------------------------------------------------+
//|                                         bouncingPipEA_mpower.mq4 |
//|                      Copyright © 2007, MetaQuotes Software Corp. |
//|                                        http://www.metaquotes.net |
//|
//| Originally coded for mPower by Zmax and modified by Robert Hill
//| using ideas posted at forex-tsd thread Follow The Bouncing Pip
//|
//| confirm entry using stochastic 14,3,3.
//| take profit default 30pips changed to 0 to allow exit at signal
//| from arrow and nonlagzigzag
//|
//| the trade is trigger when the arrow meet non lag zigzag and
//| after stochastic cross.
//| Added other tests to check including Heiken Ashi, Heiken Ashi Smoothed
//|   CCI, nonlagdot, and QQE
//|
//| for EA programmer - 
//| the entry is as follows:
//| Done 1. zigzag + arrow meet,confirmation by stochastic -when it cross
//|         Added many other filters as discussed in the thread
//| Done 2. move the S/L after xx pips. trail after its going up xx pips
//|         This is the delayed trailing stop
//| Done 3. S/L is xxpips.
//| Done 4. set take profit = xx pips...
//|         zero works better
//| Done 5. set money management - enter at xx lot after equity reach usd xxxxx
//| 6. set partial take profit - at xx pips
//|
//| Added code to check for proper ticket value
//| in case of disconnect from server or power loss
//| Ticket is retrieved from the server if any positions are open 
//|
//| 9/18/2007 Modified filter logic to allow more than 1 filter
//|           Added checking filter indicators as OR logic for exiting trades
//|           Default exit is ZigZag from original code
//+------------------------------------------------------------------+
#property copyright "Copyright © 2007, mpower, Zmax and Robert Hill"
#property link      "None"
#include <stdlib.mqh>
#include <stderror.mqh> 

// MoneyManagement method
#define NONE 1
#define NIX 2
#define BURNS 3
#define NIX2 4

// Trend
#define LONG 1
#define SHORT -1
#define FLAT 0

// Filter Method
#define NO_FILTER 1
#define HA_FILTER 2
#define HAS_FILTER 3
#define STOCH_FILTER 4
#define CCI_FILTER 5
#define DOT_FILTER 6
#define QQE_FILTER 7
#define NONLAGMA_FILTER 8

extern bool Debug = false;
//+------------------------------------------------------------------+
//| expert initialization function                                   |
//+------------------------------------------------------------------+
extern int     MagicID = 12345;

extern string  MoneyManagement = "-------------------------------------";
extern double  Lots = 0.1;
extern string  mm0 = "MM Method";
extern string  mm1 = " 1. Use Lots";
extern string  mm2 = " 2. NIX version";
extern string  mm3 = " 3. Burn0050 version";
extern string  mm4 = " 4. NIX new version w/stoploss";
extern int     MM_Method = 2;
extern bool    AccountIsMini = true;
extern double  Risk = 10; // percent
extern double  MIN_lots = 0.1;
extern double  MAX_lots = 5;

extern string  s0 = "---StopLoss Method---";
extern string  s1 = " 1. User Input";
extern string  s2 = " 2. Candle High/Low + UserInput";
extern string  s3 = " 3. Candle High/Low + Spread";
extern int     StopLossMethod = 2;
extern int     StopLoss = 30;

extern int     TakeProfit=0;

extern string  z0 = "---ZigZag settings---";
extern string  z1 = "---ZigZag Pointer---";
extern int     ExtDepth = 100;
extern int      ExtDeviation = 75;
extern int     ExtBackstep = 15;
extern string  z2 = "NonLagZigZag_v2";
extern int     Price = 0;  //Apply to Price(0-Close;1-Open;2-High;3-Low;4-Median price;5-Typical price;6-Weighted Close) 
extern int     Length = 100;  //Period of NonLagMA
extern double  PctFilter = 2;  //Dynamic filter in decimals


extern string  f0 = "---FilterMethods---";
extern string  f1 = " All useYyy switches require";
extern string  f2 = " 0 for false and 1 for true";
extern int     useWick = 0;
extern int     useHA = 0;
extern int     useHAS = 0;
extern int     useStoch = 0;
extern int     useCCI = 0;
extern int     useNonLagDot = 1;
extern int     useQQE = 0;
extern int     useNonLagMA = 0;

extern string  f3 = "---Exit Methods---";
extern int     useZigZag_Exit = 1;
extern int     useHA_Exit = 0;
extern int     useHAS_Exit = 0;
extern int     useStoch_Exit = 0;
extern int     useCCI_Exit = 0;
extern int     useNonLagDot_Exit = 0;
extern int     useQQE_Exit = 0;
extern int     useNonLagMA_Exit = 0;


extern string  f = "Wick";
extern int     Wick=0;
extern string  w1 = "Wait how many candles for confirmation";
extern int     WaitSignal=3;


extern string  h1 = "Heiken Ashi Smoothed";
extern string  has = "HAS Inputs";
extern int     MaMethod  = 2;
extern int     MaPeriod = 6;
extern int     MaMethod2  = 3;
extern int     MaPeriod2 = 2;

extern string  sto0 = "Stochastic Inputs";
extern int     K_Period = 14;
extern int     D_Period = 3;
extern int     Slowing = 3;
extern string  sto1 = "Price Mode";
extern string  sto2 = " 0 - Low/High";
extern string  sto3 = " 1 - Close/Close"; 
extern int     StochPrice = 0;
extern int     StochBuyLevel = 20;
extern int     StochSellLevel = 80;


extern string  cci = "CCI Inputs";
extern int     CCI_Period = 34;
extern string  p = "--Applied Price Types--";
extern string  p0 = " 0 = close";
extern string  p1 = " 1 = open";
extern string  p2 = " 2 = high";
extern string  p3 = " 3 = low";
extern string  p4 = " 4 = median(high+low)/2";
extern string  p5 = " 5 = typical(high+low+close)/3";
extern string  p6 = " 6 = weighted(high+low+close+close)/4";
extern int     CCI_Price = 5;
extern int     CCI_BuyCrossLevel = 0;
extern int     CCI_SellCrossLevel = 0;

extern string  dt0 = "NonLagDots settings";
extern int     NLD_Price = 0;
extern int     NLD_Length = 20;
extern int     NLD_Displace = 0;
extern int     NLD_Filter = 0;
extern int     NLD_Color = 1;
extern int     NLD_ColorBarBack = 0;
extern double  NLD_Deviation = 0;         

extern string  nl0 = "NonLagMA settings";
extern int     sPrice          = 0;  //Apply to Price(0-Close;1-Open;2-High;3-Low;4-Median price;5-Typical price;6-Weighted Close) 
extern int     sLength         =55;  //Period of NonLagMA
int            sDisplace       = 0;  //DispLace or Shift 
extern double  sPctFilter      = 0;  //Dynamic filter in decimal
int            sColor          = 1;  //Switch of Color mode (1-color)  
int            sColorBarBack   = 0;  //Bar back for color mode
extern double  sDeviation      = 0;  //Up/down deviation        


extern string  ts0 = "---TrailingStop Method---";
extern string  ts1 = " 1. None";
extern string  ts2 = " 2. PriceChannelStop";
extern string  ts3 = " 3. Breakeven + Lock";
extern string  ts4 = " 4. Delayed at input";
extern string  ts5 = " 5. Trail immediately";
extern int     TrailingStopMethod = 1;
extern string  ts6 = "2. PriceChannelStop";
extern int     Trigger = 10;
extern string  ts7 = "3. Breakeven at input settings";
extern double  BreakEvenLevel = 30;
extern int     LockInPips = 5;        // Profit Lock in pips
extern string  ts8 = "4. Delayed at input setting";
extern double  BeginTrailingStop = 35;      // Change to whatever number of pips you wish to trail your position with.

extern int     SignalCandle = 1;


bool okDownArrow,okUpArrow;
int count;
int NumOrders = 0;
double myStop, myTake;
double ZigZagUp,ZigZagDown;
double NonLagZigZag;

int init(){
   
   count=0;   
   okDownArrow=false;
   okUpArrow=false;
   return(0);
}
//+------------------------------------------------------------------+
//| expert deinitialization function                                 |
//+------------------------------------------------------------------+
int deinit(){

   return(0);
}
  
  

int getHAS()// return 1 is blue ;-1 is red
{
   double hasOpen, hasClose;
   
   hasOpen = iCustom(NULL,0,"Heiken_Ashi_Smoothed",MaMethod,MaPeriod,MaMethod2,MaPeriod2,1,SignalCandle) ;
   hasClose = iCustom(NULL,0,"Heiken_Ashi_Smoothed",MaMethod,MaPeriod,MaMethod2,MaPeriod2,0,SignalCandle) ;
   if (hasOpen < hasClose) return(SHORT);
   if (hasOpen > hasClose) return(LONG);
   return(FLAT); 
}

int getHA()
{
   double HeikenAshiOpen, HeikenAshiClose;
   
   HeikenAshiOpen=iCustom(NULL,0,"Heiken Ashi",2,SignalCandle);
   HeikenAshiClose=iCustom(NULL,0,"Heiken Ashi",3,SignalCandle);
   if (HeikenAshiOpen < HeikenAshiClose) return (LONG);  //up HA
   if (HeikenAshiOpen > HeikenAshiClose) return (SHORT); //down HA
   return(FLAT); 
}

int getStoch()
{
   double StochMain, StochSignal;
   
   StochMain = iStochastic(NULL, 0, K_Period, D_Period, Slowing, MODE_SMA, StochPrice, MODE_MAIN, SignalCandle);
   StochSignal = iStochastic(NULL, 0, K_Period, D_Period, Slowing, MODE_SMA, StochPrice, MODE_SIGNAL, SignalCandle);
   
   if (StochMain < StochBuyLevel)
   {
      if (StochSignal > StochMain) return (LONG);
   }
   
   if (StochMain > StochSellLevel)
   {
      if (StochSignal < StochMain) return (SHORT);
   }
   
   return(FLAT);
   
}

int getCCI()
{
  double CCI_Cur, CCI_Prev;
  
  CCI_Cur = iCCI(NULL, 0, CCI_Period, CCI_Price, SignalCandle);
  CCI_Prev = iCCI(NULL, 0, CCI_Period, CCI_Price, SignalCandle);
  
  if (CCI_Prev < CCI_BuyCrossLevel && CCI_Cur > CCI_BuyCrossLevel) return(LONG);
  if (CCI_Prev > CCI_SellCrossLevel && CCI_Cur < CCI_SellCrossLevel) return(SHORT);
  return(FLAT);
}

int getNonLagDot()
{

  double NLD_Long, NLD_Short;
  NLD_Long = iCustom(NULL, 0, "nonlagdot",
                      NLD_Price, NLD_Length,NLD_Displace,
                      NLD_Filter,NLD_Color, NLD_ColorBarBack,NLD_Deviation,
                      1,SignalCandle);
  NLD_Short = iCustom(NULL, 0, "nonlagdot",
                       NLD_Price, NLD_Length,NLD_Displace,
                       NLD_Filter,NLD_Color, NLD_ColorBarBack,NLD_Deviation,
                       2,SignalCandle);
                       
   if (NLD_Long < 1000) return(LONG);
   if (NLD_Short < 1000) return(SHORT);
   return(FLAT);          
}

int getQQE()
{

   double QQE_RsiMa, QQE_TrLevelSlow;
   double QQE_RsiMaPrev, QQE_TrLevelSlowPrev;
   
   QQE_RsiMa = iCustom(NULL, 0, "QQE", 0,SignalCandle);
   QQE_TrLevelSlow = iCustom(NULL, 0, "QQE", 1, SignalCandle);
   QQE_RsiMaPrev = iCustom(NULL, 0, "QQE", 0,SignalCandle + 1);
   QQE_TrLevelSlowPrev = iCustom(NULL, 0, "QQE", 1, SignalCandle + 1);
  
   if (QQE_RsiMaPrev < QQE_TrLevelSlowPrev   &&  QQE_RsiMa > QQE_TrLevelSlow) return(LONG);
   if (QQE_RsiMaPrev > QQE_TrLevelSlowPrev   &&  QQE_RsiMa < QQE_TrLevelSlow) return(SHORT);
   return(FLAT);
   
}

int getNLMA()
{
   double sNL_Long, sNL_Short;
   
    sNL_Long = iCustom(Symbol(),0,"NonLagMA_v7.1",sPrice,sLength,sDisplace,sPctFilter,sColor,sColorBarBack,sDeviation,0,0,1,SignalCandle);
    sNL_Short = iCustom(Symbol(),0,"NonLagMA_v7.1",sPrice,sLength,sDisplace,sPctFilter,sColor,sColorBarBack,sDeviation,0,0,2,SignalCandle);
//   double sNL12 = iCustom(Symbol(),NL_TF,"NonLagMA_v7.1",sPrice,sLength,sDisplace,sPctFilter,sColor,sColorBarBack,sDeviation,0,0,1,SignalCandle+1);
//   double sNL22 = iCustom(Symbol(),NL_TF,"NonLagMA_v7.1",sPrice,sLength,sDisplace,sPctFilter,sColor,sColorBarBack,sDeviation,0,0,2,SignalCandle+1);
   
   if (sNL_Long != EMPTY_VALUE) return(LONG);
   if (sNL_Short != EMPTY_VALUE) return(SHORT);
   return(FLAT); 
}

bool checkHA(int cmd)
{
   int HA;
  
   HA = getHA();
   switch (cmd)
   {
   case OP_BUY : if (HA == LONG) return(true);
                 break;
   case OP_SELL : if (HA == SHORT) return (true);
   }
   return (false);
}

bool checkHAS(int cmd)
{
   int HAS;
  
   HAS = getHAS();
   switch (cmd)
   {
   case OP_BUY : if (HAS == LONG) return(true);
                 break;
   case OP_SELL : if (HAS == SHORT) return (true);
   }
   return (false);
}

bool checkStoch(int cmd)
{
   int Stoch;
  
   Stoch = getStoch();
   switch (cmd)
   {
   case OP_BUY : if (Stoch == LONG) return(true);
                 break;
   case OP_SELL : if (Stoch == SHORT) return (true);
   }
   return (false);
}

bool checkCCI(int cmd)
{
   int CCI;
  
   CCI = getCCI();
   switch (cmd)
   {
   case OP_BUY : if (CCI == LONG) return(true);
                 break;
   case OP_SELL : if (CCI == SHORT) return (true);
   }
   return (false);
}

bool checkNLD(int cmd)
{
   int NLD;
  
   NLD = getNonLagDot();
   switch (cmd)
   {
   case OP_BUY : if (NLD == LONG) return(true);
                 break;
   case OP_SELL : if (NLD == SHORT) return (true);
   }
   return (false);
}

bool checkQQE(int cmd)
{
   int QQE;
  
   QQE = getQQE();
   switch (cmd)
   {
   case OP_BUY : if (QQE == LONG) return(true);
                 break;
   case OP_SELL : if (QQE == SHORT) return (true);
   }
   return (false);
}

bool checkNLMA(int cmd)
{
   int NLMA;
  
   NLMA = getNLMA();
   switch (cmd)
   {
   case OP_BUY : if (NLMA == LONG) return(true);
                 break;
   case OP_SELL : if (NLMA == SHORT) return (true);
   }
   return (false);
}

// Modified to allow more than one filter to be used
// All filters must be true to allow trades
bool CheckFilter(int cmd)
{

   bool rule1, rule2, rule3, rule4, rule5, rule6, rule7, rule8;
   
// Assume all rules are met
// That way if a rule is not used it is automaticaly true
   rule1 = true;
   rule2 = true;
   rule3 = true;
   rule4 = true;
   rule5 = true;
   rule6 = true;
   rule7 = true;
   rule8 = true;
   
   
   if (useHA == 1) rule1 = checkHA (cmd);
   if (rule1 == true)
   {
     if (useHAS == 1) rule2 = checkHAS(cmd);
     if (rule2 == true)
     {
       if (useStoch == 1) rule3 = checkStoch(cmd);
       if (rule3 == true)
       {
          if (useCCI == 1) rule4 = checkCCI(cmd);
          if (rule4 == true)
          {
            if (useHA == 1) rule5 = checkNLD(cmd);
            if (rule5 == true)
            {
              if (useNonLagDot == 1) rule6 = checkNLD(cmd);
              if (rule6 == true)
              {
                if (useQQE == 1) rule7 = checkQQE(cmd);
                
// Done this way to make it easier to add new rules
                
                if (rule7 == true)
                {
                   if (useNonLagMA == 1) rule8 = checkNLMA(cmd);
                }
                if (rule8 == true) return(true);
              }
            }
          }
        }
      }
   }
   
   return (false);
   
}

bool checkZigZag(int cmd)
{
   if (cmd == OP_SELL)
   {
//check down arrow & nonlag
       if ((ZigZagDown != 0) && (ZigZagDown == NonLagZigZag))return (true);
   }
   
   if (cmd == OP_BUY)
   {
      //check up arrow & nonlag
      if ((ZigZagUp != 0) && (ZigZagUp == NonLagZigZag))return (true);
   }
   return (false);
}

// Will exit when any exit method is true
bool CheckExit(int cmd)
{
   int myCmd;
   
// reverse cmd for exit check
// Exit buy needs indicator to show sell signal
// Exit sell needs indicator to show buy signal
   if (cmd == OP_BUY) myCmd = OP_SELL;
   if (cmd == OP_SELL) myCmd = OP_BUY;
   
   if (useZigZag_Exit == 1) { if (checkZigZag(myCmd) == true) return (true);}
   if (useHA_Exit == 1){ if (checkHA(myCmd) == true) return(true);}
   if (useHAS_Exit == 1){ if (checkHAS(myCmd) == true) return(true);}
   if (useStoch_Exit == 1){ if (checkStoch(myCmd) == true) return(true);}
   if (useCCI_Exit == 1){ if (checkCCI(myCmd) == true) return(true);}
   if (useNonLagDot_Exit == 1){ if (checkNLD(myCmd) == true) return(true);}
   if (useQQE_Exit == 1){ if (checkQQE(myCmd) == true) return(true);}
   if (useNonLagMA_Exit == 1){ if (checkNLMA(myCmd) == true) return(true);}
   return (false);   
}
  
//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+
int start(){
   static datetime dtBarTime = 0;
   static int ticket;
   int myTicket; 
   double myLots, mStop;
   
   
// For closed candle only check once per Bar

   if (SignalCandle == 1)
   {
     if (dtBarTime == Time[0]) return(0);  
     dtBarTime = Time[0];
   }
   
   NonLagZigZag=iCustom(NULL,0,"NonLagZigZag_v2",Price,Length,PctFilter,0,SignalCandle);   
   
   ZigZagUp=iCustom(NULL,0,"ZigZag Pointer", ExtDepth,ExtDeviation,ExtBackstep,0,SignalCandle);
   ZigZagDown=iCustom(NULL,0,"ZigZag Pointer", ExtDepth,ExtDeviation,ExtBackstep,1,SignalCandle);
   
   if ((okUpArrow == true) && (okDownArrow == false)){
      
      count=count+1;
      if (count <= WaitSignal){
//         Alert("UP count: ",count," waitSignal: ",WaitSignal);
         if (CheckFilter(OP_BUY) == true){
           myStop = GetStopLoss(OP_BUY, count);
           mStop = StopLong(Bid, myStop);
           myTake = TakeLong(Ask, TakeProfit);
           myLots = GetLots(OP_BUY, myStop, Risk);
           ticket=OrderSend(Symbol(),OP_BUY,myLots,Ask,3,mStop,myTake,"",MagicID,0,Green);
           okUpArrow=false;
           count=0;
//           Alert("zzz1");
         }  
      }else{
         count=0;
         okUpArrow=false;
      }
      
   }
   
   if ((okDownArrow == true) && (okUpArrow == false)){
      
      count=count+1;
      if (count <= WaitSignal){
//         Alert("Down count: ",count," waitSignal: ",WaitSignal);
         if (CheckFilter(OP_SELL) == true){
            myStop = GetStopLoss(OP_SELL, count);
            mStop = StopShort(Ask, myStop);
            myTake = TakeShort(Bid, TakeProfit);
            myLots = GetLots(OP_SELL, myStop, Risk);
            ticket=OrderSend(Symbol(),OP_SELL,myLots,Bid,3,mStop,myTake,"",MagicID,0,Red);      
            okDownArrow=false;
            count=0;
//            Alert("zzz2");
         }
      }else{
         okDownArrow=false;
         count=0;
      }
   }
   


   if (okDownArrow == false){
      myTicket = GetOpenTicket();
      if (myTicket > 0)
      {
         if (CheckExit (OP_BUY) == true){ //down arrow & nonlag
            CloseOrder(myTicket);
            return(0);
         }
         else
            CheckForTrail(myTicket);
      }
      if (checkZigZag(OP_SELL) == true)
      {
         if (Body_Wick(OP_SELL, 1) == true){ //if body is smaller than the wick
            okDownArrow=true;
 //           Alert("Down");
         }
      }
      
   }
   
   if (okUpArrow == false){
      myTicket = GetOpenTicket();
      if (myTicket > 0)
      {
         if (CheckExit(OP_SELL) == true){ //up arrow & nonlag
            CloseOrder(myTicket);
            return(0);
         }
         else
            CheckForTrail(myTicket);
      }
      if (checkZigZag(OP_BUY) == true)
      {
         if (Body_Wick(OP_BUY, 1) == true){ //if body is smaller than the wick
            okUpArrow=true; 
 //           Alert("Up"); 
         } 
      }
   }

   return(0);
}

int GetOpenTicket()
{
   int mTicket = 0;
   
   for (int i = OrdersTotal() - 1; i >= 0;i--)
   {
      OrderSelect(i, SELECT_BY_POS, MODE_TRADES);
      if(OrderSymbol() != Symbol()) continue;
      if (OrderMagicNumber() != MagicID) continue;
         
// We have an open trade
         mTicket = OrderTicket();
   }
   
   return (mTicket);
}

void CloseOrder(int ticket)
{
   int myTicket;

   datetime ctm;
   
   myTicket = ticket;
   
// Do this in case disconnect or power loss cause ticket to reset to 0
   if (ticket == 0)
   {
         myTicket = GetOpenTicket();
   }
   if (OrderSelect(myTicket,SELECT_BY_TICKET) == true){
     ctm = OrderCloseTime();
     if (ctm == 0)  // Order has not closed
     {
        if (OrderType() == OP_BUY){
           OrderClose(myTicket,OrderLots(),Bid,3,Green);
        }
        if (OrderType() == OP_SELL){
           OrderClose(myTicket,OrderLots(),Ask,3,Red);
        //Alert("zzzz: ticket", myTicket);
        }
     }
   }
   
   return(0);
}


void CheckForTrail(int ticket)
{
   int myTicket;
   datetime ctm;
   double OrderLTS, OrderOP;
   double OrderTP, OrderSL; 
   
   myTicket = ticket;
   
// Do this in case disconnect or power loss cause ticket to reset to 0
   if (ticket == 0)
   {
         myTicket = GetOpenTicket();
   }
   if (OrderSelect(myTicket,SELECT_BY_TICKET) == true)
   {
      ctm = OrderCloseTime();
      if (ctm == 0)  // Order has not closed
      {
         OrderOP = OrderOpenPrice();
         OrderTP = OrderTakeProfit();
         OrderSL = OrderStopLoss();
      
         if(OrderType()==OP_BUY)
         {
                  HandleTrailingStop(OP_BUY, myTicket, OrderOP, OrderSL, OrderTP);
         }
         if(OrderType()==OP_SELL)
         {
                HandleTrailingStop(OP_SELL, myTicket, OrderOP, OrderSL, OrderTP);
         }
      }
   }
}

// Modified to return stoploss in pips
double GetStopLoss(int cmd, int count)
{
   double myStopLoss;
   
   if (cmd == OP_BUY)
   {
      switch (StopLossMethod)
      {
      case 1 : myStopLoss = StopLoss;
               break;
      case 2 : myStopLoss = (Bid - iLow(Symbol(),Period(),SignalCandle)) / Point - StopLoss;
               break;
      case 3 : myStopLoss = (Bid - iLow(Symbol(),Period(),count+1)) / Point-(MarketInfo(Symbol(),MODE_SPREAD)+1);
      }
   }
   if (cmd == OP_SELL)
   {
      switch (StopLossMethod)
      {
      case 1 : myStopLoss = StopLoss;
               break;
      case 2 : myStopLoss = (iHigh(Symbol(),Period(),SignalCandle) - Ask) / Point + StopLoss;
               break;
      case 3 : myStopLoss = (iHigh(Symbol(),Period(),count+1) - Ask) / Point + (MarketInfo(Symbol(),MODE_SPREAD)+1);
      }
   }
   
   return (myStopLoss);
   
}

double StopLong(double price,int stop)
{
 if(stop==0)
  return(0);
 else
  return(price-(stop*Point));
}

double StopShort(double price,int stop)
{
 if(stop==0)
  return(0);
 else
  return(price+(stop*Point));
}

double TakeLong(double price,int take)
{
 if(take==0)
  return(0);
 else
  return(price+(take*Point));
}

double TakeShort(double price,int take)
{
 if(take==0)
  return(0);
 else
  return(price-(take*Point));
}

bool Body_Wick(int cmd, int shift){
   bool auxValue=false;
   double body,bottomWick,topWick;
   double open,close,high,low;
   
// Check switch
   if (useWick == 0) return(true);
   
   open=iOpen(Symbol(),Period(),shift);
   close=iClose(Symbol(),Period(),shift);
   low=iLow(Symbol(),Period(),shift);
   high=iHigh(Symbol(),Period(),shift);
   
   if (open < close){ //up candle
      topWick=high-close;
      body=close-open;
      bottomWick=open-low;
   }
   else{ //down candle
      topWick=high-open;
      body=open-close;
      bottomWick=close-low; 
   }
   
   
   if (cmd == OP_BUY)
   {
     if (topWick > Wick*body) auxValue=true;
   }
   
   if (cmd == OP_SELL)
   {
     if (bottomWick > Wick*body) auxValue=true;
   }
   
   
   return (auxValue);
}

double GetLots(int cmd, double myStop, double myRisk)
{
  int mStop;
  double mLots;
  
  switch (MM_Method )
  {
     case NONE  : mLots = Lots;
                  break;
     case NIX   : mLots = AutoLots();
                  break;
     case BURNS : if (cmd == OP_BUY) mStop = MathFloor((Bid - myStop) / Point); 
                  if (cmd == OP_SELL) mStop = MathFloor((myStop - Ask) / Point);
                  mLots = LotSize (mStop, myRisk);
//                  Print("StopInPips : ", mStop, "StopLoss : ", myStop, "Lots : ", mLots);
     case NIX2  : if (cmd == OP_BUY) mStop = MathFloor((Bid - myStop) / Point); 
                  if (cmd == OP_SELL) mStop = MathFloor((myStop - Ask) / Point);
                  mLots = AutoLots2(myRisk, mStop);
  }
  
  return (mLots);
  
}

// version from burn0050
double LotSize(int stopInPips, double accountRisk){

 
   double lotMM = ( AccountFreeMargin() * (accountRisk/100) )/( MarketInfo(Symbol(),MODE_TICKVALUE) * stopInPips );
       //This can be used with discretion
   if (AccountIsMini) {
       //Round to the nearest 10th - AccountIsMini needs to be a bool set at the top level
      lotMM = MathFloor(lotMM*10)/10;
   } else {
       //Round to the nearest lot
 
      lotMM = MathRound(lotMM);
 
         //To be aggressive, use this one
         //lotMM = MathCeil(lotMM);
 
   }
   if (lotMM < 0.1) lotMM = .1;
   if (lotMM > 100) lotMM = 100;
 
   return (lotMM);
}

// Version from nix
double AutoLots()
{
   int Decimals = 0;
   double mLots;
   double MaxLotPurchase = 0;
  

   //
   // don't overleverage!
   // 
   
   //int AccLeverage = AccountLeverage();
   int AccLeverage = 100;

   //
   // Step for changing lots
   //
   
   double ModeLotStep = MarketInfo(Symbol(), MODE_LOTSTEP);
   double ModeLotSize = MarketInfo(Symbol(), MODE_LOTSIZE);
   
   if(ModeLotStep == 0.01)
      Decimals = 2;
   if(ModeLotStep == 0.1)
      Decimals = 1;
   
   //
   // Calculate auto lots
   //
   
   if(ModeLotSize != 0)
      MaxLotPurchase=((AccountEquity()*AccLeverage)/ModeLotSize)*(Risk*0.01);
   else
      MaxLotPurchase=MIN_lots;
      
   mLots = StrToDouble(DoubleToStr(MaxLotPurchase,Decimals));
   
   if (mLots < MIN_lots) mLots = MIN_lots;
   if (mLots > MAX_lots) mLots = MAX_lots;

   return(mLots);    
}

// Version 2 from Nix
//double AutoLots2(int Risk, int StopLossInPips, double MIN_lots = 0.1, double MAX_lots = 5)
// MIN_Lots and MAX_Lots are inputs to the EA
double AutoLots2(int accountRisk, int StopLossInPips)
{
   int    Decimals = 0;
 
   double LotStep = MarketInfo(Symbol(), MODE_LOTSTEP);
   double LotSize = MarketInfo(Symbol(), MODE_LOTSIZE);
   double LotTickValue = MarketInfo(Symbol(), MODE_TICKVALUE);

   if(LotStep == 0.01)
      Decimals = 2;
   if(LotStep == 0.1)
      Decimals = 1;

   double LotsToRisk = ((AccountFreeMargin()*accountRisk)/100)/StopLossInPips;
   double Lots = StrToDouble(DoubleToStr(LotsToRisk/LotTickValue,Decimals));
  
   if (Lots < MIN_lots)
      Lots = MIN_lots;
   if (Lots > MAX_lots)
      Lots = MAX_lots;

   return(Lots);    
}
//+------------------------------------------------------------------+
//| HandleTrailingStop                                               |
//| Type 1 is do not trail                                           |
//| Type 2 Moves to breakeven + lock when internal TP is hit         |
//| Type 3 is like Type 5 but waits until internal TP is hit         |
//| Type 4 Move stop to breakeven + Lockin, no trail                 |
//| Type 5 waits for price to move the amount of the trailStop       |
//|        before moving stop loss then moves like type 4            |
//| Type 6 moves the stoploss without delay.                         |
//+------------------------------------------------------------------+
void HandleTrailingStop(int cmd, int ticket, double op, double os, double tp)
{
   switch (TrailingStopMethod)
   {
     case 1 : //MoveTP(cmd, ticket, op, os, tp);
              break;
     case 2 : Trail_PriceChannel(cmd, ticket, op, os, tp);
              break;
     case 3 : BreakEven_TrailingStop (cmd, ticket, op, os, tp);
              break;
     case 4 : Delayed_TrailingStop (cmd, ticket, op, os, tp);
              break;
     case 5 : Immediate_TrailingStop (cmd, ticket, op, os, tp);
              break;
    default : //MoveTP(cmd, ticket, op, os, tp);
              break;
	}
}

void Trail_PriceChannel(int cmd, int ticket, double oOP, double oSL, double oTP )
{
   double PriceChannelStopUp,PriceChannelStopDown;
        
    if (OrderType() == OP_BUY)
    {               
            
       if ((Ask-oOP) > Trigger*Point)
       {
          PriceChannelStopUp=iCustom(NULL,0,"PriceChannel_Stop_v1",0,0);
          if (PriceChannelStopUp < 1000)
          {
          //Alert("Victor buy: ",Ask-OrderOpenPrice());
          OrderModify(ticket,oOP,PriceChannelStopUp,oTP,0,Red);
          }                 
       }
    }
    if (OrderType() == OP_SELL){
       if ((oOP - Bid)> Trigger*Point)
       {
          PriceChannelStopDown=iCustom(NULL,0,"PriceChannel_Stop_v1",1,0);
          if (PriceChannelStopDown < 1000)
          {
          //Alert(" Victor sell: ",OrderOpenPrice() - Bid);
          OrderModify(ticket,oOP,PriceChannelStopDown,oTP,0,Red);
          }
       }
    }
        
}

//+------------------------------------------------------------------+
//|                                           BreakEven_TrailingStop |
//|                                  Copyright © 2006, Forex-TSD.com |
//|                         Written by MrPip,robydoby314@yahoo.com   |
//+------------------------------------------------------------------+
void BreakEven_TrailingStop(int cmd, int ticket, double oOP, double oSL, double oTP )
{
   double myStopLoss;
   
   if (cmd == OP_BUY)
   {
       if(Bid >= oOP + BreakEvenLevel * Point)
       {
// Check move stop loss

         if (oSL < oOP)
         {
// Move Stop to Breakeven + BreakEvenLock

            myStopLoss = oOP + LockInPips * Point;
            myStopLoss = ValidStopLoss(OP_BUY,Bid, myStopLoss);   
            myStopLoss = NormalizeDouble( myStopLoss, Digits);
            
            ModifyOrder(ticket,oOP, myStopLoss, oTP,LightGreen);

         }
       }
   }
     
   if (cmd == OP_SELL)
   {
       if(Ask <= oOP - BreakEvenLevel * Point)
       {
// Check move stop loss

          if((oSL > oOP) || (oSL < 0.1))
          {
// Move Stop to Breakeven + BreakEvenLock
          
             myStopLoss = oOP - LockInPips * Point;
             myStopLoss = ValidStopLoss(OP_SELL,Ask, myStopLoss);   
             myStopLoss = NormalizeDouble( myStopLoss, Digits);
             
             ModifyOrder(ticket,oOP, myStopLoss, oTP,DarkOrange);
            
          }
        }

   }
}

//+------------------------------------------------------------------+
//|                                         Delayed_TrailingStop.mq4 |
//|                                  Copyright © 2006, Forex-TSD.com |
//|                         Written by MrPip,robydoby314@yahoo.com   |
//|                                                                  |   
//| Waits for price to move the amount of the BeginTrailingStop      |
//| Moves the stoploss pip for pip after delay.                      |
//+------------------------------------------------------------------+
void Delayed_TrailingStop(int cmd, int ticket, double oOP, double oSL, double oTP )
{
   double myStopLoss;
           
   if(cmd == OP_BUY)
   {
         if(Bid >= oOP + BeginTrailingStop * Point)
         {
            myStopLoss = Bid - BeginTrailingStop * Point;
            myStopLoss = ValidStopLoss(OP_BUY,Bid, myStopLoss);
            myStopLoss = NormalizeDouble( myStopLoss, Digits);
            if (oSL < myStopLoss)
            {
               ModifyOrder(ticket,oOP, myStopLoss, oTP,LightGreen);
            }
         }
     }
     
     if (cmd == OP_SELL)
     {
         if(Ask <= oOP - BeginTrailingStop * Point)
         {
            myStopLoss = Ask + BeginTrailingStop * Point;
            myStopLoss = ValidStopLoss(OP_SELL,Ask, myStopLoss);   
            myStopLoss = NormalizeDouble( myStopLoss, Digits);
            if ((oSL > myStopLoss) || (oSL < 0.1))
            {
               ModifyOrder(ticket,oOP, myStopLoss, oTP,DarkOrange);
            }
         }
     }
}

//+------------------------------------------------------------------+
//|                                       Immediate_TrailingStop.mq4 |
//|                                  Copyright © 2006, Forex-TSD.com |
//|                         Written by MrPip,robydoby314@yahoo.com   |
//|                                                                  |   
//| Moves the stoploss without delay.                                |
//+------------------------------------------------------------------+
void Immediate_TrailingStop(int cmd, int ticket, double oOP, double oSL, double oTP)
{
   double  myStopLoss;
   
   if (cmd==OP_BUY)
   {
     myStopLoss = Bid - myStop * Point;
     if (Digits > 0) myStopLoss = NormalizeDouble( myStopLoss, Digits);
	  myStopLoss = ValidStopLoss(OP_BUY,Bid, myStopLoss);   
     myStopLoss = NormalizeDouble( myStopLoss, Digits);
     if (oSL < myStopLoss)
     {
	     ModifyOrder(ticket,oOP, myStopLoss, oTP,LightGreen);
     }


   }
   if (cmd==OP_SELL)
   {
     myStopLoss = Ask + myStop * Point;
     if (Digits > 0) myStopLoss = NormalizeDouble( myStopLoss, Digits);
     myStopLoss = ValidStopLoss(OP_SELL, Ask, myStopLoss);  
     myStopLoss = NormalizeDouble( myStopLoss, Digits);
     if (oSL > myStopLoss)
     {
       ModifyOrder(ticket,oOP, myStopLoss, oTP,DarkOrange);
     }
     

   }   
}

int ModifyOrder(int ord_ticket,double op, double oSL, double oTP, color mColor)
{
    int CloseCnt, err;
    CloseCnt=0;
    while (CloseCnt < 3)
    {
       if (OrderModify(ord_ticket,op,oSL,oTP,0,mColor))
       {
         CloseCnt = 3;
       }
       else
       {
          err=GetLastError();
          if (err == 1)
             CloseCnt = 3;
          else
          {
            Print(CloseCnt," Error modifying order : (", err , ") " + ErrorDescription(err));
            if (err>0) CloseCnt++;
          }
       }
    }
}

double ValidStopLoss(int type, double price, double SL)
{

   double minstop, pp;
   
   if (SL < 0.1) return(SL);
   
   pp = MarketInfo(Symbol(), MODE_POINT);
   minstop = MarketInfo(Symbol(),MODE_STOPLEVEL);
   if (type == OP_BUY)
   {
		 if((price - SL) < minstop*pp) SL = price - minstop*pp;
   }
   if (type == OP_SELL)
   {
       if((SL-price) < minstop*pp)  SL = price + minstop*pp;  
   }

   return(SL);   
}
//+------------------------------------------------------------------+





Sample





Analysis



Market Information Used:

Series array that contains open time of each bar
Series array that contains the lowest prices of each bar
Series array that contains the highest prices of each bar
Series array that contains open prices of each bar
Series array that contains close prices for each bar


Indicator Curves created:


Indicators Used:


Stochastic oscillator
Commodity channel index


Custom Indicators Used:
NonLagZigZag_v2
ZigZag Pointer
Heiken Ashi
Heiken_Ashi_Smoothed
QQE
NonLagMA_v7.1
PriceChannel_Stop_v1

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:

BackTest : EURUSD on H1

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

BackTest : EURUSD on H1

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

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.86 Total Net Profit:-663.12

BackTest : USDCAD on H1

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

BackTest : USDCHF on H1

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

BackTest : USDJPY on H1

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

Request Backtest for bouncingPipEA_mpowerV41


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

Pair: Period: