Product Validation fail MQL5 only. [Invalid Stops]

 

Hello,

I created an EA for both MT4 and MT5. When uploading the MT4 EA to the Marketplace, all validation succeeded with no errors. When uploading the MT5 EA to the marketplace, though, I get the error:

2020.04.30 02:05:30 failed instant sell 3.3 EURUSD at 1.08735 sl: 1.08768 [Invalid stops]

I am checking the min stop loss as mentioned here, but it doesn't seem to be working.

If I remove:

* _Point

from the calculation, all validation passes for MT5 but then fails on MT4. 

The documentation for SYMBOL_TRADE_STOPS_LEVEL is the same for both MT4 and MT5 so I'm a bit confused on what is going wrong here. Any suggestions?

Symbol Properties - Environment State - Constants, Enumerations and Structures - MQL4 Reference
  • docs.mql4.com
Symbol Properties - Environment State - Constants, Enumerations and Structures - MQL4 Reference
 

Forum on trading, automated trading systems and testing trading strategies

I cant pass mql5 validation

Fernando Carreiro, 2023.06.10 16:04

Please read the market rules and implement the checks described in the article ...

V. Product Testing

  1. Products offered through the Market service are subject to automatic pre-testing. The necessary requirements are described in the articles "The checks a trading robot must pass before publication in the Market" and "Tips for an effective product presentation on the Market".
 
That's the article I linked and where I originally got the code from. From what I can tell I am doing the same check that the article is doing. 
 
Tyler James Wanta #: That's the article I linked and where I originally got the code from. From what I can tell I am doing the same check that the article is doing. 
  1. Please paste actual code and not a screenshot of code.
  2. The problem may be in some other part of the code, because the Stops Level is in points on both MQL4 and MQL5. I can state this with certainty because I code for both MQL4 and MQL5.
 

Are there any other checks that need to be done that could result in the [Invalid Stops] error? The article linked only seems to refer to  SYMBOL_TRADE_STOPS_LEVEL for that issue. 

Its also worth re iterating that if I remove the * _Point part of the calculation, thus increasing the value, all validation passes. This kind of indicates to me that the result returned by the calculation is smaller than what it's expected to be. 

I'm not normalizing or rounding up the result returned by the calculation. It looks like the Validation is failing for a SL of 3.3 Pips. Do you by chance know what the SYMBOL_TRADES_STOP_LEVEL is for the Validation process? 

  
The checks a trading robot must pass before publication in the Market
The checks a trading robot must pass before publication in the Market
  • www.mql5.com
Before any product is published in the Market, it must undergo compulsory preliminary checks in order to ensure a uniform quality standard. This article considers the most frequent errors made by developers in their technical indicators and trading robots. An also shows how to self-test a product before sending it to the Market.
 

Yes! There is also the alignment to the tick size.

Forum on trading, automated trading systems and testing trading strategies

Tick size vs Point(), can be a little tricky in Multicurrency EA

Fernando Carreiro, 2022.03.09 12:11

Tick Size and Point Size can be very different especially on stocks and other symbols besides forex.

Always use Tick Size to adjust and align your prices, not the point size. In essence, make sure that your price quotes, are properly aligned to the Tick size (see following examples).

...
double tickSize = SymbolInfoDouble( _Symbol, SYMBOL_TRADE_TICK_SIZE );
...
double normalised_price = round( price / tick_size ) * tick_size;
...
// Or use a function
double Round2Ticksize( double price )
{
   double tick_size = SymbolInfoDouble( _Symbol, SYMBOL_TRADE_TICK_SIZE );
   return( round( price / tick_size ) * tick_size );
};

By the way, the Stops Level is compared to the exit price, not the entry price.


 

So when I calculate the SL distance, that is in ticks, because it is accurate to the number of digits on the chart. Correct? So then if I wanted to compare everything in ticks, I would just need to convert the result from  SYMBOL_TRADE_STOPS_LEVEL to ticks? The code you provided converts a price to ticks, but this wouldn't work with points, correct? How does one convert Points to ticks, for any given symbol?

Also, how come the article doesn't take Ticks into account when comparing the result from SYMBOL_TRADE_STOPS_LEVEL?

 For the note you mentioned, "By the way, the Stops Level is compared to the exit price, not the entry price." (I don't know how to link someone's comment). I assume you mentioned this because you saw entryPrice in my calculation? I'm trying to make sure the distance from the market price to the SL isn't less than SYMBOL_TRADE_STOPS_LEVEL, correct? These are all market orders, so, that distance would be MathAbs(entryPrice - stopLoss).

 
Tyler James Wanta #:

So when I calculate the SL distance, that is in ticks, because it is accurate to the number of digits on the chart. Correct? So then if I wanted to compare everything in ticks, I would just need to convert the result from  SYMBOL_TRADE_STOPS_LEVEL to ticks? The code you provided converts a price to ticks, but this wouldn't work with points, correct? How does one convert Points to ticks, for any given symbol?

Also, how come the article doesn't take Ticks into account when comparing the result from SYMBOL_TRADE_STOPS_LEVEL?

For the note you mentioned, "By the way, the Stops Level is compared to the exit price, not the entry price." (I don't know how to link someone's comment). I assume you mentioned this because you saw entryPrice in my calculation? I'm trying to make sure the distance from the market price to the SL isn't less than SYMBOL_TRADE_STOPS_LEVEL, correct? These are all market orders, so, that distance would be MathAbs(entryPrice - stopLoss).

The Stops Level, as well as any terminal provided price quotes (OHLC and tick data) are already aligned to the tick size. However, any calculated prices have to be aligned to the tick size.

Forum on trading, automated trading systems and testing trading strategies

Symbol Point Value

Fernando Carreiro, 2022.05.18 21:05

double
   dbTickSize   = SymbolInfoDouble( _symbol, SYMBOL_TRADE_TICK_SIZE  ), // Tick size
   dbTickValue  = SymbolInfoDouble( _symbol, SYMBOL_TRADE_TICK_VALUE ), // Tick value
   dbPointSize  = SymbolInfoDouble( _symbol, SYMBOL_POINT ),            // Point size
   dbPointValue = dbTickValue * dbPointSize / dbTickSize;               // Point value
Remember, it's best to use tick size and tick value in your calculations, instead of point size and its value.

There are always two price quotes (Ask and Bid).

  • A buy position opens at Ask and closes at Bid
  • A sell position opens at Bid and closes at Ask

So, the Stops Level should be compared to Bid for a buy order, and Ask for a sell order. Please take a look at the "image" that I included before.

There is also slippage to consider, as by the time the order is filled, the quotes may have changed causing the Stops Level condition to fail. So you should consider some extra deviation.

 

" So, the Stops Level should be compared to Bid for a buy order, and Ask for a sell order. Please take a look at the "image" that I included before."

They are. The bid or ask is being passed into a function as a parameter called "entryPrice". 


"The Stops Level, as well as any terminal provided price quotes (OHLC and tick data) are already aligned to the tick size."

According to the documentation, SYMBOL_TRADE_STOPS_LEVEL is in points. And according to the article you linked, https://www.mql5.com/en/forum/390453#comment_28217867, points and ticks are not the same thing. So isn't this statement false? 

Tick size vs Point(), can be a little tricky in Multicurrency EA - How to calculate stoplosses and takeprofits when dealing with multiple currencies
Tick size vs Point(), can be a little tricky in Multicurrency EA - How to calculate stoplosses and takeprofits when dealing with multiple currencies
  • 2022.03.09
  • www.mql5.com
Is the same as point()  for a specific symbol,100% though i'm not sure why they are being called and defined as different things on the docs, but the point i'm trying to make is that using point()   to calculate stoplosses and takeprofits could lead to inaccurate results when dealing with multicurrency ea's that work on different symbols and instruments. Forum on trading, automated trading systems and testing trading strategies
 
Tyler James Wanta #: "The Stops Level, as well as any terminal provided price quotes (OHLC and tick data) are already aligned to the tick size."

According to the documentation, SYMBOL_TRADE_STOPS_LEVEL is in points. And according to the article you linked, https://www.mql5.com/en/forum/390453#comment_28217867, points and ticks are not the same thing. So isn't this statement false? 

Yes, the Stops Level is in points, but it is "aligned/normalised" to the tick size. The point size is always smaller or equal to the tick size.

Example ...

Forum on trading, automated trading systems and testing trading strategies

Symbol Point Value

Fernando Carreiro, 2022.06.02 01:14

Here are two examples from AMP Global (Europe):

  • Micro E-mini S&P 500 (Futures): point size = 0.01, tick size = 0.25, tick value = $1.25
  • EURO STOXX Banks (Stock Index): point size = 0.01, tick size = 0.05, tick value = €2.50
 

Ok. That makes sense. Thanks for clearing that part up. 


I tried normalizing the price like so:

(I know I should place code instead of images but the code formatting was not working)

but this still isn't working. In fact, it lead to a larger number of [Invalid Stops] errors when running validation. Any thoughts?