NEW VERSION: CloseByHighWaterMark2.03
Added:
(1) Calc Stop to panel,
(2) Locked In Win/Loss to panel
(3) Support for push notifications to MQID every onTimer (550)
(4) EA will send another Push notification upon completion of Close All
//+------------------------------------------------------------------+ //| CloseByHighWaterMark.mq5 | //| Copyright 2025, MetaQuotes Ltd. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2025, MetaQuotes Ltd." #property link "https://www.mql5.com" #property version "1.00" #property strict #include <Trade/Trade.mqh> CPositionInfo m_position; CTrade m_trade; // HUD input bool HUD_Enable = true; input int HUD_X = 8; input int HUD_Y = 24; input int HUD_W = 400; input int HUD_H = 200; input double percentofHWMtrigger = 0.975; double hwmvalue = 0.0; int closealreadyflag = 0; double eqt = 0.0; double bl = 0.0; double calculatedstop = 0.0; double winloss = 0.0; ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void CloseAll() { for(int i = PositionsTotal() - 1; i >= 0; i--) // loop all Open Positions if (m_position.SelectByIndex(i)) // select a position { m_trade.PositionClose(m_position.Ticket()); // then close it --period Sleep(100); // Relax for 100 ms //ChartWrite("Positions", "Positions " + (string)PositionsTotal(), 100, 80, 20, PositionsColor); //Re write number of positions on the chart } ObjectDelete(0, "Positions"); //delete a Position Object } //=========================== HUD (on-chart) ========================// #define HUD_PREFIX "FiboHUD_" string HUD_BG = HUD_PREFIX+"BG"; string HUD_CAP = HUD_PREFIX+"Cap"; string HUD_VAL = HUD_PREFIX+"Val"; string HUD_UP = HUD_PREFIX+"Up"; string HUD_DN = HUD_PREFIX+"Dn"; string HUD_EDIT = HUD_PREFIX+"Edit"; string HUD_DIR = HUD_PREFIX+"Dir"; void HUD_Destroy(){ string objs[]={HUD_BG,HUD_CAP,HUD_VAL,HUD_UP,HUD_DN,HUD_EDIT,HUD_DIR}; for(int i=0;i<ArraySize(objs);++i) ObjectDelete(0,objs[i]); } void HUD_UpdateText() { if(!HUD_Enable) return; //if(ObjectFind(0,HUD_VAL)>=0) ObjectSetString(0,HUD_CAP,OBJPROP_TEXT,"HWM: "+ hwmvalue); ObjectSetString(0,HUD_VAL,OBJPROP_TEXT,"Calc Stop: "+ calculatedstop); ObjectSetString(0,HUD_UP,OBJPROP_TEXT,"Locked In Win/Loss: "+ winloss); //if(ObjectFind(0,HUD_EDIT)>=0) ObjectSetString(0,HUD_EDIT,OBJPROP_TEXT,LotsStr()); // if(ObjectFind(0,HUD_DIR)>=0) // { // int dir = PositionDirection(); // string dtxt = (dir>0 ? "Long" : dir<0 ? "Short" : "Flat"); // string dtxt = (objectCounter); // color dcol = (dir>0 ? clrLime : dir<0 ? clrTomato : clrSilver); // ObjectSetString (0,HUD_DIR,OBJPROP_TEXT,"Dir: "+dtxt); // ObjectSetInteger(0,HUD_DIR,OBJPROP_COLOR,dcol); // } } void HUD_Create() { if(!HUD_Enable){ HUD_Destroy(); return; } if(ObjectFind(0,HUD_BG)<0) { ObjectCreate(0,HUD_BG,OBJ_RECTANGLE_LABEL,0,0,0); ObjectSetInteger(0,HUD_BG,OBJPROP_XDISTANCE,HUD_X); ObjectSetInteger(0,HUD_BG,OBJPROP_YDISTANCE,HUD_Y); ObjectSetInteger(0,HUD_BG,OBJPROP_XSIZE,HUD_W); ObjectSetInteger(0,HUD_BG,OBJPROP_YSIZE,HUD_H); ObjectSetInteger(0,HUD_BG,OBJPROP_BGCOLOR,clrBlack); ObjectSetInteger(0,HUD_BG,OBJPROP_COLOR,clrBlack); ObjectSetInteger(0,HUD_BG,OBJPROP_FILL,true); ObjectSetInteger(0,HUD_BG,OBJPROP_CORNER,CORNER_LEFT_UPPER); } if(ObjectFind(0,HUD_CAP)<0) { ObjectCreate(0,HUD_CAP,OBJ_LABEL,0,0,0); ObjectSetInteger(0,HUD_CAP,OBJPROP_CORNER,CORNER_LEFT_UPPER); ObjectSetInteger(0,HUD_CAP,OBJPROP_XDISTANCE,HUD_X+10); ObjectSetInteger(0,HUD_CAP,OBJPROP_YDISTANCE,HUD_Y+5); ObjectSetString(0,HUD_CAP,OBJPROP_TEXT,"HWM: "+ hwmvalue); ////////////////////////////////////////////////////////////////////////////// ObjectSetInteger(0,HUD_CAP,OBJPROP_COLOR,clrWhite); ObjectSetInteger(0,HUD_CAP,OBJPROP_FONTSIZE,10); ObjectSetString(0,HUD_CAP,OBJPROP_FONT,"Arial"); } if(ObjectFind(0,HUD_VAL)<0) { ObjectCreate(0,HUD_VAL,OBJ_LABEL,0,0,0); ObjectSetInteger(0,HUD_VAL,OBJPROP_CORNER,CORNER_LEFT_UPPER); ObjectSetInteger(0,HUD_VAL,OBJPROP_XDISTANCE,HUD_X+10); ObjectSetInteger(0,HUD_VAL,OBJPROP_YDISTANCE,HUD_Y+25); ObjectSetString(0,HUD_VAL,OBJPROP_TEXT,"Calc Stop: "+ calculatedstop); ////////////////////////////////////////////////////////////////////////////// ObjectSetInteger(0,HUD_VAL,OBJPROP_COLOR,clrWhite); ObjectSetInteger(0,HUD_VAL,OBJPROP_FONTSIZE,10); ObjectSetString(0,HUD_VAL,OBJPROP_FONT,"Arial"); } if(ObjectFind(0,HUD_UP)<0) { ObjectCreate(0,HUD_UP,OBJ_LABEL,0,0,0); ObjectSetInteger(0,HUD_UP,OBJPROP_CORNER,CORNER_LEFT_UPPER); ObjectSetInteger(0,HUD_UP,OBJPROP_XDISTANCE,HUD_X+10); ObjectSetInteger(0,HUD_UP,OBJPROP_YDISTANCE,HUD_Y+45); ObjectSetString(0,HUD_UP,OBJPROP_TEXT,"Locked In Win/Loss: "+ winloss); ////////////////////////////////////////////////////////////////////////////// ObjectSetInteger(0,HUD_UP,OBJPROP_COLOR,clrWhite); ObjectSetInteger(0,HUD_UP,OBJPROP_FONTSIZE,10); ObjectSetString(0,HUD_UP,OBJPROP_FONT,"Arial"); } HUD_UpdateText(); } // HUD events void OnChartEvent(const int id,const long &lparam,const double &dparam,const string &sparam) { if(!HUD_Enable) return; if(id==CHARTEVENT_OBJECT_ENDEDIT && sparam==HUD_EDIT) { string txt = ObjectGetString(0,HUD_EDIT,OBJPROP_TEXT); for(int i=0;i<StringLen(txt);++i) if(StringGetCharacter(txt,i)==',') StringSetCharacter(txt,i,'.'); double v = StringToDouble(txt); if(!(v>0.0)){ HUD_UpdateText(); return; } //g_lots = NormalizeLots(v); //GlobalVariableSet(g_gvLotsKey,g_lots); HUD_UpdateText(); } } //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- EventSetTimer(550); HUD_Create(); //--- return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { //--- EventKillTimer(); } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { HUD_UpdateText(); //--- if (closealreadyflag < 1) { if (eqt = 0.0) { eqt = 11111; } else if (eqt == 11111 || (AccountInfoDouble(ACCOUNT_EQUITY))>bl) { eqt = AccountInfoDouble(ACCOUNT_EQUITY); } } bl = AccountInfoDouble(ACCOUNT_BALANCE); calculatedstop = percentofHWMtrigger*hwmvalue; if ((eqt > bl) && (eqt>hwmvalue)) { hwmvalue = eqt; } if ((closealreadyflag < 1) && (eqt > 0)) { if (eqt < calculatedstop) { CloseAll(); closealreadyflag = 1; eqt = 99999; Print("HWM: ", hwmvalue); Print("percentofHWMtrigger: ", percentofHWMtrigger); Print("calculatedstop: ", calculatedstop); SendNotification("HWM: "+ hwmvalue); } } winloss = calculatedstop-bl; } //+------------------------------------------------------------------+ void OnTimer() { //--- //double price = winloss; //string message = StringFormat("", price); // Display the message in a pop-up window Alert("ALERT: " + "Locked In Win/Loss: "+ winloss, ""); // Log the message in the terminal's log Print("LOG: " + "Locked In Win/Loss: "+ winloss, ""); SendNotification("EA Status" + "Locked In Win/Loss: "+ winloss); //Print(SendMail("EA Status" + "Locked In Win/Loss: "+ winloss, "")); } //+------------------------------------------------------------------+
(5) Adjusted percentofHWMtrigger to initialise to 0.975 because all testing has been performed at this level.
NEW VERSION: CloseByHighWaterMark4
Added:
(1) Status: level WAITING/WORKING/FINISHED
(2) Gap to STOP in panel
(3) LockedIn profit in panel
(4) Hopefully fixed bugs, removed onTimer code
//+------------------------------------------------------------------+ //| CloseByHighWaterMark.mq5 | //| Copyright 2025, MetaQuotes Ltd. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2025, MetaQuotes Ltd." #property link "https://www.mql5.com" #property version "1.00" #property strict #include <Trade/Trade.mqh> CPositionInfo m_position; CTrade m_trade; // HUD input bool HUD_Enable = true; input int HUD_X = 8; input int HUD_Y = 24; input int HUD_W = 400; input int HUD_H = 200; input double percentofHWMtrigger = 0.975; double hwmvalue = 0.0; int closealreadyflag = 0; double eqt = 0.0; double bl = 0.0; double calculatedstop = 0.0; string status = ""; double stopout = 0.0; double profit = 0.0; ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void CloseAll() { for(int i = PositionsTotal() - 1; i >= 0; i--) // loop all Open Positions if (m_position.SelectByIndex(i)) // select a position { m_trade.PositionClose(m_position.Ticket()); // then close it --period Sleep(100); // Relax for 100 ms //ChartWrite("Positions", "Positions " + (string)PositionsTotal(), 100, 80, 20, PositionsColor); //Re write number of positions on the chart } ObjectDelete(0, "Positions"); //delete a Position Object } //=========================== HUD (on-chart) ========================// #define HUD_PREFIX "FiboHUD_" string HUD_BG = HUD_PREFIX+"BG"; string HUD_CAP = HUD_PREFIX+"Cap"; string HUD_VAL = HUD_PREFIX+"Val"; string HUD_UP = HUD_PREFIX+"Up"; string HUD_DN = HUD_PREFIX+"Dn"; string HUD_EDIT = HUD_PREFIX+"Edit"; string HUD_DIR = HUD_PREFIX+"Dir"; void HUD_Destroy(){ string objs[]={HUD_BG,HUD_CAP,HUD_VAL,HUD_UP,HUD_DN,HUD_EDIT,HUD_DIR}; for(int i=0;i<ArraySize(objs);++i) ObjectDelete(0,objs[i]); } void HUD_UpdateText() { if(!HUD_Enable) return; //if(ObjectFind(0,HUD_VAL)>=0) ObjectSetString(0,HUD_CAP,OBJPROP_TEXT,"HWM: "+ DoubleToString(hwmvalue,2)); ObjectSetString(0,HUD_VAL,OBJPROP_TEXT,"Status: "+ status); ObjectSetString(0,HUD_UP,OBJPROP_TEXT,"Gap to STOP: "+ DoubleToString(stopout,2) ); ObjectSetString(0,HUD_DN,OBJPROP_TEXT,"LockedIn Profit: " + DoubleToString(profit,2)); //if(ObjectFind(0,HUD_EDIT)>=0) ObjectSetString(0,HUD_EDIT,OBJPROP_TEXT,LotsStr()); // if(ObjectFind(0,HUD_DIR)>=0) // { // int dir = PositionDirection(); // string dtxt = (dir>0 ? "Long" : dir<0 ? "Short" : "Flat"); // string dtxt = (objectCounter); // color dcol = (dir>0 ? clrLime : dir<0 ? clrTomato : clrSilver); // ObjectSetString (0,HUD_DIR,OBJPROP_TEXT,"Dir: "+dtxt); // ObjectSetInteger(0,HUD_DIR,OBJPROP_COLOR,dcol); // } } void HUD_Create() { if(!HUD_Enable){ HUD_Destroy(); return; } if(ObjectFind(0,HUD_BG)<0) { ObjectCreate(0,HUD_BG,OBJ_RECTANGLE_LABEL,0,0,0); ObjectSetInteger(0,HUD_BG,OBJPROP_XDISTANCE,HUD_X); ObjectSetInteger(0,HUD_BG,OBJPROP_YDISTANCE,HUD_Y); ObjectSetInteger(0,HUD_BG,OBJPROP_XSIZE,HUD_W); ObjectSetInteger(0,HUD_BG,OBJPROP_YSIZE,HUD_H); ObjectSetInteger(0,HUD_BG,OBJPROP_BGCOLOR,clrBlack); ObjectSetInteger(0,HUD_BG,OBJPROP_COLOR,clrBlack); ObjectSetInteger(0,HUD_BG,OBJPROP_FILL,true); ObjectSetInteger(0,HUD_BG,OBJPROP_CORNER,CORNER_LEFT_UPPER); } if(ObjectFind(0,HUD_CAP)<0) { ObjectCreate(0,HUD_CAP,OBJ_LABEL,0,0,0); ObjectSetInteger(0,HUD_CAP,OBJPROP_CORNER,CORNER_LEFT_UPPER); ObjectSetInteger(0,HUD_CAP,OBJPROP_XDISTANCE,HUD_X+10); ObjectSetInteger(0,HUD_CAP,OBJPROP_YDISTANCE,HUD_Y+6); ObjectSetString(0,HUD_CAP,OBJPROP_TEXT,"HWM: "+ hwmvalue); ////////////////////////////////////////////////////////////////////////////// ObjectSetInteger(0,HUD_CAP,OBJPROP_COLOR,clrWhite); ObjectSetInteger(0,HUD_CAP,OBJPROP_FONTSIZE,10); ObjectSetString(0,HUD_CAP,OBJPROP_FONT,"Arial"); } if(ObjectFind(0,HUD_VAL)<0) { ObjectCreate(0,HUD_VAL,OBJ_LABEL,0,0,0); ObjectSetInteger(0,HUD_VAL,OBJPROP_CORNER,CORNER_LEFT_UPPER); ObjectSetInteger(0,HUD_VAL,OBJPROP_XDISTANCE,HUD_X+10); ObjectSetInteger(0,HUD_VAL,OBJPROP_YDISTANCE,HUD_Y+36); ObjectSetString(0,HUD_VAL,OBJPROP_TEXT,"Status: "+ status); ////////////////////////////////////////////////////////////////////////////// ObjectSetInteger(0,HUD_VAL,OBJPROP_COLOR,clrWhite); ObjectSetInteger(0,HUD_VAL,OBJPROP_FONTSIZE,10); ObjectSetString(0,HUD_VAL,OBJPROP_FONT,"Arial"); } if(ObjectFind(0,HUD_UP)<0) { ObjectCreate(0,HUD_UP,OBJ_LABEL,0,0,0); ObjectSetInteger(0,HUD_UP,OBJPROP_CORNER,CORNER_LEFT_UPPER); ObjectSetInteger(0,HUD_UP,OBJPROP_XDISTANCE,HUD_X+10); ObjectSetInteger(0,HUD_UP,OBJPROP_YDISTANCE,HUD_Y+65); ObjectSetString(0,HUD_UP,OBJPROP_TEXT,"Gap to STOP: "+ stopout); ////////////////////////////////////////////////////////////////////////////// ObjectSetInteger(0,HUD_UP,OBJPROP_COLOR,clrWhite); ObjectSetInteger(0,HUD_UP,OBJPROP_FONTSIZE,10); ObjectSetString(0,HUD_UP,OBJPROP_FONT,"Arial"); } if(ObjectFind(0,HUD_DN)<0) { ObjectCreate(0,HUD_DN,OBJ_LABEL,0,0,0); ObjectSetInteger(0,HUD_DN,OBJPROP_CORNER,CORNER_LEFT_UPPER); ObjectSetInteger(0,HUD_DN,OBJPROP_XDISTANCE,HUD_X+10); ObjectSetInteger(0,HUD_DN,OBJPROP_YDISTANCE,HUD_Y+95); ObjectSetString(0,HUD_DN,OBJPROP_TEXT,"LockedIn Profit: " + profit); ////////////////////////////////////////////////////////////////////////////// ObjectSetInteger(0,HUD_DN,OBJPROP_COLOR,clrWhite); ObjectSetInteger(0,HUD_DN,OBJPROP_FONTSIZE,10); ObjectSetString(0,HUD_DN,OBJPROP_FONT,"Arial"); } HUD_UpdateText(); } // HUD events void OnChartEvent(const int id,const long &lparam,const double &dparam,const string &sparam) { if(!HUD_Enable) return; if(id==CHARTEVENT_OBJECT_ENDEDIT && sparam==HUD_EDIT) { string txt = ObjectGetString(0,HUD_EDIT,OBJPROP_TEXT); for(int i=0;i<StringLen(txt);++i) if(StringGetCharacter(txt,i)==',') StringSetCharacter(txt,i,'.'); double v = StringToDouble(txt); if(!(v>0.0)){ HUD_UpdateText(); return; } //g_lots = NormalizeLots(v); //GlobalVariableSet(g_gvLotsKey,g_lots); HUD_UpdateText(); } } //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- HUD_Create(); //--- return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { //--- } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { HUD_UpdateText(); //--- bl = AccountInfoDouble(ACCOUNT_BALANCE); eqt = AccountInfoDouble(ACCOUNT_EQUITY); if ((eqt > bl) && (eqt>hwmvalue)) { hwmvalue = eqt; } calculatedstop = percentofHWMtrigger*hwmvalue; if (calculatedstop > 0) { status = "WORKING"; } else { status = "WAITING"; } if ((closealreadyflag < 1) && (eqt > 0)) { if (eqt < calculatedstop) { CloseAll(); closealreadyflag = 1; status = "FINISHED, please reattach to chart"; Print("HWM: ", hwmvalue); Print("percentofHWMtrigger: ", percentofHWMtrigger); Print("calculatedstop: ", calculatedstop); } stopout = eqt-calculatedstop; profit = calculatedstop-bl; } } //+------------------------------------------------------------------+
It would have been more appropriate to publish the code in the CodeBase and not the forum. Please consider doing that, instead of continuing here.
CodeBase publications, will allow you to update the code and description when needed, and will also have a multi-lingual forum topic assigned to it.
- Free trading apps
- Over 8,000 signals for copying
- Economic news for exploring financial markets
You agree to website policy and terms of use
Hi There
I believe the supplied code in MT5 MQL5 is extremely useful as an EA to close all open orders when a certain percentile of the High Water Mark is breached. Please use this code at your leisure.
Simply configure the input variable: percentofHWMtrigger, as (percentofHWMtrigger >= 0.50) or (percentofHWMtrigger < 0.995) because any value within this range would be a reasonable setup.
This EA will prove to be useful for the following: Locking in elevated profits after a pre-defined deviation (fall) from High Water Mark. This removes the need for manual decision making to close trades.