#property copyright "Your Name"
#property link      "https://x.com"
#property version   "1.00"
#property strict
#property description "EA with GUI buttons for Long/Short orders, editable lot sizes, and Close All functionality"

// Input parameters for lot sizes
input double LotSize1 = 0.10; // Lot Size for Button 1
input double LotSize2 = 0.20; // Lot Size for Button 2
input double LotSize3 = 0.30; // Lot Size for Button 3
input double LotStep = 0.01;  // Lot Size Increment/Decrement Step

// Global variables
double PointValue;          // Adjusted point value for 4/5-digit brokers
string PanelPrefix = "TradePanel_";
double CurrentLot1, CurrentLot2, CurrentLot3; // Dynamic lot sizes

// Function to initialize the EA
void OnInit()
{
   // Adjust for 4 or 5-digit brokers
   PointValue = MarketInfo(Symbol(), MODE_POINT);
   if(MarketInfo(Symbol(), MODE_DIGITS) == 5 || MarketInfo(Symbol(), MODE_DIGITS) == 3)
      PointValue *= 10;

   // Initialize dynamic lot sizes
   CurrentLot1 = LotSize1;
   CurrentLot2 = LotSize2;
   CurrentLot3 = LotSize3;

   // Create the graphical panel
   CreatePanel();
}

// Function to handle deinitialization (cleanup)
void OnDeinit(const int reason)
{
   // Remove all objects created by the EA
   ObjectsDeleteAll(0, PanelPrefix);
}

// Function to create the graphical panel
void CreatePanel()
{
   // Define button and edit field properties
   int buttonWidth = 100;
   int buttonHeight = 30;
   int editWidth = 60;
   int editHeight = 20;
   int smallButtonWidth = 20;
   int xStart = 10;
   int yStart = 100; // Adjusted to drop buttons lower
   int spacing = 5;

   // Long Order Buttons and Edit Fields
   CreateButton(PanelPrefix + "Long1", "Long " + DoubleToString(CurrentLot1, 2), xStart, yStart, buttonWidth, buttonHeight, clrLime);
   CreateEdit(PanelPrefix + "EditLot1", DoubleToString(CurrentLot1, 2), xStart, yStart + buttonHeight + spacing, editWidth, editHeight);
   CreateButton(PanelPrefix + "Plus1", "+", xStart + editWidth + spacing, yStart + buttonHeight + spacing, smallButtonWidth, editHeight, clrGreen);
   CreateButton(PanelPrefix + "Minus1", "-", xStart + editWidth + 2 * spacing + smallButtonWidth, yStart + buttonHeight + spacing, smallButtonWidth, editHeight, clrRed);

   CreateButton(PanelPrefix + "Long2", "Long " + DoubleToString(CurrentLot2, 2), xStart, yStart + (buttonHeight + editHeight + 2 * spacing), buttonWidth, buttonHeight, clrYellow);
   CreateEdit(PanelPrefix + "EditLot2", DoubleToString(CurrentLot2, 2), xStart, yStart + 2 * buttonHeight + editHeight + 3 * spacing, editWidth, editHeight);
   CreateButton(PanelPrefix + "Plus2", "+", xStart + editWidth + spacing, yStart + 2 * buttonHeight + editHeight + 3 * spacing, smallButtonWidth, editHeight, clrGreen);
   CreateButton(PanelPrefix + "Minus2", "-", xStart + editWidth + 2 * spacing + smallButtonWidth, yStart + 2 * buttonHeight + editHeight + 3 * spacing, smallButtonWidth, editHeight, clrRed);

   CreateButton(PanelPrefix + "Long3", "Long " + DoubleToString(CurrentLot3, 2), xStart, yStart + 2 * (buttonHeight + editHeight + 2 * spacing), buttonWidth, buttonHeight, clrAqua);
   CreateEdit(PanelPrefix + "EditLot3", DoubleToString(CurrentLot3, 2), xStart, yStart + 3 * buttonHeight + 2 * editHeight + 4 * spacing, editWidth, editHeight);
   CreateButton(PanelPrefix + "Plus3", "+", xStart + editWidth + spacing, yStart + 3 * buttonHeight + 2 * editHeight + 4 * spacing, smallButtonWidth, editHeight, clrGreen);
   CreateButton(PanelPrefix + "Minus3", "-", xStart + editWidth + 2 * spacing + smallButtonWidth, yStart + 3 * buttonHeight + 2 * editHeight + 4 * spacing, smallButtonWidth, editHeight, clrRed);

   // Short Order Buttons and Edit Fields
   CreateButton(PanelPrefix + "Short1", "Short " + DoubleToString(CurrentLot1, 2), xStart + buttonWidth + spacing, yStart, buttonWidth, buttonHeight, clrRed);
   CreateEdit(PanelPrefix + "EditShortLot1", DoubleToString(CurrentLot1, 2), xStart + buttonWidth + spacing, yStart + buttonHeight + spacing, editWidth, editHeight);
   CreateButton(PanelPrefix + "ShortPlus1", "+", xStart + buttonWidth + editWidth + 2 * spacing, yStart + buttonHeight + spacing, smallButtonWidth, editHeight, clrGreen);
   CreateButton(PanelPrefix + "ShortMinus1", "-", xStart + buttonWidth + editWidth + 3 * spacing + smallButtonWidth, yStart + buttonHeight + spacing, smallButtonWidth, editHeight, clrRed);

   CreateButton(PanelPrefix + "Short2", "Short " + DoubleToString(CurrentLot2, 2), xStart + buttonWidth + spacing, yStart + (buttonHeight + editHeight + 2 * spacing), buttonWidth, buttonHeight, clrOrange);
   CreateEdit(PanelPrefix + "EditShortLot2", DoubleToString(CurrentLot2, 2), xStart + buttonWidth + spacing, yStart + 2 * buttonHeight + editHeight + 3 * spacing, editWidth, editHeight);
   CreateButton(PanelPrefix + "ShortPlus2", "+", xStart + buttonWidth + editWidth + 2 * spacing, yStart + 2 * buttonHeight + editHeight + 3 * spacing, smallButtonWidth, editHeight, clrGreen);
   CreateButton(PanelPrefix + "ShortMinus2", "-", xStart + buttonWidth + editWidth + 3 * spacing + smallButtonWidth, yStart + 2 * buttonHeight + editHeight + 3 * spacing, smallButtonWidth, editHeight, clrRed);

   CreateButton(PanelPrefix + "Short3", "Short " + DoubleToString(CurrentLot3, 2), xStart + buttonWidth + spacing, yStart + 2 * (buttonHeight + editHeight + 2 * spacing), buttonWidth, buttonHeight, clrPink);
   CreateEdit(PanelPrefix + "EditShortLot3", DoubleToString(CurrentLot3, 2), xStart + buttonWidth + spacing, yStart + 3 * buttonHeight + 2 * editHeight + 4 * spacing, editWidth, editHeight);
   CreateButton(PanelPrefix + "ShortPlus3", "+", xStart + buttonWidth + editWidth + 2 * spacing, yStart + 3 * buttonHeight + 2 * editHeight + 4 * spacing, smallButtonWidth, editHeight, clrGreen);
   CreateButton(PanelPrefix + "ShortMinus3", "-", xStart + buttonWidth + editWidth + 3 * spacing + smallButtonWidth, yStart + 3 * buttonHeight + 2 * editHeight + 4 * spacing, smallButtonWidth, editHeight, clrRed);

   // Close All Button
   CreateButton(PanelPrefix + "CloseAll", "Close All", xStart, yStart + 3 * (buttonHeight + editHeight + 2 * spacing), buttonWidth * 2 + spacing, buttonHeight, clrGray);
}

// Function to create a button
void CreateButton(string name, string text, int x, int y, int width, int height, color bgColor)
{
   ObjectCreate(0, name, OBJ_BUTTON, 0, 0, 0);
   ObjectSetInteger(0, name, OBJPROP_XDISTANCE, x);
   ObjectSetInteger(0, name, OBJPROP_YDISTANCE, y);
   ObjectSetInteger(0, name, OBJPROP_XSIZE, width);
   ObjectSetInteger(0, name, OBJPROP_YSIZE, height);
   ObjectSetString(0, name, OBJPROP_TEXT, text);
   ObjectSetInteger(0, name, OBJPROP_COLOR, clrBlack);
   ObjectSetInteger(0, name, OBJPROP_BGCOLOR, bgColor);
   ObjectSetInteger(0, name, OBJPROP_BORDER_COLOR, clrBlack);
   ObjectSetInteger(0, name, OBJPROP_FONTSIZE, 10);
}

// Function to create an edit field
void CreateEdit(string name, string text, int x, int y, int width, int height)
{
   ObjectCreate(0, name, OBJ_EDIT, 0, 0, 0);
   ObjectSetInteger(0, name, OBJPROP_XDISTANCE, x);
   ObjectSetInteger(0, name, OBJPROP_YDISTANCE, y);
   ObjectSetInteger(0, name, OBJPROP_XSIZE, width);
   ObjectSetInteger(0, name, OBJPROP_YSIZE, height);
   ObjectSetString(0, name, OBJPROP_TEXT, text);
   ObjectSetInteger(0, name, OBJPROP_COLOR, clrBlack);
   ObjectSetInteger(0, name, OBJPROP_BGCOLOR, clrWhite);
   ObjectSetInteger(0, name, OBJPROP_BORDER_COLOR, clrBlack);
   ObjectSetInteger(0, name, OBJPROP_FONTSIZE, 10);
   ObjectSetInteger(0, name, OBJPROP_ALIGN, ALIGN_CENTER);
}

// Function to update button labels
void UpdateButtonLabels()
{
   ObjectSetString(0, PanelPrefix + "Long1", OBJPROP_TEXT, "Long " + DoubleToString(CurrentLot1, 2));
   ObjectSetString(0, PanelPrefix + "Long2", OBJPROP_TEXT, "Long " + DoubleToString(CurrentLot2, 2));
   ObjectSetString(0, PanelPrefix + "Long3", OBJPROP_TEXT, "Long " + DoubleToString(CurrentLot3, 2));
   ObjectSetString(0, PanelPrefix + "Short1", OBJPROP_TEXT, "Short " + DoubleToString(CurrentLot1, 2));
   ObjectSetString(0, PanelPrefix + "Short2", OBJPROP_TEXT, "Short " + DoubleToString(CurrentLot2, 2));
   ObjectSetString(0, PanelPrefix + "Short3", OBJPROP_TEXT, "Short " + DoubleToString(CurrentLot3, 2));
}

// Function to handle chart events (button clicks and edit field changes)
void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam)
{
   if(id == CHARTEVENT_OBJECT_CLICK)
   {
      // Long Order Buttons
      if(sparam == PanelPrefix + "Long1") OpenOrder(OP_BUY, CurrentLot1);
      if(sparam == PanelPrefix + "Long2") OpenOrder(OP_BUY, CurrentLot2);
      if(sparam == PanelPrefix + "Long3") OpenOrder(OP_BUY, CurrentLot3);

      // Short Order Buttons
      if(sparam == PanelPrefix + "Short1") OpenOrder(OP_SELL, CurrentLot1);
      if(sparam == PanelPrefix + "Short2") OpenOrder(OP_SELL, CurrentLot2);
      if(sparam == PanelPrefix + "Short3") OpenOrder(OP_SELL, CurrentLot3);

      // Close All Button
      if(sparam == PanelPrefix + "CloseAll") CloseAllOrders();

      // Plus/Minus Buttons for Long
      if(sparam == PanelPrefix + "Plus1") AdjustLotSize(1, LotStep);
      if(sparam == PanelPrefix + "Minus1") AdjustLotSize(1, -LotStep);
      if(sparam == PanelPrefix + "Plus2") AdjustLotSize(2, LotStep);
      if(sparam == PanelPrefix + "Minus2") AdjustLotSize(2, -LotStep);
      if(sparam == PanelPrefix + "Plus3") AdjustLotSize(3, LotStep);
      if(sparam == PanelPrefix + "Minus3") AdjustLotSize(3, -LotStep);

      // Plus/Minus Buttons for Short
      if(sparam == PanelPrefix + "ShortPlus1") AdjustLotSize(1, LotStep);
      if(sparam == PanelPrefix + "ShortMinus1") AdjustLotSize(1, -LotStep);
      if(sparam == PanelPrefix + "ShortPlus2") AdjustLotSize(2, LotStep);
      if(sparam == PanelPrefix + "ShortMinus2") AdjustLotSize(2, -LotStep);
      if(sparam == PanelPrefix + "ShortPlus3") AdjustLotSize(3, LotStep);
      if(sparam == PanelPrefix + "ShortMinus3") AdjustLotSize(3, -LotStep);
   }
   else if(id == CHARTEVENT_OBJECT_ENDEDIT)
   {
      // Handle edit field changes
      if(sparam == PanelPrefix + "EditLot1" || sparam == PanelPrefix + "EditShortLot1")
      {
         double newLot = StringToDouble(ObjectGetString(0, sparam, OBJPROP_TEXT));
         if(ValidateLotSize(newLot)) CurrentLot1 = NormalizeDouble(newLot, 2);
         ObjectSetString(0, PanelPrefix + "EditLot1", OBJPROP_TEXT, DoubleToString(CurrentLot1, 2));
         ObjectSetString(0, PanelPrefix + "EditShortLot1", OBJPROP_TEXT, DoubleToString(CurrentLot1, 2));
         UpdateButtonLabels();
      }
      if(sparam == PanelPrefix + "EditLot2" || sparam == PanelPrefix + "EditShortLot2")
      {
         double newLot = StringToDouble(ObjectGetString(0, sparam, OBJPROP_TEXT));
         if(ValidateLotSize(newLot)) CurrentLot2 = NormalizeDouble(newLot, 2);
         ObjectSetString(0, PanelPrefix + "EditLot2", OBJPROP_TEXT, DoubleToString(CurrentLot2, 2));
         ObjectSetString(0, PanelPrefix + "EditShortLot2", OBJPROP_TEXT, DoubleToString(CurrentLot2, 2));
         UpdateButtonLabels();
      }
      if(sparam == PanelPrefix + "EditLot3" || sparam == PanelPrefix + "EditShortLot3")
      {
         double newLot = StringToDouble(ObjectGetString(0, sparam, OBJPROP_TEXT));
         if(ValidateLotSize(newLot)) CurrentLot3 = NormalizeDouble(newLot, 2);
         ObjectSetString(0, PanelPrefix + "EditLot3", OBJPROP_TEXT, DoubleToString(CurrentLot3, 2));
         ObjectSetString(0, PanelPrefix + "EditShortLot3", OBJPROP_TEXT, DoubleToString(CurrentLot3, 2));
         UpdateButtonLabels();
      }
   }
}

// Function to adjust lot size
void AdjustLotSize(int index, double step)
{
   double minLot = MarketInfo(Symbol(), MODE_MINLOT);
   double maxLot = MarketInfo(Symbol(), MODE_MAXLOT);
   double newLot;

   if(index == 1)
   {
      newLot = NormalizeDouble(CurrentLot1 + step, 2);
      if(ValidateLotSize(newLot))
      {
         CurrentLot1 = newLot;
         ObjectSetString(0, PanelPrefix + "EditLot1", OBJPROP_TEXT, DoubleToString(CurrentLot1, 2));
         ObjectSetString(0, PanelPrefix + "EditShortLot1", OBJPROP_TEXT, DoubleToString(CurrentLot1, 2));
      }
   }
   else if(index == 2)
   {
      newLot = NormalizeDouble(CurrentLot2 + step, 2);
      if(ValidateLotSize(newLot))
      {
         CurrentLot2 = newLot;
         ObjectSetString(0, PanelPrefix + "EditLot2", OBJPROP_TEXT, DoubleToString(CurrentLot2, 2));
         ObjectSetString(0, PanelPrefix + "EditShortLot2", OBJPROP_TEXT, DoubleToString(CurrentLot2, 2));
      }
   }
   else if(index == 3)
   {
      newLot = NormalizeDouble(CurrentLot3 + step, 2);
      if(ValidateLotSize(newLot))
      {
         CurrentLot3 = newLot;
         ObjectSetString(0, PanelPrefix + "EditLot3", OBJPROP_TEXT, DoubleToString(CurrentLot3, 2));
         ObjectSetString(0, PanelPrefix + "EditShortLot3", OBJPROP_TEXT, DoubleToString(CurrentLot3, 2));
      }
   }
   UpdateButtonLabels();
}

// Function to validate lot size
bool ValidateLotSize(double lotSize)
{
   double minLot = MarketInfo(Symbol(), MODE_MINLOT);
   double maxLot = MarketInfo(Symbol(), MODE_MAXLOT);
   if(lotSize < minLot || lotSize > maxLot)
   {
      Print("Invalid lot size: ", lotSize, ". Min: ", minLot, ", Max: ", maxLot);
      return false;
   }
   return true;
}

// Function to open a market order
void OpenOrder(int orderType, double lotSize)
{
   double price = (orderType == OP_BUY) ? MarketInfo(Symbol(), MODE_ASK) : MarketInfo(Symbol(), MODE_BID);
   double sl = 0.0, tp = 0.0; // No stop-loss or take-profit for simplicity
   int ticket = -1;

   // Validate lot size
   if(!ValidateLotSize(lotSize)) return;

   // Send order
   ticket = OrderSend(Symbol(), orderType, lotSize, price, 3, sl, tp, "TradePanel Order", 0, 0, clrBlue);
   if(ticket < 0)
      Print("OrderSend failed with error #", GetLastError());
   else
      Print("Order placed successfully, ticket: ", ticket);
}

// Function to close all open orders
void CloseAllOrders()
{
   for(int i = OrdersTotal() - 1; i >= 0; i--)
   {
      if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
      {
         if(OrderSymbol() == Symbol())
         {
            double price = (OrderType() == OP_BUY) ? MarketInfo(Symbol(), MODE_BID) : MarketInfo(Symbol(), MODE_ASK);
            if(!OrderClose(OrderTicket(), OrderLots(), price, 3, clrRed))
               Print("OrderClose failed with error #", GetLastError());
         }
      }
   }
   Print("All orders closed.");
}

// Main tick function (not used in this EA, but required)
void OnTick()
{
   // No action needed on each tick
}