Meridian Session Clock
- Libraries
-
Syarief Azman Bin Rosli
Hello and welcome to my official MQL5 profile!
I am Syarief Azman Bin Rosli, an algorithmic trading systems developer and quantitative software engineer with over a decade of specialized experience creating robust automated trading solutions for MetaTrader 5 and MetaTrader 4. - Version: 1.0
- Activations: 5
An MQL4 time library: DST-correct conversions between UTC and 12 world time zones, a model of your broker's server clock (auto-detected from price history), the Sydney, Tokyo, London and New York sessions plus your own, with open state, start and end times and OHLC range, the FX trading day and the weekend. Unlike TimeGMT(), it gives the same answers in the Strategy Tester as live. It never trades, draws or writes files. You receive the compiled Meridian_Session_Clock.ex4; this page is the complete API reference.
Quick Start
- Copy Meridian_Session_Clock.ex4 to MQL4/Libraries (File > Open Data Folder).
- Paste the #import block below into your EA, indicator or script.
- OnInit: MSC_DetectBroker("EURUSD", 104, base, conf, used), or MSC_SetBroker(MSC_US_DST, 120) if you know the server clock.
- Use server times (TimeCurrent(), Time[i]): MSC_SessionIsOpen(MSC_LONDON_SESSION, TimeCurrent()).
- Verify: run the example below in the Strategy Tester; the log prints the detected model and London's hours every bar.
Import Declaration (Copy-Paste Ready)
#import "Meridian_Session_Clock.ex4"
int MSC_ZoneOffset(int zone, datetime utc);
bool MSC_IsDST(int zone, datetime utc);
datetime MSC_ToZone(datetime utc, int zone);
datetime MSC_FromZone(datetime local, int zone);
datetime MSC_NextChange(int zone, datetime utc);
string MSC_ZoneName(int zone);
bool MSC_SetBroker(int model, int base_minutes);
int MSC_DetectBroker(string symbol, int weeks, int &base_minutes, double &confidence, int &weeks_used);
int MSC_BrokerOffset(datetime utc);
datetime MSC_ServerToUTC(datetime server_time);
datetime MSC_UTCToServer(datetime utc);
int MSC_SessionAdd(int zone, int start_minute, int end_minute, int days_mask);
void MSC_SessionClear();
string MSC_SessionName(int session);
bool MSC_SessionIsOpen(int session, datetime server_time);
datetime MSC_SessionStart(int session, datetime server_time, int index);
datetime MSC_SessionEnd(int session, datetime server_time, int index);
int MSC_SessionRange(string symbol, int timeframe, int session, datetime server_time, int index, double &result[]);
datetime MSC_TradingDayStart(datetime server_time);
bool MSC_IsWeekend(datetime server_time);
int MSC_LastError();
string MSC_ErrorText(int code);
#import
enum MSC_ZONE { MSC_UTC, MSC_LONDON, MSC_FRANKFURT, MSC_ATHENS, MSC_MOSCOW, MSC_DUBAI, MSC_SINGAPORE, MSC_TOKYO,
MSC_SYDNEY, MSC_WELLINGTON, MSC_NEW_YORK, MSC_CHICAGO };
enum MSC_MODEL { MSC_FIXED, MSC_US_DST, MSC_EU_DST };
enum MSC_SESSION { MSC_SYDNEY_SESSION, MSC_TOKYO_SESSION, MSC_LONDON_SESSION, MSC_NEW_YORK_SESSION }; Concepts
- Three kinds of time: utc; server (broker server time: TimeCurrent, bar times); local (wall time in a zone).
- Zones 0-11: UTC, London, Frankfurt, Athens, Moscow, Dubai, Singapore (also Hong Kong, Shanghai), Tokyo, Sydney, Wellington, New York, Chicago. DST follows each zone's law since 2000, including the US 2007, Sydney 2000 / 2006 / 2008, Auckland 2007 / 2008 and Moscow 2011 / 2014 changes. Supported 2000-2099; other times are computed with the same rules and flag -2.
- A local time skipped by a spring-forward change, or repeated by a fall-back change, is read with the offset in force before the change (New York 02:30 on the March change day = 07:30 UTC; 01:30 on the November day = 05:30 UTC, the first occurrence).
- Broker clock = UTC + offset. Models: 0 FIXED (base all year), 1 US DST (base + 60 in US summer: "New York close" brokers, GMT+2 / GMT+3), 2 EU DST (base + 60 in EU summer). Default 1 with base 120.
- Sessions are defined in a zone's local time, Monday-Friday by start day: 0 SYDNEY 07:00-16:00 Sydney, 1 TOKYO 09:00-18:00 Tokyo, 2 LONDON 08:00-17:00 London, 3 NEW YORK 08:00-17:00 New York; custom ids 4-15. An instance runs from start (inclusive) to end (exclusive). index 0 = the latest instance that started at or before the given time (open or finished), -1 the one before, +1 the next; -260 to 260.
API Reference
All functions set MSC_LastError. Bad zone or session ids give -1 and 0, false, "UNKNOWN" or -1.
MSC_ZoneOffset, MSC_IsDST, MSC_ToZone, MSC_FromZone
Offset of zone from UTC in minutes at utc; whether DST is in force (Moscow 2011-2014, permanent UTC+4, is not DST); utc + offset as local time; local time back to UTC with the rule above.
datetime ny = MSC_ToZone(MSC_ServerToUTC(TimeCurrent()), MSC_NEW_YORK);
MSC_NextChange and MSC_ZoneName
First offset change after utc (UTC time), 0 if none within three years (UTC, Dubai, Singapore, Tokyo, Moscow after 2014). Name of a zone, as listed above.
MSC_SetBroker
model 0-2, base_minutes -720 to 840 in steps of 15. false and -1 otherwise.
MSC_DetectBroker
Reads the first H1 bar after each weekend gap (36 hours or more) of symbol ("" = chart symbol), newest first, up to weeks (4-520, 0 = 104). FX opens on Sunday at 17:00 New York, so each week gives an offset; the model and base that fit most weeks win (ties: US DST, then EU DST, then FIXED). Returns the model and applies it when at least 60% of the weeks fit; otherwise -1 with -5 NOT DETECTED (base_minutes and confidence still filled). -3 NO DATA without H1 history. Use a 24/5 FX major: metals and indices open later on Sunday and read one hour too high (XAUUSD gave base 180 instead of 120 in the tests). Use 52 weeks or more so that DST changes are included; holiday weeks lower the confidence. In the Strategy Tester only the history the tester loaded is visible (weeks_used tells how many weeks were read).
int base, used; double conf;
int model = MSC_DetectBroker("EURUSD", 104, base, conf, used); MSC_BrokerOffset, MSC_ServerToUTC, MSC_UTCToServer
Server offset in minutes at utc; server time to UTC (rule above for the hour around a change); UTC to server time.
MSC_SessionAdd, MSC_SessionClear, MSC_SessionName
Adds a session: zone, start and end in minutes after local midnight (0-1439, different; end below start = overnight), days_mask of start days (bit 0 Sunday to bit 6 Saturday, 62 = Monday-Friday, 1-127). Returns id 4-15, or -1 with -1 or -4 SESSION LIMIT. MSC_SessionClear deletes custom sessions (ids are reused from 4). Names: SYDNEY, TOKYO, LONDON, NEW YORK, CUSTOM n.
int fra = MSC_SessionAdd(MSC_FRANKFURT, 7 * 60, 15 * 60 + 30, 62); // 07:00-15:30 Frankfurt
MSC_SessionIsOpen, MSC_SessionStart, MSC_SessionEnd
Whether instance 0 contains server_time; server time of the start or end of instance index. 0 on error.
if(MSC_SessionIsOpen(MSC_LONDON_SESSION, TimeCurrent()) && !MSC_SessionIsOpen(MSC_NEW_YORK_SESSION, TimeCurrent())) { } MSC_SessionRange
OHLC of instance index from the bars of symbol ("" = chart) on timeframe (0 = chart; M1, M5, M15, M30 or H1) whose open time is inside the instance. result[] gets 7 values: 0 open, 1 high, 2 low, 3 close, 4 time of the first bar at the high, 5 time of the first bar at the low, 6 bars. Returns the bar count; 0 with -3 NO DATA if no bar is inside; -1 for a bad timeframe, session or index. A running instance uses the bars so far.
double r[]; if(MSC_SessionRange("", PERIOD_M15, MSC_TOKYO_SESSION, TimeCurrent(), -1, r) > 0) Print("Tokyo high ", r[1]); MSC_TradingDayStart and MSC_IsWeekend
Server time of the latest 17:00 New York at or before server_time (the FX day start). Weekend = Friday 17:00 to Sunday 17:00 New York.
MSC_LastError and MSC_ErrorText
Code of the last call; text: 0 OK, -1 INVALID PARAMETER, -2 OUT OF RANGE, -3 NO DATA, -4 SESSION LIMIT, -5 NOT DETECTED, otherwise UNKNOWN.
Working Integration Example
An Expert Advisor; paste the import block and the enum lines above first.
datetime last = 0;
int OnInit()
{
int base, used; double conf;
int m = MSC_DetectBroker("EURUSD", 104, base, conf, used);
if(m < 0) MSC_SetBroker(MSC_US_DST, 120);
PrintFormat("model %d base %d conf %.2f weeks %d: %s", m, base, conf, used, MSC_ErrorText(MSC_LastError()));
return(INIT_SUCCEEDED);
}
void OnTick()
{
if(Time[0] == last) return;
last = Time[0];
datetime now = TimeCurrent();
PrintFormat("London %s - %s server, open %d, FX day since %s, weekend %d",
TimeToString(MSC_SessionStart(MSC_LONDON_SESSION, now, 0)), TimeToString(MSC_SessionEnd(MSC_LONDON_SESSION, now, 0)),
MSC_SessionIsOpen(MSC_LONDON_SESSION, now), TimeToString(MSC_TradingDayStart(now)), MSC_IsWeekend(now));
} Architecture and Notes
- Pure calculation: rules are computed, not looked up, so nothing is downloaded. The broker model and the session table are kept per program that imports the library.
- MetaTrader 4, any symbol and timeframe; EAs, indicators, scripts. Safe in the Strategy Tester and optimization: no DLLs, files, web requests, chart objects, timers or global variables. Only MSC_DetectBroker and MSC_SessionRange read bars.
- Limits: 16 sessions (4 built-in), instance index -260 to 260, years 2000-2099.
- Typical setups. Session filter: trade only while MSC_SessionIsOpen(MSC_LONDON_SESSION, now). Asian range breakout: MSC_SessionRange of MSC_TOKYO_SESSION, index 0, at the London open (Tokyo is still open then). Daily logic: reset at MSC_TradingDayStart. Backtests: call MSC_DetectBroker or MSC_SetBroker in OnInit, never TimeGMT().
- The screenshots and video show a demonstration EA built on this library; it is not part of the purchase.
Risk Notice
Session times describe when markets are usually active, not how prices will move. Check your broker's holiday schedule; test on a demo account first.
