0% found this document useful (0 votes)
13 views21 pages

My Trading EA

The document outlines the code for a trading expert advisor (EA) in MQL5, which implements a strategy based on multiple indicators including RSI, SuperTrend, and MACD. It includes parameters for risk management, trade execution, and logging of trades, with specific handling for high and low volatility conditions. The EA features mechanisms to pause trading after consecutive losses and dynamically adjusts stop-loss and take-profit levels based on market volatility.

Uploaded by

ibraheim811
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
13 views21 pages

My Trading EA

The document outlines the code for a trading expert advisor (EA) in MQL5, which implements a strategy based on multiple indicators including RSI, SuperTrend, and MACD. It includes parameters for risk management, trade execution, and logging of trades, with specific handling for high and low volatility conditions. The EA features mechanisms to pause trading after consecutive losses and dynamically adjusts stop-loss and take-profit levels based on market volatility.

Uploaded by

ibraheim811
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 21

//+------------------------------------------------------------------+

//| 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.");


}

You might also like