iCCI shift = 1 does not equal previous iCCI shift=0

 

Hi, i'm trying a CCI threshold strategy, where i sell when CCI goes from CCI<= 100 to CCI>100. 

to do this, i need to know both the current bar's CCI value and the previous bar's CCI value. 

from what i understand this is accomplished by using the "shift" argument of iCCI function  as i do here:

   double CCIsignal_0 = iCCI( NULL, 0, CCIperiod, PRICE_WEIGHTED, 0 );

   double CCIsignal_1 = iCCI( NULL, 0, CCIperiod, PRICE_WEIGHTED, 1 );

where CCIsignal_0 is the current value, and CCIsignal_1 is the previous value.

however, when i log these values, the don't make sense. if shift of 1 corresponds to the previous value as per the documentation, the previous bar's shift=0 should always equal the current bar's shift=1.

or am i missing something? here is the output of a small test:

as you can see (from the first two lines), the 5:30 CCIsignal_1 does not equal the 5:00 CCIsignal_0. 


2018.05.03 11:27:01.181 2013.06.04 05:30:00  mycci EURUSD,M30: CCIsignal_0 = 20.26011731 CCIsignal_1 = 24.54661974
2018.05.03 11:27:00.330 2013.06.04 05:00:00  mycci EURUSD,M30: CCIsignal_0 = 28.10915034 CCIsignal_1 = 31.71764145
2018.05.03 11:26:59.481 2013.06.04 04:30:00  mycci EURUSD,M30: CCIsignal_0 = 29.25829462 CCIsignal_1 = 38.23783107
2018.05.03 11:26:58.513 2013.06.04 04:00:00  mycci EURUSD,M30: CCIsignal_0 = 61.13435407 CCIsignal_1 = 58.19251902
2018.05.03 11:26:57.538 2013.06.04 03:30:00  mycci EURUSD,M30: CCIsignal_0 = 46.70957611 CCIsignal_1 = 48.40182762
2018.05.03 11:26:56.684 2013.06.04 03:00:00  mycci EURUSD,M30: CCIsignal_0 = 47.53043392 CCIsignal_1 = 51.20848537
2018.05.03 11:26:55.887 2013.06.04 02:30:00  mycci EURUSD,M30: CCIsignal_0 = 48.11842276 CCIsignal_1 = 49.85617794
2018.05.03 11:26:54.982 2013.06.04 02:00:00  mycci EURUSD,M30: CCIsignal_0 = 54.79439914 CCIsignal_1 = 55.63084107
2018.05.03 11:26:54.013 2013.06.04 01:30:00  mycci EURUSD,M30: CCIsignal_0 = 54.62691939 CCIsignal_1 = 59.08340573
2018.05.03 11:26:53.094 2013.06.04 01:00:00  mycci EURUSD,M30: CCIsignal_0 = 58.84454651 CCIsignal_1 = 65.76333857
2018.05.03 11:26:52.266 2013.06.04 00:30:00  mycci EURUSD,M30: CCIsignal_0 = 72.79191071 CCIsignal_1 = 79.55593818

2018.05.03 11:26:51.433 2013.06.04 00:00:00  mycci EURUSD,M30: CCIsignal_0 = 79.41084682 CCIsignal_1 = 83.81220327


does anyone know how to accurately obtain the previous CCI values (or any indicator for that matter)?

also i'm running the tests on open bar only, if that matters...

thanks,


Russell


 
Russell Butler: the previous bar's shift=0 should always equal the current bar's shift=1.

Never, except for the last tick of the bar.

If you use the current bar, the value will be constantly changing as the price moves, you will get false signals.

If you use shift one, you get the indicator value for the last tick (close price) of that bar.

 
whroeder1:

Never, except for the last tick of the bar.

If you use the current bar, the value will be constantly changing as the price moves, you will get false signals.

If you use shift one, you get the indicator value for the last tick (close price) of that bar.

ok. i thought the following line:

 if (Volume[0] > 1) return(0);

was enough to stop it from checking every tick, and instead only check on the open?

what i really want to do is just call the following function below on every bar close:

what should i do to modify this function so i get accurate signals as per my method above? 

thanks, i'm very new to mql4/5, just switched over from jforex ;)

void CheckSignal()
  {
   // Execute only on the first tick of a new bar, to avoid repeatedly
   // opening orders when an open condition is satisfied.
   if (Volume[0] > 1) return(0);
    
   double CCIsignal_0 = iCCI( NULL, 0, CCIperiod, PRICE_WEIGHTED, 0 );
   double CCIsignal_1 = iCCI( NULL, 0, CCIperiod, PRICE_WEIGHTED, 1 );
   int slippage = 30;
   Print("CCIsignal_0 = " + CCIsignal_0 + " CCIsignal_1 = " + CCIsignal_1); 
    
   if(CCIsignal_0 >= 100 && CCIsignal_1 < 100 )
   {
      
         if(inSell==false && inBuy==false)
         {
            orderTicket = OrderSend(Symbol(), OP_SELL, Lots, Ask, slippage,0 ,0 ,NULL, MACROSS_MAGIC_NUM, 0, Red); //Ask+StopLoss*Point, Ask-TakeProfit*Point,
            inSell = true; 
         }
         else if(inBuy == true)
         {
            OrderClose(orderTicket, Lots, Ask, slippage, Blue);    
            inBuy = false; 
         }
   }
   else if(CCIsignal_0 <= -100 && CCIsignal_1 >-100 )
   {
   
         if(inBuy==false && inSell==false)
         {
            orderTicket = OrderSend(Symbol(), OP_BUY, Lots, Bid, slippage,0 ,0 ,NULL, MACROSS_MAGIC_NUM, 0, Green); // Bid-StopLoss*Point, Bid+TakeProfit*Point,
            inBuy = true; 
         }
         else if(inSell==true)
         {               
            OrderClose(orderTicket, Lots, Bid, slippage, Yellow);           
            inSell = false;          
         }  
   }  
  }
 
Russell Butler if (Volume[0] > 1) return(0);

was enough to stop it from checking every tick, and instead only check on the open?

For a new bar test, Bars is unreliable (a refresh/reconnect can change number of bars on chart,) volume is unreliable (miss ticks,) Price is unreliable (duplicate prices and The == operand. - MQL4 and MetaTrader 4 - MQL4 programming forum.) Always use time.
I disagree with making a new bar function, because it can only be called once per tick. A variable can be tested multiple times.
          New candle - MQL4 and MetaTrader 4 - MQL4 programming forum
 
whroeder1:
For a new bar test, Bars is unreliable (a refresh/reconnect can change number of bars on chart,) volume is unreliable (miss ticks,) Price is unreliable (duplicate prices and The == operand. - MQL4 and MetaTrader 4 - MQL4 programming forum.) Always use time.
I disagree with making a new bar function, because it can only be called once per tick. A variable can be tested multiple times.
          New candle - MQL4 and MetaTrader 4 - MQL4 programming forum

cool, it works. i changed PRICE_WEIGHTED to PRICE_OPEN as well. 

2018.05.03 18:48:02.063 2018.02.28 23:30:00  mycci EURUSD,M30: CCIsignal_0 = -88.78078443 CCIsignal_1 = -65.13574378

2018.05.03 18:48:02.063 2018.02.28 23:00:00  mycci EURUSD,M30: CCIsignal_0 = -65.13574378 CCIsignal_1 = -154.81892735

2018.05.03 18:48:02.063 2018.02.28 22:30:00  mycci EURUSD,M30: CCIsignal_0 = -154.81892735 CCIsignal_1 = -99.0313403

2018.05.03 18:48:02.063 2018.02.28 22:00:00  mycci EURUSD,M30: CCIsignal_0 = -99.0313403 CCIsignal_1 = -56.24816122

2018.05.03 18:48:02.063 2018.02.28 21:30:00  mycci EURUSD,M30: CCIsignal_0 = -56.24816122 CCIsignal_1 = -90.48866394

2018.05.03 18:48:02.063 2018.02.28 21:00:00  mycci EURUSD,M30: CCIsignal_0 = -90.48866394 CCIsignal_1 = -105.76937159

2018.05.03 18:48:02.063 2018.02.28 20:30:00  mycci EURUSD,M30: CCIsignal_0 = -105.76937159 CCIsignal_1 = -234.50223998


i did most of my pre-testing based off the close using dukascopy historical data with variable spread, so i will probably try to modify it a bit to use the close instead of PRICE_OPEN, but here is what i have now:

thanks!

void CheckSignal()
{

   static datetime timeCur; 
   datetime timePre = timeCur; 
   timeCur=Time[0];
   bool isNewBar = timeCur != timePre;
   
   if(isNewBar){    
   
      double CCIsignal_0 = iCCI( NULL, PERIOD_M30, CCIperiod, PRICE_OPEN, 0 );
      double CCIsignal_1 = iCCI( NULL, PERIOD_M30, CCIperiod, PRICE_OPEN, 1 );
      
      int slippage = 30;
      Print("CCIsignal_0 = " + CCIsignal_0 + " CCIsignal_1 = " + CCIsignal_1); 
       
      if(CCIsignal_0 >= 100 && CCIsignal_1 < 100 )
      {
         
            if(inSell==false && inBuy==false)
            {
               orderTicket = OrderSend(Symbol(), OP_SELL, Lots, Ask, slippage,0 ,0 ,NULL, MACROSS_MAGIC_NUM, 0, Red); //Ask+StopLoss*Point, Ask-TakeProfit*Point,
               inSell = true; 
            }
            else if(inBuy == true)
            {
               OrderClose(orderTicket, Lots, Ask, slippage, Blue);    
               inBuy = false; 
            }
      }
      else if(CCIsignal_0 <= -100 && CCIsignal_1 >-100 )
      {
      
            if(inBuy==false && inSell==false)
            {
               orderTicket = OrderSend(Symbol(), OP_BUY, Lots, Bid, slippage,0 ,0 ,NULL, MACROSS_MAGIC_NUM, 0, Green); // Bid-StopLoss*Point, Bid+TakeProfit*Point,
               inBuy = true; 
            }
            else if(inSell==true)
            {               
               OrderClose(orderTicket, Lots, Bid, slippage, Yellow);           
               inSell = false;          
            }  
      }  
      
   }
}
Reason: