Hướng dẫn chi tiết về kiểu datetime, từ lấy thời gian hiện tại đến xử lý timezone và time filtering trong trading.
datetime trong MQL5 là kiểu dữ liệu lưu trữ ngày giờ dưới dạng số giây kể từ 00:00:00 ngày 01/01/1970 (Unix timestamp). Đây là kiểu dữ liệu quan trọng cho time-based analysis, session filtering, và schedule management.
// Thời gian server (broker time)
datetime serverTime = TimeCurrent();
// Thời gian local (máy tính)
datetime localTime = TimeLocal();
// Thời gian GMT (Greenwich Mean Time)
datetime gmtTime = TimeGMT();
// Thời gian của bar cuối cùng
datetime lastBarTime = iTime(_Symbol, PERIOD_CURRENT, 0);
Print("Server: ", TimeToString(serverTime, TIME_DATE|TIME_SECONDS));
Print("Local: ", TimeToString(localTime, TIME_DATE|TIME_SECONDS));
Print("GMT: ", TimeToString(gmtTime, TIME_DATE|TIME_SECONDS));
// DateTime → String
datetime now = TimeCurrent();
string dateOnly = TimeToString(now, TIME_DATE); // "2025.01.14"
string timeOnly = TimeToString(now, TIME_MINUTES); // "10:30"
string fullDateTime = TimeToString(now, TIME_DATE|TIME_SECONDS); // "2025.01.14 10:30:45"
// String → DateTime
string dateStr = "2025.01.14 10:30:00";
datetime converted = StringToTime(dateStr);
// Struct → DateTime
MqlDateTime timeStruct;
TimeToStruct(now, timeStruct);
Print("Year: ", timeStruct.year); // 2025
Print("Month: ", timeStruct.mon); // 1
Print("Day: ", timeStruct.day); // 14
Print("Hour: ", timeStruct.hour); // 10
Print("Minute: ", timeStruct.min); // 30
Print("Second: ", timeStruct.sec); // 45
Print("Day of Week: ", timeStruct.day_of_week); // 0=Sunday, 1=Monday, etc.
// DateTime → Struct
datetime timestamp = StructToTime(timeStruct);
datetime now = TimeCurrent();
// Cộng/trừ giây
datetime in1Hour = now + 3600; // +1 hour (3600 seconds)
datetime in1Day = now + 86400; // +1 day (86400 seconds)
datetime in1Week = now + 604800; // +1 week (604800 seconds)
// Sử dụng PeriodSeconds() để tính toán
int periodSeconds = PeriodSeconds(PERIOD_H1); // 3600
datetime nextBar = now + periodSeconds;
// So sánh datetime
datetime openTime = iTime(_Symbol, PERIOD_D1, 0);
if(now >= openTime) {
Print("Current time is after today's open");
}
// Tính khoảng cách thời gian (delta)
datetime time1 = StringToTime("2025.01.14 10:00:00");
datetime time2 = StringToTime("2025.01.14 14:30:00");
int deltaSeconds = (int)(time2 - time1); // 16200 seconds
int deltaMinutes = deltaSeconds / 60; // 270 minutes
int deltaHours = deltaMinutes / 60; // 4.5 hours
Print("Delta: ", deltaHours, " hours and ", deltaMinutes % 60, " minutes");
// Kiểm tra trading session
bool IsTradingSession(int startHour, int startMin, int endHour, int endMin) {
MqlDateTime timeStruct;
TimeToStruct(TimeCurrent(), timeStruct);
int currentMinutes = timeStruct.hour * 60 + timeStruct.min;
int startMinutes = startHour * 60 + startMin;
int endMinutes = endHour * 60 + endMin;
return (currentMinutes >= startMinutes && currentMinutes < endMinutes);
}
// Sử dụng
bool isAsianSession = IsTradingSession(0, 0, 9, 0); // 00:00 - 09:00
bool isEuropeanSession = IsTradingSession(8, 0, 17, 0); // 08:00 - 17:00
bool isUSSession = IsTradingSession(14, 30, 21, 0); // 14:30 - 21:00
if(isEuropeanSession) {
Print("Currently in European trading session");
}
// Kiểm tra ngày trong tuần
bool IsTradingDay() {
MqlDateTime timeStruct;
TimeToStruct(TimeCurrent(), timeStruct);
// 0=Sunday, 6=Saturday
return (timeStruct.day_of_week >= 1 && timeStruct.day_of_week <= 5);
}
// Tránh giao dịch vào cuối tuần
if(!IsTradingDay()) {
Print("Weekend - No trading");
return;
}
// Lấy thời gian của các bars
datetime barTime0 = iTime(_Symbol, PERIOD_CURRENT, 0); // Current bar
datetime barTime1 = iTime(_Symbol, PERIOD_CURRENT, 1); // Previous bar
// Kiểm tra new bar
static datetime lastBarTime = 0;
datetime currentBarTime = iTime(_Symbol, PERIOD_CURRENT, 0);
if(currentBarTime != lastBarTime) {
Print("New bar detected!");
lastBarTime = currentBarTime;
// Execute logic on new bar
}
// Copy bar times
datetime barTimes[];
ArraySetAsSeries(barTimes, true);
CopyTime(_Symbol, PERIOD_H1, 0, 100, barTimes);
// Tìm bar theo thời gian
datetime targetTime = StringToTime("2025.01.14 10:00:00");
int barShift = iBarShift(_Symbol, PERIOD_H1, targetTime);
Print("Bar shift: ", barShift);
// Timeframe conversions
int h1Seconds = PeriodSeconds(PERIOD_H1); // 3600
int d1Seconds = PeriodSeconds(PERIOD_D1); // 86400
ENUM_TIMEFRAMES tf = Period(); // Current timeframe
// Cấu trúc để lưu news time
struct NewsEvent {
datetime time;
string title;
int impact; // 1=Low, 2=Medium, 3=High
};
// Kiểm tra có news trong khoảng thời gian không
bool IsNewsTime(NewsEvent &events[], int minutesBefore, int minutesAfter) {
datetime now = TimeCurrent();
for(int i = 0; i < ArraySize(events); i++) {
datetime newsTime = events[i].time;
int deltaMinutes = (int)(MathAbs(now - newsTime) / 60);
if(deltaMinutes <= minutesBefore || deltaMinutes <= minutesAfter) {
if(events[i].impact >= 2) { // Medium or High impact
Print("News event nearby: ", events[i].title);
return true;
}
}
}
return false;
}
// Tránh trading 30 phút trước và sau news
NewsEvent myEvents[];
// ... populate events from calendar
if(IsNewsTime(myEvents, 30, 30)) {
Print("Skip trading - News time");
return;
}
// EA chỉ trade trong giờ nhất định
input int TradeStartHour = 8; // 08:00
input int TradeEndHour = 17; // 17:00
bool IsAllowedTradingTime() {
MqlDateTime timeStruct;
TimeToStruct(TimeCurrent(), timeStruct);
// Kiểm tra ngày trong tuần (Monday-Friday)
if(timeStruct.day_of_week < 1 || timeStruct.day_of_week > 5)
return false;
// Kiểm tra giờ
if(timeStruct.hour < TradeStartHour || timeStruct.hour >= TradeEndHour)
return false;
// Tránh 30 phút cuối session
if(timeStruct.hour == TradeEndHour - 1 && timeStruct.min >= 30)
return false;
return true;
}
// Trong OnTick()
void OnTick() {
if(!IsAllowedTradingTime()) {
return; // Skip logic
}
// Trading logic here...
}
// Close all positions trước cuối tuần
void CheckWeekendClose() {
MqlDateTime timeStruct;
TimeToStruct(TimeCurrent(), timeStruct);
// Friday after 21:00 - close all positions
if(timeStruct.day_of_week == 5 && timeStruct.hour >= 21) {
CloseAllPositions();
}
}
// ❌ SLOW: Convert to struct mỗi lần
void SlowMethod() {
for(int i = 0; i < 1000; i++) {
MqlDateTime timeStruct;
TimeToStruct(TimeCurrent(), timeStruct);
if(timeStruct.hour == 10) {
// Do something
}
}
}
// ✅ FAST: Convert một lần, cache kết quả
void FastMethod() {
MqlDateTime timeStruct;
TimeToStruct(TimeCurrent(), timeStruct);
int currentHour = timeStruct.hour;
for(int i = 0; i < 1000; i++) {
if(currentHour == 10) {
// Do something
}
}
}
TimeCurrent() (server time) cho trading logicMqlDateTime struct thay vì convert nhiều lầnstatic datetime để detect new bar== cho time ranges, dùng >= và <