Loop not saving values to array

 
bool once=0;
double z[];

void OnTick()
  {
//---
        if(!once)
        {
                int j = 0;
                for(int i=0; i<100 && j<5; i++)
                {
                double y = iCustom(Symbol(), PERIOD_CURRENT, "ZigZag", 12, 5, 3, 0, i);
                if(y!=0.0 && y!=EMPTY_VALUE)
                {
//                      Comment("Loop ran");
                        z[j] = y;
                        Comment("Value stored"/*IntegerToString(i, 0)*/);
                        j++;
                }
           }
           once = 1;
        }
//Comment("Z0 = ", DoubleToString(z[0], 5) + ", Z1 = " + DoubleToString(z[1], 5) + ", Z2 = " + DoubleToString(z[2], 5) + ", Z3 = " + DoubleToString(z[3], 5) + IntegerToString(j,0));

  }
Hi there. I've been playing around to try and figure out how the ZigZag indicator works to incorporate it in my EA and, thanks to another thread where I found how to use iCustom, I've come up with this code. I just don't understand why it is not saving the values into the array. According to me, as I read the code, it should go into a loop where it looks at the last 100 candles and save 4 ZigZag points in the array. If 4 points were reached before 100 candles the loop will stop. I used the comments to see whether the values saved corresponds to the indicator on the chart, but it only saves the first one IF it is currently busy plotting it. All the others are 0. The counter doesn't increment either. Am I doing it right or is there something that I don't know of?
Documentation on MQL5: Technical Indicators / iCustom
Documentation on MQL5: Technical Indicators / iCustom
  • www.mql5.com
iCustom - Technical Indicators - MQL5 Reference - Reference on algorithmic/automated trading language for MetaTrader 5
 

Where do you size the array z?

You should get into the habit of using true or false for bools.

Topics concerning MT4 and MQL4 have their own section.

In future please post in the correct section.

I have moved your topic to the MQL4 and Metatrader 4 section.

 

Thank you. I only noticed now what I did regarding sectioning, apologies.

I had it defined before and then took it out (troubleshooting). I just forgot to put it back in. It made no difference to the outcome though.

I normally use true and false in my bools, but because I'm only learning the behaviour of the operation I'm using 1 and 0.
.

 
PLZFrosty:

I had it defined before and then took it out (troubleshooting). I just forgot to put it back in. It made no difference to the outcome though.

Post the code that you are actually using so that the array is sized.

PLZFrosty:

I normally use true and false in my bools, but because I'm only learning the behaviour of the operation I'm using 1 and 0.

When you are learning is the time NOT to get into bad habits.

With longer blocks of code others (and possibly even you) may mistake a bool variable for an int variable.

 
//+------------------------------------------------------------------+
//|                                                  Test ZigZag.mq4 |
//|                        Copyright 2020, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2020, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict
#resource "\\Indicators\\ZigZag.ex4"

bool    once = false;
double  z[4];

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
   
  }

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
        static bool once = false;
        if(!once)
        {
                int j = 0;
                for(int i=0; i<100 && j<5; i++)
                {
                        double y = iCustom(Symbol(), PERIOD_CURRENT, "ZigZag", 12, 5, 3, 0, i);
                        if(y!=0.0 && y!=EMPTY_VALUE)
                        {
//                              Comment("Loop ran");
                                z[j] = y;
                                Comment("Value stored"/*IntegerToString(i, 0)*/);
                                j++;
                        
                        }
                }
           once = true;
        }
//Comment("Z0 = ", DoubleToString(z[0], 5) + ", Z1 = " + DoubleToString(z[1], 5) + ", Z2 = " + DoubleToString(z[2], 5) + ", Z3 = " + DoubleToString(z[3], 5) + IntegerToString(j,0));

  }

I changed the bools for you... It's not that I'm learning bad habits. The main EA that I am writing has true and false on all the bools. Like I said, it's only a temporary code to understand THIS operation. Anyway, this is the whole code. Is there something wrong in the way that I perceive how the code should work? The variable "once" is that I only want the whole code to run once. The loop should obviously run towards it's conditions.

I greyed out a lot of Comment() functions, but it's because i didn't want to delete them while I'm busy searching for where the code is going haywire. The Comment that is not greyed out is where I found it doesn't go further (or stores one value and that's it).

 

Please forgive me. I have no idea why, but I just tested it now and it saved the values as I expected it to save. I literally just closed and opened the program, well, I gave up last night and opened it today, and it worked... Sorry about that...

 

It worked because you restarted the EA. The errors are not suddenly fixed.

Globally declared

bool    once = false;

In OnTick()

   static bool once = false;

You should have got a warning about this when you compiled. Don't ignore warnings - fix them and delete the static declaration.

This is a check that you may want to be done for you to test if you switch TF etc.

So set the bool in OnInit()

Avoid hardcoding array sizes as this can lead to errors when you change it in one section of code and forget to change it elsewhere.

ALWAYS check in the Experts tab when things are not working as you expect. If you had checked you would have found that you are getting an array out of range error.

double  z[4];
             for(int i=0; i<100 && j<5; i++)
                {
                        double y = iCustom(Symbol(), PERIOD_CURRENT, "ZigZag", 12, 5, 3, 0, i);
                        if(y!=0.0 && y!=EMPTY_VALUE)
                        {
//                              Comment("Loop ran");
                                z[j] = y;
                                Comment("Value stored"/*IntegerToString(i, 0)*/);
                                j++;
                        
                        }
                }

When j==4 you try to access z[4] when the array only goes to z[3] , 0,1,2 and 3.


#property copyright ""
#property link      ""
#property version   "1.00"
#property strict
//#resource "\\Indicators\\ZigZag.ex4"

input int  ArraySize=4;

bool    once = false;
double  z[];

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
{
   once = false;
   ArrayResize(z,ArraySize);
   //Print("once = ",once);
//---
   return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//---
}
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
{
//---
   if(!once)
     {
      int j = 0;
      for(int i=0; i<100 && j<ArraySize; i++)
        {
         double y = iCustom(Symbol(), PERIOD_CURRENT, "ZigZag", 12, 5, 3, 0, i);
         if(y!=0.0 && y!=EMPTY_VALUE)
           {
            //Comment("Loop ran");
            z[j] = y;
            Comment("Value stored"/*IntegerToString(i, 0)*/);
            j++;

           }
        }
      once = true;
     }

   string text="";
   for(int x=0; x<ArraySize; x++)
     {
      text+="z"+(string)x+" = "+DoubleToString(z[x], 5)+"\n";
     }

   Comment(text);
}
//+------------------------------------------------------------------+
Reason: