Which is the most guaranteed way of verifying if a price level was crossed?

 

Hi,


for my EA, I need to constantly check if a given price level was crossed. For example, if the current quote broke out the established value for a partial exit and, therefore, a market order needs to be executed at that moment.

The most obvious way of doing this is constantly checking if the current price (the current candle's close) is bigger or equal or then lesser or equal then the desired value.

The problem with this approach is that MT5 eventually don't call OnTick for every new tick: in a moment of volatility, it's possible that a tick might have reached the desired value, with the high or low of that candle showing that, but MT5's OnTick wasn't called and with the quote retracting moments later, the previous algorithm end up failing on its mission.


A simple way of countering this would be to use the current candle's high or low instead of close when doing the checking. This effectivally covers all loss ticks by OnTick. But unfortunately this technique is a failure when using when the reference value is to close to the candle such as when a frequently updated trailing stop is used during a big candle. In that case, the algorithm might tell the stop loss value was reached when actually the only thing that happend was that it was brought to inside the current's candle body.

So with that this in mind, I'ld like to know which is the known way of most effectivaly checking for price crossing. I considered using CopyTicks, picking up the last X ticks and checking one by one if they crossed the reference, but that not only it is processing and time consuming, it doesn't actually do the job unleast a big number of ticks is considered. 

 
Martin Bittencourt:

Hi,


for my EA, I need to constantly check if a given price level was crossed. For example, if the current quote broke out the established value for a partial exit and, therefore, a market order needs to be executed at that moment.

The most obvious way of doing this is constantly checking if the current price (the current candle's close) is bigger or equal or then lesser or equal then the desired value.

The problem with this approach is that MT5 eventually don't call OnTick for every new tick: in a moment of volatility, it's possible that a tick might have reached the desired value, with the high or low of that candle showing that, but MT5's OnTick wasn't called and with the quote retracting moments later, the previous algorithm end up failing on its mission.


A simple way of countering this would be to use the current candle's high or low instead of close when doing the checking. This effectivally covers all loss ticks by OnTick. But unfortunately this technique is a failure when using when the reference value is to close to the candle such as when a frequently updated trailing stop is used during a big candle. In that case, the algorithm might tell the stop loss value was reached when actually the only thing that happend was that it was brought to inside the current's candle body.

So with that this in mind, I'ld like to know which is the known way of most effectivaly checking for price crossing. I considered using CopyTicks, picking up the last X ticks and checking one by one if they crossed the reference, but that not only it is processing and time consuming, it doesn't actually do the job unleast a big number of ticks is considered. 

I stopped the follow you on the highlighted part, what do you mean ?

Also why CopyTicks() (which is effectively very slow) "doesn't actually do the job" ?

 
Alain Verleyen:

I stopped the follow you on the highlighted part, what do you mean ?

Also why CopyTicks() (which is effectively very slow) "doesn't actually do the job" ?

Hi Alain, thanks for your time.

Regarding the market line, here is a picture showing an example:


Example

As you can see, a sell operation started at the red arrow and a stop loss was put above it. This operation is configured to update the stop loss line maintaining a fixed distance of the lowest developed price at every new 10 ticks. So when the operation started, the stop was a little higher, but since the operation developed and the price fell the stop loss was adjusted several times becoming closer to the current candle's high. In a few moments (this is from the tester), the price will drop a little more, the stop loss will once again be adjusted and, this time, it will be inside the candle's body, that is lower then the candle's high. In this case, the algorithm above will erroniously understand that the stop loss line was crossed (high[0] >= stopLineValue).

Regarding CopyTicks, what I meant was: it's not guaranteed to do the job unleast a big number of ticks is considered. This is because the market may be in a high volatility moment when, let's say, 10 ticks were fired whith OnTick only picking up the last of them. In this case, the tick crossing my reference value may have been the first and, so, unleast I do a CopyTicks of 10 or more, my validation will fail. 

 
Martin Bittencourt:

Hi Alain, thanks for your time.

Regarding the market line, here is a picture showing an example:


As you can see, a sell operation started at the red arrow and a stop loss was put above it. This operation is configured to update the stop loss line maintaining a fixed distance of the lowest developed price at every new 10 ticks. So when the operation started, the stop was a little higher, but since the operation developed and the price fell the stop loss was adjusted several times becoming closer to the current candle's high. In a few moments (this is from the tester), the price will drop a little more, the stop loss will once again be adjusted and, this time, it will be inside the candle's body, that is lower then the candle's high. In this case, the algorithm above will erroniously understand that the stop loss line was crossed (high[0] >= stopLineValue).

Ok I understand your concern. But if you check on each tick you can also monitor the high of the candle and only consider it when it's changed AFTER your last price comparison. So only consider the high IF ticks were effectively missed.

Regarding CopyTicks, what I meant was: it's not guaranteed to do the job unleast a big number of ticks is considered. This is because the market may be in a high volatility moment when, let's say, 10 ticks were fired whith OnTick only picking up the last of them. In this case, the tick crossing my reference value may have been the first and, so, unleast I do a CopyTicks of 10 or more, my validation will fail. 

You should consider using CopyTicksRange() which allow you to select ticks with 2 dates in milliseconds. So you only requests ticks from that last one to current time.

 

Alternatively consider modify (split) the EA to run on multi cores. The faster your OnTick code, the less ticks missed. Try to avoid loops as much as possible, calculate only what is necessary.

Further reading https://www.mql5.com/en/articles/197

 

Alain Verleyen:
Ok I understand your concern. But if you check on each tick you can also monitor the high of the candle and only consider it when it's changed AFTER your last price comparison. So only consider the high IF ticks were effectively missed.

I'm not quite sure I understood, so let me be: what you mean is that I should keep stored the last high and low values of the current candle and every tick get them again, compare with the stored values to see if they changed, and only if they did so, check if a crossing happened?

Alain Verleyen:
You should consider using CopyTicksRange() which allow you to select ticks with 2 dates in milliseconds. So you only requests ticks from that last one to current time. 

You mean, every OnTick call I store the datetime info of the present tick and, in the next OnTick, I call CopyRicksRange from that stored datetime to the current OnTick? If so, it really sounds better then 'blindly' checking a fixed number of previous ticks!

 
Enrique Dangeroux:

Alternatively consider modify (split) the EA to run on multi cores. The faster your OnTick code, the less ticks missed. Try to avoid loops as much as possible, calculate only what is necessary.

Further reading https://www.mql5.com/en/articles/197

Thanks Enrique for the suggestion! I'll have a look at the article. Unfortunately I'm not sure if it will suits me since I plan to run many EAs and I imagine MT5 would automatically divide some for some cores, other to other cores. And if it is so that happens when multiple EAs are running, I guess such computation splitting ends up being unnecessary.

 
Martin Bittencourt:

I'm not quite sure I understood, so let me be: what you mean is that I should keep stored the last high and low values of the current candle and every tick get them again, compare with the stored values to see if they changed, and only if they did so, check if a crossing happened?

Yes as your problem in case the high/low cross your price is to know if it just happened (or from the last time you checked). And take into account that your "price trigger" may move.

You mean, every OnTick call I store the datetime info of the present tick and, in the next OnTick, I call CopyRicksRange from that stored datetime to the current OnTick? If so, it really sounds better then 'blindly' checking a fixed number of previous ticks!

Yes but it's not a datetime, it's a long, as it is milliseconds precision.

And I suppose you have to use high/low checking OR ticks but not both.

 
Alain Verleyen:

And I suppose you have to use high/low checking OR ticks but not both.

Thanks Alain for the help; the correction worked perfectly! :)

Now it's good to notice that your last comment about either using one these methods, but not both, is actually incorrect; both are needed to counter a specific, yet similar problem.

While most trading systems start an operation at the start of a new candle, some strategies opens a new position during a running candle. In such cases, when the runnig candle is already big and the stop loss is short, it may happen that the stop loss already starts inside the signal candle. And in such cases the usage of high or low of the current candle fails: in the original form, in the next tick it would already tells the stop loss was triggered (in a bearish operation as in my example, high[0] > stop loss). And in the improved version suggested by you, the EA would identify the crossing of the stop loss too late (again in a bearish operation, it would wait for a new high[0] to be formed, but by then the price would have already crossed the stop loss long ago, or even worst: it may have crossed and then bounced back with the crossing never to be identified). 

So this is why I've been using both strategies: if I'm still inside the candle when the operation started, I use the CopyTicks algorithm; but if I'm am in a future candlestick, I use the high/low approach since it consumes less computational power.

 
Martin Bittencourt:

Thanks Alain for the help; the correction worked perfectly! :)

Now it's good to notice that your last comment about either using one these methods, but not both, is actually incorrect; both are needed to counter a specific, yet similar problem.

While most trading systems start an operation at the start of a new candle, some strategies opens a new position during a running candle. In such cases, when the runnig candle is already big and the stop loss is short, it may happen that the stop loss already starts inside the signal candle. And in such cases the usage of high or low of the current candle fails: in the original form, in the next tick it would already tells the stop loss was triggered (in a bearish operation as in my example, high[0] > stop loss). And in the improved version suggested by you, the EA would identify the crossing of the stop loss too late (again in a bearish operation, it would wait for a new high[0] to be formed, but by then the price would have already crossed the stop loss long ago, or even worst: it may have crossed and then bounced back with the crossing never to be identified). 

Not sure exactly how you coded it, but it's possible to code such things without using CopyTicksXXX(). Doesn't really matter.

So this is why I've been using both strategies: if I'm still inside the candle when the operation started, I use the CopyTicks algorithm; but if I'm am in a future candlestick, I use the high/low approach since it consumes less computational power.

If your solution works using both technique that's fine. Good job.
Reason: