MQL5 Market Watch Symbol Switcher with Dynamic Buttons
Thursday, August 6, 2026We would like to share a useful MQL5 indicator that creates a dynamic symbol switcher panel directly on the chart. The main purpose of this tool is to make it easier for traders to switch between symbols listed in the Market Watch window without manually opening a new chart or searching for the symbol from the toolbar.
This indicator is especially helpful for traders who monitor many currency pairs, gold (XAUUSD), indices, or other instruments throughout the day. With a single click, the chart will instantly change to the selected symbol while keeping the current timeframe unchanged.
Main Features
The script automatically reads all symbols that are currently visible in the Market Watch window. For each symbol, it creates a button on the chart. The active chart symbol is highlighted with a different color, making it easy to identify which instrument is currently displayed.
Key features include:
Automatically loads symbols from Market Watch.
Creates one clickable button for each symbol.
Keeps the current timeframe when switching symbols.
Highlights the active symbol.
Customizable panel position (left, right, top, or bottom).
Adjustable button size and spacing.
Removes all created objects automatically when the indicator is removed.
How the Indicator Works
1. Panel Location
The first section defines an enumeration called PANEL_LOCATION. This allows the user to choose where the button panel will appear on the chart:
Left
Right
Top
Bottom
This makes the interface flexible for different chart layouts.
2. Layout Settings
The following input parameters control the appearance of the buttons:
ButtonsPerRowButtonWidthButtonHeightStartXStartYGapXGapY
By changing these values, you can create a vertical list, a horizontal row, or a grid of buttons.
3. Loading Market Watch Symbols
The LoadMarketWatch() function reads all symbols that are visible in the Market Watch window using:
SymbolsTotal(true)
SymbolName(i, true)
Only visible symbols are loaded, which keeps the panel clean and relevant.
4. Creating Buttons
The CreateSymbolButton() function creates an OBJ_BUTTON object for each symbol. The button text is set to the symbol name, and the background color changes depending on whether the symbol is the currently active chart symbol.
If the symbol is active, the button uses ActiveColor; otherwise, it uses InactiveColor.
5. Switching Symbols
The most important part is inside OnChartEvent():
ChartSetSymbolPeriod(0, symbol, (ENUM_TIMEFRAMES)_Period);
When a button is clicked, the chart changes to the selected symbol while preserving the current timeframe. For example, if you are on H1 EURUSD and click XAUUSD, the chart becomes H1 XAUUSD.
6. Refreshing Active Highlight
The RefreshButtons() function updates the button colors so the active symbol is always highlighted. This function is called both after a click and during chart recalculation.
7. Cleaning Up
The OnDeinit() function deletes all objects whose names start with the defined prefix. This prevents leftover buttons from remaining on the chart after the indicator is removed.
Why This Tool Is Useful
Many traders use multiple charts to monitor several instruments. However, opening many charts can consume screen space and system resources. This indicator provides a lightweight alternative: one chart, many symbols.
I personally find it useful for:
Scalping multiple forex pairs
Switching quickly between XAUUSD, GBPUSD, EURUSD, and USDJPY
Checking the same setup across different symbols
Reducing chart clutter
Because the indicator uses standard chart objects, it does not require any external libraries or DLLs.
The original code is:
//+------------------------------------------------------------------+
//| MarketWatchSwitcher_v1.mq5 |
//+------------------------------------------------------------------+
#property strict
#property indicator_chart_window
#property indicator_plots 0
//--- panel location
enum PANEL_LOCATION
{
PANEL_LEFT = 0,
PANEL_RIGHT = 1,
PANEL_TOP = 2,
PANEL_BOTTOM = 3
};
input PANEL_LOCATION PanelLocation = PANEL_BOTTOM;
//--- layout
input int ButtonsPerRow = 1;
input int ButtonWidth = 90;
input int ButtonHeight = 22;
input int StartX = 10;
input int StartY = 10;
input int GapX = 5;
input int GapY = 5;
//--- colors
input color ActiveColor = clrOrange;
input color InactiveColor = clrDodgerBlue;
input color TextColor = clrWhite;
string Prefix = "MWBTN_";
string Symbols[];
int TotalSymbols = 0;
//+------------------------------------------------------------------+
//| Create one button |
//+------------------------------------------------------------------+
void CreateSymbolButton(string symbol, int x, int y)
{
string name = Prefix + symbol;
if(ObjectFind(0, name) >= 0)
ObjectDelete(0, name);
ObjectCreate(0, name, OBJ_BUTTON, 0, 0, 0);
ObjectSetInteger(0, name, OBJPROP_CORNER, CORNER_LEFT_UPPER);
ObjectSetInteger(0, name, OBJPROP_XDISTANCE, x);
ObjectSetInteger(0, name, OBJPROP_YDISTANCE, y);
ObjectSetInteger(0, name, OBJPROP_XSIZE, ButtonWidth);
ObjectSetInteger(0, name, OBJPROP_YSIZE, ButtonHeight);
ObjectSetString(0, name, OBJPROP_TEXT, symbol);
//--- highlight active symbol
color bg = (symbol == _Symbol) ? ActiveColor : InactiveColor;
ObjectSetInteger(0, name, OBJPROP_BGCOLOR, bg);
ObjectSetInteger(0, name, OBJPROP_COLOR, TextColor);
ObjectSetInteger(0, name, OBJPROP_BORDER_COLOR, clrBlack);
ObjectSetInteger(0, name, OBJPROP_FONTSIZE, 9);
}
//+------------------------------------------------------------------+
//| Load Market Watch visible symbols |
//+------------------------------------------------------------------+
void LoadMarketWatch()
{
TotalSymbols = SymbolsTotal(true);
ArrayResize(Symbols, TotalSymbols);
for(int i = 0; i < TotalSymbols; i++)
Symbols[i] = SymbolName(i, true);
}
//+------------------------------------------------------------------+
//| Create all buttons |
//+------------------------------------------------------------------+
void CreateAllButtons()
{
int chartW = (int)ChartGetInteger(0, CHART_WIDTH_IN_PIXELS);
int chartH = (int)ChartGetInteger(0, CHART_HEIGHT_IN_PIXELS);
for(int i = 0; i < TotalSymbols; i++)
{
int row = i / ButtonsPerRow;
int col = i % ButtonsPerRow;
int x = StartX + col * (ButtonWidth + GapX);
int y = StartY + row * (ButtonHeight + GapY);
//--- right side
if(PanelLocation == PANEL_RIGHT)
{
x = chartW - StartX - ButtonWidth - col * (ButtonWidth + GapX);
}
//--- bottom side
if(PanelLocation == PANEL_BOTTOM)
{
y = chartH - StartY - ButtonHeight - row * (ButtonHeight + GapY);
}
CreateSymbolButton(Symbols[i], x, y);
}
}
//+------------------------------------------------------------------+
//| Refresh active highlight |
//+------------------------------------------------------------------+
void RefreshButtons()
{
for(int i = 0; i < TotalSymbols; i++)
{
string name = Prefix + Symbols[i];
if(ObjectFind(0, name) >= 0)
{
color bg = (Symbols[i] == _Symbol) ? ActiveColor : InactiveColor;
ObjectSetInteger(0, name, OBJPROP_BGCOLOR, bg);
}
}
}
//+------------------------------------------------------------------+
//| Initialization |
//+------------------------------------------------------------------+
int OnInit()
{
LoadMarketWatch();
CreateAllButtons();
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Chart events |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
const long &lparam,
const double &dparam,
const string &sparam)
{
if(id == CHARTEVENT_OBJECT_CLICK)
{
if(StringFind(sparam, Prefix) == 0)
{
string symbol = StringSubstr(sparam, StringLen(Prefix));
// switch symbol, keep timeframe
ChartSetSymbolPeriod(0, symbol, (ENUM_TIMEFRAMES)_Period);
RefreshButtons();
}
}
}
//+------------------------------------------------------------------+
//| Deinitialization |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
int total = ObjectsTotal(0);
for(int i = total - 1; i >= 0; i--)
{
string name = ObjectName(0, i);
if(StringFind(name, Prefix) == 0)
ObjectDelete(0, name);
}
}
//+------------------------------------------------------------------+
//| Calculation |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
const long &tick_volume[],
const long &volume[],
const int &spread[])
{
RefreshButtons();
return(rates_total);
}
//+------------------------------------------------------------------+
Final Thoughts
This MQL5 Market Watch Switcher is a simple but practical utility for everyday trading. It demonstrates several useful MQL5 concepts, including chart objects, event handling, dynamic arrays, and symbol management.
Feel free to customize the colors, button arrangement, and panel location to match your trading workspace. You can also extend the project by adding features such as favorite symbols, search filters, timeframe buttons, or automatic chart templates.
Below is the complete source code of the indicator. Copy it into MetaEditor, save it as MarketWatchSwitcher_v1.mq5 or other name you want, compile it, and attach it to any chart.
Happy coding and happy trading!
