//+------------------------------------------------------------------+
//|                                                  MACD Sample.mq4 |
//|                      Copyright © 2005, MetaQuotes Software Corp. |
//|                                       http://www.metaquotes.net/ |
//+------------------------------------------------------------------+

extern int        TakeProfit              = 999;
extern double     Lots                    = 0.1;
extern bool       TrailingStop            = true;
extern double     P_SARStep               = 0.02; 
extern double     P_SARMax                = 0.2; 
extern int        P_PACPer                = 5;
extern int        P_PACShift              = 0;
extern int        P_PACMode               = 2;
extern int        P_STDPer                = 5;
extern int        P_STDMin                = 5;
extern int        P_STDMax                = 20;
extern int        P_STDFMin               = 55;

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int start()
  {
   int cnt, ticket, total;
// initial data checks
// it is important to make sure that the expert works with a normal
// chart and the user did not make any mistakes setting external 
// variables (Lots, StopLoss, TakeProfit, 
// TrailingStop) in our case, we check TakeProfit
// on a chart of less than 100 bars
   if(Bars<100)
     {
      Print("bars less than 100");
      return(0);  
     }
   if(TakeProfit<10)
     {
      Print("TakeProfit less than 10");
      return(0);  // check TakeProfit
     }
// to simplify the coding and speed up access
// data are put into internal variables

//  MA 5 Upper and Lower Channels are defined
 
    double PACUpp0 = iMA(NULL,0,P_PACPer,P_PACShift,P_PACMode,PRICE_HIGH,0);  //MA 5 PRICE_HIGH now
    double PACUpp1 = iMA(NULL,0,P_PACPer,P_PACShift,P_PACMode,PRICE_HIGH,1);  //MA 5 PRICE_HIGH 1 bar ago
    
    double PACLow0 = iMA(NULL,0,P_PACPer,P_PACShift,P_PACMode,PRICE_LOW,0);   //MA 5 PRICE_LOW now
    double PACLow1 = iMA(NULL,0,P_PACPer,P_PACShift,P_PACMode,PRICE_LOW,1);   //MA 5 PRICE_LOW 1 bar ago
    
//  Heiken Ashi Close     
    
    double haClose0 = (Open[0]+High[0]+Low[0]+Close[0])*(0.25);      //Heiken Ashi Close now
    double haClose1 = (Open[1]+High[1]+Low[1]+Close[1])*(0.25);      //Heiken Ashi Close 1 bar ago
//Print("HeikenAshi0 = ", haClose0);
//Print("HeikenAshi1 = ", haClose1);

//  Calculates the Parabolic Stop and Reverse system

    double PSAR0       = iSAR(NULL,0,P_SARStep,P_SARMax,0);    
    double PSAR1       = iSAR(NULL,0,P_SARStep,P_SARMax,1); 

//  MA 2 Linear weighted - weighted Close

    double MAV0        = iMA (NULL,0,2,0,MODE_LWMA,PRICE_WEIGHTED,0);   //MA 2 Linear weighted - weighted Close.  now
    double MAV1        = iMA (NULL,0,2,0,MODE_LWMA,PRICE_WEIGHTED,1);   //MA 2 Linear weighted - weighted Close.  1 bar ago
//Print("MoveAve0 = ", MAV0);
//Print("MoveAve1 = ", MAV1);

//  Setting up an RSI array in Reverse Order

      double RSI[];
      ArrayResize(RSI,35);
      ArraySetAsSeries(RSI,true);
      for(int i=0; i<=34; i++)
      {
           RSI[i] = (iRSI(NULL,0,13,PRICE_CLOSE,i)); 
      }

       double Green0 = iMAOnArray(RSI,0,2,0,MODE_SMA,0);
       double Green1 = iMAOnArray(RSI,0,2,0,MODE_SMA,1);
//Print("Green0 = ",Green0);

       double Red0   = iMAOnArray(RSI,0,7,0,MODE_SMA,0);
       double Red1   = iMAOnArray(RSI,0,7,0,MODE_SMA,1);
//Print("Red0 = ",Red0);

       double Yellow0  = iMAOnArray(RSI,0,26,0,MODE_SMA,0);
//       double Yellow1  = iMAOnArray(RSI,0,26,0,MODE_SMA,1);
//Print("Yellow0 = ",Yellow0);
      double BlueUpp0 = iBandsOnArray(RSI,0,34,1.6185,0,MODE_UPPER,0);  
      double BlueUpp1 = iBandsOnArray(RSI,0,34,1.6185,0,MODE_UPPER,1);  
      double BlueLow0 = iBandsOnArray(RSI,0,34,1.6185,0,MODE_LOWER,0);  
      double BlueLow1 = iBandsOnArray(RSI,0,34,1.6185,0,MODE_LOWER,1);
//Print("Band0 = ",Band0);

      double Force[];
      ArrayResize(Force,14);
      ArraySetAsSeries(Force,true);
      for(int k=0; k<=13; k++)
      {
         Force[k]= (iForce(NULL,0,13,MODE_SMMA,PRICE_TYPICAL,k));
      }
       double FFast0 = iMAOnArray(Force,0,3,0,MODE_EMA,0);
       double FFast1 = iMAOnArray(Force,0,3,0,MODE_EMA,1);
       double FSlow0 = iMAOnArray(Force,0,13,0,MODE_EMA,0);
       double FSlow1 = iMAOnArray(Force,0,13,0,MODE_EMA,1);
       double STDF0 =  iStdDevOnArray(Force,0,13,0,MODE_EMA,0);
       double STDF1 =  iStdDevOnArray(Force,0,13,0,MODE_EMA,1);
//Print("STDF0 = ",STDF0);

       double STD0 = iStdDev(NULL,0,P_STDPer,0,MODE_LWMA,PRICE_WEIGHTED,0);
       double STD1 = iStdDev(NULL,0,P_STDPer,0,MODE_LWMA,PRICE_WEIGHTED,1);

    
   total=OrdersTotal();
   if(total<1) 
     {
      // no opened orders identified
      if(AccountFreeMargin()<(1000*Lots))
        {
         Print("We have no money. Free Margin = ", AccountFreeMargin());
         return(0);  
        }
      // check for long position (BUY) possibility
      // Entry-Rules for LONG positions:
      // 1. haClose > upper PAC moving average AND
      // 2. PAC moving average trending up AND
      // 3. TDI: RSI (green line) > 50 and TSL (red line) and MBL (yellow line) AND
      // 4. TDI: RSI (green line) < 68
//          ignore >50 <68, add Force, Standard Deviation and Parabolic SAR confirmation
      if(
//----------------------Price Action Channel Breakout----------------------
                  haClose0 >  PACUpp0
               && haClose0 >  haClose1
               && PACUpp0  >  PACUpp1
//----------------------Relative Strength Index------------------------
               && Green0   >  Green1
               && Green0   >= Red0
               && Red0     >= Red1
               && Green0   >= Yellow0
//               && Yellow0  >= Yellow1
//----------------------Parabolic SAR and Moving Average---------------------
               && PSAR0    <  MAV0
//----------------------Force Index------------------------
               && FFast0     >  FFast1    
               && FFast0     >  FSlow0    
               && FSlow0     >  FSlow1
//----------------------Standard Deviation------------------------
               && STDF0   >  STDF1
               && STDF0   >  (P_STDFMin*Point)
               && STD0   >  STD1
               && STD0   >  (P_STDMin*Point)
               && STD0   <  (P_STDMax*Point)
        )
        
        {
         ticket=OrderSend(Symbol(),OP_BUY,Lots,Ask,3,0,Ask+TakeProfit*Point,"macd sample",16384,0,Green);
         if(ticket>0)
           {
            if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES)) Print("BUY order opened : ",OrderOpenPrice());
           }
         else Print("Error opening BUY order : ",GetLastError()); 
         return(0); 
        }
      // check for short position (SELL) possibility
      // Entry-Rules for SHORT positions:
      // 1. haClose < lower PAC moving average AND
      // 2. PAC moving average trending down AND
      // 3. TDI: RSI (green line) < 50 and TSL (red line) and MBL (yellow line) AND
      // 4. TDI: RSI (green line) > 32 
//          ignore <50 >32, add Force, Standard Deviation and Parabolic SAR confirmation

      if(
//----------------------Price Action Channel Breakout----------------------
                  haClose0 <  PACLow0
               && haClose0 <  haClose1
               && PACLow0  <  PACLow1
//----------------------Relative Strength Index------------------------
               && Green0   <  Green1
               && Green0   <= Red0
               && Red0     <= Red1
               && Green0   <= Yellow0
//               && Yellow0  <= Yellow1
//----------------------Parabolic SAR and Moving Average---------------------
               && PSAR0    >  MAV0
//----------------------Force Index------------------------
               && FFast0     <  FFast1    
               && FFast0     <  FSlow0    
               && FSlow0     <  FSlow1
//----------------------Standard Deviation------------------------
               && STDF0   >  STDF1
               && STDF0   >  (P_STDFMin*Point)
               && STD0   >  STD1
               && STD0   >  (P_STDMin*Point)
               && STD0   <  (P_STDMax*Point)
         )
        {
         ticket=OrderSend(Symbol(),OP_SELL,Lots,Bid,3,0,Bid-TakeProfit*Point,"macd sample",16384,0,Red);
         if(ticket>0)
           {
            if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES)) Print("SELL order opened : ",OrderOpenPrice());
           }
         else Print("Error opening SELL order : ",GetLastError()); 
         return(0); 
        }
      return(0);
     }
   // it is important to enter the market correctly, 
   // but it is more important to exit it correctly...   
   for(cnt=0;cnt<total;cnt++)
     {
      OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);
      if(OrderType()<=OP_SELL &&   // check for opened position 
         OrderSymbol()==Symbol()  && // check for symbol
         OrderTicket() == ticket)
        {
         if(OrderType()==OP_BUY)   // long position is opened
           {
            // should it be closed?
            // Exit-Rules for LONG positions:
            // 1. Positive bar is much shorter than the previous bar or changes to a negative bar at close OR
            // 2. Bar closes inside the channel OR
            // 3. TDI: RSI (green line) crosses back below the RSL (red line) AND
            // 4. TDI: RSI > 68 AND
            // 5. TDI: RSI crosses back below the upper volatility band to the downside.
            // replace condition 4 by change of direction of Force moving averages
            // add Parabolic SAR exit instead of stop loss.
            if(
                (   PSAR1 <  MAV1
                 && PSAR0 >  MAV0
                )
                || (
                  Green0   <  Green1
               && Green0   <= Red0
               && Green0   <= BlueUpp0
               && haClose0  <=  PACUpp0
               && haClose0   <  haClose1
               && FFast0  < FFast1
               && FFast0  < FSlow0
               && STD0   <  STD1
                  )
               )
                {
                 OrderClose(OrderTicket(),OrderLots(),Bid,3,Violet); // close position
                 return(0); // exit
                }
            // check for trailing stop TS HANDLED BY PSAR
            if(TrailingStop==true)  
//              {                 
//               if(Bid-OrderOpenPrice()>Point*TrailingStop)
//                 {
//                  if(OrderStopLoss()<Bid-Point*TrailingStop)
                    {
                     OrderModify(OrderTicket(),OrderOpenPrice(),PSAR0,OrderTakeProfit(),0,Green);
                     return(0);
                    }
//                 }
//              }
           }
         else // go to short position
           {
            // should it be closed?
            // Exit-Rules for SHORT positions:
            // 1. Negative bar is much shorter than the previous bar or changes to a positive bar at close OR
            // 2. Bar closes inside the channel OR
            // 3. TDI: RSI (green line) crosses back above the RSL (red line) AND
            // 4. TDI: RSI < 32 AND
            // 5. TDI: RSI crosses back above the lower volatility band to the upside.
            // replace condition 4 by change of direction of Force moving averages
            // add Parabolic SAR exit instead of stop loss.
            if( 
                (   PSAR1 >  MAV1
                 && PSAR0 <  MAV0
                )
                || (
                  Green0   >  Green1
               && Green0   >= Red0
               && Green0   >= BlueLow0
               && haClose0  >=  PACLow0
               && haClose0  >  haClose1
               && FFast0  > FFast1
               && FFast0  > FSlow0
               && STD0   <  STD1
                  )
               )
              {
               OrderClose(OrderTicket(),OrderLots(),Ask,3,Violet); // close position
               return(0); // exit
              }
            // check for trailing stop TS HANDLED BY PSAR
            if(TrailingStop==true)  
//              {                 
//               if((OrderOpenPrice()-Ask)>(Point*TrailingStop))
//                 {
//                  if((OrderStopLoss()>(Ask+Point*TrailingStop)) || (OrderStopLoss()==0))
                    {
                     OrderModify(OrderTicket(),OrderOpenPrice(),PSAR0,OrderTakeProfit(),0,Red);
                     return(0);
                    }
//                 }
//              }
           }
        }
     }
   return(0);
  }
// the end.