วันนี้เราจะมาพูดถึง ZigZag ที่สมบูรณ์แบบ ซึ่งเป็นเครื่องมือที่ช่วยให้นักเทรดสามารถวิเคราะห์กราฟได้อย่างมีประสิทธิภาพมากยิ่งขึ้น!
นี่คือ ZigZag ที่เรียบง่ายแต่รวดเร็ว ไม่ต้องกังวลเกี่ยวกับจุดสูงสุดที่ผิดพลาด เพราะการดึงจุดสูงสุดได้ถูกปรับให้รวดเร็วยิ่งขึ้น

ข้อดี:
- ฟังก์ชันการคำนวณที่ใช้เวลามากที่สุดคือ iBarShift ซึ่งถูกแทนที่ด้วย ArrayBSearch ทำให้ตัวชี้วัดนี้มีประสิทธิภาพมากกว่าใน MQL4
- ข้อมูลที่จำเป็นสำหรับแต่ละแท่งเทียนสามารถเข้าถึงได้ทั้งในปัจจุบันและสามารถให้ EA เข้าถึงได้ในทุกช่วงเวลาของประวัติศาสตร์
- ไม่มีจุดสูงสุดที่ถูกระงับ
- วิธีการหาจุดสูงสุดที่มีประสิทธิภาพโดยไม่ต้องค้นหาค่าของตัวชี้วัด
- รวดเร็วมาก
- ทำงานได้อย่างถูกต้องแม้เมื่อมีการแทรกประวัติหรือเปลี่ยนกรอบเวลา
- เหมาะสำหรับการใช้งานใน EA
ข้อเสีย:
- ต้องการหน่วยความจำมาก ZigZag ต้องใช้ 2 บัฟเฟอร์ (เพียง 1 บัฟเฟอร์ไม่เพียงพอเพราะมีการหน่วงเวลา) สำหรับการวาดภาพที่ถูกต้อง แต่ที่นี่ใช้งาน 5 บัฟเฟอร์ ซึ่งผมคิดว่าข้อเสียนี้ถูกบดบังด้วยข้อดีข้อที่ 6
- มีเส้นเพิ่มเติมที่จำเป็นเพื่อให้ข้อมูลมองเห็นได้สำหรับ Expert Advisor เส้นเหล่านี้ไม่ควรปรากฏให้เห็น
หลักการ:
ZigZag ถูกวาดโดยหลักการของการสร้างช่อง ช่องสามารถกำหนดได้ในหน่วยจุด (IdealZZ) หรือในเปอร์เซ็นต์ (IdealZZP)
การดึงจุดสูงสุด:
inputint ChannelWidth=100; #property indicator_chart_windowdatetime LastTime; int ZZHandle; //+------------------------------------------------------------------+//| ฟังก์ชันการเริ่มต้นตัวชี้วัดที่กำหนดเอง |//+------------------------------------------------------------------+voidOnInit() { LastTime = 0; ZZHandle = iCustom(_Symbol, Period(), "IdealZZ", ChannelWidth); } //+------------------------------------------------------------------+//| ฟังก์ชัน GetValue |//+------------------------------------------------------------------+bool GetValue(double dir,int bar,int prevBar,double &peak, int &peakBar,datetime &peakTime,constdatetime &T[]) { if(dir<0) { double t[1]; if(0>=CopyBuffer(ZZHandle,2,bar,1,t)) returnfalse; int i= ArrayBsearch(T, (datetime)t[0]); if(i==prevBar) { if(0>=CopyBuffer(ZZHandle,2,bar+1,1,t)) returnfalse; i=ArrayBsearch(T,(datetime)t[0]); } double v[1]; if(0>=CopyBuffer(ZZHandle,1,i,1,v)) returnfalse; if(v[0]==EMPTY_VALUE) { if(0>=CopyBuffer(ZZHandle,2,bar+1,1,t)) returnfalse; i=ArrayBsearch(T,(datetime)t[0]); if(0>=CopyBuffer(ZZHandle,1,i,1,v)) returnfalse; } peak=v[0]; peakBar=i; peakTime=(datetime)t[0]; } elseif(dir>0) { double t[1]; if(0>=CopyBuffer(ZZHandle,3,bar,1,t)) returnfalse; int i= ArrayBsearch(T, (datetime)t[0]); if(i==prevBar) { if(0>=CopyBuffer(ZZHandle,3,bar+1,1,t)) returnfalse; i=ArrayBsearch(T,(datetime)t[0]); } double v[1]; if(0>=CopyBuffer(ZZHandle,0,i,1,v)) returnfalse; if(v[0]==EMPTY_VALUE) { if(0>=CopyBuffer(ZZHandle,3,bar+1,1,t)) returnfalse; i=ArrayBsearch(T,(datetime)t[0]); if(0>=CopyBuffer(ZZHandle,0,i,1,v)) returnfalse; } peak=v[0]; peakBar=i; peakTime=(datetime)t[0]; } else { return(false); } return(true); } //+------------------------------------------------------------------+//| ฟังก์ชัน SetPt |//+------------------------------------------------------------------+void SetPt(string name,double price,datetime time) { ObjectCreate(0,name,OBJ_ARROW,0,time,price); ObjectSetInteger(0,name,OBJPROP_ARROWCODE,108); ObjectSetDouble(0,name,OBJPROP_PRICE,price); ObjectSetInteger(0,name,OBJPROP_TIME,time); } //+------------------------------------------------------------------+//| ฟังก์ชันการคำนวณตัวชี้วัดที่กำหนดเอง |//+------------------------------------------------------------------+intOnCalculate(constint rates_total, constint prev_calculated, constdatetime &T[], constdouble &open[], constdouble &high[], constdouble &low[], constdouble &close[], constlong &tick_volume[], constlong &volume[], constint &spread[]) { if(LastTime==T[0]) return(rates_total); LastTime=T[0]; ArraySetAsSeries(T,true); double dir_[1]; if(0>=CopyBuffer(ZZHandle,4,1,1,dir_)) return rates_total; double dir=dir_[0]; double rdir=-dir; if(dir==EMPTY_VALUE) return(rates_total); double v1,v2,v3,v4,v5; int i1,i2,i3,i4,i5; datetime t1,t2,t3,t4,t5; if( GetValue(dir,1,0,v1,i1,t1,T) && GetValue(rdir,i1,0,v2,i2,t2,T) && GetValue(dir,i2,i1,v3,i3,t3,T) && GetValue(rdir,i3,i2,v4,i4,t4,T) && GetValue(dir,i4,i3,v5,i5,t5,T) ) { SetPt("1",v1,t1); SetPt("2",v2,t2); SetPt("3",v3,t3); SetPt("4",v4,t4); SetPt("5",v5,t5); Print(v1," ",v2," ",v3," ",v4," ",v5," ",i1," ",i2," ",i3," ",i4," ",i5); } else { Print("ดูเหมือนว่าจะมีข้อผิดพลาด..."); } return(rates_total); } //+------------------------------------------------------------------+
ตัวอย่างนี้เป็นตัวชี้วัดที่ทำเครื่องหมาย (หนึ่งครั้งต่อแท่งเทียน) จุดสูงสุดห้าจุดแรก (รวมถึงจุดที่กำลังสร้างอยู่)
หมายเหตุ! โค้ดอาจทำงานไม่ถูกต้อง หากเปิดโหมด zero bar
โหมด Zero Bar:
โหมดนี้สามารถเปิดใช้งานในตัวแปร DrawZeroBar โค้ด ซึ่งจะถูกปิดใช้งานโดยค่าเริ่มต้น ไม่แนะนำให้เปิดใช้งาน โดยเฉพาะอย่างยิ่งหากตัวชี้วัดนี้ใช้ใน Expert Advisor
ขอให้สนุกกับการใช้งาน! หากพบข้อบกพร่องใด ๆ โปรดแจ้งให้ทราบด้วยนะครับ

ความคิดเห็น 0