From Novice to Expert: Developing a Geographic Market Awareness with MQL5 Visualization
Contents
Introduction
In my recent publications on market session periods, the main goal has been to bring the personality of each session into clear view—not just its clock times. Many sources explain when Sydney, Tokyo, London, and New York open and close, but far fewer focus on how session awareness itself strengthens trading psychology. Knowing which part of the world is active and why the price is moving the way it is can calm the mind and sharpen decision-making.
The forex market’s 24-hour cycle is really a geographical symphony, yet most traders experience it as a flat timeline. We see hours and candles, not Sydney waking up, London pouring its morning tea, or New York’s afternoon volatility surge. This disconnect between time-based charts and geography-based liquidity is like trading without truly seeing the market’s heartbeat.
In this article, we address that gap by turning the chart itself into a live world map slide player using MQL5 bitmap capabilities. Instead of a static background, we’ll build an intelligent visual layer that highlights the currently active sessions in real time, directly on the chart. It becomes custom theming with a purpose: at a glance, the eye sees which session is driving price, overlaps are instantly recognizable, and your psychology stays anchored to the global rhythm of the market. From there, we’ll move into the core implementation and develop the tools that make this session-aware visualization possible.

By the end we will have an intelligent engine that controls the themes shown in the image
A Historical Perspective: How Time Shaped Modern Trading
The concept of trading sessions emerged not from design but from necessity. In the 1970s, as currencies began floating freely, a pattern emerged naturally: when Sydney traders went home, Tokyo was waking up. When Tokyo closed, London was opening. This handoff created the modern session cycle that now moves $7.5 trillion daily.
What began as geographic necessity evolved into opportunity. Professional traders noticed something profound: overlaps weren't just handoffs—they were amplifiers. The three-hour London-New York overlap accounts for only 12.5% of the trading day but generates 40% of EURUSD movement. This isn't random—it's the market's geographical reality made visible through price.
For decades, traders managed session awareness through mental calculations, multiple time-zone clocks, or simple color-coded charts. These solutions shared a common flaw: they added cognitive load instead of creating intuition. You had to think about sessions rather than feel them.
Modern trading psychology research reveals a critical insight: professionals don't just analyze markets—they develop market sense. They "feel" when London is about to open, and they "sense" when Asian liquidity is fading. This isn't mystical—it's pattern recognition that transforms conscious knowledge into subconscious awareness. But this takes years to develop naturally. What if we could accelerate it?
Our Mission: Making the Invisible Visible
This is where our journey begins. We are not building another indicator that adds more data to our screen. We are creating a visual translation layer between the market's geographical reality and our chronological chart.
Imagine the trading platform transforming into a dynamic world map where
- Australia glows blue when Sydney is active.
- Japan illuminates as Tokyo takes over.
- Europe comes alive with London's energy.
- The Americas light up during New York hours.
Research in financial visualization shows that spatial representation of temporal data improves decision speed by 30% and accuracy by 22%. By seeing sessions geographically, you begin to develop the market sense that typically takes years of experience.
MQL5 is our paintbrush for this visualization. We're leveraging its unique capabilities:
- Resource embedding to create seamless visual experiences
- Event-driven architecture that responds to market rhythms naturally
- Object-oriented design for clean, maintainable code
- Real-time notifications that keep you informed without distraction
Every line of code serves a purpose: reducing your cognitive load while increasing market awareness. We are building what professional traders have quietly used for years but retail traders rarely access: institutional-grade session visualization.
Trading success often hinges on subtle awareness—knowing not just what's happening, but why it's happening. When you see EURUSD stall during Asian hours, it's not just "low volatility"—it's the geographical reality of Tokyo focusing on JPY pairs. When GBPUSD explodes at 8 AM GMT, it's not just "news"—it's London's massive liquidity pool coming online.
This tool bridges the gap between:- Knowledge and intuition
- Analysis and awareness
- Trading and market participation
Our Implementation Philosophy
As we build, these are the steps:
- Visual-first, data-second: The display must communicate instantly.
- Non-invasive design: It enhances your workspace without cluttering it.
- Configurable intelligence: Adapts to your trading style and broker.
- Professional robustness: Handles edge cases and errors gracefully.
In the coming sections, we'll transform this vision into reality. We'll start with the core engine that calculates session states, then layer on visualization, then add intelligent notifications. Each step builds on the last, creating a tool that's greater than the sum of its parts.
But this is more than a coding tutorial. It's about developing an in-depth relationship with the market's rhythm. By the end, you won't just have a new tool—you'll have a new way of seeing the markets.
Implementation
To keep the workflow beginner-friendly, I started by sourcing two base world maps under Creative Commons licenses from Google Images—one with a bright blue ocean for the light theme and another with a dark grey palette for the dark theme. Each image was opened in GIMP and scaled to a consistent landscape aspect ratio (for example, 1920×1080), so that it sits nicely behind most MetaTrader 5 charts without looking stretched or distorted. The key idea is to treat these maps as “slide backgrounds,” so they should be clean, readable, and not overloaded with extra decorations.
Once the base maps were in place, I used GIMP’s text and shape tools to add simple, readable labels for each trading session directly onto the image. On the blue-ocean map, I highlighted and labeled regions for Sydney, Tokyo, London, and New York in colors that match the session colors in the code, placing the text close to the relevant part of the world without covering too much coastline. I repeated the same process on the dark-grey map, using slightly brighter, “neon-style” colors so the labels stand out against the darker background. The goal here is subtle guidance: the eye should immediately see which part of the world we’re referring to, but the elements must remain soft enough that candles and price action stay readable on top.
After that, each themed map was exported from GIMP as a separate BMP file ready for MQL5. For every session, I made a dedicated slide (for example, world_sydney.bmp, world_tokyo.bmp, and so on for the light theme, plus matching _dark versions for the dark theme), ensuring I exported in BMP format so MetaTrader 5 can embed them as resources. These files were then placed into the MQL5\Images folder, where the EA can access them and switch between them in real time according to the active market session.
At this stage, we walk through how we transform abstract market timing into visual intuition. This isn't just another indicator; we're building a full visual awareness system that lets us see the market's heartbeat. I'll explain each section for a deeper understanding. We’ll proceed in two stages: first, we’ll revisit an existing library file and adapt it for use in our current project; then we’ll move on to developing the main code.
Building on Existing Foundations: Adapting SessionVisualizer.mqh
Before we begin constructing our main EA logic, let's recognize an important professional development principle: we don't need to reinvent every component. After preparing our world map images, we also need a way to mark session boundaries directly on the price chart. Instead of building this from scratch, we revisited an excellent existing resource from our past article.
The original SessionVisualizer.mqh file, provided comprehensive session visualization with OHLC rectangles, wicks, and detailed labels. However, for our project, we needed something more subtle—visual markers that would complement rather than compete with our world map slides.
Strategic Modifications for Our Needs
Here are the key modifications to adapt this component for our slide-based visualization approach:
1. Introducing a Mode Toggle
We added a simple but powerful flag that changes the entire visualization approach:
private: bool m_markers_only; // NEW: when true, only draw time markers public: void SetMarkersOnly(bool markers_only) { m_markers_only = markers_only; }
This single boolean determines whether we show the full OHLC visualization (original behavior) or just minimal boundary markers (our adaptation).
2. Creating a Minimalist Drawing Method
We implemented a new DrawSessionMarkers() method that provides exactly what our project needs:
void DrawSessionMarkers(const SessionInfo &sess, datetime t_open, datetime t_close, bool is_current) { // Creates clean vertical lines at session boundaries // with minimal labels showing session abbreviations }
This method produces:
- Subtle vertical lines marking session open and close times
- Tiny text labels (SYD, TOK, LON, NY) without overwhelming the chart
- Visual distinction between current sessions (solid lines) and historical ones (dotted)
3. Smart Conditional Logic
We modified the existing DrawSessionVisuals() method to use our new approach when appropriate:
void DrawSessionVisuals(const SessionInfo &sess, datetime t_open, datetime t_close, double o,double h,double l,double c, bool is_current) { // --- markers-only mode: keep chart minimal if(m_markers_only) { DrawSessionMarkers(sess, t_open, t_close, is_current); return; } // ... original comprehensive drawing logic }
This conditional approach preserves backward compatibility while providing our streamlined output.
This modification demonstrates several professional development practices:
- Resource Efficiency: We leveraged existing, tested code rather than starting from scratch.
- Purpose-Driven Design: We adapted functionality to match our specific project requirements—complementary visualization, not comprehensive analysis.
- Non-Destructive Enhancement: We added new capabilities without removing or breaking existing ones. The original component remains fully functional for other applications.
- User Experience Focus: Our adaptation reduces visual clutter while maintaining essential information, creating a better experience for traders using our world map visualization.
The modified SessionVisualizer.mqh file is attached below this article, and the original remains available at the MQL5 article link for developers who need the comprehensive visualization. This approach—adapting rather than rebuilding—allowed us to focus our development efforts on the unique aspects of our project.
Now, with our visual assets prepared and our session marker component adapted, we're ready to build the main WorldSessionSlides EA that brings these elements together into a cohesive trading tool.
The WorldSessionSlides EA
1. Setting the Foundation: Properties and Resources
We start with #property strict because professional code doesn't cut corners—this enforces strong typing and catches errors early.
The real magic begins with the #resource directives. Instead of loading images from disk during runtime (which would fail if users move files), we embed them directly into the EX5 file. Think of it like baking your ingredients into the cake—no external dependencies, no missing files. We provide both light and dark theme options because serious traders work in different environments; some prefer bright charts during the day, while others need dark themes for night sessions.
//+------------------------------------------------------------------+ //| WorldSessionSlides.mq5 | //| Session-based world map slideshow + session time markers | //| with terminal & push notifications on session changes | //+------------------------------------------------------------------+ #property strict #property copyright "Clemence Benjamin" #property link "https://mql5.com" #property version "1.00" //--- Embed BLUE OCEAN bitmaps as resources #resource "\\Images\\world_idle.bmp" #resource "\\Images\\world_sydney.bmp" #resource "\\Images\\world_tokyo.bmp" #resource "\\Images\\world_london.bmp" #resource "\\Images\\world_newyork.bmp" //--- Embed DARK GRAY theme bitmaps as resources #resource "\\Images\\world_idle_dark.bmp" #resource "\\Images\\world_sydney_dark.bmp" #resource "\\Images\\world_tokyo_dark.bmp" #resource "\\Images\\world_london_dark.bmp" #resource "\\Images\\world_newyork_dark.bmp"
2. Configuring User Preferences: The Input Section
We're not hard-coding session times because brokers differ—some might have Sydney opening at 21:00, others at 22:00. By making these inputs, we ensure our tool works globally.
We give users three tiers of alerts. Some traders want peace and quiet (NOTIFY_OFF), others want to know every session change, while serious volatility traders might only care about overlaps where the real action happens. The push notification option is deliberately defaulted to false—mobile alerts should be an opt-in choice, not an annoyance.
//--- Inputs: session times in broker time (hours 0..23) input int InpSydneyOpen = 22; input int InpSydneyClose = 7; // ... (other session inputs) //--- Timer period in seconds input int InpCheckPeriod = 15; //--- Theme toggle: false = blue ocean, true = dark gray input bool InpUseDarkTheme = false; //--- Marker control input bool InpShowSessionMarkers = true; input int InpMarkersGMTOffset = 0; //--- Notification control enum ENUM_NOTIFY_MODE { NOTIFY_OFF = 0, NOTIFY_SESSION_CHANGES, NOTIFY_OVERLAPS_ONLY }; input ENUM_NOTIFY_MODE InpNotifyMode = NOTIFY_SESSION_CHANGES; input bool InpTerminalAlerts = true; input bool InpPushNotifications = false;
3. Core Logic: Time Calculations and Bitmask Magic
HourInRange() handles a tricky reality—some sessions cross midnight. Sydney (22:00 to 07:00) wraps around, so we need logic that understands "22 or later OR before 7" rather than a simple range check.
The GetSessionMaskFromTime() function is where we get clever. Instead of tracking each session with separate variables, we use a bitmask—a single integer where each bit represents a session's state. Bit 0 for Sydney, bit 1 for Tokyo, and so on. This gives us several advantages: we can check multiple sessions at once (overlaps), compare states quickly, and use minimal memory. When we see mask |= (1 << SESSION_SYDNEY), we're setting the Sydney bit without affecting others.
bool HourInRange(int start_hour,int end_hour,int h) { if(start_hour < end_hour) return (h >= start_hour && h < end_hour); if(start_hour > end_hour) return (h >= start_hour || h < end_hour); return(false); } int GetSessionMaskFromTime(datetime t) { MqlDateTime st; TimeToStruct(t,st); int h = st.hour; int mask = 0; if(HourInRange(InpSydneyOpen,InpSydneyClose,h)) mask |= (1 << SESSION_SYDNEY); // ... other sessions return(mask); }
4. Session Intelligence: Overlap Detection and Priority
When two sessions overlap, which map do we show? Our priority system (New York > London > Tokyo > Sydney) reflects market importance. The New York-London overlap shows New York, and the London-Tokyo overlap shows London—this matches where most liquidity flows.
The label builder handles all combinations: single sessions show "LONDON SESSION (LIVE)", overlaps show "LONDON + NEW YORK SESSIONS (OVERLAP)". This immediate visual feedback tells us what's active, and whether we are in high-liquidity periods.
//+------------------------------------------------------------------+ //| Build a bitmask of all active sessions at time t | //| bit 0: Sydney, bit 1: Tokyo, bit 2: London, bit 3: New York | //+------------------------------------------------------------------+ int GetSessionMaskFromTime(datetime t) { MqlDateTime st; TimeToStruct(t,st); int h = st.hour; int mask = 0; if(HourInRange(InpSydneyOpen,InpSydneyClose,h)) mask |= (1 << SESSION_SYDNEY); if(HourInRange(InpTokyoOpen,InpTokyoClose,h)) mask |= (1 << SESSION_TOKYO); if(HourInRange(InpLondonOpen,InpLondonClose,h)) mask |= (1 << SESSION_LONDON); if(HourInRange(InpNewYorkOpen,InpNewYorkClose,h)) mask |= (1 << SESSION_NEWYORK); return(mask); } //+------------------------------------------------------------------+ //| Count how many sessions are active in mask (for overlaps) | //+------------------------------------------------------------------+ int CountActiveSessions(int mask) { int count = 0; for(int i=0; i<4; ++i) { if(mask & (1<<i)) count++; } return(count); } //+------------------------------------------------------------------+ //| Pick one "dominant" session from a mask (for bitmap selection) | //| Priority: New York > London > Tokyo > Sydney | //+------------------------------------------------------------------+ int DominantSessionFromMask(int mask) { if((mask & (1 << SESSION_NEWYORK)) != 0) return SESSION_NEWYORK; if((mask & (1 << SESSION_LONDON)) != 0) return SESSION_LONDON; if((mask & (1 << SESSION_TOKYO)) != 0) return SESSION_TOKYO; if((mask & (1 << SESSION_SYDNEY)) != 0) return SESSION_SYDNEY; return SESSION_NONE; } //+------------------------------------------------------------------+ //| Build human-readable label from mask (handles overlaps) | //+------------------------------------------------------------------+ string BuildSessionLabel(int mask) { if(mask == 0) return "NO MAJOR SESSION (IDLE MAP)"; string label = ""; int count = 0; if((mask & (1 << SESSION_SYDNEY)) != 0) { if(count > 0) label += " + "; label += "SYDNEY"; count++; } if((mask & (1 << SESSION_TOKYO)) != 0) { if(count > 0) label += " + "; label += "TOKYO"; count++; } if((mask & (1 << SESSION_LONDON)) != 0) { if(count > 0) label += " + "; label += "LONDON"; count++; } if((mask & (1 << SESSION_NEWYORK)) != 0) { if(count > 0) label += " + "; label += "NEW YORK"; count++; } if(count > 1) label += " SESSIONS (OVERLAP)"; else label += " SESSION (LIVE)"; return(label); }
5. Professional Visualization: Chart Objects Done Right
They create chart objects without proper management. Our EnsureBackgroundObject() pattern checks if the object exists before creating it, preventing duplicates. The OBJPROP_BACK, true is crucial—it places our map behind price candles, so we're enhancing the chart, not blocking it.
CenterBackgroundToChart() shows professional attention to detail. We read the actual image dimensions from the resource, then center it mathematically. If the chart is smaller than our map, we allow negative offsets—the image gets cropped symmetrically. This maintains visual quality without distortion.
//+------------------------------------------------------------------+ //| Create background bitmap label if missing | //+------------------------------------------------------------------+ void EnsureBackgroundObject() { // Make sure chart is NOT in foreground mode so BACK objects sit behind candles ChartSetInteger(0,CHART_FOREGROUND,false); if(ObjectFind(0,g_bg_name) < 0) { if(!ObjectCreate(0,g_bg_name,OBJ_BITMAP_LABEL,0,0,0)) { Print(__FUNCTION__,": failed to create bitmap label, error=",GetLastError()); return; } ObjectSetInteger(0,g_bg_name,OBJPROP_CORNER,CORNER_LEFT_UPPER); ObjectSetInteger(0,g_bg_name,OBJPROP_BACK,true); // draw behind candles } } //+------------------------------------------------------------------+ //| Center the bitmap in the chart, using its original size | //| - No scaling; symmetric cropping when chart is smaller | //+------------------------------------------------------------------+ void CenterBackgroundToChart(const string file) { if(ObjectFind(0,g_bg_name) < 0) return; // Chart size in pixels int chartW = (int)ChartGetInteger(0,CHART_WIDTH_IN_PIXELS); int chartH = (int)ChartGetInteger(0,CHART_HEIGHT_IN_PIXELS); if(chartW <= 0 || chartH <= 0) return; // Read image size from resource uint imgW = 0, imgH = 0; uint data[]; if(!ResourceReadImage(file,data,imgW,imgH)) { // Fallback: put object at (0,0) and stretch object to chart ObjectSetInteger(0,g_bg_name,OBJPROP_XDISTANCE,0); ObjectSetInteger(0,g_bg_name,OBJPROP_YDISTANCE,0); ObjectSetInteger(0,g_bg_name,OBJPROP_XSIZE,chartW); ObjectSetInteger(0,g_bg_name,OBJPROP_YSIZE,chartH); return; } if(imgW == 0 || imgH == 0) return; int imgWi = (int)imgW; int imgHi = (int)imgH; // Object size = image size (no scaling) ObjectSetInteger(0,g_bg_name,OBJPROP_XSIZE,imgWi); ObjectSetInteger(0,g_bg_name,OBJPROP_YSIZE,imgHi); // Compute offset so that image center aligns with chart center int xOffset = (chartW - imgWi) / 2; int yOffset = (chartH - imgHi) / 2; // Negative offsets are allowed (chart will crop symmetrically) ObjectSetInteger(0,g_bg_name,OBJPROP_XDISTANCE,xOffset); ObjectSetInteger(0,g_bg_name,OBJPROP_YDISTANCE,yOffset); }
6. Notification System: Smart Alerts
The check if(InpNotifyMode == NOTIFY_OVERLAPS_ONLY && active < 2) return means it won't bother someone who only cares about volatility periods. Notice how we include both symbol and timeframe in the message—if you're running this on multiple charts, you'll know exactly which one changed.
void NotifySessionChange(int old_mask,int new_mask) { if(InpNotifyMode == NOTIFY_OFF) return; int active = CountActiveSessions(new_mask); if(InpNotifyMode == NOTIFY_OVERLAPS_ONLY && active < 2) return; string msg = "WorldSessionSlides: " + BuildSessionLabel(new_mask) + " on " + _Symbol + " [" + EnumToString((ENUM_TIMEFRAMES)_Period) + "]"; if(InpTerminalAlerts) Alert(msg); if(InpPushNotifications) SendNotification(msg); }
7. Event-Driven Architecture: The Main Loop
Instead of constantly checking (which wastes CPU), we use OnTimer() to sample at reasonable intervals (default 15 seconds). We only update when something actually changes—comparing bitmasks is lightning fast.
The OnChartEvent() handler shows foresight: when users resize charts, our map re-centers automatically. No glitches, no manual adjustments needed.
void OnTimer() { int mask_now = GetSessionMaskFromTime(TimeCurrent()); if(mask_now != g_current_session_mask) { int old_mask = g_current_session_mask; g_current_session_mask = mask_now; ShowSessionSlideByMask(g_current_session_mask); NotifySessionChange(old_mask, g_current_session_mask); } } void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam) { if(id == CHARTEVENT_CHART_CHANGE) { EnsureBackgroundObject(); if(g_last_bitmap_file != "") CenterBackgroundToChart(g_last_bitmap_file); } }
8. Clean Initialization and Shutdown
OnInit() sets everything up correctly on the first run. We clamp the timer period to at least 5 seconds—preventing users from accidentally setting 1-second checks that would hog CPU.
OnDeinit() is equally important. We kill our timer, delete our chart objects, and clean up session markers. No memory leaks, no orphaned objects left on charts.
int OnInit() { g_current_session_mask = GetSessionMaskFromTime(TimeCurrent()); ShowSessionSlideByMask(g_current_session_mask); if(InpShowSessionMarkers) { g_sess_vis.SetGMTOffset(InpMarkersGMTOffset); g_sess_vis.SetShowWicks(false); g_sess_vis.SetMarkersOnly(true); g_sess_vis.RefreshSessions(1); } g_check_period = (InpCheckPeriod < 5 ? 5 : InpCheckPeriod); EventSetTimer(g_check_period); return(INIT_SUCCEEDED); } void OnDeinit(const int reason) { EventKillTimer(); ObjectDelete(0,g_bg_name); ObjectDelete(0,g_text_name); if(InpShowSessionMarkers) g_sess_vis.ClearAll(); }
Testing
Our comprehensive testing protocol—executed across both the MetaTrader 5 terminal and integrated strategy tester—validated the system's core functionality with exceptional precision. The session detection algorithm consistently triggered correct visual transitions, while the rendering engine maintained stable performance without memory leaks or graphical artifacts.

Testing the WorldSessionSlides
The attached image series captures definitive proof points:
- Session-Specific Maps: Sydney, Tokyo, London, and New York sessions each display their corresponding highlighted regions
- Dynamic Transitions: Timestamped sequences show smooth handoffs between sessions
- Overlap Scenarios: Multiple active sessions correctly display with combined labeling
- Theme Adaptation: Consistent rendering in both Blue Ocean and Dark Gray themes
- Notification Integration: Terminal alerts firing precisely at session boundaries
These results confirm that traders can now visually track global market activity in real-time, transforming temporal data into spatial awareness. The strategy tester journal shows that we can receive session alerts too; see the log snippet below.
2025.12.03 11:33:55.238 2025.12.01 07:00:00 Alert: WorldSessionSlides: TOKYO SESSION (LIVE) on EURUSD [PERIOD_M5] 2025.12.03 11:33:59.696 2025.12.01 08:00:00 Alert: WorldSessionSlides: TOKYO + LONDON SESSIONS (OVERLAP) on EURUSD [PERIOD_M5] 2025.12.03 11:34:06.315 2025.12.01 09:00:00 Alert: WorldSessionSlides: LONDON SESSION (LIVE) on EURUSD [PERIOD_M5] 2025.12.03 11:34:21.396 2025.12.01 13:00:00 Alert: WorldSessionSlides: LONDON + NEW YORK SESSIONS (OVERLAP) on EURUSD [PERIOD_M5] 2025.12.03 11:34:39.553 2025.12.01 17:00:00 Alert: WorldSessionSlides: NEW YORK SESSION (LIVE) on EURUSD [PERIOD_M5] 2025.12.03 11:34:55.388 2025.12.01 22:00:00 Alert: WorldSessionSlides: SYDNEY SESSION (LIVE) on EURUSD [PERIOD_M5]
Conclusion
In summary, we have successfully engineered a simple yet useful visual trading tool that transforms abstract market timing into immediate geographical intuition. By implementing an intelligent session detection system paired with dynamic world map visualization, we have solved the critical problem of temporal disorientation in global markets. The solution demonstrates that professional MQL5 development bridges technical precision with practical trading psychology, creating tools that display information and fundamentally enhance market perception.
Technically, our implementation showcases industry best practices through its efficient bitmask session tracking, resource-embedded graphics, and event-driven architecture. The rigorous testing validation confirms the system's reliability across both live and historical environments, with flawless session transitions and adaptive theme rendering. This project exemplifies how robust coding methodologies—encompassing proper memory management, error handling, and user-centric design—produce tools worthy of professional trading environments.
Ultimately, this tool represents more than just another indicator; it signifies a shift toward visual intelligence in trading workflows. By making the market's geographical rhythms intuitively accessible, we empower traders to develop deeper market sense while reducing cognitive load. The project successfully proves that when technical excellence meets trading insight, the result transforms how traders interact with—and understand—the global market's continuous flow.
However, there were some unusual observations during testing. While most slides displayed with clear visuals, a few showed light “showers” or glitches. My first thought was that this might be related to small RAM, but the logs reported no errors, so it’s also possible that some of the images were simply too heavy to process smoothly. I am still investigating the root cause of this glitch and will be happy to share my findings in a future update.
All source files and images used in this project are attached below, along with their descriptions in the attachments table. You’re welcome to join the discussion in the comments section. Until our next publication, stay tuned.
Key Lessons
| Key Lesson | Description |
|---|---|
| Bitmask State Management | Master efficient session tracking using bitwise operations—storing multiple session states in a single integer for fast overlap detection and minimal memory usage, while enabling sophisticated market analysis. |
| Event-Driven Architecture | Design efficient systems using OnTimer() for periodic checks and OnChartEvent() for responsive UI updates, allowing session visualization to run seamlessly without resource-intensive polling loops. |
| Time Mathematics with Wrap-around Logic | Implement robust time range calculations that handle sessions crossing midnight correctly, a critical skill for accurate global market analysis across different time zones. |
| Resource Embedding & Management | Learn to embed bitmap files directly into EX5 executables using #resource directives, creating professional visual tools that maintain portability across different trading environments. |
| Session-Specific Strategy Alignment | Understand and program for session characteristics: Tokyo's technical precision for JPY pairs, London's directional momentum for EUR/GBP, and optimal overlap periods for volatility strategies. |
| Overlap Opportunity Detection | Implement logic that identifies and highlights critical overlap periods (Tokyo-London, London-New York) where liquidity surges create premium trading opportunities across multiple styles. |
| Professional Chart Object Handling | Master proper creation, positioning, and cleanup of chart objects with attention to rendering layers (BACK vs FRONT), ensuring visual clarity without interfering with price action analysis. |
| Session-Based Risk Management | Develop systems that automatically adjust trading parameters based on session volatility patterns—higher activity during overlaps versus reduced risk during single sessions or dead zones. |
| Modular Code Reusability | Apply professional development practices by adapting existing components (SessionVisualizer.mqh) with specialized modes while preserving original functionality for future projects. |
| Configurable Notification Systems | Build flexible alert systems with multiple notification modes tailored to different trading styles—from conservative overlap-only alerts to comprehensive session-change notifications. |
Attachments
| Source File | Version | Description |
|---|---|---|
| WorldSessionSlides.mq5 | 1.01 | Main expert advisor file containing the core session visualization logic, notification system, and chart event handlers. This file implements the dynamic world map display with real-time session tracking. |
| SessionVisualizer.mqh | 1.03 | Helper include file responsible for drawing session time markers on the price chart. Provides visual indicators for session boundaries and overlaps with configurable GMT offset and display settings. |
| Light_theme.zip | 1.00 | Blue Ocean theme graphical assets containing world map bitmaps for all trading sessions. Must be unpacked into the MQL5/Images folder to enable light theme visualization. |
| Dark_theme.zip | 1.00 | Dark Gray theme graphical assets containing world map bitmaps for all trading sessions. Must be unpacked into the MQL5/Images folder to enable dark theme visualization. |
Warning: All rights to these materials are reserved by MetaQuotes Ltd. Copying or reprinting of these materials in whole or in part is prohibited.
This article was written by a user of the site and reflects their personal views. MetaQuotes Ltd is not responsible for the accuracy of the information presented, nor for any consequences resulting from the use of the solutions, strategies or recommendations described.
Chaos Game Optimization (CGO)
Reimagining Classic Strategies (Part 19): Deep Dive Into Moving Average Crossovers
Automating Trading Strategies in MQL5 (Part 45): Inverse Fair Value Gap (IFVG)
Statistical Arbitrage Through Cointegrated Stocks (Part 8): Rolling Windows Eigenvector Comparison for Portfolio Rebalancing
- Free trading apps
- Over 8,000 signals for copying
- Economic news for exploring financial markets
You agree to website policy and terms of use