ผู้เขียนจริง:
วิทอลด์ วอซเนียก
ในบทความนี้เราจะพูดถึง Cycle Period ซึ่งเป็นอินดิเคเตอร์ที่ช่วยวัดความเปลี่ยนแปลงของราคาสินทรัพย์ทางการเงิน โดยอินดิเคเตอร์นี้จะเก็บข้อมูลค่าจากรอบการตลาดใน Buffer ของมัน ซึ่งค่าดังกล่าวจะไม่สามารถคงที่ได้ตลอดไป เนื่องจากมีการเปลี่ยนแปลงอยู่เสมอ
อินดิเคเตอร์นี้ถูกออกแบบมาเพื่อใช้ร่วมกับออสซิลเลเตอร์ เพื่อให้สามารถปรับตัวเข้ากับรอบการตลาดที่เปลี่ยนแปลงอยู่เสมอ ทำให้การวิเคราะห์มีความยืดหยุ่นมากขึ้น
แรงบันดาลใจในการสร้างอินดิเคเตอร์นี้มาจากบทความของ จอห์น อีเลอส์ ในปี 2002 ที่ชื่อว่า "Using The Fisher Transform" ที่เผยแพร่ในนิตยสาร "Technical Analysis Of Stock & Commodities".

การใช้งานอินดิเคเตอร์ Cycle Period ต้องมีการประกาศตัวแปร Handle ของอินดิเคเตอร์ในระดับโกลบอล เพื่อให้สามารถใช้งานในโค้ดของอินดิเคเตอร์อื่น ๆ ได้ (เช่น ในออสซิลเลเตอร์ RVI):
//---- ประกาศตัวแปรประเภท int สำหรับ Handle ของอินดิเคเตอร์ int CP_Handle;
จากนั้นต้องรับ Handle ของอินดิเคเตอร์ Cycle Period ในบล็อกการเริ่มต้นของอินดิเคเตอร์ RVI:
//---- รับ Handle ของอินดิเคเตอร์ CyclePeriod CP_Handle=iCustom(NULL,0,"CyclePeriod",Alpha); if(CP_Handle==INVALID_HANDLE) { Print(" ไม่สามารถรับ Handle ของอินดิเคเตอร์ CyclePeriod ได้"); return(1); }
ตอนนี้เราได้ตัวแปร Alpha ซึ่งเป็นพารามิเตอร์อินพุตของอินดิเคเตอร์ที่ใช้และอัตราส่วนการเฉลี่ยของช่วงเวลา ตัวแปรนี้ต้องถูกเปลี่ยนเป็นพารามิเตอร์อินพุตของอินดิเคเตอร์ที่พัฒนาขึ้น:
//+----------------------------------------------+ //| พารามิเตอร์อินพุตของอินดิเคเตอร์ | //+----------------------------------------------+ input double Alpha=0.07; // อัตราส่วนการปรับเรียบของอินดิเคเตอร์
พารามิเตอร์อินพุต Length ก่อนหน้านี้ต้องถูกลบออกจากรายการพารามิเตอร์อินพุต และเปลี่ยนเป็นตัวแปรภายในฟังก์ชัน OnCalculate()
ขนาดของอาร์เรย์ที่ใช้สำหรับการปรับเรียบของอินดิเคเตอร์จะถูกกำหนดโดยค่าของพารามิเตอร์ Length:
//---- การแจกจ่ายหน่วยความจำสำหรับอาร์เรย์ตัวแปร ArrayResize(Count,Length); ArrayResize(Value1,Length); ArrayResize(Value2,Length);
ค่าพารามิเตอร์นี้มีการเปลี่ยนแปลงอยู่เสมอ จึงควรกำหนดขนาดของอาร์เรย์เหล่านี้ให้มีค่ามากกว่าหรือเท่ากับค่าที่คาดว่าจะสูงที่สุด
เมื่อวิเคราะห์กราฟของอินดิเคเตอร์ เราจะเห็นว่าค่านี้ไม่เกิน 100 ดังนั้นขนาดของอาร์เรย์จะมีค่าเท่ากับ:
//---- การแจกจ่ายหน่วยความจำสำหรับอาร์เรย์ตัวแปร ArrayResize(Count,MAXPERIOD); ArrayResize(Value1,MAXPERIOD); ArrayResize(Value2,MAXPERIOD);
และต่อจากนั้น ค่ารอบสำหรับแท่งปัจจุบันในบล็อก OnCalculate() จะต้องถูกดึงจาก Buffer ของอินดิเคเตอร์ CyclePeriod เพื่อใช้แทนค่าของพารามิเตอร์อินพุต Length ที่เคยมีอยู่ก่อนหน้านี้:
//---- ลูปการคำนวณอินดิเคเตอร์หลัก for(bar=first; bar<rates_total && !IsStopped(); bar++) { //---- คัดลอกข้อมูลใหม่ที่ปรากฏลงในอาร์เรย์ if(CopyBuffer(CP_Handle,0,rates_total-1-bar,4,period)<=0) return(RESET); Length=int(MathFloor((4.0*period[0]+3.0*period[1]+2.0*period[2]+period[3])/20.0)); if(bar<Length) Length=bar; // ตัดการปรับเรียบให้ลดลงตามจำนวนแท่งที่แท้จริง
ในกรณีนี้จะมีการดึงค่าล่าสุดสี่ค่าจาก Buffer ของอินดิเคเตอร์ CyclePeriod และทำการปรับเรียบแบบเชิงเส้น หลังจากนั้นค่าที่ได้จะถูกใช้เป็นระยะเวลา Length สำหรับการปรับเรียบ และในที่สุดจะต้องมีการเปลี่ยนแปลงบรรทัดที่ท้ายของโค้ดอินดิเคเตอร์:
if(bar<rates_total-1) Recount_ArrayZeroPos(Count,MAXPERIOD);
ในที่สุดเราก็ได้รับ Adaptive RVI ออสซิลเลเตอร์:

โพสต์ที่เกี่ยวข้อง
- เครื่องมือ Open Range Breakout สำหรับ MetaTrader 5
- เครื่องมือ Master Tools - อินดิเคเตอร์สำหรับ MetaTrader 4
- Volume Profile + Range v6.0: เครื่องมือวิเคราะห์การซื้อขายใน MetaTrader 5
- FX Multi-Meter II: เครื่องมือช่วยเทรดที่ครบครันสำหรับนักลงทุน
- สัญญาณข้ามค่าเฉลี่ยเคลื่อนที่ครั้งเดียว - เครื่องมือช่วยเทรดใน MetaTrader 4