ในช่วงไม่กี่ปีที่ผ่านมา เริ่มมีการพูดถึงและใช้งาน Expert Advisor (EA) สำหรับฟอเร็กซ์ ซึ่งดำเนินการซื้อขายโดยอิงตามช่วงเวลาเฉพาะของวันหรือวันในสัปดาห์ เช่น การอนุญาตหรือห้ามให้ EA เปิดออเดอร์ตามเวลาที่เซสชันการซื้อขายฟอเร็กซ์ในภูมิภาคเอเชียสิ้นสุดลง การผูกเวลาของเซสชันตลาดเข้ากับกลยุทธ์การซื้อขายของโปรแกรมอัตโนมัติอาจกลายเป็นแนวคิดใหม่ที่มีศักยภาพสูงในการพัฒนาโปรแกรมเทรดอัตโนมัติ แต่…ในฐานะผู้ที่มีประสบการณ์ตรงจากการทดลองใช้โปรแกรมซื้อขายอย่างเข้มข้น ผมจึงตั้งคำถามสำคัญก่อนว่า: «เวลาที่เราเห็นใต้กราฟราคาคือเวลาแบบใด และควรผูก EA เข้ากับเวลาใดจึงจะเหมาะสม?» คำตอบบางประการที่ได้รับนั้นน่าสนใจมากจนผมตัดสินใจแบ่งปันกับเพื่อนร่วมอาชีพทุกท่านที่กำลังพัฒนาโปรแกรมเทรดอัตโนมัติ
นักเทรดใช้เวลาแบบใด?
ตอนเย็น บนคอมพิวเตอร์ของผมระบุเวลาท้องถิ่นไว้ที่ประมาณ 22:00 (ผมตัดเศษนาทีออกเพื่อให้เข้าใจง่าย) ซึ่งเป็นเวลาในประเทศยูเครน (GMT+2) หรือเทียบเท่ากับ 20:00 GMT จากนั้น ผมเปิด กราฟ GBPUSD ไทม์เฟรม H1 ใน แพลตฟอร์ม MetaTrader 4 ของโบรกเกอร์ Alpari (การทดสอบทั้งหมดนี้ทำบนบัญชีเดโม โดยโบรกเกอร์ที่ระบุไว้ในบทความนี้เลือกมาโดยสุ่ม — ผมได้ทำการทดลองเช่นนี้กับบริษัทอื่นอีกสี่แห่ง) เวลาของแท่งปัจจุบัน (Current Bar) บนกราฟคือ 21:00 ส่วนเวลาของแท่งก่อนหน้า (Time[1]) คือ 20:00
จากนั้น ผมเปิดกราฟคู่สกุลเงินเดียวกันและไทม์เฟรมเดียวกันบน แพลตฟอร์ม MetaTrader 4 ของโบรกเกอร์ InstaForex เวลาของแท่งปัจจุบันคือ 22:00 และเวลาของแท่งก่อนหน้าคือ 21:00 จากนั้น ผมขอให้เพื่อนนักเทรดที่อาศัยอยู่ในเซนต์ปีเตอร์สเบิร์ก (GMT+3) ตรวจสอบเวลาผ่าน Skype: เวลาท้องถิ่นของเขาคือ 23:19 ส่วนแท่งที่ปิดล่าสุดบน MT4 ของ Alpari แสดงเวลา 21:00 ซึ่งสอดคล้องกับข้อมูลของผม
ตอนนี้ เราพิจารณาค่าราคาปิดของแท่งก่อนหน้าบนกราฟ GBPUSD H1: สำหรับ Alpari คือ 1.60963 (ราคา 5 ตำแหน่งทศนิยม) ส่วน InstaForex คือ 1.6097 (ราคา 4 ตำแหน่งทศนิยม)
ข้อความนี้อธิบายความแตกต่างของเวลาปิดตลาดสำหรับคู่เงิน Alpai (21:00), InstaTrader (22:00), และ GMT (20:00 หรือ 22:00) รวมถึงเวลาของเทรดเดอร์ในเซนต์ปีเตอร์สเบิร์ก (23:00) ซึ่งแตกต่างกันเนื่องจากเขตเวลาท้องถิ่น เครื่องหมายเหล่านี้แสดงถึงความจำเป็นในการปรับตั้งเวลาของหุ่นยนต์เทรดให้สอดคล้องกับกราฟของโบรกเกอร์ที่ใช้
นี่คือค่าที่ฟังก์ชัน TimeCurrent() ของ MQL4 ให้มาโดยตรง และค่าที่จะปรากฏเมื่อใช้โค้ดบรรทัดนี้: TimeToStr( TimeCurrent(), TIME_SECONDS) อย่างไรก็ตาม นี่ไม่ใช่เวลาที่ผมต้องการใช้ในการซิงโครไนซ์การทำงานของ EA อย่างแน่นอน
เวลาคือเงิน
ความแตกต่างของมาตรวัดเวลาที่แต่ละโบรกเกอร์ให้มานั้นส่งผลต่อการซื้อขายจริงอย่างไร?
1. หนึ่งในสาเหตุหลักที่ทำให้ผลการทดสอบ EA ในโปรแกรม MetaTrader 4 บนประวัติราคาจากโบรกเกอร์ที่ต่างกัน ไม่สามารถให้ผลลัพธ์ที่ตรงกันอย่างสมบูรณ์แบบได้เลย ก็เพราะ “หนึ่งวัน” ของแต่ละโบรกเกอร์จะเริ่มและสิ้นสุดในช่วงเวลาที่ต่างกัน
2. สำหรับ EA ที่使用时间อย่างชัดเจน (เช่น เพื่ออนุญาตหรือห้ามการเปิดออเดอร์ตามช่วงเวลาที่กำหนด) คุณจะ ไม่สามารถทำการทดสอบหรือปรับแต่งกลยุทธ์ได้อย่างแม่นยำ เนื่องจากประวัติราคาที่ใช้ในการทดสอบจะผูกกับเวลาของโบรกเกอร์ (ซึ่งเป็นเวลาเสมือน) ไม่ใช่กับเวลาจริงของเซสชันการซื้อขายในตลาดโลก
เราจะแก้ไขปัญหานี้ได้อย่างไร?
บนอินเทอร์เน็ต (ผมเสียใจที่ไม่สามารถระบุแหล่งที่มาได้) ผมเคยพบฟังก์ชันที่สามารถดึงค่าเวลาท้องถิ่นของคอมพิวเตอร์คุณ (GetWinLocalDateTime()) และเวลา GMT ที่สอดคล้องกัน (GetWinUtcDateTime() หรือที่เรียกกันอีกอย่างว่า UTC) ไปยังโปรแกรม MQL4 โดยให้ค่าในรูปแบบ datetime เดียวกับที่ MQL4 ใช้ (เช่นเดียวกับฟังก์ชันในตัว TimeCurrent()):
#import “kernel32.dll”
int SystemTimeToFileTime(int& TimeArray[], int& FileTimeArray[]);
int FileTimeToLocalFileTime(int& FileTimeArray[], int& LocalFileTimeArray[]);
void GetSystemTime(int& TimeArray[]);
#import
datetime GetWinLocalDateTime() {
double hundrednSecPerSec = 10.0 * 1000000.0;
double bit32to64 = 65536.0 * 65536.0;
double secondsBetween1601And1970 = 11644473600.0;
int TimeArray[4];
int FileTimeArray[2]; // 100 นาโนวินาที นับตั้งแต่ 1 มกราคม 1601 (UTC)
int LocalFileTimeArray[2]; // 100 นาโนวินาที นับตั้งแต่ 1 มกราคม 1601 (เวลาท้องถิ่น)
GetSystemTime( TimeArray );
SystemTimeToFileTime( TimeArray, FileTimeArray );
FileTimeToLocalFileTime( FileTimeArray, LocalFileTimeArray );
double lfLo32 = LocalFileTimeArray[0];
if( lfLo32 < 0 )
lfLo32 = bit32to64 + lfLo32;
double ticksSince1601 = LocalFileTimeArray[1] * bit32to64 + lfLo32;
double secondsSince1601 = ticksSince1601 / hundrednSecPerSec;
double secondsSince1970 = secondsSince1601 – secondsBetween1601And1970;
return (secondsSince1970);
}
datetime GetWinUtcDateTime() {
double hundrednSecPerSec = 10.0 * 1000000.0;
double bit32to64 = 65536.0 * 65536.0;
double secondsBetween1601And1970 = 11644473600.0;
int TimeArray[4];
int FileTimeArray[2]; // 100 นาโนวินาที นับตั้งแต่ 1 มกราคม 1601 (UTC)
GetSystemTime( TimeArray );
SystemTimeToFileTime( TimeArray, FileTimeArray );
double lfLo32 = FileTimeArray[0];
if(lfLo32 < 0) lfLo32 = bit32to64 + lfLo32; double ticksSince1601 = FileTimeArray[1] * bit32to64 + lfLo32; double secondsSince1601 = ticksSince1601 / hundrednSecPerSec; double secondsSince1970 = secondsSince1601 – secondsBetween1601And1970; return (secondsSince1970); }
ท่านใดสนใจสามารถนำฟังก์ชันนี้ไปใช้งานได้ ต่อไปนี้คือตัวอย่างสคริปต์ที่คำนวณเวลาเปิดแท่งทั้งในรูปแบบเวลาท้องถิ่นและเวลา GMT โดยไม่ขึ้นกับเวลาที่โบรกเกอร์กำหนดไว้ — เรียบง่ายแต่ได้ผล:
start() {
int serv2lock = TimeLocal() – TimeCurrent(),
serv2utc = GetWinUTCDateTime() – TimeCurrent(),
local2utc = GetWinUTCDateTime() – GetWinLocalDateTime();
Print( “เวลาเปิดแท่ง (Time[0]):”,
” server=” + TimeToStr( Time[ 0 ], TIME_DATE | TIME_SECONDS ),
” local=” + TimeToStr( Time[ 0 ] + serv2lock, TIME_DATE | TIME_SECONDS ),
” UTC=” + TimeToStr( Time[ 0 ] + serv2utc, TIME_DATE | TIME_SECONDS )
);
}
ผลลัพธ์ที่ได้บน MetaTrader 4 ของโบรกเกอร์ต่างๆ:
– โบรกเกอร์ Alpari:
2011.02.11 01:07:36 LocalTime2 EURUSD, H1: เวลาเปิดแท่ง (Time[0]): server=2011.02.11 00:00:00 local=2011.02.11 01:00:01 UTC=2011.02.10 23:00:01.
ตอนนี้ทุกอย่างถูกต้องแล้ว แม้วันที่ก็จะเปลี่ยนไปอย่างถูกต้อง (วันที่ท้องถิ่นกับเวลา UTC ต่างกัน)
– โบรกเกอร์ InstaForex:
2011.02.11 01:07:52 LocalTime2 GBPUSD,H1: เวลาเปิดแท่ง (Time[0]): server=2011.02.11 01:00:00 local=2011.02.11 01:00:13 UTC=2011.02.10 23:00:13.
ไม่ว่าโบรกเกอร์ จะให้เวลาแบบใด ราคาและเวลาสุดท้ายจะตรงกันเมื่อแปลงเป็นเวลาท้องถิ่นหรือ UTC
ตอนนี้เราก็ใกล้เคียงกับเป้าหมายของการผูกการทำงานของ EA เข้ากับเวลา GMT มากขึ้นแล้ว — แต่ก็ต้องมีเงื่อนไขว่า นาฬิกาในระบบคอมพิวเตอร์ต้องตรง และตั้งค่า Time Zone ให้ถูกต้อง ซึ่งในทางปฏิบัติมักมีปัญหา
ใช้เซิร์ฟเวอร์เวลาแม่นยำ NTP หรือ SNTP
ที่น่าสนใจกว่าคือการเรียกใช้ เครือข่ายเซิร์ฟเวอร์เวลาแม่นยำระดับโลกที่รองรับโปรโตคอล NTP หรือ SNTP จากโค้ด MQL4 โดยตรง
แนวคิดคือการดึงเวลาจากเซิร์ฟเวอร์กลาง แล้วใช้ค่านั้นเป็นฐานอ้างอิงสำหรับ Timestamp ทั้งหมดในโปรแกรม อย่างไรก็ตาม การเรียกเวลาผ่านโปรโตคอล NTP จากภายในโปรแกรมนั้น ผมเข้าใจดีในระบบปฏิบัติการ UNIX แต่สำหรับ Windows ผมยังไม่ทราบวิธีการที่ชัดเจน ดังนั้น ผมจะแสดงวิธีการซิงโครไนซ์เวลาของระบบคอมพิวเตอร์คุณกับเซิร์ฟเวอร์ NTP/SNTP ทุกครั้งที่เปิดเครื่อง โดยเฉพาะอย่างยิ่งใน Windows XP:
1. หลังจากระบบปฏิบัติการโหลดเสร็จ ให้หยุดบริการเวลาของระบบผ่านช่อง Run Command: > net stop w32time
2. กำหนดที่อยู่เซิร์ฟเวอร์เวลา NTP (หรือรายการที่อยู่หลายแห่ง ดูรายละเอียดด้านล่าง):
> net time /setsntp:ntp.vc.ukrtel.net
3. คุณสามารถตรวจสอบว่าเซิร์ฟเวอร์ NTP ใดที่ระบบตั้งไว้เป็นค่าเริ่มต้นสำหรับการซิงโครไนซ์ (แต่ไม่ได้หมายความว่าเป็นตัวเลือกที่ดีที่สุด):
> net time /querysntp
4. หลังจากตั้งค่าเซิร์ฟเวอร์แล้ว ให้เริ่มบริการเวลาของ Windows XP อีกครั้ง:
> net start w32time
ภายใน 25 วินาทีหลังจากขั้นตอนเหล่านี้ เวลาในระบบจะปรับแก้ให้ตรงกับเวลาสากลที่แม่นยำ โดยมีความคลาดเคลื่อนเพียงไม่กี่มิลลิวินาที! ลองตั้งเวลาเครื่องให้ผิด แล้วดูว่าระบบแก้ไขกลับมาถูกต้องหลังทำตามขั้นตอนนี้หรือไม่
หลังจากขั้นตอนที่ 2 บริการเวลาจะจำค่าที่อยู่เซิร์ฟเวอร์ NTP ไว้ และคุณไม่จำเป็นต้องตั้งค่าใหม่เว้นแต่จะต้องการเปลี่ยนแปลง
เราจะหาที่อยู่เซิร์ฟเวอร์เวลาแม่นยำได้จากที่ใด? ตัวอย่างหนึ่งที่ผมยกมาข้างต้นคือ ukrtel.net ซึ่งเป็นบริการของ Ukrtelecom คุณสามารถค้นหาที่อยู่เซิร์ฟเวอร์ที่เชื่อถือได้กว่าร้อยแห่งได้ที่ หน้านี้ ซึ่งมีเซิร์ฟเวอร์ในรัสเซียประมาณ 40 แห่ง และยูเครน 2 แห่ง สามารถเลือกใช้ได้ตามสะดวก
หากต้องการระบุรายการเซิร์ฟเวอร์เวลาหลายแห่งพร้อมกัน (เพื่อความปลอดภัย) ให้ใช้รูปแบบดังนี้ — ต้องใส่เครื่องหมายคำพูด และคั่นที่อยู่เซิร์ฟเวอร์แต่ละแห่งด้วยช่องว่าง:
> net time /setsntp:”ntp.vc.ukrtel.net ntp21.vniiftri.ru”
แล้วสำหรับ Windows Vista และ Windows 7 ล่ะ? จากข้อมูลในฟอรัมออนไลน์ ยืนยันว่า Windows 7 ใช้วิธีจัดการบริการเวลาเหมือนกัน ส่วน Windows Vista นั้นผมไม่มีข้อมูลเพิ่มเติม
หมายเหตุ: ผมพบเว็บไซต์ที่ให้บริการตรวจสอบเวลา GMT ซึ่งอาจมีประโยชน์มากในการทดลองต่างๆ ที่เกี่ยวข้องกับเวลา: http://wwp.greenwichmeantime.com/