# Arrays elude me

[Deleted]
I don't have a programing background but I have been teaching myself MQ4 for the last 6 months. I get most of it now but arrays, I've got a mental block. I've read the documentation repeatedly but, I still haven't got to grips with them. I don't understand how you get the data into an array in the first place. By way of example...

Suppose you wanted to calculate the average number of bars that a trade stayed open for say the last 20 trades. The trade opens, I start counting bars until it closes, I now have an variable defining the length (in bars) of the last trade. When the next trade opens, the variable is subsequently overwritten, but obviously, I need the array to hold the first value and keep adding as new values are calculated. Holding these values escapes me.... I suppose (and what I understand for the documentation) I could set 20 variables (say A-T) and cascade the results down the list of variables as new data comes in (ie, A=10, next event, A=12,B=10 etc, all the way to T) and then initialise the array "int myarray[20]={A,B,C...T}". This doesn't seem very efficient though... and what if I now want the last 50? a load more coding?

Logically, it would seem better to just hold a list of all results of my bar counting (or a defined number that can be easily changed) and use the averaging period in iMAOnArray to select the 20 (or however many) results. Achieving that, escapes me though. I would really appreciate if someone could explain to me how you would get these variables into the array to enable calculations... or show me some example code. I've read the Arrays tutorial and to be honest, that has just left me confused.

V
79

Hi Viffer,

arrays are just a set of values under common name. You can have:
A=10, B=5, C=8
or
A1=10, A2=5, A3=8
or
A[1]=10, A[2]=5, A[3]=8

the last one will be an array A, it will have 3 elements and its index will go from 1 to 3.

Now in MQL4 all arrays start at 0, so it actually should be:
A[0]=10, A[1]=5, A[2]=8

the array A will contain 3 elements again, however its index will start at 0 and go to 2. Thats how MQL4 (and some other languages) represent arrays.

The default arrays in MQL4 that keep the values of the the bars on a chart - High[], Low, Open, Close - all start at 0 and go to Bars-1. 'Bars' contains the length of the array and because it start at 0, therefore its last index will be Bars-1 (see the example above again if needed).

- you need to have 2 things - an array and its current length i.e. how many trades you have already put into it.
- so you define an array TRADES[100] for example - meaning it can keep UP to 100 trades (you can change this number according to your needs as well as you can resize the array if needed)
- and then you define int TRADE_COUNT=0. This will be your counter, your index, i.e. how many trades you are keeping into the array. Every time you finish with a trade you increase this with 1 i.e. TRADE_COUNT++;
- and so on, every time you increase TRADE_COUNT...
Thats why your values never get overwritten, instead you have an array that keeps all the values.
And the beauty of it is that the code is always the same because you always work with TRADES[TRADE_COUNT]. You just increase TRADE_COUNT with 1 every time so in fact it will always be different variable...
At the end your array will contain the info you need:

Hope the above helps!

thank you
Automated
--
grid trading EA in action, +558 pips in 24 hours:

[Deleted]
A perfect explanation. Many thanks for your thoughtful response.

I've tried it out in some test code and it seems to work great. I'm measuring the number of bars momentum is above 100 (for sake of any other event) holding the answer in an arrray and then retrieving it. So I think I understand it now. Obviously, I'm focused on the array code rather than the event code.

Thanks again
V

//+------------------------------------------------------------------+
//|                                                   array test.mq4 |
//|

datetime upt;
int myvar,i=0;
double myarray[10];
double myhistorical,myavg;

//+------------------------------------------------------------------+
//| expert initialization function                                   |
//+------------------------------------------------------------------+
int init()
{
//----

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

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

double mom=iMomentum(NULL,0,14,0,1);
double pmom=iMomentum(NULL,0,14,0,2);

if(mom>100 && pmom<100 && iVolume(NULL,0,0)==1)
{
upt=iTime(NULL,0,0);
}

if(mom<100 && pmom>100 && iVolume(NULL,0,0)==1 && upt>0)
{
myvar=iBarShift(NULL,0,upt);
Alert("Crossed Down after ", myvar, " bars");
myarray[i]=myvar;
i++;
}

myhistorical=myarray[i-3];
myavg= iMAOnArray(myarray,0,5,0,MODE_SMA,0);

if(iVolume(NULL,0,0)==1)
{
Alert("myhistorical ",myhistorical," myavg ",myavg, " i ",i-1, " latest value ", myarray[i-1]);
}

//----
return(0);
}
//+------------
[Deleted]
Sorry, meant to add, presumably if the array is initially set to 100 elements, when TRADE_COUNT=101 the array simply drops the lowest index so there would be no value for Trade[0]. Is this correct?
[Deleted]
Viffer:
Sorry, meant to add, presumably if the array is initially set to 100 elements, when TRADE_COUNT=101 the array simply drops the lowest index so there would be no value for Trade[0]. Is this correct?

element_count=ArrayResize(myarray,i+1); after i++.

Adding this seems to solve my problem and I will be able to utilise this principle in my EA but I can't help wondering if this is the "proper" way to handle the situation. An array could surely get unweildy if it's allowed to re size itself to infinity. Is there a way to handle the index counter to keep it within the range of the initial element count. How do I put in trade [101], drop trade[0] and thereby maintain the 100 latest results?
[Deleted]

you basically want to loop thru your index and shift all the values up (or down) by one index value, then proceed to overwrite the contents of the last (or first) element with the most recent trade result

something like:

for(i=99;i>=1;i--)
{
myarray[i]=myarray[i-1];
}
this will result in the 100th myarray value being overwritten by the contents of the 99th element (so oldest trade data is "dropped off the edge of the array") and the 1st array element (myarray[0]) is left ready to be overwritten by the most recent trade data
[Deleted]
1005phillip:

you basically want to loop thru your index and shift all the values up (or down) by one index value, then proceed to overwrite the contents of the last (or first) element with the most recent trade result

something like:

this will result in the 100th myarray value being overwritten by the contents of the 99th element (so oldest trade data is "dropped off the edge of the array") and the 1st array element (myarray[0]) is left ready to be overwritten by the most recent trade data

That makes sense. thanks for your help
[Deleted]
I've got my array into my EA and working the way I need it to, so thanks for your help. But before I go and work out a load more coding, I would be grateful if someone could confirm that my thought process is correct in using this array. I want to use iMAOnArray and have noticed that the average (obviously) won't calculate properly until all the elements are full. This is made worse if the averaging period is shorter than the number of elements, 'cos the array fills up backwards compared to the way iMAOnArray reads it (i guess I could change this with setasseries), but either way, there is a lag before my average calculates properly. Given that Arrays can't be held on the terminal, this is a potential disaster in the event of a system crash. Correct?

I can hold my average result as a global variable... it would make sense then to "seed" my array in init() filling it with the current global average figure.. thereby iMAonArray calculates the right answer at first iteration.

Whilst that will solve my current problem (i think) I'm wondering again, if there is a better way... what if I also use the high and low value in my EA and the system crashes. Do I just lose the data held in my array and have to wait for the array to fill up again before an EA would use the proper values?

V
79

it seems that the issue you describe in you latest post is not with arrays but with potential crashes and loss of data. One solution to this is to save the values of your array in a file. For example since you add a value to the array only once a bar you can save the whole array right after it (i.e. save the whole array once a bar). Then in case of a crash you would have all your data saved in a file. And in your Init() you can load the array from this file thus having all the data immediately...
You will need to account for the time (bars) passed between the crash and restart too...

thank you
Automated
--
grid trading EA, +558 pips in 24 hours:

http://grid9.forexmosaic.com/ - 8621 pips in 7 weeks of grid trading

[Deleted]
Yeah, I'm playing around in my test code to discover more about arrays and what factors I need to consider when using them. The solution you describe is far better than the work around I could come up with. Never done save as file before so more reading for me.
Thanks again
V