//+------------------------------------------------------------------+
//|               Information EA-MT5                                 |
//|               Copyright of Taube Adrian                          |
//|               Started- 19, August, 2024                          |
//|               Modified- 28, August, 2024                         |
//|               Further Modified- 25, September, 2024              |
//|               Further Modified- 02, October, 2024                |
//+------------------------------------------------------------------+
#property strict

// Input variables for customization
input int textX = 10;                      // X position on chart
input int textY = 10;                      // Y position on chart
input int textSize = 12;                   // Text size
input color textColor = clrWhite;          // Text color
input int lineSpacing = 15;                // Spacing between lines
input int timerInterval = 1;               // Timer interval in seconds

// Input for equity change notification threshold
input double equityChangeNotification = 500;  // Equity change (Up/Down) - Notification

// Variables to track maximum and minimum values
double maxDrawdown = 0;
double maxTemporaryProfit = 0;
double maxMargin = 0;
double maxEquity = 0;
double minEquity = 0;

// Variables for daily values
double dailyMaxDrawdown = 0;
double dailyMaxTemporaryProfit = 0;
double dailyMaxMargin = 0;
double dailyMaxEquity = 0;
double dailyMinEquity = 0;

// Variables to track equity changes for notifications
double initialEquity = 0;  // Track the starting equity when EA is installed

// Track the last known day to reset daily values after 12 AM broker time
int lastDay = 0;

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
   // Set the initial minEquity and daily values
   initialEquity = AccountInfoDouble(ACCOUNT_EQUITY);
   minEquity = initialEquity;
   ResetDailyValues();

   // Create text objects on the chart
   CreateTextLabel("MaxDrawdown", "Maximum Account Drawdown = 0", textX, textY);
   CreateTextLabel("DailyMaxDrawdown", "TODAY Maximum Account Drawdown = 0", textX, textY + lineSpacing);

   CreateTextLabel("MaxTempProfit", "Maximum Account Temporary Profit = 0", textX, textY + 2 * lineSpacing);
   CreateTextLabel("DailyMaxTempProfit", "TODAY Maximum Account Temporary Profit = 0", textX, textY + 3 * lineSpacing);

   CreateTextLabel("MaxMargin", "Maximum Account Margin = 0", textX, textY + 4 * lineSpacing);
   CreateTextLabel("DailyMaxMargin", "TODAY Maximum Account Margin = 0", textX, textY + 5 * lineSpacing);

   CreateTextLabel("MaxEquity", "Maximum Account Equity = 0", textX, textY + 6 * lineSpacing);
   CreateTextLabel("DailyMaxEquity", "TODAY Maximum Account Equity = 0", textX, textY + 7 * lineSpacing);

   CreateTextLabel("MinEquity", "Minimum Account Equity = 0", textX, textY + 8 * lineSpacing);
   CreateTextLabel("DailyMinEquity", "TODAY Minimum Account Equity = 0", textX, textY + 9 * lineSpacing);

   // Set a timer for regular updates
   EventSetTimer(timerInterval);

   // Initialize the lastDay variable to the current day
   lastDay = TimeDay(TimeCurrent());

   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
   // Delete the text objects when EA is removed
   ObjectDelete(0, "MaxDrawdown");
   ObjectDelete(0, "DailyMaxDrawdown");
   ObjectDelete(0, "MaxTempProfit");
   ObjectDelete(0, "DailyMaxTempProfit");
   ObjectDelete(0, "MaxMargin");
   ObjectDelete(0, "DailyMaxMargin");
   ObjectDelete(0, "MaxEquity");
   ObjectDelete(0, "DailyMaxEquity");
   ObjectDelete(0, "MinEquity");
   ObjectDelete(0, "DailyMinEquity");

   // Kill the timer on deinitialization
   EventKillTimer();
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
   static datetime lastTickTime = 0;
   if (TimeCurrent() - lastTickTime >= timerInterval)
     {
      UpdateAccountInfo();
      lastTickTime = TimeCurrent();
     }

   // Check for equity change notification
   double currentEquity = AccountInfoDouble(ACCOUNT_EQUITY);
   double equityChange = currentEquity - initialEquity;

   // Send a notification if the equity change exceeds the threshold (positive or negative)
   if (MathAbs(equityChange) >= equityChangeNotification)
     {
      // Determine if equity increased or decreased
      string changeDirection = (equityChange > 0.0) ? "UP" : "DOWN";

      // Get broker name and account type (LIVE=REAL or DEMO)
      string brokerName = AccountInfoString(ACCOUNT_COMPANY);
      string accountType = (AccountInfoInteger(ACCOUNT_TRADE_MODE) == ACCOUNT_TRADE_MODE_DEMO)
                           ? "DEMO"
                           : "LIVE=REAL";

      // Send notification
      string message = StringFormat(
          "Equity %s by %.2f %s.\n"                // Line 1: Equity change (UP or DOWN)
          "Current Equity = %.2f %s.\n"            // Line 2: Current equity
          "Broker: %s.\n"                          // Line 3: Broker name
          "Account: %s.",                          // Line 4: Account type (LIVE=REAL or DEMO)
          changeDirection,                         // Equity direction (UP or DOWN)
          MathAbs(equityChange),                   // Absolute value of equity change
          AccountInfoString(ACCOUNT_CURRENCY),     // Currency (e.g., USD)
          currentEquity,                           // Current equity value
          AccountInfoString(ACCOUNT_CURRENCY),     // Currency (e.g., USD)
          brokerName,                              // Broker name
          accountType                              // Account type (LIVE=REAL or DEMO)
      );
      SendNotification(message);

      // Reset the initial equity to the current equity for tracking further changes
      initialEquity = currentEquity;
     }

   // Reset daily values after 12 AM broker time
   CheckAndResetDailyValues();
  }
//+------------------------------------------------------------------+
//| Timer function for regular updates                               |
//+------------------------------------------------------------------+
void OnTimer()
  {
   UpdateAccountInfo();
  }
//+------------------------------------------------------------------+
//| Function to update account info and text labels                  |
//+------------------------------------------------------------------+
void UpdateAccountInfo()
  {
   // Get the account currency symbol
   string currencySymbol = AccountInfoString(ACCOUNT_CURRENCY);

   // Get current account values
   double equity = AccountInfoDouble(ACCOUNT_EQUITY);
   double balance = AccountInfoDouble(ACCOUNT_BALANCE);
   double margin = AccountInfoDouble(ACCOUNT_MARGIN);

   // Update maximum and minimum values
   double drawdownCurrency = balance - equity;
   double drawdownPercent = (balance > 0.0) ? (drawdownCurrency / balance) * 100.0 : 0.0;
   if (drawdownCurrency > maxDrawdown)
      maxDrawdown = drawdownCurrency;

   if (equity > maxEquity)
      maxEquity = equity;

   if (equity < minEquity)
      minEquity = equity;

   double tempProfitCurrency = equity - balance;
   double tempProfitPercent = (balance > 0.0) ? (tempProfitCurrency / balance) * 100.0 : 0.0;
   if (tempProfitCurrency > maxTemporaryProfit)
      maxTemporaryProfit = tempProfitCurrency;

   if (margin > maxMargin)
      maxMargin = margin;

   // Daily values
   if (drawdownCurrency > dailyMaxDrawdown)
      dailyMaxDrawdown = drawdownCurrency;

   if (equity > dailyMaxEquity)
      dailyMaxEquity = equity;

   if (equity < dailyMinEquity)
      dailyMinEquity = equity;

   if (tempProfitCurrency > dailyMaxTemporaryProfit)
      dailyMaxTemporaryProfit = tempProfitCurrency;

   if (margin > dailyMaxMargin)
      dailyMaxMargin = margin;

   // Calculate percentage values for display
   double maxMarginPercent = (balance > 0.0) ? (maxMargin / balance) * 100.0 : 0.0;
   double maxEquityPercent = (balance > 0.0) ? (maxEquity / balance) * 100.0 : 0.0;
   double minEquityPercent = (balance > 0.0) ? (minEquity / balance) * 100.0 : 0.0;

   // Update text labels with currency symbol
   ObjectSetString(0, "MaxDrawdown", OBJPROP_TEXT,
                   StringFormat("Maximum Account Drawdown = %.2f %s (%.2f%% of Balance)", maxDrawdown, currencySymbol, drawdownPercent));
   ObjectSetString(0, "DailyMaxDrawdown", OBJPROP_TEXT,
                   StringFormat("TODAY Maximum Account Drawdown = %.2f %s", dailyMaxDrawdown, currencySymbol));

   string tempProfitText = (maxTemporaryProfit > 0.0)
                           ? StringFormat("Maximum Account Temporary Profit = %.2f %s (%.2f%% of Balance)", maxTemporaryProfit, currencySymbol, tempProfitPercent)
                           : StringFormat("Maximum Account Temporary Profit = %.2f %s", maxTemporaryProfit, currencySymbol);

   ObjectSetString(0, "MaxTempProfit", OBJPROP_TEXT, tempProfitText);
   ObjectSetString(0, "DailyMaxTempProfit", OBJPROP_TEXT,
                   StringFormat("TODAY Maximum Account Temporary Profit = %.2f %s", dailyMaxTemporaryProfit, currencySymbol));

   ObjectSetString(0, "MaxMargin", OBJPROP_TEXT,
                   StringFormat("Maximum Account Margin = %.2f %s (%.2f%% of Balance)", maxMargin, currencySymbol, maxMarginPercent));
   ObjectSetString(0, "DailyMaxMargin", OBJPROP_TEXT,
                   StringFormat("TODAY Maximum Account Margin = %.2f %s", dailyMaxMargin, currencySymbol));

   ObjectSetString(0, "MaxEquity", OBJPROP_TEXT,
                   StringFormat("Maximum Account Equity = %.2f %s (%.2f%% of Balance)", maxEquity, currencySymbol, maxEquityPercent));
   ObjectSetString(0, "DailyMaxEquity", OBJPROP_TEXT,
                   StringFormat("TODAY Maximum Account Equity = %.2f %s", dailyMaxEquity, currencySymbol));

   ObjectSetString(0, "MinEquity", OBJPROP_TEXT,
                   StringFormat("Minimum Account Equity = %.2f %s (%.2f%% of Balance)", minEquity, currencySymbol, minEquityPercent));
   ObjectSetString(0, "DailyMinEquity", OBJPROP_TEXT,
                   StringFormat("TODAY Minimum Account Equity = %.2f %s", dailyMinEquity, currencySymbol));

   // Set font size and color for all labels
   SetTextProperties("MaxDrawdown");
   SetTextProperties("DailyMaxDrawdown");
   SetTextProperties("MaxTempProfit");
   SetTextProperties("DailyMaxTempProfit");
   SetTextProperties("MaxMargin");
   SetTextProperties("DailyMaxMargin");
   SetTextProperties("MaxEquity");
   SetTextProperties("DailyMaxEquity");
   SetTextProperties("MinEquity");
   SetTextProperties("DailyMinEquity");
  }
//+------------------------------------------------------------------+
//| Function to reset daily values                                   |
//+------------------------------------------------------------------+
void ResetDailyValues()
  {
   dailyMaxDrawdown = 0;
   dailyMaxTemporaryProfit = 0;
   dailyMaxMargin = 0;
   dailyMaxEquity = AccountInfoDouble(ACCOUNT_EQUITY);
   dailyMinEquity = AccountInfoDouble(ACCOUNT_EQUITY);
  }
//+------------------------------------------------------------------+
//| Function to create or update text label on the chart             |
//+------------------------------------------------------------------+
void CreateTextLabel(string name, string text, int x, int y)
  {
   if (!ObjectFind(0, name))
     {
      ObjectCreate(0, name, OBJ_LABEL, 0, 0, 0);
      ObjectSetInteger(0, name, OBJPROP_CORNER, CORNER_LEFT_UPPER);
      ObjectSetInteger(0, name, OBJPROP_XDISTANCE, x);
      ObjectSetInteger(0, name, OBJPROP_YDISTANCE, y);
     }
   ObjectSetString(0, name, OBJPROP_TEXT, text);
  }
//+------------------------------------------------------------------+
//| Function to set text properties for labels                       |
//+------------------------------------------------------------------+
void SetTextProperties(string name)
  {
   ObjectSetInteger(0, name, OBJPROP_COLOR, textColor);
   ObjectSetInteger(0, name, OBJPROP_FONTSIZE, textSize);
  }
//+------------------------------------------------------------------+
//| Function to check and reset daily values at 12 AM                |
//+------------------------------------------------------------------+
void CheckAndResetDailyValues()
  {
   datetime currentTime = TimeCurrent();
   int currentDay = TimeDay(currentTime);

   // If the day has changed (i.e., it's a new day), reset daily values
   if (currentDay != lastDay)
     {
      ResetDailyValues();
      lastDay = currentDay;
     }
  }
//+------------------------------------------------------------------+