

How to Build a Custom Multi‑Timeframe Dashboard in MT5
Table of Contents
- Introduction
- What Is a Custom Multi‑Timeframe Dashboard
- Why a Custom Multi‑Timeframe Dashboard Matters for Traders and Investors
- Core Concepts
- Step‑by‑Step Guide
- Practical Tips for Better Results
- Common Mistakes to Avoid
- Frequently Asked Questions
- Conclusion
Introduction
When the EUR/USD pair slipped below 1.0800 on a thin‑liquidity morning, a handful of scalpers who were watching both a 5‑minute chart and a 30‑minute trend panel avoided a false breakout that sent many stop‑losses into the market. Their edge did not come from a proprietary indicator; it came from a live, self‑built dashboard that merged two timeframes into a single visual pane.
Most MetaTrader 5 (MT5) users cling to the platform’s default chart window, flipping between timeframes manually or stacking separate windows that drift out of sync. That workflow injects latency at the worst possible moment—when a trader needs to confirm a higher‑timeframe bias before entering a rapid‑fire trade. A custom multi‑timeframe dashboard removes the manual step, trims visual clutter, and lets you embed risk metrics such as ATR‑based stop distances right beside the price action.
In the pages that follow, we walk through the construction of a live dashboard in MT5 using MQL5. You will see the class design that aggregates higher‑timeframe data, the chart‑synchronization tricks that keep sub‑charts locked, the label widgets that turn numbers into instant visual cues, the timer‑driven refresh that balances freshness with CPU load, and an optional DLL rendering path for pixel‑perfect graphics. By the end, you will own a reusable template that can be adapted to any instrument—from S&P 500 futures to GBP/JPY—without rewriting the core logic.
What Is a Custom Multi‑Timeframe Dashboard?
A custom multi‑timeframe dashboard is a single chart window that simultaneously displays price data, indicators, and risk metrics drawn from two or more timeframes. Instead of opening separate charts, the dashboard aggregates higher‑timeframe OHLC (open‑high‑low‑close) bars, computes derived values such as moving‑average crossovers or RSI levels, and paints them as panels, labels, or miniature sub‑charts that remain locked to the primary timeframe.
Picture a trader running a 5‑minute scalping chart of EUR/USD while a compact panel at the top shows the 30‑minute bullish or bearish candle pattern. The panel updates in real time, so the trader can instantly tell whether the short‑term move aligns with the longer‑term bias. No extra windows, no mouse‑driven switching—just a single pane that tells the whole story.
Why a Custom Multi‑Timeframe Dashboard Matters for Traders and Investors
Professional prop desks and retail day traders alike rely on multi‑timeframe confirmation to filter out noise. The Commodity Futures Trading Commission’s (CFTC) periodic reports on retail forex activity repeatedly highlight that traders who ignore higher‑timeframe context suffer larger drawdowns during volatile sessions. A dashboard that surfaces that context in real time reduces the probability of “trend‑blind” entries that erode capital.
Institutional researchers monitoring the Nasdaq‑100 often overlay a 4‑hour volatility band on a 15‑minute price chart to gauge when liquidity dries up. Ignoring such a band can lead to slippage that chips away at the Sharpe ratio. By embedding the band directly into the chart, a trader can adjust position size or tighten stops before the market thins.
In short, a well‑built dashboard:
– Aligns entry decisions with the dominant trend, nudging win‑rate probability upward.
– Shows risk metrics (ATR, implied volatility) without forcing a window change, helping size positions with precision.
– Saves screen real‑estate, allowing the trader to focus on order flow rather than juggling windows.
MQL5 Class for Aggregating Higher‑Timeframe OHLC Data — mechanism explained
MQL5’s CopyRates function returns an array of MqlRates structures for any symbol and timeframe. A custom class—let’s call it CMTF_Aggregator—can wrap this call, cache the last N higher‑timeframe bars, and expose methods such as GetClose(int shift) or IsBullish(int shift).
Scenario: A scalper on EUR/USD wants to know whether the current 30‑minute candle is bullish. The class pulls the latest 30‑minute bar, checks if Close > Open, and returns a Boolean. The main script queries the class each tick; when the result flips from false to true, a label on the dashboard changes color from red to green, signaling alignment.
ChartSetInteger with CHART_TIMEFRAME to Sync Sub‑Charts — mechanism explained
MT5 permits multiple sub‑charts (objects of type OBJCHART) to be embedded within a primary chart. By invoking ChartSetInteger(subChartID, CHARTTIMEFRAME, PERIOD_M30), the sub‑chart automatically renders the chosen higher timeframe. The parent chart can remain on a 5‑minute timeframe, while the sub‑chart stays locked to 30 minutes.
Scenario: A GBP/JPY trader runs a 1‑hour primary chart. A secondary sub‑chart placed at the top of the window shows a 4‑hour RSI and ATR. Because the sub‑chart’s timeframe is set with ChartSetInteger, the RSI line updates only when a new 4‑hour bar closes, preserving the integrity of the volatility measure while the primary chart scrolls through each minute tick.
ObjectCreate and ObjectSet for Dynamic Label Widgets — mechanism explained
Labels (OBJLABEL) are lightweight text objects positioned in pixel coordinates. Using ObjectCreate(0, "TrendPanel", OBJLABEL, 0, 0, 0) followed by ObjectSetString and ObjectSetInteger for font size, background color, and alignment, a script can render a live panel that reflects the aggregated data from the class.
Scenario: The scalper’s dashboard includes a label that reads “30‑M Trend: Bullish”. When the higher‑timeframe class detects a bearish reversal, the script calls ObjectSetString to change the text and ObjectSetInteger to switch the background from green to red. The change occurs instantly, giving the trader a visual cue without re‑loading the chart.
OnTimer Event for Periodic Data Refresh — mechanism explained
Polling higher‑timeframe data on every tick can be wasteful because a 30‑minute bar updates only once per half hour. The OnTimer event, set with EventSetTimer(10) for a ten‑second interval, triggers a refresh routine that checks whether a new higher‑timeframe bar has formed (TimeCurrent() - lastBarTime >= periodSeconds). If so, the aggregator updates its cache and the dashboard redraws.
Scenario: During the London session, the GBP/JPY trader’s dashboard refreshes every ten seconds. When the 4‑hour ATR spikes, the timer fires, the aggregator pulls the new ATR value, and the label displaying “4‑H ATR: 0.0125” updates. The trader can instantly adjust the stop‑loss distance based on the fresh volatility figure.
Custom DLL Integration for Advanced Chart Rendering (Optional) — mechanism explained
For pixel‑perfect graphics, a DLL written in C++ can expose a function that draws directly onto the chart’s device context. MQL5’s import directive loads the DLL, and the script calls the function each timer tick, passing coordinates and color values. This approach bypasses the limited styling options of built‑in objects, enabling gradient fills or anti‑aliased shapes.
Scenario: A hedge‑fund analyst monitoring the VIX wants a semi‑transparent heat map that fades from green (low volatility) to red (high volatility) behind the price candles. By invoking a custom DLL, the dashboard paints the heat map behind the chart without obscuring price action, delivering a visual risk overlay that would be impossible with standard MT5 objects alone.
Core Concepts
Step 1 — Define the Aggregator Class
Create a new MQL5 file, for example MTF_Aggregator.mqh. Inside, declare a class that stores the symbol, higher timeframe, and a dynamic array of MqlRates. Implement a constructor that calls CopyRates for the last 500 bars, and a method Refresh() that checks TimeCurrent() against the timestamp of the most recent cached bar. If a new bar exists, call CopyRates again to append it.
Action: Write the class, compile it, and include it in your main script with #include.
Step 2 — Create Sub‑Chart Objects and Sync Timeframes
In the OnInit() function of your expert advisor or script, call ChartCreate(0, "SubChart1", 0, 0, 0) to generate a sub‑chart. Then set its timeframe: ChartSetInteger(SubChart1, CHARTTIMEFRAME, PERIOD_M30). Adjust its size with ChartSetInteger(SubChart1, CHARTWIDTHINPIXELS, 300) and position it at the top of the primary chart using ChartSetInteger(SubChart1, CHARTYDISTANCE, 0).
Action: Repeat for any additional panels, such as a 4‑hour ATR panel, assigning distinct IDs like "SubChart2".
Step 3 — Add Dynamic Labels for Trend and Risk Metrics
Use ObjectCreate(0, "TrendLabel", OBJLABEL, 0, 0, 0). Set its font, size, and background:
ObjectSetInteger(0, "TrendLabel", OBJPROP_FONTSIZE, 12);
ObjectSetInteger(0, "TrendLabel", OBJPROP_BACK, clrLime);
In the OnTimer routine, retrieve the higher‑timeframe trend from the aggregator (aggregator.IsBullish(0)) and update the label text with ObjectSetString.
Similarly, create a label "ATRLabel" that displays the latest ATR value calculated from the higher‑timeframe close series. Use iATR with the higher timeframe as the source.
Action: Ensure each label’s OBJPROP_XDISTANCE and OBJPROP_YDISTANCE place it inside the sub‑chart’s header area for a clean layout.
Step 4 — Set Up the Timer for Efficient Refreshes
At the end of OnInit(), invoke EventSetTimer(10) to fire every ten seconds. Implement OnTimer() to:
1. Call aggregator.Refresh() – updates only if a new bar formed.
2. Re‑calculate derived indicators (moving averages, RSI) using the refreshed data.
3. Update all labels and, if using a DLL, call the rendering function.
Remember to clear the timer in OnDeinit() with EventKillTimer().
Action: Test the timer by watching the label change as a new 30‑minute candle closes during the New York session.
Step 5 — (Optional) Integrate a Custom DLL for Advanced Graphics
If you need gradient backgrounds or custom shapes, write a C++ DLL exposing a function DrawHeatMap(HWND chartHandle, double volatility). Compile it with the MT5 SDK, place the DLL in the Libraries folder, and import it in MQL5:
#import "HeatMap.dll"
void DrawHeatMap(int chart_id, double vol);
#import
Call DrawHeatMap(0, latestATR) inside OnTimer. Verify that the broker allows DLL usage; some brokers restrict it for security reasons.
Action: Test on a demo account first; disable the DLL if you encounter performance lag.
Step 6 — Deploy and Validate on Multiple Instruments
Attach the script to an EUR/USD 5‑minute chart and verify that the 30‑minute trend panel updates correctly. Then switch to a GBP/JPY 1‑hour chart; the 4‑hour ATR panel should reflect the new symbol automatically because the aggregator uses Symbol() at runtime.
Action: Record a short video of the dashboard reacting to a live news spike to confirm latency stays within acceptable bounds (typically under 200 ms on a standard broadband connection).
Practical Tips for Better Results
– Cache only needed bars. Storing 500 high‑timeframe bars for every symbol can consume RAM; limit the array to the most recent 200 to keep the EA lightweight.
– Align label colors with risk thresholds. For example, set the ATR label background to red when ATR exceeds 0.015 on GBP/JPY, signaling that a wider stop may be required.
– Lock the primary chart’s scroll. Use ChartSetInteger to prevent accidental zoom changes that would misalign the sub‑charts.
– Test the timer interval. A ten‑second interval works for 30‑minute and 4‑hour panels; for 1‑minute higher‑timeframe panels, a two‑second interval reduces lag without overloading the CPU.
– Validate DLL signatures. Brokers that enforce the “Allow DLL imports” setting may reject unsigned libraries; sign your DLL with a trusted certificate to avoid runtime errors.
– Monitor CPU usage in the MetaTrader terminal. If the dashboard pushes CPU above 30 % on a typical laptop, consider trimming the number of sub‑charts or increasing the timer interval.
– Document each panel’s purpose. Adding a small “Help” label that explains the metric (e.g., “ATR = Average True Range, 4‑H”) reduces confusion when you revisit the script after weeks of inactivity.
Common Mistakes to Avoid
– Hard‑coding the symbol. Using a fixed symbol like “EURUSD” prevents the dashboard from adapting when you switch charts.
– Refreshing on every tick. Pulling higher‑timeframe data each tick creates unnecessary network traffic and can cause lag.
– Neglecting to kill the timer. Forgetting EventKillTimer() leaves the timer running after the script is removed, leading to orphaned processes.
– Overloading the chart with too many objects. Each label and sub‑chart consumes graphic resources; clutter reduces readability and can cause the terminal to crash.
– Skipping error handling for CopyRates. If the broker’s server is momentarily unavailable, CopyRates returns –1; ignoring this can corrupt the aggregator’s cache.
How do I build a multi‑timeframe dashboard in MT5?
Start by creating an MQL5 class that pulls higher‑timeframe OHLC data with CopyRates. Then embed sub‑charts using ChartCreate and lock their timeframe with ChartSetInteger. Add dynamic labels via ObjectCreate and refresh everything on a timed interval using OnTimer. The steps above outline the full workflow.
What indicators can be combined in a custom MT5 dashboard?
Any built‑in indicator that accepts a timeframe argument can be used: moving averages, RSI, MACD, ATR, and even custom oscillators. Because the dashboard pulls higher‑timeframe price series, you can compute volatility‑adjusted stop levels, trend strength, or correlation metrics across symbols.
Why use a multi‑timeframe dashboard for day trading?
Day traders benefit from confirming short‑term entries with a higher‑timeframe bias. A live dashboard eliminates the need to switch windows, reducing reaction time and helping avoid trades that go against the prevailing trend—a common source of drawdowns documented by the CFTC.
When should I refresh the dashboard data?
Refresh frequency depends on the highest timeframe displayed. For 30‑minute or 4‑hour panels, a ten‑second timer is sufficient. For a 1‑minute higher‑timeframe panel, a two‑second interval keeps the data fresh without overloading the CPU.
Can I share my custom MT5 dashboard with other traders?
Yes. Compile the script into an .ex5 file and distribute the source .mq5 if you want others to modify it. If you used a custom DLL, include the DLL and ensure the recipient’s terminal allows DLL imports.
Is coding in MQL5 required to build a multi‑timeframe dashboard?
While MT5’s built‑in “Multiple Timeframe” indicator offers a simple overlay, a fully custom dashboard with dynamic panels, risk metrics and optional DLL graphics requires MQL5 programming. The language is C‑like, and the core concepts—classes, timers, and chart objects—are covered in MetaQuotes’ documentation.
Conclusion
The essential lesson is that a well‑engineered dashboard fuses higher‑timeframe context with real‑time price action, turning a fragmented workflow into a single, actionable view. Your next step is to copy the provided class template, attach it to a demo chart, and experiment with one additional panel—perhaps a volatility heat map for the VIX.
Remember, any dashboard is a tool, not a guarantee. Market conditions can shift in seconds, and a mis‑aligned stop or an over‑reliant trend filter can still produce losses. Test thoroughly, respect position‑size limits, and keep your risk‑management framework front‑and‑center. Happy coding, and trade responsibly.
—
This article is for educational purposes only and does not constitute investment advice. Trading and investing carry risk of loss; never invest more than you can afford to lose.
Last reviewed August 2026.
Last reviewed: August 2026




















































