Join our fan page
- Views:
- 2128
- Rating:
- Published:
- 2024.09.16 13:04
- Updated:
- 2024.09.21 17:57
-
Need a robot or indicator based on this code? Order it on Freelance Go to Freelance
Update:
I've made a significant update to this library, which I use to optimize my expert advisors. This version is streamlined, but you can easily extend it to include everyday tasks you might want to automate. For example, you could add restrictions on trading after a failed prop firm challenge or resume trading on Monday after either a successful or failed challenge.
All the changes and additions to this library are outlined at the end of the code. This framework is flexible and can be adapted to your specific needs, whether it’s adding more complex logic for trading restrictions, scheduling trades, or fine-tuning performance based on optimization results.
Feel free to customize it further for your routine tasks!
This library is designed for testing Expert Advisors (EAs) in MetaTrader 5 with a specific focus on proprietary firm trading requirements. The goal is to simulate trading environments where the trader must meet certain profit and loss thresholds to pass a firm's challenge. The EA adjusts the account balance by resetting it to the initial value whenever specified profit or loss percentages are reached, mimicking the rules of many prop firms.
Here is the complete structure for the Expert Advisor (EA) using the BalanceReset.mqh library. This setup integrates the balance reset logic directly into the EA while maintaining clean separation of functions through the #include directive:
#include <BalanceReset.mqh> // Include the balance reset library //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { InitBalance(); // Initialize the starting balance return INIT_SUCCEEDED; } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { CheckBalanceAndReset(); // Check and reset balance based on thresholds } //+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { PrintBalanceResetResults(); // Output balance reset results to the log }
Key Functions
-
Adjustable Profit and Loss Thresholds
- The library allows you to adjust the profit and loss thresholds that trigger balance resets during the backtesting process. These thresholds can be changed using input parameters, which makes it easier to customize the testing conditions.
Example:
input double profit_threshold = 8.0; // Profit threshold, default is 8% input double loss_threshold = -6.0; // Loss threshold, default is -6%
2. Initial Balance Initialization
- This function stores the initial account balance at the beginning of the test. It only runs on the first tick to capture the initial starting balance.
Example:
void InitBalance() { initial_balance = AccountInfoDouble(ACCOUNT_BALANCE); // Storing the initial balance }
3. Balance Reset Logic
- The core of the library checks the current balance against the initial balance to calculate the percentage of profit or loss. If the profit exceeds the specified threshold (e.g., 8%) or the loss exceeds its threshold (e.g., -6%), the balance is reset to the initial value.
- Profit reset: The TesterWithdrawal function is used to withdraw the excess amount to bring the balance back to the initial value when the profit threshold is reached.
- Loss reset: The TesterDeposit function restores the balance to the initial amount when the loss threshold is triggered.
Example:
void CheckBalanceAndReset() { double current_balance = AccountInfoDouble(ACCOUNT_BALANCE); if (initial_balance == 0) { initial_balance = current_balance; // First tick, store the initial balance } double profit_percentage = (current_balance - initial_balance) / initial_balance * 100.0; if (profit_percentage >= profit_threshold) { double withdrawal_amount = current_balance - initial_balance; if (TesterWithdrawal(withdrawal_amount)) { successful_resets++; ArrayResize(reset_times, ArraySize(reset_times) + 1); reset_times[ArraySize(reset_times) - 1] = TimeCurrent(); Print("Profit reached. Balance has been reset to the initial value."); } } if (profit_percentage <= loss_threshold) { double deposit_amount = initial_balance - current_balance; if (TesterDeposit(deposit_amount)) { unsuccessful_resets++; ArrayResize(reset_times, ArraySize(reset_times) + 1); reset_times[ArraySize(reset_times) - 1] = TimeCurrent(); Print("Loss reached. Balance has been reset to the initial value."); } } }
4. Result Logging
- After the test is completed, this function outputs the number of successful resets (for both profit and loss) and the number of days between each reset. This provides insights into how frequently the balance resets occurred during the test.
Example:
void PrintBalanceResetResults() { PrintFormat("Number of successful profit resets: %d", successful_resets); PrintFormat("Number of successful loss resets: %d", unsuccessful_resets); for (int i = 1; i < ArraySize(reset_times); i++) { int days_between_resets = (reset_times[i] - reset_times[i-1]) / 86400; // 86400 seconds in one day PrintFormat("Days between reset %d and reset %d: %d days", i, i + 1, days_between_resets); } }
Conclusion
This library helps in simulating a trading environment that adheres to common proprietary trading firm requirements. By resetting the balance when predefined profit and loss thresholds are met, it allows traders to test their strategies more effectively and analyze the performance of their EA based on prop firm rules.
Description of Code Changes and Additions:
The new code includes several enhancements and additions compared to the old code. Below is a detailed explanation of what has been added and modified:
New Input Parameters:
-
max_loss and min_won :
input double max_loss = 1; // Max loss input double min_won = 1; // Min won
Purpose: These input parameters allow you to set the maximum allowable loss ( max_loss ) and the minimum number of successful profit resets required ( min_won ). They provide more control over the optimization conditions.
Additional Variables:
-
reset_status[] :
string reset_status[]; // Array to store the status of each reset
Purpose: An array added to store the status ("Profit reset" or "Loss reset") of each balance reset event.
stopOptimization :
bool stopOptimization = false;
Purpose: A flag used to indicate when the optimization should be stopped based on certain conditions.
badResult :
bool badResult = false; // Flag to indicate a bad optimization result
Purpose: A flag to mark the optimization result as unfavorable, which can be used to influence the outcome in OnTester() .
Modifications in CheckBalanceAndReset() :
-
Recording Reset Status:
ArrayResize(reset_status, ArraySize(reset_status) + 1); // Resize the array to record the reset status reset_status[ArraySize(reset_status) - 1] = "Profit reset"; // Record the status
Purpose: When a profit reset occurs, the status is recorded in the reset_status[] array.
Handling Loss Resets with Optimization Stop Condition:
if (TesterDeposit(deposit_amount)) { unsuccessful_resets++; // Increase the counter for unsuccessful loss resets // Record reset time and status ArrayResize(reset_status, ArraySize(reset_status) + 1); reset_status[ArraySize(reset_status) - 1] = "Loss reset"; { stopOptimization = true; CheckStopCondition(); // Check if optimization should be stopped } PrintFormat("Loss reached. Balance has been reset to the initial value."); }
Purpose: After a loss reset, the code now increments unsuccessful_resets , records the status, sets stopOptimization to true , and calls CheckStopCondition() to determine if the optimization should be halted.
New Function CheckStopCondition() :
void CheckStopCondition() { if(stopOptimization) { Print("Stopping current optimization pass"); badResult = true; // Mark the result as bad TesterStop(); } }
Purpose: This function checks if stopOptimization is true and, if so, marks the result as bad and stops the current optimization pass using TesterStop() .
New Function OnTester() :
double OnTester() { // If the number of successful resets is less than the minimum required or badResult is set if(successful_resets < min_won || badResult) { Print("Optimization failed: returning a highly unfavorable result."); // Return a highly unfavorable result to spoil the optimization pass return -999999; } // Calculate the difference between successful and unsuccessful resets int reset_difference = successful_resets - unsuccessful_resets; // Check if the difference is negative if(reset_difference < 0) { Print("Negative difference between successful and unsuccessful resets. Returning a highly unfavorable result."); // Return a highly unfavorable result if the difference is negative return -999999; } // Output the difference to the log PrintFormat("Difference between successful and unsuccessful resets: %d", reset_difference); // Return the difference as the result of the tester return reset_difference; }
Purpose: This function provides a custom criterion for the optimization process. It checks if the number of successful resets meets the minimum requirement or if the result is bad. It calculates the difference between successful and unsuccessful resets and returns this value unless the difference is negative, in which case it returns a highly unfavorable result to influence the optimizer.
Enhancements in PrintBalanceResetResults() :
// Output the dates of each reset and the number of days between them for(int i = 1; i < ArraySize(reset_times); i++) { // Calculate the number of days between resets int days_between_resets = (reset_times[i] - reset_times[i-1]) / 86400; // 86400 seconds in one day // Print the reset dates, status, and the days between them PrintFormat("Reset %d: %s (%s), Reset %d: %s (%s), Days between: %d days", i, TimeToString(reset_times[i-1], TIME_DATE), reset_status[i-1], i + 1, TimeToString(reset_times[i], TIME_DATE), reset_status[i], days_between_resets); }
Purpose: The function now not only outputs the number of resets but also details each reset event, including the date, status, and the number of days between resets. This provides a more comprehensive log of the reset activities.
Variables Initialization and Usage:
-
Initial Balance Check:
if(initial_balance == 0) { initial_balance = current_balance; }
Purpose: Ensures that the initial_balance is set correctly at the first tick.
Profit Percentage Calculation:
double profit_percentage = (current_balance - initial_balance) / initial_balance * 100.0;
Purpose: Calculates the profit or loss percentage relative to the initial balance.
Summary of Additions:
-
Control Over Optimization Process:
- The code now includes mechanisms to stop the optimization process based on specific conditions, such as exceeding the maximum number of unsuccessful resets or not achieving the minimum number of successful resets.
-
Enhanced Logging and Tracking:
- The addition of reset_status[] and detailed logging in PrintBalanceResetResults() allows for better tracking of reset events and their outcomes.
-
Integration with Optimizer via OnTester() :
- By implementing OnTester() , the script can communicate results back to the optimization engine, influencing the selection of parameter sets based on custom criteria.

This Expert Advisor (EA) for MetaTrader leverages a combination of technical indicators, including RSI, ATR, and moving averages, to identify high-probability trading opportunities. Equipped with dynamic lot sizing, trailing stops, and performance-based adjustments, it is tailored to optimize trading decisions and manage risk effectively in volatile market conditions.

is a text for the neutral network would like to know your opinion.

A real-time monitoring tool for MetaTrader 5 that displays key financial data, allows quick symbol switching, and customizable symbol lists. Save and reload symbols, reset lists, and customize text and panel colors for a personalized trading experience.

Alerts on trendline break