Trang chủ Kiến thức DateTime trong MQL5: Làm Việc với Thời Gian
Knowledge

DateTime trong MQL5: Làm Việc với Thời Gian

14 tháng 11, 2025

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: Kiểu Dữ Liệu Thời Gian

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.

Lấy Thời Gian Hiện Tại

// 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));

Chuyển Đổi DateTime

// 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);

Các Phép Toán với DateTime

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");

Time Filtering: Trading Sessions

// 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;
}

Working with Bars and Timeframes

// 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

News and Economic Calendar Filtering

// 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;
}

Ứng Dụng Thực Tế: Time-Based EA Logic

// 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();
    }
}

Performance: Datetime vs Timestamp

// ❌ 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
        }
    }
}

Best Practices

  • ✅ Sử dụng TimeCurrent() (server time) cho trading logic
  • ✅ Cache MqlDateTime struct thay vì convert nhiều lần
  • ✅ Kiểm tra weekend và news events trước khi trade
  • ✅ Sử dụng static datetime để detect new bar
  • ⛔ Tránh hardcode timezone offsets, sử dụng broker time
  • ⛔ Không so sánh datetime với == cho time ranges, dùng >=<

Bài Tập Thực Hành

  1. Viết hàm kiểm tra có phải giờ overlap giữa European và US session không (14:30-17:00 GMT)
  2. Tạo hàm tính số ngày trade còn lại trong tháng (bỏ qua weekend)
  3. Viết EA đóng tất cả positions nếu đã mở quá 24 giờ

Tài Liệu Tham Khảo