ButtonCloseBuySell
Download scriptThis tool is designed to provide traders with a streamlined, visual interface for managing active trades directly on their MetaTrader 4 charts. Rather than manually closing each individual position one by one, this script introduces a simplified "bulk action" system that allows for the simultaneous management of all open buy or sell orders based on specific user-defined criteria.
Key Functionalities
Dynamic Profit Tracking The script continuously monitors your open positions and calculates the real-time financial status of your trades. It specifically looks at the net profit, including essential factors like swap fees and commissions. These totals are automatically updated on the screen, providing you with an instant snapshot of your current earnings or losses for both "Buy" and "Sell" categories.
Interactive Dashboard Buttons The core of this tool is the creation of two interactive buttons on your trading chart:
- Close Buys: Displays the cumulative profit of all active buy positions.
- Close Sells: Displays the cumulative profit of all active sell positions.
By providing these visual totals directly on the buttons, the script removes the guesswork of calculating gains manually before deciding to exit a position.
Smart Filtering Logic To ensure the tool only interacts with the trades you intend to manage, it employs three layers of filtering:
- Symbol Matching: It identifies orders specifically tied to the chart you are currently viewing.
- Magic Number Recognition: It can distinguish between trades placed manually and those opened by other automated systems (Expert Advisors).
- Comment Filtering: You can optionally set a specific "Filter Comment" to ensure the script only affects a certain subset of trades that share a specific label.
One-Click Execution When you click either button, the script immediately executes a command to close every relevant open position (either all buys or all sells) that meets your criteria. It processes these orders from the most recent to the oldest to ensure a clean and successful execution. If any trade fails to close for any reason, the tool will trigger an alert notification to inform you of the specific error.
Summary of Benefits
This script simplifies the user experience by consolidating complex order management into a clean, two-button dashboard. It provides high-level clarity on portfolio performance while offering a fast, reliable way to exit positions with precision and ease.
//+------------------------------------------------------------------+
//| ButtonCloseBuySell.mq4 |
//| Copyright 2017, Erich Focht |
//+------------------------------------------------------------------+
#property copyright "Copyright 2017, Erich Focht (elfo13)"
#property link ""
#property version "1.00"
#property strict
//--- input parameters
input int Magic = 0; // Magic number, -1 for all, 0 for manual
input string FilterComment = ""; // Filter by order comment string
input int Slippage = 3; // Maximum allowed slippage
//
double profitB = 0.0, profitS = 0.0;
int OnInit()
{
ObjectCreate(0, "CloseBuy", OBJ_BUTTON, 0, 0, 0);
ObjectSetInteger(0, "CloseBuy", OBJPROP_XDISTANCE, 331);
ObjectSetInteger(0, "CloseBuy", OBJPROP_YDISTANCE, 0);
ObjectSetInteger(0, "CloseBuy", OBJPROP_XSIZE, 105);
ObjectSetInteger(0, "CloseBuy", OBJPROP_YSIZE, 16);
ObjectSetString(0, "CloseBuy", OBJPROP_FONT, "Arial");
ObjectSetInteger(0, "CloseBuy", OBJPROP_FONTSIZE, 8);
ObjectSetInteger(0, "CloseBuy", OBJPROP_COLOR, White);
ObjectSetInteger(0, "CloseBuy", OBJPROP_BGCOLOR, clrDarkSlateBlue);
ObjectSetInteger(0, "CloseBuy", OBJPROP_BORDER_COLOR, Yellow);
ObjectSetInteger(0, "CloseBuy", OBJPROP_BORDER_TYPE, BORDER_FLAT);
ObjectSetInteger(0, "CloseBuy", OBJPROP_BACK, false);
ObjectSetInteger(0, "CloseBuy", OBJPROP_HIDDEN, true);
ObjectSetInteger(0, "CloseBuy", OBJPROP_STATE, false);
ObjectCreate(0,"CloseSell", OBJ_BUTTON, 0, 0, 0);
ObjectSetInteger(0,"CloseSell", OBJPROP_XDISTANCE, 225);
ObjectSetInteger(0,"CloseSell", OBJPROP_YDISTANCE, 0);
ObjectSetInteger(0,"CloseSell", OBJPROP_XSIZE, 105);
ObjectSetInteger(0,"CloseSell", OBJPROP_YSIZE, 16);
ObjectSetString(0, "CloseSell", OBJPROP_FONT, "Arial");
ObjectSetInteger(0, "CloseSell", OBJPROP_FONTSIZE, 8);
ObjectSetInteger(0, "CloseSell", OBJPROP_COLOR, White);
ObjectSetInteger(0, "CloseSell", OBJPROP_BGCOLOR, clrDarkMagenta);
ObjectSetInteger(0, "CloseSell", OBJPROP_BORDER_COLOR, Yellow);
ObjectSetInteger(0, "CloseSell", OBJPROP_BORDER_TYPE, BORDER_FLAT);
ObjectSetInteger(0, "CloseSell", OBJPROP_BACK, false);
ObjectSetInteger(0, "CloseSell", OBJPROP_HIDDEN, true);
ObjectSetInteger(0, "CloseSell", OBJPROP_STATE, false);
calc_profits();
ObjectSetString(0, "CloseBuy", OBJPROP_TEXT,
"Close Buys " + DoubleToStr(profitB, 2));
ObjectSetString(0, "CloseSell", OBJPROP_TEXT,
"Close Sells " + DoubleToStr(profitS, 2));
return(INIT_SUCCEEDED);
}
void OnDeinit(const int reason)
{
ObjectDelete(0,"CloseBuy");
ObjectDelete(0,"CloseSell");
}
void calc_profits()
{
profitB = 0.0; profitS = 0.0;
for (int cnt = 0; cnt < OrdersTotal(); cnt++) {
if (!OrderSelect(cnt, SELECT_BY_POS))
continue;
if ((Magic >= 0 && OrderMagicNumber() != Magic) || OrderSymbol() != Symbol())
continue;
if (StringLen(FilterComment) > 0 && StringCompare(FilterComment, OrderComment(), true) != 0)
continue;
if (OrderCloseTime() == 0) {
if (OrderType() == OP_BUY)
profitB += OrderProfit() + OrderSwap() + OrderCommission();
else if (OrderType() == OP_SELL)
profitS += OrderProfit() + OrderSwap() + OrderCommission();
}
}
}
void OnTick()
{
calc_profits();
ObjectSetString(0, "CloseBuy", OBJPROP_TEXT,
"Close Buys " + DoubleToStr(profitB, 2));
ObjectSetString(0, "CloseSell", OBJPROP_TEXT,
"Close Sells " + DoubleToStr(profitS, 2));
}
void OnChartEvent(const int id, const long &lparam,
const double &dparam, const string &sparam)
{
if (sparam == "CloseBuy") {
CloseOpenPositions(OP_BUY);
ObjectSetInteger(0, "CloseBuy", OBJPROP_STATE, false);
}
if (sparam == "CloseSell") {
CloseOpenPositions(OP_SELL);
ObjectSetInteger(0, "CloseBuy", OBJPROP_STATE, false);
}
}
void CloseOpenPositions(int op)
{
for (int cnt = OrdersTotal() - 1; cnt >= 0; cnt--) {
if (!OrderSelect(cnt, SELECT_BY_POS))
continue;
if ((Magic >= 0 && OrderMagicNumber() != Magic) || OrderSymbol() != Symbol())
continue;
if (StringLen(FilterComment) > 0 && StringCompare(FilterComment, OrderComment(), true) != 0)
continue;
if (OrderCloseTime() == 0 && OrderType() == op) {
if (!OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(),
Slippage, CLR_NONE))
Alert("Close attempt for order #", OrderTicket(),
" returned error code ", GetLastError());
}
}
}
Comments