//+------------------------------------------------------------------+
//|                                             CloseAllOnTarget.mq5 |
//|                                       Copyright © 2023, tidicofx |
//|                                               tidicofx@yahoo.com |
//|                                              developed for david |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2023, tidicofx"
#property link      "tidicofx@yahoo.com"
#define   Version   "1.00"
#property version   Version
#property strict
//+------------------------------------------------------------------+
#include <Trade\trade.mqh>
//+------------------------------------------------------------------+
#import "user32.dll"
int GetAncestor(int, int);
int PostMessageW(int hWnd,int Msg,int wParam,int lParam);
#import
#define MT4_WMCMD_EXPERTS  33020 
#define WM_COMMAND         0x0111
//+------------------------------------------------------------------+
#define  OP_BUY 0
#define  OP_SELL 1
#define  ERROR 9876543210
//+------------------------------------------------------------------+
//| Input Parameters Definition                                      |
//+------------------------------------------------------------------+
input bool CloseOnLoss = false;
input double LossAmountDollar = 0;
input double LossAmountPercent = 0;
input bool CloseOnProfit = false;
input double ProfitAmountDollar = 0;
input double ProfitAmountPercent = 0;
input bool DisableAutoTrading = false;
//+------------------------------------------------------------------+
//| Local Parameters Definition                                      |
//+------------------------------------------------------------------+
string lbl = "CAT.", gbl;
bool _res;
CTrade trade;
string sfont="Tahoma";
int isize=9;
//+------------------------------------------------------------------+
//| expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
{
  //------------------------------------------------------------------
  ChartSetInteger(0, CHART_FOREGROUND, false);
  EventSetTimer(1);
  //------------------------------------------------------------------
  return (INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
  //------------------------------------------------------------------
  EventKillTimer();
  if (reason==REASON_REMOVE || reason==REASON_RECOMPILE) ObjectsDeleteAll(0, lbl);
  Comment("");
  //------------------------------------------------------------------
}
//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+
void OnTimer()
{
  OnTick();
  ChartRedraw();
}
//+------------------------------------------------------------------+
void OnTick()
{
  //------------------------------------------------------------------
  if (CloseOnLoss && LossAmountDollar!=0 && AccountInfoDouble(ACCOUNT_PROFIT)<=-MathAbs(LossAmountDollar))
  {
    Print("try to close all orders on loss target dollar");
    CloseAllPositions();
  }
  else if (CloseOnLoss && LossAmountPercent!=0 && AccountInfoDouble(ACCOUNT_BALANCE)>0 && AccountInfoDouble(ACCOUNT_PROFIT)/AccountInfoDouble(ACCOUNT_BALANCE)*100<=-MathAbs(LossAmountPercent))
  {
    Print("try to close all orders on loss target percent");
    CloseAllPositions();
  }
  else if (CloseOnProfit && ProfitAmountDollar!=0 && AccountInfoDouble(ACCOUNT_PROFIT)>=ProfitAmountDollar)
  {
    Print("try to close all orders on profit target dollar");
    CloseAllPositions();
  }
  else if (CloseOnProfit && ProfitAmountPercent!=0 && AccountInfoDouble(ACCOUNT_BALANCE)>0 && AccountInfoDouble(ACCOUNT_PROFIT)/AccountInfoDouble(ACCOUNT_BALANCE)*100>=ProfitAmountDollar)
  {
    Print("try to close all orders on profit target dollar");
    CloseAllPositions();
  }
  string com="Close All V"+Version;
  com=com+"\n"+"Current PL: "+DoubleToString(AccountInfoDouble(ACCOUNT_PROFIT), 2);
  if (CloseOnLoss) com=com+"\n"+"Loss Target Dollar: "+DoubleToString(LossAmountDollar, 2);
  if (CloseOnLoss) com=com+"\n"+"Loss Target %: "+DoubleToString(LossAmountPercent, 2);
  if (CloseOnProfit) com=com+"\n"+"Profit Target Dollar: "+DoubleToString(ProfitAmountDollar, 2);
  if (CloseOnProfit) com=com+"\n"+"Profit Target %: "+DoubleToString(ProfitAmountPercent, 2);
  Comment(com);
  //------------------------------------------------------------------
}
//+------------------------------------------------------------------+
void CloseAllPositions()
{
  //------------------------------------------------------------------
  bool anyClosed=true; int j=0;
  while (anyClosed && j<100)
  {
    anyClosed=false;
    for (int i=PositionsTotal()-1; i>=0; i--)
    {
      //------------------------------------------------------------------
      ulong ticket=PositionGetTicket(i);
      _res=PositionSelectByTicket(ticket);
      //------------------------------------------------------------------
      trade.PositionClose(ticket);
      anyClosed=true;
      //------------------------------------------------------------------
    }
    j ++;
  }
  anyClosed=true; j=0;
  while (anyClosed && j<100)
  {
    anyClosed=false;
    for (int i=OrdersTotal()-1; i>=0; i--)
    {
      //------------------------------------------------------------------
      ulong ticket=OrderGetTicket(i);
      _res=OrderSelect(ticket);
      //------------------------------------------------------------------
      trade.OrderDelete(ticket);
      anyClosed=true;
      //------------------------------------------------------------------
    }
    j ++;
  }
  //------------------------------------------------------------------
  if (DisableAutoTrading)
  {
    int main=GetAncestor((int)ChartGetInteger(0, CHART_WINDOW_HANDLE), 2);
    PostMessageW(main, WM_COMMAND, MT4_WMCMD_EXPERTS, 0);
    ExpertRemove();
  }
  //------------------------------------------------------------------
}
//+------------------------------------------------------------------+
void DrawLabel(string name, string text, int x, int y, color col, ENUM_ANCHOR_POINT anchor)
{
  if (ObjectFind(0, name) == -1)
  {
    ObjectCreate(0, name, OBJ_LABEL, 0, 0, 0);
    ObjectSetInteger(0, name, OBJPROP_BACK, false);
    ObjectSetInteger(0, name, OBJPROP_SELECTED, false);
    ObjectSetInteger(0, name, OBJPROP_SELECTABLE, false);
    ObjectSetInteger(0, name, OBJPROP_HIDDEN, true);
    ObjectSetInteger(0, name, OBJPROP_CORNER, CORNER_LEFT_UPPER);
    ObjectSetInteger(0, name, OBJPROP_ANCHOR, anchor);
    ObjectSetInteger(0, name, OBJPROP_ZORDER, 2);
  }
  if (ObjectGetInteger(0, name, OBJPROP_COLOR) != col) ObjectSetInteger(0, name, OBJPROP_COLOR, col);
  if (ObjectGetInteger(0, name, OBJPROP_XDISTANCE) != x) ObjectSetInteger(0, name, OBJPROP_XDISTANCE, x);
  if (ObjectGetInteger(0, name, OBJPROP_YDISTANCE) != y) ObjectSetInteger(0, name, OBJPROP_YDISTANCE, y);
  ObjectSetString(0, name, OBJPROP_FONT, sfont);
  ObjectSetInteger(0, name, OBJPROP_FONTSIZE, isize);
  ObjectSetString(0, name, OBJPROP_TEXT, text);
  ObjectSetInteger(0, name, OBJPROP_ANCHOR, anchor);
}
//+------------------------------------------------------------------+
void DrawPanel(string name, int left, int top, int width, int height, color fill, color cborder, ENUM_BORDER_TYPE border = BORDER_SUNKEN)
{
  if (ObjectFind(0, name) == -1)
  {
    ObjectCreate(0, name, OBJ_RECTANGLE_LABEL, 0, 0, 0);
    ObjectSetInteger(0, name, OBJPROP_CORNER, 0);
    ObjectSetInteger(0, name, OBJPROP_XSIZE, width);
    ObjectSetInteger(0, name, OBJPROP_YSIZE, height);
    ObjectSetInteger(0, name, OBJPROP_BGCOLOR, fill);
    ObjectSetInteger(0, name, OBJPROP_BORDER_TYPE, border);
    ObjectSetInteger(0, name, OBJPROP_COLOR, cborder);
    ObjectSetInteger(0, name, OBJPROP_STYLE, STYLE_SOLID);
    ObjectSetInteger(0, name, OBJPROP_WIDTH, 1);
    ObjectSetInteger(0, name, OBJPROP_BACK, false);
    ObjectSetInteger(0, name, OBJPROP_HIDDEN, true);
    ObjectSetInteger(0, name, OBJPROP_SELECTABLE, false);
  }
  ObjectSetInteger(0, name, OBJPROP_XDISTANCE, left);
  ObjectSetInteger(0, name, OBJPROP_YDISTANCE, top);
}
//+------------------------------------------------------------------+
void DrawButton(string name, string text, int left, int top, int width, int height, color fore, color fill, color border, int zorder=10)
{
  if (ObjectFind(0, name) == -1)
  {
    ObjectCreate(0, name, OBJ_BUTTON, 0, 0, 0);
    ObjectSetInteger(0, name, OBJPROP_CORNER, 0);
    ObjectSetInteger(0, name, OBJPROP_XSIZE, width);
    ObjectSetInteger(0, name, OBJPROP_YSIZE, height);
    ObjectSetInteger(0, name, OBJPROP_HIDDEN, true);
    ObjectSetInteger(0, name, OBJPROP_SELECTABLE, false);
    ObjectSetString(0, name, OBJPROP_FONT, sfont);
    ObjectSetInteger(0, name, OBJPROP_FONTSIZE, isize);
    ObjectSetInteger(0, name, OBJPROP_BGCOLOR, fill);
    ObjectSetInteger(0, name, OBJPROP_BORDER_COLOR, border);
    ObjectSetInteger(0, name, OBJPROP_BACK, false);
    ObjectSetInteger(0, name, OBJPROP_STATE, false);
    ObjectSetInteger(0, name, OBJPROP_ZORDER, zorder);
  }
  ObjectSetInteger(0, name, OBJPROP_COLOR, fore);
  ObjectSetInteger(0, name, OBJPROP_BGCOLOR, fill);
  ObjectSetInteger(0, name, OBJPROP_BORDER_COLOR, border);
  if (text=="-0") text = "0";
  ObjectSetString(0, name, OBJPROP_TEXT, text);
  ObjectSetInteger(0, name, OBJPROP_XDISTANCE, left);
  ObjectSetInteger(0, name, OBJPROP_YDISTANCE, top);
}
//+------------------------------------------------------------------+
void StringSplit2(string InputString, string &ResultArray[], string Separator)
{
  ArrayResize(ResultArray, 0);
  int lenSeparator = StringLen(Separator), NewArraySize;
  while (InputString != "") {
    int p = StringFind(InputString, Separator);
    if (p == -1) {
      NewArraySize = ArraySize(ResultArray) + 1;
      ArrayResize(ResultArray, NewArraySize);      
      ResultArray[NewArraySize - 1] = InputString;
      InputString = "";
    } else {
      NewArraySize = ArraySize(ResultArray) + 1;
      ArrayResize(ResultArray, NewArraySize);      
      ResultArray[NewArraySize - 1] = StringSubstr(InputString, 0, p);
      InputString = StringSubstr(InputString, p + lenSeparator);
      if (InputString == "") {
         ArrayResize(ResultArray, NewArraySize + 1);      
         ResultArray[NewArraySize] = "";
      }
    }     
  }
}
//+------------------------------------------------------------------+
void SetText(string name, string text)
{
  if (ObjectFind(0, name) != -1) ObjectSetString(0, name, OBJPROP_TEXT, text);
}
//+------------------------------------------------------------------+
string GetText(string name)
{
  if (ObjectFind(0, name) != -1) return (ObjectGetString(0, name, OBJPROP_TEXT));
  return ("");
}
//+------------------------------------------------------------------+
string GetOrderTypeName(int type)
{
  if (type == OP_BUY) return ("Buy");
  else if (type == OP_SELL) return ("Sell");
  else return("None");
}
//+------------------------------------------------------------------+
