//+------------------------------------------------------------------+
//| MyTradingEA.mq5 |
//+------------------------------------------------------------------+
#property copyright "Your Name"
#property version "1.04"
#property strict
#include <Trade\Trade.mqh> // Ensure necessary include for trade
functions
//--- Input parameters
input double HighRisk = 5.0; // Risk percentage for high volatility
trades (1% increased significantly for high volatility)
input double LowRisk = 0.7; // Risk percentage for low volatility
trades (0.7% for lower risk trades)
input int MagicNumber = 123456; // Unique identifier for EA's orders
input int Slippage = 10; // Maximum slippage in points
//--- Global variables
int rsiHandle;
int superTrendHandle;
int macdHandle; // MACD handle
int consecutiveLosses = 0;
int maxConsecutiveLosses = 5; // Set the maximum number of
consecutive losses before pausing
bool isPaused = false; // Boolean flag to pause trading
datetime pauseEndTime; // Track when to resume trading
int fileHandle; // Global file handle for logging trades
//--- Indicator parameters
int RSI_Period = 7;
double SuperTrend_Multiplier = 1.00;
ENUM_TIMEFRAMES Timeframe = PERIOD_M1;
//--- MACD parameters
int MACD_FastPeriod = 7; // Fine-tuned MACD settings to increase trade
frequency
int MACD_SlowPeriod = 18; // Fine-tuned MACD settings to increase trade
frequency
int MACD_SignalPeriod = 6;
//--- ATR settings for dynamic SL/TP and volatility check
double atrStopLossMultiplierHighVolatility = 3.5; // Increased ATR
multiplier for stop-loss in high volatility
double atrStopLossMultiplierLowVolatility = 2.5; // Reduced ATR multiplier
for stop-loss in low volatility
double atrTakeProfitMultiplierHighVolatility = 5.0; // Increased ATR
multiplier for take-profit in high volatility
double atrTakeProfitMultiplierLowVolatility = 3.0; // Increased ATR
multiplier for take-profit in low volatility
double volatilityLotMultiplier = 3.0; // Significantly increase lot
size in high volatility
double riskRewardRatio = 2.0; // Risk/Reward ratio for take-profit
calculation
double atrVolatilityThreshold = 0.0008; // Threshold to determine high or
low volatility (adjusted for flexibility)
double minStopLossPoints = 10 * _Point; // Minimum stop loss to prevent
very tight stop loss
//--- Tracking last trade time to avoid overtrading
datetime lastTradeTime = 0;
int cooldownTime = 120; // Reduce cooldown time to 10 minutes for
higher trade frequency
//--- Volatility check variables
bool isHighVolatility = false; // Track volatility status
datetime nextVolatilityCheckTime = 0; // Track when to check volatility
again
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
// Initialize logging file (CSV)
fileHandle = FileOpen("TradeLog.csv", FILE_CSV | FILE_READ |
FILE_WRITE | FILE_SHARE_WRITE | FILE_SHARE_READ);
if (fileHandle > 0)
// Write headers to the log file
FileWrite(fileHandle,
"TradeID,Date,Time,Symbol,TradeType,EntryPrice,ExitPrice,ReasonEntry,Re
asonExit,P&L,ATR,RSI,SuperTrend,MACD,Duration,LotSize,Remarks");
// Print message confirming file has been opened
string filePath = TerminalInfoString(TERMINAL_DATA_PATH) + "\\
MQL5\\Files\\TradeLog.csv";
Print("Log file has been successfully opened at: ", filePath);
else
{
Print("Failed to open trade log file");
// Initialize RSI
rsiHandle = iRSI(_Symbol, Timeframe, RSI_Period, PRICE_CLOSE);
if (rsiHandle == INVALID_HANDLE)
Print("Failed to create RSI handle");
return(INIT_FAILED);
// Initialize SuperTrend (custom indicator)
superTrendHandle = iCustom(_Symbol, Timeframe, "SuperTrend
Indicator", SuperTrend_Multiplier);
if (superTrendHandle == INVALID_HANDLE)
Print("Failed to create SuperTrend handle");
return(INIT_FAILED);
// Initialize MACD
macdHandle = iMACD(_Symbol, Timeframe, MACD_FastPeriod,
MACD_SlowPeriod, MACD_SignalPeriod, PRICE_CLOSE);
if (macdHandle == INVALID_HANDLE)
Print("Failed to create MACD handle");
return(INIT_FAILED);
return(INIT_SUCCEEDED);
}
void OnDeinit(const int reason)
// If the file is open, close it and print the file path
if (fileHandle > 0)
FileClose(fileHandle);
// Get the terminal data path for where the file is stored
string filePath = TerminalInfoString(TERMINAL_DATA_PATH) + "\\
MQL5\\Files\\TradeLog.csv";
Print("Trading session finished. Log file saved at: ", filePath);
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
// Check if trading is paused and if the pause time has elapsed
if (isPaused)
if (TimeCurrent() < pauseEndTime)
Print("Trading paused due to consecutive losses. Resuming at: ",
TimeToString(pauseEndTime, TIME_DATE | TIME_MINUTES));
return; // Exit OnTick, skipping trading logic
}
else
Print("Resuming trading after pause");
isPaused = false;
consecutiveLosses = 0; // Reset consecutive losses count
// Ensure all handles are valid
if (superTrendHandle == INVALID_HANDLE || rsiHandle ==
INVALID_HANDLE || macdHandle == INVALID_HANDLE)
Print("One or more indicators failed to initialize.");
LogFailedTrade("Indicator Initialization Failure");
return;
// Check volatility based on scheduled intervals
if (TimeCurrent() >= nextVolatilityCheckTime)
double atrValue = GetATR(20, isHighVolatility);
if (atrValue > 0)
CheckVolatility(atrValue);
// Ensure trades are only processed within trading hours
if (!IsWithinTradingHours())
Print("Outside trading hours.");
return;
// Check if a new bar has formed (ensure we are not processing forming
bars)
static datetime lastBarTime = 0;
datetime newBarTime = iTime(_Symbol, Timeframe, 1);
if (newBarTime == lastBarTime) return;
lastBarTime = newBarTime; // Update with the latest completed bar
// Fetch indicator values for the last fully formed bar (index 1)
double rsiValue[1], superTrendValue[1];
double macdLine[1], signalLine[1];
// Fetch RSI for the last closed bar
if (CopyBuffer(rsiHandle, 0, 1, 1, rsiValue) <= 0)
Print("Failed to retrieve valid RSI value for previous bar.");
LogFailedTrade("RSI Indicator Failure");
return;
// Fetch SuperTrend for the last closed bar
if (CopyBuffer(superTrendHandle, 0, 1, 1, superTrendValue) <= 0)
Print("Failed to retrieve valid SuperTrend value for previous bar.");
LogFailedTrade("SuperTrend Indicator Failure");
return;
// Fetch MACD line and Signal line for the last closed bar
if (CopyBuffer(macdHandle, 0, 0, 1, macdLine) <= 0 ||
CopyBuffer(macdHandle, 1, 0, 1, signalLine) <= 0)
Print("Failed to retrieve valid MACD values.");
LogFailedTrade("MACD Indicator Failure");
return;
// Log ATR for debugging
double atrValue = GetATR(20, 2); // ATR used in trade decision
Print("Current ATR Value: ", atrValue);
// Define buy and sell signals
bool buySignal = false, sellSignal = false;
// Buy condition: RSI ≤ 45, SuperTrend is bullish, and MACD line crosses
above the signal line
if (rsiValue[0] <= 45 && superTrendValue[0] < iClose(_Symbol,
Timeframe, 1) && macdLine[0] > signalLine[0])
buySignal = true;
Print("Buy Signal: RSI <= 45, SuperTrend bullish, MACD cross above
signal line.");
}
// Sell condition: Fine-tuned for RSI ≥ 55, SuperTrend is bearish, and
MACD line crosses below the signal line
if (rsiValue[0] >= 55 && superTrendValue[0] > iClose(_Symbol,
Timeframe, 1) && macdLine[0] < signalLine[0])
sellSignal = true;
Print("Sell Signal: RSI >= 55, SuperTrend bearish, MACD cross below
signal line.");
// Avoid overtrading: check if 10 minutes have passed since the last
trade
if (TimeCurrent() - lastTradeTime < cooldownTime) // Cooldown adjusted
for higher trade frequency
Print("Overtrading protection activated. Waiting before placing new
trades.");
return;
// Execute trades based on signals
if (buySignal)
double stopLoss, takeProfit;
CalculateSLTP(atrValue, stopLoss, takeProfit); // Dynamic SL/TP based
on ATR
double lotSize = CalculateLotSize(stopLoss / _Point, isHighVolatility ?
HighRisk : LowRisk); // Lot size based on adjusted risk
Print("Executing Buy Trade: ATR = ", atrValue, ", SL = ", stopLoss, ",
TP = ", takeProfit);
if (OpenPosition(ORDER_TYPE_BUY, lotSize, stopLoss, takeProfit))
lastTradeTime = TimeCurrent(); // Update last trade time to avoid
overtrading
LogTrade("BUY", atrValue, stopLoss, takeProfit, "RSI <= 45,
SuperTrend bullish, MACD cross above signal line.");
else
LogFailedTrade("Buy Order Failed");
if (sellSignal)
double stopLoss, takeProfit;
CalculateSLTP(atrValue, stopLoss, takeProfit); // Dynamic SL/TP based
on ATR
double lotSize = CalculateLotSize(stopLoss / _Point, isHighVolatility ?
HighRisk : LowRisk); // Lot size based on adjusted risk
Print("Executing Sell Trade: ATR = ", atrValue, ", SL = ", stopLoss, ",
TP = ", takeProfit);
if (OpenPosition(ORDER_TYPE_SELL, lotSize, stopLoss, takeProfit))
lastTradeTime = TimeCurrent(); // Update last trade time to avoid
overtrading
LogTrade("SELL", atrValue, stopLoss, takeProfit, "RSI >= 55,
SuperTrend bearish, MACD cross below signal line.");
}
else
LogFailedTrade("Sell Order Failed");
void LogTrade(string tradeType, double atrValue, double stopLoss, double
takeProfit, string reason)
datetime currentTime = TimeCurrent();
MqlDateTime timeStruct;
TimeToStruct(currentTime, timeStruct);
double currentPrice = SymbolInfoDouble(_Symbol, SYMBOL_BID);
string date = TimeToString(currentTime, TIME_DATE);
string time = TimeToString(currentTime, TIME_MINUTES);
string symbol = _Symbol;
double profitLoss = 0.0; // Update this when you track profit/loss
// Write to file using the global fileHandle
if (fileHandle > 0)
FileWrite(fileHandle, timeStruct.day, date, time, symbol, tradeType,
currentPrice, stopLoss, takeProfit, reason, profitLoss, atrValue);
else
Print("File handle is invalid, unable to write to the file.");
}
void LogFailedTrade(string reason)
int errorCode = GetLastError(); // Get the error code
datetime currentTime = TimeCurrent();
MqlDateTime timeStruct;
TimeToStruct(currentTime, timeStruct);
string date = TimeToString(currentTime, TIME_DATE);
string time = TimeToString(currentTime, TIME_MINUTES);
string symbol = _Symbol;
// Write to file using the global fileHandle
if (fileHandle > 0)
FileWrite(fileHandle, "FAILED", date, time, symbol, "", "", "", reason +
" - Error Code: " + IntegerToString(errorCode), "", "", "", "");
else
Print("File handle is invalid, unable to write to the file.");
//+------------------------------------------------------------------+
//| ATR Calculation with Retry Mechanism |
//+------------------------------------------------------------------+
double GetATR(int period, bool highVolatility)
int atrHandle = iATR(_Symbol, Timeframe, period);
if (atrHandle == INVALID_HANDLE)
Print("Failed to create ATR handle");
return(0);
double atrValues[1];
if (CopyBuffer(atrHandle, 0, 0, 1, atrValues) > 0 &&
IsValidValue(atrValues[0]))
IndicatorRelease(atrHandle);
Print("ATR Value: ", atrValues[0], " for period: ", period); // Log ATR
value for debugging
return atrValues[0]; // Return valid ATR
Print("Failed to get valid ATR value.");
IndicatorRelease(atrHandle);
return(0);
//+------------------------------------------------------------------+
//| Volatility Check |
//+------------------------------------------------------------------+
void CheckVolatility(double atr)
if (atr > atrVolatilityThreshold)
{
if (!isHighVolatility)
Print("Volatility increased, entering high volatility mode.");
isHighVolatility = true;
// If high volatility, check less frequently (e.g., every 10 minutes)
nextVolatilityCheckTime = TimeCurrent() + 600;
else
if (isHighVolatility)
Print("Volatility decreased, entering low volatility mode.");
isHighVolatility = false;
// If low volatility, check more frequently (e.g., every minute)
nextVolatilityCheckTime = TimeCurrent() + 60;
//+------------------------------------------------------------------+
//| SL/TP Calculation Based on ATR |
//+------------------------------------------------------------------+
void CalculateSLTP(double atr, double &stopLoss, double &takeProfit)
if (isHighVolatility)
{
stopLoss = atr * atrStopLossMultiplierHighVolatility; // Increased SL
buffer during high volatility
takeProfit = atr * atrTakeProfitMultiplierHighVolatility; // Increased TP
multiplier for high volatility
else
stopLoss = atr * atrStopLossMultiplierLowVolatility; // Regular ATR-
based stop loss for low volatility
takeProfit = atr * atrTakeProfitMultiplierLowVolatility; // Increased TP
for low volatility
// Ensure stop loss is not too tight by setting a minimum value
if (stopLoss < minStopLossPoints)
stopLoss = minStopLossPoints;
Print("Stop Loss: ", stopLoss, ", Take Profit: ", takeProfit); // Debugging
logs
//+------------------------------------------------------------------+
//| Lot Size Calculation based on Risk Percentage |
//+------------------------------------------------------------------+
double CalculateLotSize(double slPoints, double riskPercentage)
double balance = AccountInfoDouble(ACCOUNT_BALANCE);
double riskAmount = balance * riskPercentage / 100.0;
double tickValue = SymbolInfoDouble(_Symbol,
SYMBOL_TRADE_TICK_VALUE);
double tickSize = SymbolInfoDouble(_Symbol,
SYMBOL_TRADE_TICK_SIZE);
double pointValue = tickValue / tickSize;
double lotSize = riskAmount / (slPoints * pointValue);
// Apply multiplier for high volatility to increase lot size significantly
if (isHighVolatility)
lotSize *= volatilityLotMultiplier;
double lotStep = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_STEP);
double minLot = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN);
double maxLot = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MAX);
lotSize = MathMax(minLot, MathFloor(lotSize / lotStep) * lotStep);
lotSize = MathMin(lotSize, maxLot);
Print("Calculated Lot Size: ", lotSize); // Debugging log for lot size
return(lotSize);
//+------------------------------------------------------------------+
//| Open Position Function |
//+------------------------------------------------------------------+
bool OpenPosition(ENUM_ORDER_TYPE orderType, double lotSize, double
stopLoss, double takeProfit)
{
// Get the price for the order type
double price = (orderType == ORDER_TYPE_BUY) ?
SymbolInfoDouble(_Symbol, SYMBOL_ASK) : SymbolInfoDouble(_Symbol,
SYMBOL_BID);
double slPrice = (orderType == ORDER_TYPE_BUY) ? price - stopLoss :
price + stopLoss;
double tpPrice = (orderType == ORDER_TYPE_BUY) ? price +
takeProfit : price - takeProfit;
MqlTradeRequest request;
MqlTradeResult result;
ZeroMemory(request);
ZeroMemory(result);
request.action = TRADE_ACTION_DEAL; // Immediate order execution
request.symbol = _Symbol;
request.type = orderType; // ENUM_ORDER_TYPE (BUY or SELL)
request.volume = lotSize;
request.price = price;
request.sl = slPrice;
request.tp = tpPrice;
request.deviation = Slippage;
request.magic = MagicNumber;
request.comment = "My EA Trade";
// Send the trade request
if (!OrderSend(request, result))
{
Print("OrderSend failed with error: ", GetLastError());
return false;
if (result.retcode == TRADE_RETCODE_DONE)
Print("Trade successful: Ticket ", result.order, ", SL: ", request.sl, ",
TP: ", request.tp);
return true;
else
Print("Trade failed: Retcode ", result.retcode);
return false;
//+------------------------------------------------------------------+
//| Validate Indicator Value |
//+------------------------------------------------------------------+
bool IsValidValue(double value)
return value != EMPTY_VALUE && value < 1e10 && value > -1e10;
//+------------------------------------------------------------------+
//| Trading Hours Check |
//+------------------------------------------------------------------+
bool IsWithinTradingHours()
{
// Use TimeCurrent() to get the current server time
datetime currentTime = TimeCurrent();
MqlDateTime timeStruct;
TimeToStruct(currentTime, timeStruct);
int currentHour = timeStruct.hour;
// Example: trade only between 00:00 and 24:00 (adjust as needed)
return (currentHour >= 0 && currentHour <= 23);
//+------------------------------------------------------------------+
//| OnTrade Event for Consecutive Losses Handling |
//+------------------------------------------------------------------+
void OnTradeTransaction(const MqlTradeTransaction &trans, const
MqlTradeRequest &request, const MqlTradeResult &result)
// Ensure we are dealing with a closed deal (transaction type related to
order history)
if (trans.type == TRADE_TRANSACTION_DEAL_ADD)
ulong dealTicket = trans.deal; // Get the deal ticket from the
transaction
double lastProfit = 0;
// Loop through the trade deals history to get the profit for the last
closed deal
for (int i = HistoryDealsTotal() - 1; i >= 0; i--)
{
ulong deal = HistoryDealGetTicket(i); // Get the deal ticket for
each closed deal
if (deal == dealTicket)
lastProfit = HistoryDealGetDouble(deal, DEAL_PROFIT); // Get
the profit of the closed deal
break;
// Check if the last trade was a loss
if (lastProfit < 0)
consecutiveLosses++;
Print("Trade loss detected. Consecutive losses: ",
consecutiveLosses);
else
consecutiveLosses = 0; // Reset consecutive losses if the trade
was profitable
// If consecutive losses exceed the max allowed, pause trading for 15
minutes
if (consecutiveLosses >= maxConsecutiveLosses)
isPaused = true;
pauseEndTime = TimeCurrent() + 900; // Pause for 15 minutes
(900 seconds)
Print("Pausing trading for 15 minutes due to consecutive losses.");
}