2025-04-16 11:59:03 -04:00
|
|
|
#property copyright "Santiago Cruz"
|
|
|
|
#property link "https://www.mql5.com/en/users/algo-trader/"
|
2025-02-19 22:47:55 -05:00
|
|
|
#property version "1.00"
|
2025-02-19 22:46:37 -05:00
|
|
|
|
2025-02-19 22:47:55 -05:00
|
|
|
// Input parameters for optimization
|
|
|
|
input double StopLoss = 50.0; // Stop Loss in points
|
|
|
|
input double TakeProfit = 100.0; // Take Profit in points
|
|
|
|
input int MATimePeriod = 14; // Moving Average Period
|
|
|
|
|
|
|
|
// Global variables
|
|
|
|
double balance;
|
|
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
//| Expert initialization function |
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
int OnInit()
|
|
|
|
{
|
|
|
|
balance = AccountBalance();
|
|
|
|
return(INIT_SUCCEEDED);
|
|
|
|
}
|
|
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
//| Expert tick function |
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
void OnTick()
|
|
|
|
{
|
|
|
|
// Simple trading logic based on Moving Average
|
|
|
|
double ma[];
|
|
|
|
ArraySetAsSeries(ma, true);
|
|
|
|
int maHandle = iMA(_Symbol, _Period, MATimePeriod, 0, MODE_SMA, PRICE_CLOSE);
|
|
|
|
CopyBuffer(maHandle, 0, 0, 3, ma);
|
|
|
|
|
|
|
|
if(!PositionSelect(_Symbol)) // If no position is open
|
|
|
|
{
|
|
|
|
if(ma[1] > ma[2] && ma[0] > ma[1]) // Buy signal
|
|
|
|
{
|
|
|
|
double sl = Ask() - StopLoss * _Point;
|
|
|
|
double tp = Ask() + TakeProfit * _Point;
|
|
|
|
trade.Buy(0.1, _Symbol, Ask(), sl, tp, "Buy Order");
|
|
|
|
}
|
|
|
|
else if(ma[1] < ma[2] && ma[0] < ma[1]) // Sell signal
|
|
|
|
{
|
|
|
|
double sl = Bid() + StopLoss * _Point;
|
|
|
|
double tp = Bid() - TakeProfit * _Point;
|
|
|
|
trade.Sell(0.1, _Symbol, Bid(), sl, tp, "Sell Order");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
//| Tester function |
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
double OnTester()
|
|
|
|
{
|
|
|
|
// Calculate metrics after testing
|
|
|
|
double profit = TesterStatistics(STAT_PROFIT); // Total profit
|
|
|
|
double trades = TesterStatistics(STAT_TRADES); // Number of trades
|
|
|
|
double maxDrawdown = TesterStatistics(STAT_EQUITY_DD); // Maximum drawdown
|
|
|
|
|
|
|
|
// Avoid division by zero
|
|
|
|
if(trades == 0) return 0.0;
|
|
|
|
|
|
|
|
// Custom criterion: Profit per trade adjusted by drawdown
|
|
|
|
double customCriterion = (profit / trades) - maxDrawdown;
|
|
|
|
|
|
|
|
// Ensure non-negative result for optimization
|
|
|
|
if(customCriterion < 0) customCriterion = 0.0;
|
|
|
|
|
|
|
|
Print("OnTester: Profit = ", profit, ", Trades = ", trades, ", Custom Criterion = ", customCriterion);
|
|
|
|
return customCriterion;
|
|
|
|
}
|
|
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
//| Expert deinitialization function |
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
void OnDeinit(const int reason)
|
|
|
|
{
|
|
|
|
// Cleanup code if needed
|
|
|
|
}
|