Problem getting values from array

 
Passing ExtMapBuffer[x] to a function results in 0.0 being received. Print()ing the original (stored) value prior to passing also results in 0.0. The original calculation (sum / MA_Period) prints correctly.

Yet the indicator draws the line correctly so presumably ExtMapBuffer[] is being assigned ok yet it doesnt print the right value.

The following moving average indicator shows the problem.

I'm puzzled but then I'm an mq4 newbie.

Any help would be much appreciated.

Mobius

#property indicator_chart_window
#property indicator_buffers 1
#property indicator_color1 Red

extern int     MA_Period  = 13;
extern int     MA_Shift     = 0;
extern int     MA_Method = 0;
extern color Color           = Red;

double ExtMapBuffer[]; // The mapped indicator buffer
double Dup[];              // My duplicate array

int ExtCountedBars = 0;

int init()
 {
  int     draw_begin;
  string short_name;
   
  SetIndexStyle(0, DRAW_LINE);
  SetIndexShift(0, MA_Shift);
  IndicatorDigits(MarketInfo(Symbol(), MODE_DIGITS));
   
  if(MA_Period < 2) 
    MA_Period = 13;
     
  draw_begin = MA_Period - 1;
  short_name = "SMA(";
    
 IndicatorShortName(short_name + MA_Period + ")");
 SetIndexDrawBegin(0, draw_begin);
 SetIndexBuffer(0, ExtMapBuffer);
  
 return(0);
}

int start()
{
 if(Bars <= MA_Period) 
   return(0);
   
 ExtCountedBars = IndicatorCounted();
 
 if(ExtCountedBars < 0) 
   return(-1);
   
 if(ExtCountedBars > 0) 
   ExtCountedBars--;
   
 sma();
   
 return(0);
}

void sma()  // Simple Moving Average
{
 double sum = 0;
 int       i,
           pos = Bars - ExtCountedBars - 1;
        
 if(pos < MA_Period) 
   pos = MA_Period;
   
 for(i = 1; i < MA_Period; i++, pos--)
   sum += Close[pos];
   
 while(pos >= 0)
  {
   sum += Close[pos];

   ExtMapBuffer[pos] = sum / MA_Period; // Store the value in the indicator buffer for display
   Dup[pos]              = sum / MA_Period; // Take a copy for my purposes

   Print("Dup[pos]= " + Dup[pos] + " pos= " + pos + " sum= " + sum + " sum / MA_Period= " + sum / MA_Period + " Close[pos]= " + Close[pos]);

   sum -= Close[pos + MA_Period - 1];

   pos--;
  }
 
 if(ExtCountedBars < 1)
   for(i = 1; i < MA_Period; i++) 
     ExtMapBuffer[Bars - i] = 0;
}
 
Found the answer:

double dTmp = ExtMapBuffer[pos]; // Extracts the value



Mobius

 
Well that poke in the ribs may have worked but the following skeletal EA still has the problem:

double ExtMapBuffer[];
double dBuf[];

int ExtCountedBars = 0;
int LastBars       = 0;
int MA_Period      = 13;

int init()  
{
 UpdateMa();
 return(0);  
}

int deinit()
{ 
 return(0);  
}

int start()
{
 return(0);
}

void UpdateMa()
{
 if(Bars > MA_Period)
  { 
   ExtCountedBars = LastBars;
   
   if(ExtCountedBars >= 0) 
    {
     if(ExtCountedBars > 0) 
       ExtCountedBars--;
       
     sma();
     
     LastBars = Bars - 1;
    }
  }
}

void sma()  // Simple Moving Average
{
 double sum = 0;
 int    i,
        pos = Bars - ExtCountedBars - 1;

 if(pos < MA_Period) 
   pos = MA_Period;

 for(i = 1; i < MA_Period; i++, pos--)
   sum += Close[pos];
 
 while(pos >= 0)
  {
   sum += Close[pos];

   // THIS ILLUSTRATES THE PROBLEM:
  
   double dT1 = sum / MA_Period;
  
   ExtMapBuffer[pos] = sum / MA_Period;
   dBuf[pos]         = dT1;
  
   double dT2 = ExtMapBuffer[pos];
   double dT3 = dBuf[pos];
  
   Print("dT1= " + dT1 + " dT2= " + dT2 + " dT3= " + dT3 + " pos= " + pos);
  
   sum -= Close[pos + MA_Period - 1];
   pos--;
  }

 if(ExtCountedBars < 1)           // Zero initial bars
   for(i = 1; i < MA_Period; i++) 
     ExtMapBuffer[Bars - i] = 0;
}
 
Passing ExtMapBuffer[x] to a function results in 0.0 being received. Print()ing the original (stored) value prior to passing also results in 0.0. The original calculation (sum / MA_Period) prints correctly.

Yet the indicator draws the line correctly so presumably ExtMapBuffer[] is being assigned ok yet it doesnt print the right value.

The following moving average indicator shows the problem.

I'm puzzled but then I'm an mq4 newbie.

Any help would be much appreciated.

Mobius


You need :
1) To declarate number of Indicator's Buffers
IndicatorBuffers(2);


2) To assigne Dup[] array with Indicator's Buffer 2nd index.

SetIndexBuffer(1, Dup);



Run this indictor and view log

//+------------------------------------------------------------------+
//|                                                       Mobius.mq4 |
//|                      Copyright © 2007, MetaQuotes Software Corp. |
//|                                        http://www.metaquotes.ru/ |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2007, MetaQuotes Software Corp."
#property link      "http://www.metaquotes.ru/"

#property indicator_chart_window
#property indicator_buffers 1
#property indicator_color1 Red

extern int     MA_Period =13;
extern int     MA_Shift    =0;
extern int     MA_Method=0;
extern color Color          =Red;

double ExtMapBuffer[]; // The mapped indicator buffer
double Dup[];              // My duplicate array

int ExtCountedBars=0;

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int init()
  {
   int     draw_begin;
   string short_name;
   
   IndicatorBuffers(2);
   SetIndexStyle(0, DRAW_LINE);
   SetIndexShift(0, MA_Shift);
   IndicatorDigits(MarketInfo(Symbol(), MODE_DIGITS));

   if(MA_Period < 2)
      MA_Period=13;

   draw_begin=MA_Period - 1;
   short_name="SMA(";

   IndicatorShortName(short_name + MA_Period + ")");
   SetIndexDrawBegin(0, draw_begin);
   SetIndexBuffer(0, ExtMapBuffer);
   SetIndexBuffer(1, Dup);

   return(0);
  }

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int start()
  {
   if(Bars<=MA_Period)
      return(0);

   ExtCountedBars=IndicatorCounted();

   if(ExtCountedBars < 0)
      return(-1);

   if(ExtCountedBars > 0)
      ExtCountedBars--;

   sma();

   return(0);
  }

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void sma()  // Simple Moving Average
  {
   double sum=0;
   int       i,
   pos=Bars - ExtCountedBars - 1;

   if(pos < MA_Period)
      pos=MA_Period;

   for(i=1; i < MA_Period; i++, pos--)
      sum+=Close[pos];

   while(pos>=0)
     {
      sum+=Close[pos];

      ExtMapBuffer[pos]=sum/MA_Period; // Store the value in the indicator buffer for display
      Dup[pos]             =sum/MA_Period; // Take a copy for my purposes

      if (pos<100)Print("Dup[pos]= ",Dup[pos]);

      sum-=Close[pos + MA_Period - 1];

      pos--;
     }

   if(ExtCountedBars < 1)
      for(i=1; i < MA_Period; i++)
         ExtMapBuffer[Bars - i]=0;
  }
//+------------------------------------------------------------------+
 
Read, please, following topics
"MQL4: IndicatorBuffers"
"MQL4: SetIndexBuffer"
"MQL4: ArrayResize"

and about init(), start() and deinit()
"MQL4: Program Run"
"MQL4: Special functions"
 
If your questions will still remaine after studing documentation, I'll reply additionly.
 
Hi Rosh,

Read that. Its doesnt explain why the array double operator [] returns 0.0 instead of the stored value. Explicitly dimensioning the array solves the problem until the dimension is exceeded but that isnt how the examples imply arrays should operate.

Regards,

Mobius
 
Really? Tomorrow I investigate your inquiry.
 
Hi Rosh,

Read that. Its doesnt explain why the array double operator [] returns 0.0 instead of the stored value. Explicitly dimensioning the array solves the problem until the dimension is exceeded but that isnt how the examples imply arrays should operate.

Regards,

Mobius

I and have not understood that is required to you. I have altered your first indicator also it works correctly now. I at all desire cannot name the second code the indicator, and it be no point to consider it while it does not become correctly written.
 
Hi Rosh,

If you read my posts carefully you will see that I fixed the 1st reported (indicator) problem myself (by first assigning the array element to a simple double before passing to the function Print()).

The problem remains with the Expert Advisor example I included in my post of 18.03.07 16:38, i.e. the workaround that got the array operator [] functioning correctly in the indicator did not work in the Expert Advisor hence my further post.

The issue is not related to declaring indicator buffers (the first example I posted did actually work as an indicator - it was in fact one of your example custom indicators minus the comments plus some test code).

The issue is the functioning of either operator [] in an array declared within an Expert Advisor or the functioning of operator =. As the problem also occurs when the array element is passed as an argument to a function, I would suggest the former.

If you look at this part of the *EA* code you will see the problem to which I refer (ignore the naming of the array ExtMapBuffer, it is not mapped):

while(pos >= 0)
{
sum += Close[pos];

// THIS ILLUSTRATES THE PROBLEM:

double dT1 = sum / MA_Period;

ExtMapBuffer[pos] = sum / MA_Period;
dBuf[pos] = dT1;

double dT2 = ExtMapBuffer[pos];
double dT3 = dBuf[pos];

Print("dT1= " + dT1 + " dT2= " + dT2 + " dT3= " + dT3 + " pos= " + pos);

sum -= Close[pos + MA_Period - 1];
pos--;
}

Regards,

Mobius
 
Hmmm... I don't see in this test whish you name EA ArrayResize() function. It's first.
Second. Did you see those links I put above? May be you have'nt tine for it.

I see "MQL4: Special functions" and view:
I
t is not recommended to call start() function from init() function or to perform trade operations, as chart data, market prices, etc. can be incomplete by the moment of the module initialization. The init() and deinit() functions must finish their working as soon as possible and, in no case, shall they loop when trying to start its full-fledged working before the start() function is called.


Then I see "MQL4: ArrayResize" and view:
Sets a new size for the first dimension. If executed successfully, it returns count of all elements contained in the array after resizing, otherwise, returns zero, and array is not resized.
Note: Array declared at a local level in a function and resized will remain unchanged after the function has completed its operation. After the function has been recalled, such array will have a size differing from the declared one.


It's not "problem getting values from array" , it is problem with you desire to study.
Sorry, I haven't time. Here is code:
//+------------------------------------------------------------------+
//|                                                     MobiusEA.mq4 |
//|                      Copyright © 2007, MetaQuotes Software Corp. |
//|                                        http://www.metaquotes.ru/ |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2007, MetaQuotes Software Corp."
#property link      "http://www.metaquotes.ru/"

double ExtMapBuffer[];
double dBuf[];

int ExtCountedBars=0;
int LastBars      =0;
int MA_Period     =13;

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int init()
  {
   UpdateMa();
   return(0);
  }

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int deinit()
  {
   return(0);
  }

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int start()
  {
   return(0);
  }

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void UpdateMa()
  {
   Print("Function UpdateMA starting");
   if(Bars > MA_Period)
     {
      Print("Pass condition if(Bars > MA_Period)");
      ExtCountedBars=LastBars;

      if(ExtCountedBars>=0)
        {
         Print("Pass condition if(ExtCountedBars>=0)");
         if(ExtCountedBars > 0)
            {
            Print("Pass condition if(ExtCountedBars > 0)");
            ExtCountedBars--;
            }
         sma();

         LastBars=Bars - 1;
        }
     }
  }

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void sma()  // Simple Moving Average
  {
   double sum=0;
   int    i,pos=Bars - ExtCountedBars - 1;
   int N=Bars;
   Print("Function SMA starting");
   ArrayResize(ExtMapBuffer,N);
   

   if(pos < MA_Period)
      pos=MA_Period;

   for(i=1; i < MA_Period; i++, pos--)
      sum+=Close[pos];

   while(pos>=0)
     {
      sum+=Close[pos];

      // THIS ILLUSTRATES THE PROBLEM:

      double dT1=sum/MA_Period;

      ExtMapBuffer[pos]=sum/MA_Period;
      dBuf[pos]        =dT1;
      
      double dT2=ExtMapBuffer[pos];
      double dT3=dBuf[pos];

      Print("dT1= " + dT1 + " dT2= " + dT2 + " dT3= " + dT3 + " pos= " + pos);

      sum-=Close[pos + MA_Period - 1];
      pos--;
     }

   if(ExtCountedBars < 1)           // Zero initial bars
      for(i=1; i < MA_Period; i++)
         ExtMapBuffer[Bars - i]=0;
  }
//+------------------------------------------------------------------+