How To Get 1 Indicator Value per Candle?

 

Right now I'm working with the Bollinger Bands on the daily timeframe, buying when price goes below the lower band and selling when prices goes above the upper band. However, when I run this code below in the Strategy Tester the bollinger bands are updated with every tick. I would like to only have 1 single bollinger band value taken at the beginning of each daily candle instead of it continually updating. How can I do this? Thanks!


//+------------------------------------------------------------------+
//|                                                       Mark 1.mq5 |
//|                                                      Joshua Blew |
//+------------------------------------------------------------------+
#property copyright "Joshua Blew"
#property version   "1.00"

//--- input parameters
input int      StopLoss=30;      // Stop Loss
input int      TakeProfit=60;   // Take Profit
input int      BB_Period=5;      // Bollinger Bands Period
input int      EA_Magic=12345;   // EA Magic Number
input double   Lot=0.1;          // Lots to Trade

//--- Other parameters
int bbandsHandle; // handle for our Bollinger Bands indicator
double upper[],mid[],lower[]; // Dynamic arrays to hold the values of Upper, Middle, & Lower Band values for each bars
double p_low; // Variable to store the close value of a bar
double p_high;
int STP, TKP;   // To be used for Stop Loss & Take Profit values
double upperVal;
double lowerVal;

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
  
  //--- Get handle for Bollinger Bands indicator
   bbandsHandle=iBands(_Symbol,PERIOD_D1,BB_Period,0,2,PRICE_CLOSE);
   //--- What if handle returns Invalid Handle
   if(bbandsHandle<0)
   {
      Alert("Error Creating Handles for indicators - error: ",GetLastError(),"!!");
      return(-1);
   }

//--- Let us handle currency pairs with 5 or 3 digit prices instead of 4
   STP = StopLoss;
   TKP = TakeProfit;
   if(_Digits==5 || _Digits==3)
     {
      STP = STP*10;
      TKP = TKP*10;
     }
   return(0);
  }
  
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//--- Release our indicator handles
   IndicatorRelease(bbandsHandle);
  }
  
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//--- Do we have enough bars to work with
   if(Bars(_Symbol,_Period)<6) // if total bars is less than 60 bars
     {
      Alert("We have less than 6 bars, EA will now exit!!");
      return;
     }  

// We will use the static Old_Time variable to serve the bar time.
// At each OnTick execution we will check the current bar time with the saved one.
// If the bar time isn't equal to the saved time, it indicates that we have a new tick.

   static datetime Old_Time;
   datetime New_Time[1];
   bool IsNewBar=false;

// copying the last bar time to the element New_Time[0]
   int copied=CopyTime(_Symbol,_Period,0,1,New_Time);
   if(copied>0) // ok, the data has been copied successfully
     {
      if(Old_Time!=New_Time[0]) // if old time isn't equal to new bar time
        {
        
          //--- Copy the new values of our indicators to buffers (arrays) using the handle
         if(CopyBuffer(bbandsHandle,0,0,3,mid)<0 || CopyBuffer(bbandsHandle,1,0,3,upper)<0
            || CopyBuffer(bbandsHandle,2,0,3,lower)<0)
           {
            Alert("Error copying Bollinger Bands indicator Buffers - error:",GetLastError(),"!!");
            ResetLastError();
            return;
           }
         else
         {
            upperVal = NormalizeDouble(upper[0],5);
            lowerVal = NormalizeDouble(lower[0],5);
         }
           
         IsNewBar=true;   // if it isn't a first call, the new bar has appeared
         
         if(MQL5InfoInteger(MQL5_DEBUGGING)) Print("We have new bar here ",New_Time[0]," old time was ",Old_Time);
         Old_Time=New_Time[0];            // saving bar time
        }
     }
   else
     {
      Alert("Error in copying historical times data, error =",GetLastError());
      ResetLastError();
      return;
     }

//--- EA should only check for new trade if we have a new bar
   if(IsNewBar==false)
     {
      return;
     }
 
//--- Do we have enough bars to work with
   int Mybars=Bars(_Symbol,_Period);
   if(Mybars<6) // if total bars is less than 60 bars
     {
      Alert("We have less than 6 bars, EA will now exit!!");
      return;
     }

//--- Define some MQL5 Structures we will use for our trade
   MqlTick latest_price;      // To be used for getting recent/latest price quotes
   MqlTradeRequest mrequest;  // To be used for sending our trade requests
   MqlTradeResult mresult;    // To be used to get our trade results
   MqlRates mrate[];          // To be used to store the prices, volumes and spread of each bar
   ZeroMemory(mrequest);      // Initialization of mrequest structure
/*
     Let's make sure our arrays values for the Rates, ADX Values and MA values 
     is store serially similar to the timeseries array
*/
// the rates arrays
   ArraySetAsSeries(mrate,true);
// the Upper Band values array
   ArraySetAsSeries(upper,true);
// the Mid Band values array
   ArraySetAsSeries(mid,true);
// the Lower Band values arrays
   ArraySetAsSeries(lower,true);


//--- Get the last price quote using the MQL5 MqlTick Structure
   if(!SymbolInfoTick(_Symbol,latest_price))
     {
      Alert("Error getting the latest price quote - error:",GetLastError(),"!!");
      return;
     }

//--- Get the details of the latest 3 bars
   if(CopyRates(_Symbol,_Period,0,3,mrate)<0)
     {
      Alert("Error copying rates/history data - error:",GetLastError(),"!!");
      ResetLastError();
      return;
     }
     
//--- we have no errors, so continue
//--- Do we have positions opened already?
   bool Buy_opened=false;  // variable to hold the result of Buy opened position
   bool Sell_opened=false; // variables to hold the result of Sell opened position

   if(PositionSelect(_Symbol)==true) // we have an opened position
     {
      if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY)
        {
         Buy_opened=true;  //It is a Buy
        }
      else if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_SELL)
        {
         Sell_opened=true; // It is a Sell
        }
     }

// Copy the bar close price for the previous bar prior to the current bar, that is Bar 1
   p_low=mrate[1].low; // bar 1 low price
   p_high=mrate[1].high; // bar 1 high price
   
   
   // Info of the last tick.
//-----------------------
   
// To be used for getting recent/latest price quotes
   MqlTick Latest_Price; // Structure to get the latest prices      
   SymbolInfoTick(Symbol() ,Latest_Price); // Assign current prices to structure 

// The BID price.
   static double dBid_Price; 

// The ASK price.
   static double dAsk_Price; 

   dBid_Price = Latest_Price.bid;  // Current Bid price.
   dAsk_Price = Latest_Price.ask;  // Current Ask price.

/*
    1. Check for a long/Buy Setup : MA-8 increasing upwards, 
    previous price close above it, ADX > 22, +DI > -DI
*/
//--- Declare bool type variables to hold our Buy Conditions
   bool Buy_Condition_1=(dBid_Price < lowerVal); // MA-8 Increasing upwards

//--- Putting all together   
   if(Buy_Condition_1)
     {
      // any opened Buy position?
      if(Buy_opened)
        {
         Alert("We already have a Buy Position!!!");
         return;    // Don't open a new Buy Position
        }
      ZeroMemory(mrequest);
      mrequest.action = TRADE_ACTION_DEAL;                                  // immediate order execution
      mrequest.price = NormalizeDouble(latest_price.ask,_Digits);           // latest ask price
      mrequest.sl = NormalizeDouble(latest_price.ask - STP*_Point,_Digits); // Stop Loss
      mrequest.tp = NormalizeDouble(latest_price.ask + TKP*_Point,_Digits); // Take Profit
      mrequest.symbol = _Symbol;                                            // currency pair
      mrequest.volume = Lot;                                                 // number of lots to trade
      mrequest.magic = EA_Magic;                                             // Order Magic Number
      mrequest.type = ORDER_TYPE_BUY;                                        // Buy Order
      mrequest.type_filling = ORDER_FILLING_FOK;                             // Order execution type
      mrequest.deviation=100;                                                // Deviation from current price
      //--- send order
      OrderSend(mrequest,mresult);
      // get the result code
      if(mresult.retcode==10009 || mresult.retcode==10008) //Request is completed or order placed
        {
         Alert("A Buy order has been successfully placed with Ticket#:",mresult.order,"!!");
        }
      else
        {
         Alert("The Buy order request could not be completed -error:",GetLastError());
         ResetLastError();           
         return;
        }
        
     }
/*
    2. Check for a Short/Sell Setup : MA-8 decreasing downwards, 
    previous price close below it, ADX > 22, -DI > +DI
*/
//--- Declare bool type variables to hold our Sell Conditions
   bool Sell_Condition_1 = (dAsk_Price > upperVal);  // MA-8 decreasing downwards

//--- Putting all together
   if(Sell_Condition_1)
     {
      // any opened Sell position?
      if(Sell_opened)
        {
         Alert("We already have a Sell position!!!");
         return;    // Don't open a new Sell Position
        }
      ZeroMemory(mrequest);
      mrequest.action=TRADE_ACTION_DEAL;                                // immediate order execution
      mrequest.price = NormalizeDouble(latest_price.bid,_Digits);           // latest Bid price
      mrequest.sl = NormalizeDouble(latest_price.bid + STP*_Point,_Digits); // Stop Loss
      mrequest.tp = NormalizeDouble(latest_price.bid - TKP*_Point,_Digits); // Take Profit
      mrequest.symbol = _Symbol;                                          // currency pair
      mrequest.volume = Lot;                                              // number of lots to trade
      mrequest.magic = EA_Magic;                                          // Order Magic Number
      mrequest.type= ORDER_TYPE_SELL;                                     // Sell Order
      mrequest.type_filling = ORDER_FILLING_FOK;                          // Order execution type
      mrequest.deviation=100;                                             // Deviation from current price
      //--- send order
      OrderSend(mrequest,mresult);
      // get the result code
      if(mresult.retcode==10009 || mresult.retcode==10008) //Request is completed or order placed
        {
         Alert("A Sell order has been successfully placed with Ticket#:",mresult.order,"!!");
        }
      else
        {
         Alert("The Sell order request could not be completed -error:",GetLastError());
         ResetLastError();
         return;
        }
        
     }
   return;
  }
//+------------------------------------------------------------------+