개요
- 메타트레이더 에서의 시각은 UTC 로 통일되어 있지 않고 브로커 마다 다르며 , 통상 UTC + 2, UTC +3 으로 되어있다. 브로커의 서버 위치의 로컬 시라고 설명하고 있으나 꼭 그렇지도 않다. 암튼 난 이 시간을 메타시간이라고 표현한다.
- 메타 트레이더 코딩 하는 경우에도 모든 시간들은 메타 시간으로 반환되기 때문에 UTC 가 아니어서 더 헷갈리게 만들고 있으며, 시간 관련 주요 정보 활용하는 코드 작성시 일관성 훼손하는 주범이다.
- - 예로 캔들 데이터 구조체인 MqlRate 의 멤버로 time 이 있는데 이 시간 역시 메타시간 이다. 그 외 mql5 의 모든 시간이 메타시간 임.
- utc 로 변환하는 함수들은 직접 구현해야 하는데, 단순이 UTC+2 처럼 항상고정적이면 쉽게 UTC 로 변환 가능하나 상황을 복잡하게 하는 것은 메타시간에 일광절약 시간이 적용되는 경우이다. 따라서 메타시간을 정확하게 UTC 로 변환하려면 메타시간이 속한 시간대 점검하고 동시에 일광절약 시간 적용여부도 점검하여 최종 UTC 시간으로 변환해야 함.
잡설. 메타트레이더가 이런 쓰레기 시각을 사용하는 이유 추정.
- 메타트레이더가 첫 출시된 시점이 2005년이었고 글로벌 금융데이터 개념이 약했던 것으로 보임.
- 비록 유용하지 않은 시각임에도 일관성 있게 유지 하는 특성은 장점에 해당하긴 한다. 일관성이 유지되면 활용하는 측 에서 일관성 있게 해결 할 수 있기 때문이다.
- 메타트레이더의 최고의 장점 중의 하나가 그들이 제품에서 표현하는 기능 및 내부 규칙 적용의 엄격함과 일관성을 유지하고 있다는 점이다. 이런 저런 잡다한 문제들 혹은 오만 소비자들의 잡다구리한 요구사항에 다 맞추겠다고 자기 모순적 땜빵 처리하는 것보다는 훨씬 좋은 특성이다.
비교 : 모든 암호화폐 거래소 API (예 : bybit API) 들을 보면 시각 정보는 모두 공통적으로 UTC 시각이 표준으로 정착되었음. <- 이게 정상임.
코드1. UTC 대비 메타시간의 오프셋 시 구하기.
- 메타시간 = UTC + 오프셋 에서 오프셋 구하는 것.
- 실시간 호출한 시점에 DST(Daylight Saving Time. 일광절약 시간대 ) 적용된다면 mql 내장 함수인 TimeCurrent() ; 에는 DST 적용된 시간이 반환된다.
void CCy_MetaTimeToUTC_1::calc_meta_time_offset_sec()
{
// TimeCurrent() : 메타 서버의 현재 시각 확보. 초단위.
// TimeGMT() : UTC 현재 시각 확보. 초단위.
m_MetaTime_OffsetSec = TimeCurrent() - TimeGMT(); // 메타타임의 오프셋시간 초단위로 받았음.
// 메타시각에서 DST 적용 여부를 점검할 필요가 없음
// TimeCurrent()와 TimeGMT()의 차이는 이미 DST가 적용된 서버 시간과 UTC 시간의 차이.
Print("m_MetaTime_OffsetSec = ", m_MetaTime_OffsetSec);
}
위 코드의 문제점들
1. 실시간 현재 시점 상태만 알 수 있음.
위 코드에서 사용된 MQL5 내장 함수 TimeCurrent() ; TimeGMT() 는 호출한 시점의 상태만 알 수 있기 때문에, 이 정보만으로는 코드내에서 과거 캔들 1000개를 요청하여 시간정보를 UTC 로 변환하는 용도로 사용 못한다. 호출한 시점 기준 과거 1000개들 캔들 내에서 시간대가 변경되었다면 어떤 캔들 시점부터 DST 가 적용되었는지 알아야만 정확한 UTC 로 변환 가능하다.
2. 위 코드는 메타트레이더의 백테스팅 하는 Strategy Tester 에서 실행하면 아래처럼 작동한다.
TimeCurrent() 반환값 : Stratgey Tester 실행환경에서는 백테스트용으로 사전에 저장된 데이터에 기록된 시간을 반환하는데 . 이 시간이 메타시간으로 기록되어있기에 TimeCurrent() 반환값은 메타시각이다.
TimeGMT() 반환값 : Stratgey Tester 실행환경에서는 이 값은 TimeCurrent() 와 동일한 값을 반환함. 즉, 백 데이터 저장 체계에서 메타시각인 시점의 UTC 시각을 알 수 있는 정보 기록이 안되고 있음. 메타 시각이 써머타임까지 적용되고 있는 것이라면 UTC 로 변환할 수 있는 변환 정보도 같이 기록되어야 하는데 이 부분이 백데이터용 데이터 저장 형식에 반영되어있지 않음.
코드1의 결론 : 위 코드1과 같은 같은 방법으로는 실시간 틱 데이터의 시각을 UTC 로 변환하는 용도로만 사용가능하다.
코드2. DST( Datlight Saving Time ) 의 세밀한 정보를 코드에 포함하기
- 아래 코드 처럼 DST 정보가 있는 구조체 정의하여 특정 메타시간 의 DST 적용여부를 점검하면서 UTC 변환 처리해야하는데 해당 브로커에 적용중인 DST 의 정확한 정보를 구할 수 있어야 한다.
- 아래 DST 구조체는 월일 만 표기하고 있는데, 이 DST 정책이 한 5년 정도 적용되다가 폐지되었다면 추가로 DST 적용 년 정보도 있어야 한다.
// DST 규칙 정보 구조체
struct DST_Info {
int start_month; // DST 시작 월
int start_day; // DST 시작 일
int end_month; // DST 종료 월
int end_day; // DST 종료 일
int offset; // DST 적용 시 추가 오프셋 (시간 단위)
};
// DST가 적용되는지 확인하는 함수
bool IsDST(datetime local_time, DST_Info dst_info, int year) {
// DST 시작일과 종료일 설정
datetime start_dst = TimeSet(0, dst_info.start_month, dst_info.start_day, year);
datetime end_dst = TimeSet(0, dst_info.end_month, dst_info.end_day, year);
// DST가 시작일과 종료일 사이에 있는지 확인
return (local_time >= start_dst && local_time <= end_dst);
}
// 브로커 시간대 오프셋 (예: GMT+3)
int broker_offset = 3;
// DST 정보 (예: 3월 두 번째 일요일부터 11월 첫 번째 일요일까지)
DST_Info dst_info = {3, 8, 11, 1, 1};
// 서버 시간에서 UTC로 변환하는 함수
datetime ConvertToUTC(datetime server_time_bar, int offset, DST_Info dst_info) {
int year = TimeYear(server_time_bar);
int actual_offset = offset;
// DST 적용 여부 확인
if (IsDST(server_time_bar, dst_info, year)) {
actual_offset += dst_info.offset;
}
return server_time_bar - (actual_offset * 3600); // 시간 단위로 오프셋 변환
}
// 예시 사용:
// MqlRates 구조체 배열 선언 및 데이터 가져오기
MqlRates rates[];
int count = CopyRates(_Symbol, PERIOD_M1, 0, 10, rates);
if (count > 0)
{
// 첫 번째 바의 서버 시간을 UTC로 변환
datetime utc_time_bar = ConvertToUTC(rates[0].time, broker_offset, dst_info);
Print("UTC Time (Bar): ", TimeToString(utc_time_bar, TIME_DATE | TIME_MINUTES));
}
참고.
Strategy Tester 에서 TimeGMT() 실행이 정확하지 않은 문제 해결 위한 라이브러리 제작자도 있음.
https://www.mql5.com/en/code/48291
https://www.mql5.com/en/code/48650
금융 데이터에서 시각 정보 매니징 위한 절대 규칙 : UTC
- 데이터 기록시 UTC 시각을 기록하면 모든 이후 상황과 체계들이 깔끔하고 명확함에도, 로컬시각과 그 와중에 작위적인 써머타임 시각까지 겹쳐져 잡탕이 되었다. 써머타임 같은 경우는 한동안 시행하다가 폐지하는 경우도 발생가능하므로 일관성 마저 없다.
- 암호화폐의 경우 API (예 : 바이비트 API 등 )로 제공되는 모든 시각은 일관되게 모두 UTC 로 되어있어 아무런 혼선 이 발생하지 않는다. 이게 당연한거다.
- 글로벌 금융데이터들 (유럽에 있는 FXTM의 데이터, 싱가포르에 있는 바이비트 거래소의 데이터, 미국에 있는 FXCM 의 데이터 등 ... ) 관리하는 경우, 로컬시에 서머타임까지 적용되었다 말았다하는 혼선 일으키는 쓰레기 개판 잡탕 시각 절대 사용하지 말고 UTC 로 일관되게 시각 정보를 관리하는 게 당연함.
- 꼭 로컬시로 보여달라는 사용자가 있는 경우에만 UTC 를 로컬시로 표현하면 되고 구질구질한 일광절약 적용여부도 사람에게만 표현해 주면 된다. 일광절약용으로 시간대를 임의 변경하는 이런 개념은 정말 치가 떨릴 정도로 무지 몽매 오만 방자한 발상이다. 완전 작위적인 것이다. 써머타임 적용해서 에너지 손실 줄였다고 해도 이 시간대 변경하는 과정에서 에너지 더 사용해야 하는건 몰라? 해당 지역 서버 시간 모두 변경해야 하고, 시각 정보 중요한 매니징 해야 하는 사람들이 이 시간대 처리하느라고 개노가다 하는 과정에서 에너지 손실 더 많이 생긴다. 이 빡대가리들아..
일광절약을 위해 굳이 시간대를 변경하지 않고 9시 출근을 8시 출근하고 퇴근시간을 6시에서 5시로 출퇴근 시간을 변경해도 될것을 빡대가리 정책 결정권자가 딴에는 묘수라고 생각했나봄... 묘수는 무슨... 그들이 대중을 얼마나 무지하고 단순한 집단으로 보는지 알 수 있게 하는 대목임. 뭐... 비록 진짜 대중이 좀 무지하고 단순 무식한 애들이 많긴 하다만...
한국도 과거 잠시 일광절약 시간대 적용했다가 폐지되었었지, 한국인 대부분이 쓰잘데기 없는 짓거리라고 여겼음. 역시 한국인이 세계 평균보다는 좀 더 높은 지능을 가진 건 사실인듯함.
상위 정리
첫 등록 : 2024.08.27
최종 수정 : 2024.08.28
단축 주소 : https://igotit.tistory.com/5791
'트레이딩 > 메타트레이더 코딩' 카테고리의 다른 글
MQL5. 외부 프로그램으로 실시간 데이터 송신 . SendMessage, PostMessage, WM_COPYDATA (0) | 2024.09.06 |
---|---|
메타트레이더 5 . ONNX 모델 직접 지원 . (0) | 2024.08.29 |
MQL5 . 기본 자료형 바이트 크기 및 표준 자료형 대응표 (0) | 2024.08.28 |
메타트레이더 . VSCode 에서 MQL Tools 기반 쾌적 코딩 환경 구축 (2) | 2024.05.27 |
메타트레이더 . 코딩 . OnTimer . 시간격 이벤트 (1) | 2023.05.04 |
댓글