Tyler James Wanta #: 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?
Please paste actual code and not a screenshot of code. It is working ...use the CODE button (Alt-S) when inserting code.
Showing just a small portion of your code is not going to be enough to solve the issue.
We don't know what the rest of the code is doing nor do we know what values are being passed, nor do we know how you are placing the order or modifying the position.
Print out your values and show the log results of actual testing in your strategy tester. Don't carry out a validation until the results in the tester produce the correct results.
Test under different circumstances and change the values in the Symbol's contract specifications so you can see how your code is behaving.
For example, you are using MathAbs, which is only acceptable if the rest of the code has already filtering out incorrect values. Imagine however, if you set the stop-loss on the wrong side of the price, then your code with MathAbs would not catch that.
Also, you are doing floating point comparison. That is not always good, because equality in floating point can fail. So, although it is not error, it is advisable, given that you have to align to tick size and that Stops Level is in points (and already am integer value), then convert and use integer arithmetic and comparison.
Initially, when I started with MQL, I would manipulate prices as "doubles". Nowadays, especially in the more complex EA's, I manipulate prices as "ints". At the very first opportunity, I convert a price into ticks:
int priceTicks = (int) round( price / tickSize );
From then on, all my calculations and manipulations are done with "ints". Not only is it more memory compact and much faster, but comparisons are much easier to handle. Doing a "priceA == priceB" for "doubles" is quite problematic, but not for "ints" because it gives exact matches. Not to mention, that in this way prices, stop sizes, etc. are ALWAYS aligned.
Then, just before I have to place or modify an order, I then convert it back:
priceTicks * tickSize
EDIT: I do the same for volume/lots by using the broker's Lot-Step.
Ticket Type of 1 is a buy. We can see the Entry is at the Ask, as it should be. Also, the entry and exit are normalized.
The tricky part is that the min SL is 0. I am using the default metaquotes-Demo server on MT5 for testing.
If I run this on MT4, where I do have an account with a broker, this is the log:
2023.06.10 17:16:53.0992023.01.12 04:46:22 The Retirement Achiever EA EURUSD,H1: Entry: 1.0768, SL: 1.0755, Normalized SL Dist.: 0.0013, Original SL Dist.: 0.001300000000000079, Ticket Type: 1, Ask: 1.0768, Bid: 1.0767, Min SL: 10, Min SL Points: 0.0001
Is there a way to connect to a metaquotes-demo server on MT5 with a Min SL? Otherwise I don't see anything else that could be an issue.
You are working with 3 current prices "Entry Price", "Ask", "Bid". What if somewhere in your code the entry price is not set correctly? Rethink your code to reduce the possibility of an error.
You have shown the output of your log prints, but you did not show the log output of the actual order being sent and filled.
Even if an account, does not have a Stops Level by default, set one yourself in the tester (on MT5):
When upping the min SL to 100 and adding more logging, everything works as expected, and no order gets placed:
2023.06.10 17:42:38.8642023.06.02 02:00:00 Entry: 1.07658, SL: 1.07586, Normalized SL Dist.: 0.00072, Original SL Dist.: 0.0007200000000000539, Ticket Type: 1, Ask: 1.07658, Bid: 1.07654, Min SL: 100, Min SL Points: 0.001
2023.06.10 17:42:38.8642023.06.02 02:00:00 Normalized Price: 0.00072, is smaller than min SL: 0.001
Everything seems to be working as expected on my end but when uploading it to the marketplace it still fails validation with [Invalid Stops]. I'm not placing a TP and I am never modifying the orders.
Tyler James Wanta #: I set a Min SL and here is some more logging info. The trades are going through fine here at 10 When upping the min SL to 100 and adding more logging, everything works as expected, and no order gets placed:
Everything seems to be working as expected on my end but when uploading it to the marketplace it still fails validation with [Invalid Stops]. I'm not placing a TP and I am never modifying the orders.
Ok, now show us the validation results, with your debugs prints still active. Show as much as possible. So we can pickup on clues if necessary.
test on EURUSD,H1 (netting)
2019.04.0502:21:30 failed instant buy 2.8 EURUSD at 1.12236 sl: 1.12200 [Invalid stops]
2019.04.1103:30:06 failed instant sell 3.1 EURUSD at 1.12732 sl: 1.12763 [Invalid stops]
2019.04.1604:21:25 failed instant sell 3.2 EURUSD at 1.12999 sl: 1.13030 [Invalid stops]
2019.04.1803:00:02 failed instant sell 2.85 EURUSD at 1.12960 sl: 1.12995 [Invalid stops]
2019.04.2302:00:34 failed instant buy 3.1 EURUSD at 1.12607 sl: 1.12575 [Invalid stops]
2019.04.2902:39:30 failed instant sell 3.55 EURUSD at 1.11476 sl: 1.11507 [Invalid stops]
2019.05.0303:00:42 failed instant sell 2.9 EURUSD at 1.11714 sl: 1.11751 [Invalid stops]
2019.05.0615:46:42 failed instant sell 0.5 EURUSD at 1.11787, close #68buy 0.5 EURUSD 1.12009 [Modification failed due to order or position being close to market]
2019.05.0615:46:42 failed instant sell 0.5 EURUSD at 1.11788, close #68buy 0.5 EURUSD 1.12009 [Modification failed due to order or position being close to market]
2019.05.0615:46:42 failed instant sell 0.5 EURUSD at 1.11787, close #68buy 0.5 EURUSD 1.12009 [Modification failed due to order or position being close to market]
2019.05.0615:46:43 failed instant sell 0.5 EURUSD at 1.11788, close #68buy 0.5 EURUSD 1.12009 [Modification failed due to order or position being close to market]
2019.05.0615:46:43 failed instant sell 0.5 EURUSD at 1.11787, close #68buy 0.5 EURUSD 1.12009 [Modification failed due to order or position being close to market]
2019.05.0615:46:43 failed instant sell 0.5 EURUSD at 1.11788, close #68buy 0.5 EURUSD 1.12009 [Modification failed due to order or position being close to market]
2019.05.0615:46:43 failed instant sell 0.5 EURUSD at 1.11787, close #68buy 0.5 EURUSD 1.12009 [Modification failed due to order or position being close to market]
2019.05.0615:46:44 failed instant sell 0.5 EURUSD at 1.11788, close #68buy 0.5 EURUSD 1.12009 [Modification failed due to order or position being close to market]
2019.05.0615:46:44 failed instant sell 0.5 EURUSD at 1.11787, close #68buy 0.5 EURUSD 1.12009 [Modification failed due to order or position being close to market]
2019.05.0615:46:44 failed instant sell 0.5 EURUSD at 1.11788, close #68buy 0.5 EURUSD 1.12009 [Modification failed due to order or position being close to market]
2019.05.0615:46:44 failed instant sell 0.5 EURUSD at 1.11787, close #68buy 0.5 EURUSD 1.12009 [Modification failed due to order or position being close to market]
2019.05.0615:46:45 failed instant sell 0.5 EURUSD at 1.11788, close #68buy 0.5 EURUSD 1.12009 [Modification failed due to order or position being close to market]
2019.05.0615:46:45 failed instant sell 0.5 EURUSD at 1.11787, close #68buy 0.5 EURUSD 1.12009 [Modification failed due to order or position being close to market]
2019.05.0615:46:45 failed instant sell 0.5 EURUSD at 1.11789, close #68buy 0.5 EURUSD 1.12009 [Modification failed due to order or position being close to market]
Please note that the test is being run on a "netting" account.
Given that you mentioned that you are coding an EA for both MQL4 and MQL5, it would make more sense to be testing against a "hedging" account on MT5 and not a "netting" account.
These should all be placement of new orders or close of existing orders. The EA doesn't do any modification to the orders once they are placed. Do I need to check Freeze level when closing a position?
The code should work with a netting account. It only opens a single position at a time, and in only one direction at a time. I've tested this and made sure this works.
Tyler James Wanta #: These should all be placement of new orders or close of existing orders. The EA doesn't do any modification to the orders once they are placed. Do I need to check Freeze level when closing a position? The code should work with a netting account. It only opens a single position at a time, and in only one direction at a time. I've tested this and made sure this works.
For the closing of the positions you need to also check the Freeze Level.
As for the rest, without access to the complete code or more debug information (given that your prints are not being output in the verification process), it is difficult to analyse the issue.
Try doing a verification against a "hedging" account and see if a similar situation comes up or not. If the results are different between "hedging" and "netting", then there is definitely a "netting" incomparability.
Tables below show calculation values that limit the conduction of trades when opening, closing, placing, deleting or modifying orders.
To get the minimum distance to StopLevel and freezing distance FreezeLevel the MarketInfo() function should be called.
Requirements.
Correct prices used when performing trade operations.
Order Type
Open Price
Close Price
Open Price of a Pending Order
Transforming a Pending Order into aMarket Order
Buy
Ask
Bid
Sell
Bid
Ask
BuyLimit
Below the current Ask price
Ask price reaches open price
SellLimit
Above the current Bid price
Bid price reaches open price
BuyStop
Above the current Ask price
Ask price reaches open price
SellStop
Below the current Bid price
Bid price reaches open price
The possibility of deleting a pending order is regulated by the FreezeLevel parameter.
StopLevel Minimum Distance Limitation.
A trade operation will not be performed if any of the following conditions is disrupted.
Order Type
Open Price
StopLoss (SL)
TakeProfit (TP)
Buy
Modification is prohibited
Bid-SL ≥ StopLevel
TP-Bid ≥ StopLevel
Sell
Modification is prohibited
SL-Ask ≥ StopLevel
Ask-TP ≥ StopLevel
BuyLimit
Ask-OpenPrice ≥ StopLevel
OpenPrice-SL ≥ StopLevel
TP-OpenPrice ≥ StopLevel
SellLimit
OpenPrice-Bid ≥ StopLevel
SL-OpenPrice ≥StopLevel
OpenPrice-TP ≥ StopLevel
BuyStop
OpenPrice-Ask ≥ StopLevel
OpenPrice-SL ≥ StopLevel
TP-OpenPrice ≥ StopLevel
SellStop
Bid-OpenPrice ≥ StopLevel
SL-OpenPrice ≥ StopLevel
OpenPrice-TP ≥ StopLevel
FreezeLevel Limitation (Freezing Distance).
Market orders can not be closed if the StopLoss and TakeProfit values violate the FreezLevel parameter requirements. StopLoss or TakeProfit orders can not be modified if StopLoss or TakeProfit values violate the StopLevel parameter requirements. Pending orders can not be deleted or modified if the declared open price violates the FreezeLevel parameter requirements.
Tyler James Wanta #: 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?
Please paste actual code and not a screenshot of code. It is working ...use the CODE button (Alt-S) when inserting code.
Showing just a small portion of your code is not going to be enough to solve the issue.
We don't know what the rest of the code is doing nor do we know what values are being passed, nor do we know how you are placing the order or modifying the position.
Print out your values and show the log results of actual testing in your strategy tester. Don't carry out a validation until the results in the tester produce the correct results.
Test under different circumstances and change the values in the Symbol's contract specifications so you can see how your code is behaving.
For example, you are using MathAbs, which is only acceptable if the rest of the code has already filtering out incorrect values. Imagine however, if you set the stop-loss on the wrong side of the price, then your code with MathAbs would not catch that.
Also, you are doing floating point comparison. That is not always good, because equality in floating point can fail. So, although it is not error, it is advisable, given that you have to align to tick size and that Stops Level is in points (and already am integer value), then convert and use integer arithmetic and comparison.
Here is a bit more code:
The issue is that the check in 'CheckStopLoss', for the Min SL, isn't working.
Here is a log from a trade in the tester:
2023.06.10 17:09:06.242 2023.06.06 03:12:00 Entry: 1.07146, SL: 1.07095, Normalized SL Dist.: 0.00051, Original SL Dist.: 0.0005100000000000104, Ticket Type: 1, Ask: 1.07146, Bid: 1.07144, Min SL: 0
Ticket Type of 1 is a buy. We can see the Entry is at the Ask, as it should be. Also, the entry and exit are normalized.
The tricky part is that the min SL is 0. I am using the default metaquotes-Demo server on MT5 for testing.
If I run this on MT4, where I do have an account with a broker, this is the log:
2023.06.10 17:16:53.099 2023.01.12 04:46:22 The Retirement Achiever EA EURUSD,H1: Entry: 1.0768, SL: 1.0755, Normalized SL Dist.: 0.0013, Original SL Dist.: 0.001300000000000079, Ticket Type: 1, Ask: 1.0768, Bid: 1.0767, Min SL: 10, Min SL Points: 0.0001
Is there a way to connect to a metaquotes-demo server on MT5 with a Min SL? Otherwise I don't see anything else that could be an issue.
Here is a bit more code:
The issue is that the check in 'CheckStopLoss', for the Min SL, isn't working.
Here is a log from a trade in the tester:
2023.06.10 17:09:06.242 2023.06.06 03:12:00 Entry: 1.07146, SL: 1.07095, Normalized SL Dist.: 0.00051, Original SL Dist.: 0.0005100000000000104, Ticket Type: 1, Ask: 1.07146, Bid: 1.07144, Min SL: 0
Ticket Type of 1 is a buy. We can see the Entry is at the Ask, as it should be. Also, the entry and exit are normalized.
The tricky part is that the min SL is 0. I am using the default metaquotes-Demo server on MT5 for testing.
If I run this on MT4, where I do have an account with a broker, this is the log:
2023.06.10 17:16:53.099 2023.01.12 04:46:22 The Retirement Achiever EA EURUSD,H1: Entry: 1.0768, SL: 1.0755, Normalized SL Dist.: 0.0013, Original SL Dist.: 0.001300000000000079, Ticket Type: 1, Ask: 1.0768, Bid: 1.0767, Min SL: 10, Min SL Points: 0.0001
Is there a way to connect to a metaquotes-demo server on MT5 with a Min SL? Otherwise I don't see anything else that could be an issue.
You are working with 3 current prices "Entry Price", "Ask", "Bid". What if somewhere in your code the entry price is not set correctly? Rethink your code to reduce the possibility of an error.
You have shown the output of your log prints, but you did not show the log output of the actual order being sent and filled.
Even if an account, does not have a Stops Level by default, set one yourself in the tester (on MT5):
The entry price is set here and is not wrong:
I set a Min SL and here is some more logging info. The trades are going through fine here at 10
2023.06.10 17:39:43.874 2023.06.05 05:00:04 Entry: 1.07009, SL: 1.07077, Normalized SL Dist.: 0.00068, Original SL Dist.: 0.0006800000000000139, Ticket Type: 2, Ask: 1.0701100000000001, Bid: 1.07009, Min SL: 10, Min SL Points: 0.0001
2023.06.10 17:39:43.874 2023.06.05 05:00:04 market sell 1.41 EURUSD sl: 1.07077 (1.07009 / 1.07011 / 1.07009)
2023.06.10 17:39:43.874 2023.06.05 05:00:04 deal #10 sell 1.41 EURUSD at 1.07009 done (based on order #10)
2023.06.10 17:39:43.874 2023.06.05 05:00:04 deal performed [#10 sell 1.41 EURUSD at 1.07009]
2023.06.10 17:39:43.874 2023.06.05 05:00:04 order performed sell 1.41 at 1.07009 [#10 sell 1.41 EURUSD at 1.07009]
2023.06.10 17:39:43.876 2023.06.05 05:00:04 CTrade::OrderSend: market sell 1.41 EURUSD sl: 1.07077 [done at 1.07009]
When upping the min SL to 100 and adding more logging, everything works as expected, and no order gets placed:
2023.06.10 17:42:38.864 2023.06.02 02:00:00 Entry: 1.07658, SL: 1.07586, Normalized SL Dist.: 0.00072, Original SL Dist.: 0.0007200000000000539, Ticket Type: 1, Ask: 1.07658, Bid: 1.07654, Min SL: 100, Min SL Points: 0.001
2023.06.10 17:42:38.864 2023.06.02 02:00:00 Normalized Price: 0.00072, is smaller than min SL: 0.001
Everything seems to be working as expected on my end but when uploading it to the marketplace it still fails validation with [Invalid Stops]. I'm not placing a TP and I am never modifying the orders.
Everything seems to be working as expected on my end but when uploading it to the marketplace it still fails validation with [Invalid Stops]. I'm not placing a TP and I am never modifying the orders.
Ok, now show us the validation results, with your debugs prints still active. Show as much as possible. So we can pickup on clues if necessary.
Are these placement of new orders or modifications to existing positions?
For this error, you are not checking the Freeze Level.
For these, the same question — are these placement of new orders or modifications to existing positions?
Please note that the test is being run on a "netting" account.
Given that you mentioned that you are coding an EA for both MQL4 and MQL5, it would make more sense to be testing against a "hedging" account on MT5 and not a "netting" account.
Is you code compatible with netting account?
These should all be placement of new orders or close of existing orders. The EA doesn't do any modification to the orders once they are placed. Do I need to check Freeze level when closing a position?
The code should work with a netting account. It only opens a single position at a time, and in only one direction at a time. I've tested this and made sure this works.
For the closing of the positions you need to also check the Freeze Level.
As for the rest, without access to the complete code or more debug information (given that your prints are not being output in the verification process), it is difficult to analyse the issue.
Try doing a verification against a "hedging" account and see if a similar situation comes up or not. If the results are different between "hedging" and "netting", then there is definitely a "netting" incomparability.
By the way here are the equivalent requirements for MQL4 ... https://book.mql4.com/appendix/limits