Friday, March 20, 2009

MQL 4: Relation of user programs with internal arrays terminal

In a previous article we discussed the general interaction of the performing environment MetaTrader'a with a custom program. Today will be examined in detail the mechanisms linking the variables of user programs with a special area of memory - the internal representation of data in the memory of the terminal.
During the terminal is processing a large amount of data, which stores the entire history of a particular instrument at a given time interval. History is loaded into the terminal of the special files from the disk of your computer, and then in the process of on-line with MetaTrader'om load over the Internet from your broker. Historical data about each tool is stored in dynamic memory running MetaTrader'a in six volumes, each of which is available from MQL-user program. Not hard to guess that the six arrays are as follows: an array of Open, an array of Low, array High, an array of Close, the array and an array of Time Volume. User program elements for each of the above ranges are available under the name of the array and index. Index - the number of bars for which the requested data. For example, if you want to know the value of the price of opening a bar, formed by three periods ago, the program we will write Open [3].

It is often convenient to program, instead of full names of the arrays to use their abbreviated synonyms. For this example, you can record short: O [3]. The other five arrays, too, have their synonyms:

use of L is equivalent to Low,
H ~ High,
C ~ Close,
T ~ Time,
V ~ Volume.

In the above diagram clearly illustrates the fact that each bar corresponds to a set of six arrays of elements of historical data. The index of the cell array corresponds to the number bar. Number of elements in each of the data sets due to the number of historical data stored in the history of MetaTrader'a. The program can find it, referring to the built-in variable MQL "Bars". The figure also shows that the numbering of the bars is carried out from scratch. For readability, you can compare the number of bars with his age in the interim period of the current schedule. The older the age, the greater the number of bars, this bar is not yet formed and the number is zero, it can be considered as "babies." If we look at the yearly charts, you get a complete analogy with the age of bar numbers person.

Now pay attention to the fact that this method of treatment to the historical data provides information only about the instrument and the time interval scheduling, which is attached to the user program.

If you want to get data from the history of another time period or other tool, it should be used specifically for the intended function of the arsenal of MQL 4.

After consideration of the built-in MetaTrader arrays for storing and working with historical data, go to the question of user interaction with the environment MetaTrader'a, namely - to consider the array of indicators for the drawing.

In the last article, we will, considering the source code skeleton indicator, cooked with the wizard creating advisors, drew attention to the existence of a global array ExtMapBuffer1. Let's go back to a more detalnmu the topic.

By analogy with the above described arrays of historical data, the data for drawing the custom indicator is also stored in internal arrays allocated MetaTrader'om. As we already know from previous articles, such arrays may be allocated to eight. But pre-allocate memory in MetaTrader'e for these arrays, it would not be very economical, since not every indicator will draw all of the eight schedules. This means that when you start indicator, MetaTrader must be clearly informed of the number of arrays, it should provide data for the indicator and, last but not least, the number of arrays MetaTrader be taken into account, otrisovyvaya indicator on the graph.

The programmer can communicate this information through the feature indicator indicator_buffers. Furthermore, for illustration, we assume that we have set this property equal to three.

But by itself the number of available ad indicator arrays nothing will. Even the announcement of three variables, which must contain an indicator, does not help. Pledged arrays need to relate to the allocation of these memories in order to make them truly relevant in drawing the indicator executable environment MetaTradder'a.

Binding a custom program with these arrays occurs via the function call SetIndexBuffer. The first parameter is passed the number allocated to the array, the second - the name of the variable declared as an array without the elements.

The picture shows a situation that will happen only after a call of this function, as shown below:

SetIndexBuffer (0, ExtMapBuffer1);

In doing so, being the binding of the variable ExtMapBuffer1 with the first (with the number "0") array, a dedicated performing environment. Note that in accordance with the property indicator indicator_buffers equal to three, two allocated array remain unconnected.

If we try to refer to elements of arrays of variable ExtMapBuffer2 and ExtMapBuffer3, non-distributed MetatRader'om memory will not work. All our efforts will not be visible on the screen of the terminal. As you have probably guessed, these arrays also have to associate with a distributed memory MetaTrader'om using the following calls:

SetIndexBuffer (1, ExtMapBuffer2);
SetIndexBuffer (2, ExtMapBuffer3);

Now let's investigate how to fill the arrays, which are available to us through the associated
variables of the program. Let us turn to the skeleton of the indicator, which had been prepared for us to master the creation of advisors, and look more function start ().

int start ()
(
int counted_bars = IndicatorCounted ();
//---- TODO: add your code here
//----
return (0);
)

You can see that the artist has added a line, which is created and initialized integer variable counted_bars. After the function call IndicatorCounted (), the variable will contain a number of bars, which is already calculated the value created by the indicator.

One could do without it, but if we see that the artist so insistently invites us to enjoy this way of working with data, we can see so far is not much point to disregard the recommendations.
If we decide not to use IndicatorCounted () to find out what the bars have already calculated the indicator, then we would have to invent their own way of doing this, or could have been a time when the performing environment MetaTrader'a function called start (), recalculate the value of the indicator at all bars.

The latter method can be very computer load calculations, and when the price schedules attached to the large number of indicators, ignoring the call to the function IndicatorCounted (), we felt a certain discomfort because of the slow reaction of the terminal for our actions.
To avoid problems with the excessive computational load, it is suggested every time you call the performing environment to find out how many bars have already been taken into account when calculating the values of the indicator at the previous calls of the function start (). This is the first line of code our function start ().
After that, usually checked, there has not been there when you call MQL-function IndicatorCounted () of any errors. If counted_bars less than zero, the error occurred, and it makes no sense to continue this iteration of calculating the indicator.
In the case of an error we return from the function start () using the directive return. Pointing as a parameter in the directive, we return a negative value, thus, returns this number in the performing Wednesday terminal, allowing MetaTrader'u understand that computation is not performed or performed incorrectly due to an error. If the error does not happen, then we can continue to calculate and further algorithm works most of the indicators matches:

. if the number of recorded bars greater than zero, it takes away from the unit to ensure that this iteration in any case once again to calculate the value of the indicator, obtained in the previous call to start ();
. calculate the number of bars in which you want to calculate the indicator values (based on converted bar);
. in a cycle of performing computations on the values of the indicator bar and enters the required values in the arrays are allocated to the performing environment and associated with some variables of the program during its initialization.
All together, it looks something like this, as shown in the following example, provided detailed comments:

int start ()
(
int limit = 0;
/ / Get the number of recorded
/ / In previous iterations of the bars
int counted_bars = IndicatorCounted ();
/ / Check whether there was an error
if (counted_bars <0)> 0) counted_bars -;
/ / How many bars you need to calculate
/ / At this time?
limit = Bars-counted_bars;
/ / Execute the main loop
/ / Calculating the values of the indicator
for (int i = 0; i
Alexander Ivanov

No comments: