update to my mt5 libs to include better comments

This commit is contained in:
Matt Corcoran
2025-07-12 15:29:30 +02:00
parent ec3fc120ce
commit 136522ef1c
31 changed files with 1389 additions and 2024 deletions
+60 -7
View File
@@ -1,10 +1,25 @@
#include <Trade/Trade.mqh>
// ---------------------------------------------------------------------
// ENUM: CUSTOM_MAX_TYPE
// ---------------------------------------------------------------------
// Defines the types of custom performance criteria that can be used
// for calculating max optimization targets.
//
// Values:
// - CM_WIN_LOSS_RATIO : Use win/loss ratio.
// - CM_WIN_PERCENT : Use win percentage.
// ---------------------------------------------------------------------
enum CUSTOM_MAX_TYPE {
CM_WIN_LOSS_RATIO,
CM_WIN_PERCENT
};
// ---------------------------------------------------------------------
// CLASS: CustomMax
// ---------------------------------------------------------------------
// Calculates custom performance criteria for use in optimizations.
// ---------------------------------------------------------------------
class CustomMax : public CObject {
protected:
double custom_criteria;
@@ -16,6 +31,17 @@ public:
double calculate_custom_criteria(CUSTOM_MAX_TYPE cm_type, int min_trades = 0);
};
// ---------------------------------------------------------------------
// Calculates the selected custom criteria metric.
//
// Parameters:
// - cm_type : The selected criteria type to calculate.
// - min_trades : Optional minimum number of trades (default 0).
//
// Logic:
// - Calls the appropriate private method based on cm_type.
// - Returns the resulting metric (or 0 if invalid).
// ---------------------------------------------------------------------
double CustomMax::calculate_custom_criteria(CUSTOM_MAX_TYPE cm_type, int min_trades) {
switch(cm_type) {
case CM_WIN_LOSS_RATIO:
@@ -31,22 +57,49 @@ double CustomMax::calculate_custom_criteria(CUSTOM_MAX_TYPE cm_type, int min_tra
return custom_criteria;
}
// Returns the win/loss ratio, with min trades check
// ---------------------------------------------------------------------
// Calculates win/loss ratio with a minimum trade count check.
//
// Parameters:
// - min_required_trades : Minimum number of trades required.
//
// Logic:
// - Returns wins / losses if minimum is met.
// - Prevents division by zero.
// ---------------------------------------------------------------------
double CustomMax::win_loss_ratio(int min_required_trades) {
double wins = TesterStatistics(STAT_PROFIT_TRADES);
double losses = TesterStatistics(STAT_LOSS_TRADES);
double total_trades = TesterStatistics(STAT_TRADES);
if((min_required_trades > 0 && total_trades < min_required_trades) || total_trades == 0) return 0;
if(losses == 0) return 0; // Prevent division by zero
if ((min_required_trades > 0 && total_trades < min_required_trades) || total_trades == 0)
return 0;
if (losses == 0)
return 0;
return wins / losses;
}
// Returns the win percentage, with min trades check
// ---------------------------------------------------------------------
// Calculates win percentage with a minimum trade count check.
//
// Parameters:
// - min_required_trades : Minimum number of trades required.
//
// Logic:
// - Returns (wins / total) * 100 if minimum is met.
// - Filters out invalid math results.
// ---------------------------------------------------------------------
double CustomMax::win_percent_min_trades(int min_required_trades) {
double wins = TesterStatistics(STAT_PROFIT_TRADES);
double total_trades = TesterStatistics(STAT_TRADES);
if((min_required_trades > 0 && total_trades < min_required_trades) || total_trades == 0) return 0;
double result = wins / total_trades * 100;
if(!MathIsValidNumber(result)) return 0;
if ((min_required_trades > 0 && total_trades < min_required_trades) || total_trades == 0)
return 0;
double result = (wins / total_trades) * 100;
if (!MathIsValidNumber(result))
return 0;
return result;
}
+61 -31
View File
@@ -1,4 +1,18 @@
enum MODE_SPLIT_DATA{
// ---------------------------------------------------------------------
// ENUM: MODE_SPLIT_DATA
// ---------------------------------------------------------------------
// Defines how to split data during testing based on time attributes.
//
// Values:
// - NO_SPLIT : Do not split, always return true.
// - ODD_YEARS : Include only odd-numbered years.
// - EVEN_YEARS : Include only even-numbered years.
// - ODD_MONTHS : Include only odd-numbered months.
// - EVEN_MONTHS : Include only even-numbered months.
// - ODD_WEEKS : Include only odd-numbered weeks.
// - EVEN_WEEKS : Include only even-numbered weeks.
// ---------------------------------------------------------------------
enum MODE_SPLIT_DATA {
NO_SPLIT,
ODD_YEARS,
EVEN_YEARS,
@@ -8,44 +22,60 @@ enum MODE_SPLIT_DATA{
EVEN_WEEKS
};
// ---------------------------------------------------------------------
// CLASS: TestDataSplit
// ---------------------------------------------------------------------
// Provides logic to determine whether the current date falls within
// a selected split group for testing or optimization purposes.
// ---------------------------------------------------------------------
class TestDataSplit {
public:
bool in_test_period(MODE_SPLIT_DATA data_split_method);
bool in_test_period(MODE_SPLIT_DATA data_split_method);
};
// ---------------------------------------------------------------------
// Determines whether the current time falls in the selected group.
//
// Parameters:
// - data_split_method : Enum value defining the split strategy.
//
// Logic:
// - Extracts current date components (year, month, ISO week).
// - Returns true if current time matches the given split rule.
// ---------------------------------------------------------------------
bool TestDataSplit::in_test_period(MODE_SPLIT_DATA data_split_method) {
string result[];
string string_tc = TimeToString(TimeCurrent());
string result[];
string string_tc = TimeToString(TimeCurrent());
// Extract components from datetime string (assumes YYYY.MM.DD format)
ushort u_sep = StringGetCharacter(".", 0);
StringSplit(string_tc, u_sep, result);
// Extract components from datetime string (assumes YYYY.MM.DD format)
ushort u_sep = StringGetCharacter(".", 0);
StringSplit(string_tc, u_sep, result);
bool odd_year = int(result[0]) % 2;
bool odd_month = int(result[1]) % 2;
bool odd_year = int(result[0]) % 2;
bool odd_month = int(result[1]) % 2;
// Calculate week of the year (basic approximation)
MqlDateTime dt;
TimeToStruct(TimeCurrent(), dt);
int iDay = (dt.day_of_week + 6) % 7 + 1; // Convert to 1=Mon,...,7=Sun
int iWeek = (dt.day_of_year - iDay + 10) / 7; // Estimate ISO week number
bool odd_week = iWeek % 2;
// Calculate week of the year (approximate ISO week)
MqlDateTime dt;
TimeToStruct(TimeCurrent(), dt);
int i_day = (dt.day_of_week + 6) % 7 + 1; // Convert to 1=Mon,...,7=Sun
int i_week = (dt.day_of_year - i_day + 10) / 7; // Approximate ISO week number
bool odd_week = i_week % 2;
// Split logic depending on mode
if (data_split_method == NO_SPLIT)
return true;
if (data_split_method == ODD_YEARS && odd_year)
return true;
if (data_split_method == EVEN_YEARS && !odd_year)
return true;
if (data_split_method == ODD_MONTHS && odd_month)
return true;
if (data_split_method == EVEN_MONTHS && !odd_month)
return true;
if (data_split_method == ODD_WEEKS && odd_week)
return true;
if (data_split_method == EVEN_WEEKS && !odd_week)
return true;
// Split logic depending on mode
if (data_split_method == NO_SPLIT)
return true;
if (data_split_method == ODD_YEARS && odd_year)
return true;
if (data_split_method == EVEN_YEARS && !odd_year)
return true;
if (data_split_method == ODD_MONTHS && odd_month)
return true;
if (data_split_method == EVEN_MONTHS && !odd_month)
return true;
if (data_split_method == ODD_WEEKS && odd_week)
return true;
if (data_split_method == EVEN_WEEKS && !odd_week)
return true;
return false;
return false;
}