Real-Time ZigZag Pip Range Display with Configurable Parameters on MT4

Development Log · 2025-02

1. Title

Real-Time ZigZag Pip Range Display with Configurable Parameters on MT4

2. Date / Phase

Phase: Indicator Development / Real-Time Visualization Date: 2025-02

3. Background

การสนทนาเริ่มต้นจากความต้องการสร้างเครื่องมือบน MetaTrader 4 (MT4) ที่สามารถแสดงค่า Pip Range ของเส้น ZigZag (ZZ) แบบ Real-Time บนมุมขวาล่างของหน้าจอchart โดยมีเงื่อนไขว่าเมื่อเกิดการกลับตัว (reversal) ของเส้น ZigZag ให้ลบค่าที่คำนวณไว้เดิมและแทนที่ด้วยค่าของเส้นใหม่ทันที นอกจากนี้ยังต้องการแสดง Pip Range ของแท่งเทียนก่อนหน้า (Previous Candlestick Bar) ในบรรทัดแยกต่างหาก โดยใช้รูปแบบตัวอักษร Century Gothic ขนาด 20 สีขาวสำหรับค่า ZZ และสีเทาสำหรับค่า Previous Bar

เป้าหมายคือการสร้าง Visualization Layer ที่ช่วยให้เทรดเดอร์เห็นขนาดของ Swing ที่สำคัญ (ผ่าน ZigZag) และความผันผวนของแท่งล่าสุดได้ในพริบตา โดยไม่ต้องคำนวณด้วยตนเอง

4. Key Insights

การพัฒนาในครั้งนี้ได้เปิดเผยประเด็นสำคัญหลายประการ ดังนี้

ประการแรก – การแยก Layer ระหว่าง Indicator กับ Visualization แม้ว่า ZigZag จะเป็น indicator มาตรฐานของ MT4 อยู่แล้ว แต่การจะดึงค่ามาแสดงผลแบบ Real-Time จำเป็นต้องใช้ iCustom() เรียก buffer ของ ZigZag โดยตรง การออกแบบที่ถูกต้องคือสร้าง indicator ใหม่ที่ทำหน้าที่เป็น wrapper ครอบ ZigZag อีกชั้นหนึ่ง แทนที่จะแก้ไข ZigZag ต้นฉบับ ซึ่งเป็นแนวทางที่รักษา modularity และป้องกันการพังของ indicator หลัก

ประการที่สอง – ปัญหา Property ของ Object ใน MQL4 การพัฒนาเริ่มต้นพบข้อผิดพลาดสำคัญสองประการ ได้แก่ การใช้ OBJPROP_FONT ผ่าน ObjectSetInteger ซึ่งเป็น improper enumerator และการ implicit conversion จาก string เป็น number ข้อค้นพบคือ MQL4 แยก method สำหรับ property ต่างชนิดกันอย่างชัดเจน กล่าวคือ ObjectSetString ใช้สำหรับ OBJPROP_TEXT และ OBJPROP_FONT ขณะที่ ObjectSetInteger ใช้สำหรับ OBJPROP_COLOR, OBJPROP_FONTSIZE, OBJPROP_CORNER, และ OBJPROP_XDISTANCE การเข้าใจ distinction นี้เป็นพื้นฐานสำคัญของการเขียน Object-based UI บน MT4

ประการที่สาม – การจัดการตำแหน่ง Object บน Chart การวาง label ให้ "ชิดขอบขวาเกินไป" เป็นปัญหาด้าน UX ที่พบในการทดสอบรอบแรก การแก้ไขทำได้โดยการเพิ่ม input parameter XOffset เพื่อให้ผู้ใช้ปรับระยะห่างจากขอบขวาได้อย่างอิสระ แนวคิดนี้สะท้อนหลักการ Configurability over Hardcoding ซึ่งเป็น pattern ที่ควรใช้กับการวาง UI element ทั้งหมด

ประการที่สี่ – การขยายพารามิเตอร์ของ ZigZag ให้ Configurable การเปลี่ยน Depth, Deviation และ Backstep จากค่าคงที่ (12, 5, 3) ให้กลายเป็น input parameter ทำให้ผู้ใช้สามารถปรับความไวของ ZigZag ได้ตาม timeframe และ instruments โดยไม่ต้องแก้ไข source code และเมื่อทำการส่งค่าผ่าน iCustom() แล้ว ค่าเหล่านี้จะถูกใช้ในการคำนวณ ZZ Pip Range โดยอัตโนมัติ

ประการที่ห้า – การแสดง Context ของพารามิเตอร์บน Label การเพิ่มข้อความ (Depth: X, Dev: Y, Back: Z) ต่อท้ายค่า Pip Range เป็นการรวม context เข้ากับ value ซึ่งช่วยให้ผู้ใช้ทราบทันทีว่าค่าที่เห็นมาจากการตั้งค่าใด ลดความสับสนเมื่อเปิดหลาย chart พร้อมกัน แนวคิดนี้เทียบได้กับ self-documenting UI ที่ลด cognitive load ของผู้ใช้งาน

5. Decisions

การตัดสินใจที่ชัดเจนจากบทสนทนานี้มีดังนี้

หนึ่ง สร้าง indicator ใหม่ชื่อ ZZ_PipRange แทนการแก้ไข ZigZag ต้นฉบับ โดยใช้ iCustom() เรียก buffer หมายเลข 1 (Low) และ 2 (High) ของ ZigZag

สอง ใช้ OBJ_LABEL สองตัว ได้แก่ ZZPipRangeLabel สำหรับค่า ZZ Pip Range (สีขาว) และ BarPipRangeLabel สำหรับค่า Previous Bar Range (สีเทา) โดยวางใน corner หมายเลข 3 (bottom-right)

สาม เพิ่ม input parameters สำหรับ ZigZag ทั้งสามตัว ได้แก่ ZigZagDepth, ZigZagDeviation, ZigZagBackstep เพื่อให้ผู้ใช้ปรับได้

สี่ เพิ่ม input parameter XOffset สำหรับควบคุมระยะห่างจากขอบขวา เพื่อแก้ปัญหา label ชิดขอบเกินไป

ห้า แสดงค่า Depth, Deviation และ Backstep ไว้ใน label text ของ ZZ Pip Range เพื่อให้ context ปรากฏบนหน้าจอเสมอ

หก ใช้ font Century Gothic ขนาด 20 ตามข้อกำหนด โดยตั้งค่าผ่าน ObjectSetString สำหรับ OBJPROP_FONT และ ObjectSetInteger สำหรับ OBJPROP_FONTSIZE

6. Philosophy

บทสนทนานี้สะท้อนหลักคิดสำคัญว่า "เครื่องมือที่ดีต้องบอกได้ว่าตัวเองกำลังทำงานอย่างไร" การที่ label แสดงทั้งค่า Pip Range และพารามิเตอร์ที่ใช้คำนวณ เป็นการยกระดับจาก passive display ไปสู่ self-explanatory display ซึ่งลดภาระทางความคิดของผู้ใช้ และช่วยให้ตรวจสอบความถูกต้องของค่าที่เห็นได้ทันที

อีกนัยหนึ่งคือ การแก้ไขปัญหาเฉพาะหน้า (เช่น label ชิดขอบ) ควรแก้ที่ ระดับการออกแบบ ไม่ใช่ ระดับ hardcode การเพิ่ม XOffset เป็น input parameter ไม่ได้แก้แค่ปัญหาเฉพาะบุคคล แต่เปิดโอกาสให้ปรับแต่งได้อย่างไม่มีที่สิ้นสุด แนวคิดนี้สอดคล้องกับหลัก "configuration over customization" ที่เครื่องมือควรปรับตัวได้ตามบริบทของผู้ใช้ แทนที่จะบังคับผู้ใช้ให้ปรับตัวตามเครื่องมือ

7. Future Work

สิ่งควรดำเนินการต่อจากบทสนทนานี้ ได้แก่

หนึ่ง เพิ่มการคำนวณ Pip Range ย้อนหลังหลาย Swing เพื่อแสดงค่าเฉลี่ย (Average Swing Size) ซึ่งช่วยในการประเมินความผันผวนเชิงสถิติ

สอง พิจารณาการเปลี่ยนจาก iCustom ไปใช้การคำนวณ ZigZag ภายใน (native implementation) เพื่อลด dependency กับ indicator ภายนอก และเพิ่มประสิทธิภาพ

สาม ขยายการแสดงผลไปยัง panel แบบ multi-line ที่รวมค่า Pip Range ของ Swing ปัจจุบัน, Swing ก่อนหน้า, และค่าเฉลี่ย เพื่อให้เห็นภาพรวมของ structure

สี่ เพิ่ม option ให้ผู้ใช้เลือกได้ว่าจะแสดง label ใน corner ใด และสามารถ toggle การแสดง context parameters ได้

ห้า ทดสอบบน instruments ที่มี Point value แตกต่างกัน (เช่น XAUUSD, indices) เพื่อยืนยันว่าการคำนวณ pip range ถูกต้องในทุก asset class

8. Closing Note

การพัฒนาครั้งนี้เริ่มจากความต้องการเล็กๆ ในการเห็นค่า Pip Range ของ ZigZag บนหน้าจอ แต่ได้เปิดเผยหลักการสำคัญหลายชั้น ทั้งในด้านเทคนิคของ MQL4 ที่บังคับให้แยกแยะ method ตามชนิดของ property, ในด้านการออกแบบ UI ที่ต้องให้ความสำคัญกับ position และ context, และในด้านปรัชญาของการสร้างเครื่องมือที่ "อธิบายตัวเองได้" ผลลัพธ์คือ indicator ที่ไม่เพียงแสดงค่าที่ต้องการ แต่ยังสื่อสารว่าค่านั้นเกิดขึ้นได้อย่างไร ทำให้ผู้ใช้สามารถไว้วางใจและปรับแต่งเครื่องมือได้อย่างมั่นใจ นี่คือก้าวเล็กๆ ที่สะท้อนแนวคิดใหญ่ ว่าเครื่องมือที่ดีควรเป็นทั้ง mirror ที่สะท้อนข้อมูล และ map ที่บอกเส้นทางของข้อมูลนั้นไปพร้อมกัน