Indicator displays wrong values when compiled once

 

Hi again

I have a problem with a custom indicator. When attached to a chart it displays inherently a wrong value - it needs to be compiled up to three times to get the correct one (see below: 0,265 vs. 8,50), would be pleased for some help...

//+------------------------------------------------------------------+
//| Start function                          
//+------------------------------------------------------------------+
int start()
 {int counted = IndicatorCounted();
  if(counted < MA_Period) counted = MA_Period; // Don't look past end
  for(int i = Bars-1-counted; i>=0; i--)
   slope[i]    = slope(i, Symbol(), SymbolX);
//---- done
   return(0);
  }
  
//+------------------------------------------------------------------+
// Calculating slope
//+------------------------------------------------------------------+
double slope(int i, string symbolY, string symbolX)
   {double meanrY, meanrX, ssYX, ssXX, b;
    int k, limit=i+MA_Period;
    
    for(k=i; k<limit; k++)
   {
    rY[k]       = iClose(symbolY,0,k)/iOpen(symbolY,0,k)-1;
    rX[k]       = iClose(symbolX,0,k)/iOpen(symbolX,0,k)-1; 
   }
    meanrY      = iMAOnArray(rY,0,MA_Period,0,MODE_SMA,i);
    meanrX      = iMAOnArray(rX,0,MA_Period,0,MODE_SMA,i);
    
    for(k=i; k<limit; k++)
   {  
    sqerryYxX[k]= (rX[k]-meanrX)*(rY[k]-meanrY);
    sqerrxX[k]  = MathPow(rX[k]-meanrX,2);
   } 
    ssYX        = iMAOnArray(sqerryYxX,0,MA_Period,0,MODE_SMA,i)*MA_Period;
    ssXX        = iMAOnArray(sqerrxX,0,MA_Period,0,MODE_SMA,i)*MA_Period;
                            
    b           = ssYX/ssXX;                  
    return(b);
   }
Files:
slopeyx_1.mq4  3 kb
 
  1. Post all relevant code.  rX[] rY[] not shown.
  2. Are they series arrays as iMaOnArray expects?
  3. it needs to be compiled up to three times to get the correct one
    Compiling is irrelevant. You are not checking whether you have history for each symbol, waiting for history to be loaded and avoiding the divide by zero when you don't

  4. rY[k]       = iClose(symbolY,0,k)/iOpen(symbolY,0,k)-1;
    rX[k]       = iClose(symbolX,0,k)/iOpen(symbolX,0,k)-1; 
    Since the pair is NOT your chart's you can not assume that your chart's k matches another pair. On a new bar, the other pair's zero is your one if it hasn't yet seen a tick. In the tester, the other chart isn't shifted at all, your zero (bar under test) will be thousands of bar.
    int iY = ibarShift(symbolY,0, Time[k]),
        iX = ibarShift(symbolX,0, Time[k]);
    rY[k]       = iClose(symbolY,0,iY)/iOpen(symbolY,0,iY)-1;
    rX[k]       = iClose(symbolX,0,iX)/iOpen(symbolX,0,iX)-1; 

  5. The remaining code looks bogus, I see a square (MathPow) but no root.

 
WHRoeder: The remaining code looks bogus, I see a square (MathPow) but no root.

Ty Roeder, I really appreciate your help!

The slope of a linear regression curve is calculated by dividing the sum of squares (->ssYX/ssXX) - there is no need for a root. But anyway ty for your reply - guess it will be very helpfull!

 

WHRoeder:

Compiling is irrelevant. You are not checking whether you have history for each symbol, waiting for history to be loaded and avoiding the divide by zero when you don't

Since the pair is NOT your chart's you can not assume that your chart's k matches another pair. On a new bar, the other pair's zero is your one if it hasn't yet seen a tick. In the tester, the other chart isn't shifted at all, your zero (bar under test) will be thousands of bar.


I got the part about matching the timeseries... iY seems to be redundant as it simply returns k (please correct me if Im wrong). Additionally I arranged the buffers used by iMAOnArray as series arrays ... but the problem remains: the indicator has to be compiled three times until it displays the correct value.
//+------------------------------------------------------------------+
//| Start function                          
//+------------------------------------------------------------------+
int start()
 {int counted = IndicatorCounted();
  if(counted < MA_Period) counted = MA_Period;
  for(int i = Bars-1-counted; i>=0; i--)
   b[i]    = slope(i, Symbol(), SymbolX);
//---- done
   return(0);
  }
  
//+------------------------------------------------------------------+
// Calculating slope
//+------------------------------------------------------------------+
double slope(int i, string symbolY, string symbolX)
   {double meanrY, meanrX, ssYX, ssXX, b;
    int  k, limit=i+MA_Period;
    ArraySetAsSeries(rY,true);
    ArraySetAsSeries(rX,true);
    ArraySetAsSeries(sqerryYxX,true);
    ArraySetAsSeries(sqerrxX,true);
         
    for(k=i; k<limit; k++)
   {int iX      = iBarShift(symbolX,0,Time[k]);
    rY[k]       = iClose(symbolY,0,k)/iOpen(symbolY,0,k)-1;
    rX[k]       = iClose(symbolX,0,iX)/iOpen(symbolX,0,iX)-1; 
   }
    meanrY      = iMAOnArray(rY,0,MA_Period,0,MODE_SMA,i);
    meanrX      = iMAOnArray(rX,0,MA_Period,0,MODE_SMA,i);
    
    for(k=i; k<limit; k++)
   {  
    sqerryYxX[k]= (rX[k]-meanrX)*(rY[k]-meanrY);
    sqerrxX[k]  = MathPow(rX[k]-meanrX,2);
   } 
    ssYX        = iMAOnArray(sqerryYxX,0,MA_Period,0,MODE_SMA,i)*MA_Period;
    ssXX        = iMAOnArray(sqerrxX,0,MA_Period,0,MODE_SMA,i)*MA_Period;
                            
    b           = ssYX/ssXX;                  
    return(b);
   }

 

WHRoeder

Compiling is irrelevant.


Today (or better: over night) things changed a bit: the indicator actually displayed the correct values without excessive compiling, the problem is that this actually took an undefined amount of time (guess several hours) to take place, before the indi magically changed his mind wrong values were displayed inherently.