|
|
|
|
|
|
|
|
Let's consider how an indicator, written for MetaTrader3, is converted to MQL-4. Though MQL-2 is much more simple there are some peculiarities that influence creation of difficult indicators. The first difference is that in MQL-2 the indicator could draw no more than two indices, that is why several indicators were to be created when necessary.
The second restriction is that because of slow work of the language-interpreter the indicator's work (calculations in the indicator or expert's body) ended compulsorily in some definite period of time. That is why utility variable was used to store the index of the latest calculated bar and the cycle kept working from the remembered value. In MQL-4 for optimisation purposes function IndicatorsCounted() was created.
The third restriction: very few numbers of chart drawing, in MT3 there was a line, a histogram and arrows. The indicators code in MQL-2 is the following
|
|
|
|
The interface is commented in green, it is simple. Then in Inputs section input parameters are given. We should only specify how we will declare them in MQL-4. |Variables ppor(100),mpor(-100) are used to draw the second buffer. Indicator buffers in MQL-4 always have type double, let's declare them just in the same manner.
Variable per is a period of indicator CCI(), that is why let's declare it as type int. Variable t3_period(8) is used to calculate values of type double, though it should mean some integral-valued period and it can be declared differently, I will declare it with type double. Variable b is clear. Variable x_prd is not used.
Let's declare all the variables (Variable), except shift, as type double. Everything is ready to write an indicator. Let's start the procedure:
|
|
|
|
The indicator name remained the same as in MT3, though in the code it is RoundPrice.
|
|
|
|
Let's copy the variables from mql code, change Inputs into double, declare them in the interface. Note that this part of the code is calculated uselessly every tick though the values of the variables do not change:
|
|
|
|
That is why we may place this part of calculation into that part of the indicator only once, after the indicator is run, to block init().
Operator if() requires minimum correction.
|
|
|
|
We ignore operator SetLoopCount(0);. Let's copy the code again and work the syntax out to MQL-4. Let's replace opening operator Begin and closing operator End with the braces:
|
|
|
|
We should only convert the rest three marked blocks and everything will be ready. Operators SetIndexValue() and SetIndexValue2() in MQL-2 fill out the indicator arrays №1 and №2. That's why let's write down:
|
|
|
|
Technical indicator iCCI() is also simple to convert, let's only add parameters of the instrument and time-frame. In MQL-2 there were two technical indicators: iCCI() and iCCIEx(). The difference between them is that the first one was built at close prices, for the second one we were to set the prices type for calculation. You can refer to MT3 Help. Note the fourth difference of MT3, detailed help in Russian.
Let's replace the last thing and the indicator is ready.
|
|
|
|
Let's run the indicator in both terminals to compare, in MT3
|
|
|
|
and MT4
|
|
|
|
The error may be explained by different ways of price drawing. In MT3 the indicator is calculated much slower.
Now we can analyse the code of the indicator to improve it, optimizing the mechanism of the indicator calculation. The first question is connected with the cycle where both indicator arrays are zeroed out.
|
|
|
|
Moreover we did not use function InditarorCounted(). Let's comment-out the cycle and introduce the calculation limiter.
|
|
|
|
Then there are two questions. The first one is why when we count for the first time with counted_bars equal to zero limit is set as equal to Bars-per. Below we find that call of the technical indicator iCCI() with period per is used for calculations. If we draw it into the chart we see that indicator CCI(14)starts forming only from the 15th bar from the end. Before it its values are not specified.
|
|
|
|
If they have been calculated already (counted_bars are more than zero) , then Bars-counted_bars are usually equal to one. To optimize the calculations we will try to count the minimum number of bars, decreasing limit by one we comply with both variants. In the first case the result will be limit=Bars-per-1, in the second one limit=0.
Here optimisation may be considered to be completed but for one thing. Should we apply our last variant of the indicator to the 15 min chart and wait about half an hour (for other two bars to appear) and then apply the same indicator with the same parameters but with different colors (to distinguish them) we will see that there is a great difference.
|
|
|
|
It turns out that our indicator changes its readings with the course of time. In such cases they say that the indicator draws itself. In this case variables values meant to calculate the indicator on the zero bar just flow. For it let's add output of these variables values to the log. Let's save our new indicator with name SmCCI-2.mq4 and start to modify it.
|
|
|
|
As we see all the variables flow. Now it is clear what we needed the cycle, where indicator values zeroed on every tick, for.
|
|
|
|
We should fix (stabilize) variables e1, e2 ... e6 and our problems will be solved. Calculation of each variable for the current bar depends on the value of this variable on the previous bar. This reminds the algorithm of calculation of the exponential moving average. This method may be applied to store these variables in the indicator buffers. Let's declare e1Buffer[],e2Buffer[]…e6Buffer[] for it.
|
|
|
|
Arrays have been declared, now let's replace the variables with the correspondent arrays. Two important moments are marked in the picture. If they are violated it may trigger malfunction of the indicator. These are the most popular errors if the indicator uses more indicator buffers than displayed. In this case the mistake may be looked for in the indicator log.
|
|
|
|
Let's run both variants of the indicator in the chart, in two bars let's place another one, the first variant (which is “swimming”), and we will see that the second variant does not change its figures with the course of time unlike the first one.
|
|
|
|
Of course, to some extent the indicator under consideration turned out to be simple. If we needed 9 or more indicator buffers we would introduce additional variables where values on the previous bar (something like prev_e1, prev_e2… prev_e6) would be stored or we would just declare arrays.
Here conversion of the code from MQL-2 to MQL-4 may be considered completed. Indicators may be downloaded here .
Go to article «OrderSend()».
|
|