Table of Contents
- Introduction
- Understanding StopLevel and FreezeLevel
- Why Validate Trades Before Sending or Modifying Orders?
- Introducing the CTradeValidation Class
- Real-World Example
- Get the Code
- Conclusion
If you’re developing an Expert Advisor (EA) for MetaTrader 5—whether for your own use or for publication on the MQL5 Market—one of the most important aspects is robust trade validation. Many new developers overlook this, leading to EAs that frequently encounter errors, miss trades, or even put trading accounts at risk.
This article will walk you through the importance of trade validation, introduce the CTradeValidation class, and provide detailed explanations and practical examples for every function in the class. By the end, you’ll understand how to make your EA more professional, reliable, and market-ready.
Before diving into the details, it’s highly recommended to familiarize yourself with:
- The checks a trading robot must pass before publication in the Market
- Requirements and limitations in making trades
- Order Characteristics and Rules for Making Trades
The CTradeValidation class implements all the necessary checks based on the following MetaTrader rules.
Understanding StopLevel and FreezeLevel
1. StopLevel
Definition: The minimum distance (in points) required between the current price and Stop Loss (SL) or Take Profit (TP) levels to place or modify orders.
Key Rules:
- Market Orders (Buy/Sell):
- For Buy orders: Bid - SL ≥ StopLevel and TP - Bid ≥ StopLevel
- For Sell orders: SL - Ask ≥ StopLevel and Ask - TP ≥ StopLevel
- Pending Orders:
- BuyLimit: Open price must be Ask - OpenPrice ≥ StopLevel
- SellStop: Open price must be Bid - OpenPrice ≥ StopLevel
Examples:
- Buy Order:
- Current Bid = 1.2000, StopLevel = 10 points (0.0010)
- Valid SL: ≤ 1.1990 (since 1.2000 - 1.1990 = 0.0010)
- Invalid SL: 1.1995 (rejected as it’s only 5 points away)
- SellLimit Order:
- Open price set at 1.2050, Bid = 1.2000, StopLevel = 15 points
- Valid if 1.2050 - 1.2000 ≥ 0.0015 (valid here: 50 points > 15)
2. FreezeLevel
Definition: A price band around the current market price where orders cannot be modified, deleted, or closed.
Key Rules:
- Market Orders:
- Cannot close if SL/TP is within FreezeLevel
- Example: If FreezeLevel = 5 pips, and current Bid = 1.2000, you cannot set TP at 1.2004 (only 4 pips away)
- Pending Orders:
- Cannot modify or delete if open price is within FreezeLevel of the current price
Examples:
- Pending BuyStop Order:
- Open price = 1.2050, current Ask = 1.2045, FreezeLevel = 5 pips
- If the price moves to 1.2047 (within 3 pips of open price), you cannot delete/modify the order
- Market Buy Order:
- SL set at 1.1990, TP at 1.2050, current Bid = 1.2000, FreezeLevel = 10 pips
- If Bid moves to 1.1995, you cannot modify SL/TP as they are within the freeze zone
3. Key Differences
Feature | StopLevel | FreezeLevel |
---|---|---|
Purpose | Ensures valid SL/TP placement | Blocks modifications near execution |
Applies to | Order placement/modification | Order modification/deletion |
Violation Error | Error 130 (invalid stops) | Error 145 (order frozen) |
4. Practical Code Example
|
|
Output: If EURUSD has StopLevel = 10 and FreezeLevel = 5, this prints 0.0010 and 0.0005 (assuming 4-digit pricing).
5. Common Scenarios
- Pending Order Placement:
- Trying to set a BuyLimit at 1.1990 when Ask = 1.2000 and StopLevel = 15 points will fail (distance = 10 points < 15)
- Modifying SL on a Buy Order:
- Original SL = 1.1990, new SL = 1.1995 (current Bid = 1.2000, FreezeLevel = 5 pips)
- If 1.2000 - 1.1995 = 5 pips, modification is blocked
- Deleting a Pending SellStop:
- Open price = 1.1900, current Bid = 1.1903, FreezeLevel = 5 pips
- Deletion fails as the price is within the freeze zone
6. Broker-Specific Behavior
- ECN Brokers: Often have StopLevel = 0, but dynamic checks apply
- News Events: FreezeLevel may spike during high volatility to prevent scalping
Why Validate Trades Before Sending or Modifying Orders?
1. Broker and Platform Rules
Every broker and symbol has specific trading rules:
- StopLevel: The minimum distance (in points) required between the current price and your stop loss (SL) or take profit (TP)
- FreezeLevel: A zone near the current price where you cannot modify or delete orders
- Lot Size Limits: Minimum, maximum, and step size for trading volumes
- Margin Requirements: You must have enough free margin to open or modify a position
- Tick Size: The smallest price increment for the symbol
If you ignore these, your EA will:
- Get frequent “Invalid Stops” or “Not enough money” errors
- Miss trading opportunities
- Risk being rejected from the MQL5 Market for poor reliability
2. Professionalism and Trust
A professional EA:
✅ Checks all conditions before sending/modifying orders
✅ Handles all possible errors gracefully
✅ Protects the trader’s account from unexpected behavior
If you want your EA to be trusted by others (or yourself!), validation is not optional—it’s essential.
Introducing the CTradeValidation Class
The CTradeValidation class is designed to centralize and simplify all the checks you need before trading. It helps you:
- Validate order placement, modification, and deletion
- Calculate safe lot sizes
- Ensure compliance with all broker and symbol rules
Let’s explore every function in this class, with detailed explanations and practical code examples.
1. Constructor: CTradeValidation(string _symbol, bool use_max_level = false)
What It Does
Initializes the validation object for a specific symbol, fetching all the necessary trading parameters (point size, stop level, freeze level, pip value, etc.).
Parameters
string _symbol
: The symbol you want to trade (e.g., “EURUSD”)bool use_max_level
(optional, default: false):- If true, the class will use the maximum of the symbol’s stop level and freeze level for all validations
- This is extra safe, ensuring your EA never gets rejected due to either restriction
Example
|
|
When to Use use_max_level
Some brokers set a freeze level that is higher than the stop level. If you want to avoid any risk of your order being rejected due to either, set use_max_level
to true. This is especially useful for EAs you plan to sell or distribute.
2. GetStopLevel & GetFreezeLevel
What They Do
GetStopLevel()
: Returns the minimum distance (in points) required between the current price and your SL/TPGetFreezeLevel()
: Returns the freeze level (in points) where modifications are not allowed
Example
|
|
Practical Use
Before setting SL/TP or modifying orders, check these values to ensure your prices are valid. For example, if the stop level is 200 points, your SL/TP must be at least 200 points away from the current price.
3. CalculateValidLot
What It Does
Calculates a valid lot size based on your risk percentage, entry price, and stop loss, ensuring it fits the broker’s lot limits.
Parameters
double sl_price
: The stop loss pricedouble entry_price
: The entry price for the tradedouble risk_percent
: The percentage of your account balance you want to risk
Example
|
|
Practical Scenario
Suppose you want to risk 1% of your account on each trade. This function calculates the lot size that matches your risk, taking into account the distance to your stop loss and the symbol’s tick value. It also ensures the lot size is within the broker’s allowed range.
4. CheckMargin
What It Does
Checks if you have enough free margin to open a position with the given lot size and order type. Optionally, it can reduce the lot size to the maximum allowed by your margin.
Parameters
double &lot_size
: The lot size you want to check (may be reduced if not enough margin)ENUM_ORDER_TYPE order_type
: The type of order (e.g., ORDER_TYPE_BUY)bool use_max_margin
(optional, default: true): If true, will reduce the lot size to the maximum possible if you don’t have enough margin
Example
|
|
Practical Scenario
If you try to open a trade with a lot size that’s too large for your available margin, this function will either reject the trade or (if use_max_margin
is true) reduce the lot size to the maximum possible.
5. CalculateMaxLot
What It Does
Calculates the maximum lot size you can open with your available margin for a given order type.
Parameters
ENUM_ORDER_TYPE order_type
double available_margin
Example
|
|
Practical Scenario
If you want to scale your position size based on your account’s free margin, use this function to find the maximum safe lot size.
6. GetPipPoint
What It Does
Returns the pip value for the symbol (useful for calculating distances in pips).
Example
|
|
Practical Scenario
If you want to set your stop loss 20 pips away, you can calculate the price distance as 20 * validation.GetPipPoint()
.
7. Round2Ticksize
What It Does
Rounds a price to the nearest valid tick size for the symbol.
Parameters
double price
: The price to round
Example
|
|
Practical Scenario
Some symbols have a tick size of 0.01, others 0.0001. This function ensures your prices are always valid for the symbol, avoiding rejections.
8. ValidateOrderPlacement
What It Does
Checks if your stop loss and take profit are at valid distances for a new order (market or pending).
Parameters
ENUM_ORDER_TYPE order_type
: The type of order (e.g., ORDER_TYPE_BUY)double sl_price
: The stop loss pricedouble tp_price
: The take profit pricedouble open_price
(optional): The entry price for pending orders
Example
|
|
Practical Scenario
This function prevents sending orders that will be rejected due to SL/TP being too close to the price, which is a common error for new EAs.
9. ValidateSLModify
What It Does
Checks if modifying the stop loss is allowed (for both market and pending orders).
Parameters
ENUM_ORDER_TYPE order_type
double old_sl
: The current stop lossdouble new_sl
: The new stop loss you want to setdouble open_price
(optional): The open price for pending orders
Example
|
|
Practical Scenario
If you want to move your stop loss to break even, this function checks if the new SL is valid according to broker rules.
10. ValidateTPModify
What It Does
Checks if modifying the take profit is allowed.
Parameters
ENUM_ORDER_TYPE order_type
double old_tp
: The current take profitdouble new_tp
: The new take profit you want to setdouble open_price
(optional): The open price for pending orders
Example
|
|
Practical Scenario
If you want to trail your take profit as the trade moves in your favor, this function ensures your new TP is valid.
11. ValidateOpenPriceModify
What It Does
Checks if you can modify the open price of a pending order (Buy Limit, Sell Limit, Buy Stop, Sell Stop).
Parameters
ENUM_ORDER_TYPE order_type
double old_open_price
double new_open_price
Example
|
|
Practical Scenario
If you want to move a pending order closer to the market, this function checks if the new price is allowed.
12. ValidateClosePosition
What It Does
Checks if you can close a position, ensuring SL/TP are not within the freeze level.
Parameters
ENUM_ORDER_TYPE order_type
double sl_price
double tp_price
Example
|
|
Practical Scenario
If your SL or TP is too close to the current price, the broker may not allow you to close the position. This function checks for that.
13. ValidateDeletePendingOrder
What It Does
Checks if you can delete a pending order, ensuring the open price is not within the freeze level.
Parameters
ENUM_ORDER_TYPE order_type
double open_price
Example
|
|
Practical Scenario
If you try to delete a pending order that’s too close to the market price, the broker may reject the request. This function prevents that.
Real-World Example: Using CTradeValidation in an EA
Here’s a simple example of how you might use this class in your EA’s order logic:
|
|
Get the Code
The complete CTradeValidation class is available for free on GitHub. You can download and use it in your projects:
GitHub Repository: Trade_Validation
The repository contains:
- Complete source code of the CTradeValidation class
- Example usage
- Documentation
- Free to use in your projects
Conclusion
By using the CTradeValidation class, you make your EA:
🛡️ More robust and error-free
🚀 Ready for the MQL5 Market
💰 Safer for your own and your clients’ accounts
🧩 Easier to maintain and extend
Always validate before you trade!
This is the mark of a professional EA developer.
If you have questions or want to see more examples, feel free to ask in the comments!