//@Name:Zig-Zag Frequency //@Description:Draws horizontal lines at every zig-zag peak and trough to highlight possilbe support/resistance levels. var zigzagPerc = 15; //zig-zag percentage var patternDataType = 0; //use High-Low data or Close to calculate var showZZ = true; var showPeak = true; var showTrough = true; var zigzagCol = Colour.Cyan; var zigzagStyle = 0; var zigzagWidth = 1; var peakCol = Colour.Green; var peakStyle = 0; var peakWidth = 0; var troughCol = Colour.Red; var troughStyle = 0; var troughWidth = 0; var zz; function init(status) { if (status == Loading || status == Editing) { zigzagPerc = storage.getAt(0); patternDataType = storage.getAt(1); zigzagCol = storage.getAt(2); zigzagStyle = storage.getAt(3); zigzagWidth = storage.getAt(4); peakCol = storage.getAt(5); peakStyle = storage.getAt(6); peakWidth = storage.getAt(7); troughCol = storage.getAt(8); troughStyle = storage.getAt(9); troughWidth = storage.getAt(10); showZZ = storage.getAt(11);; showPeak = storage.getAt(12);; showTrough = storage.getAt(13);; } if (status == Adding || status == Editing) { dlg = new Dialog("Select Period Length", 180, 92); dlg.addOkButton(); dlg.addCancelButton(); dlg.addNumEdit("NUM1",8,-1,-1,-1,"","% Zig-Zag",zigzagPerc,1,100); dlg.addTickBox("TB1",8,-1,110,-1,"Use Close, not High/Low",patternDataType); dlg.addTickBox("TB2",8,37,10,-1,"",showZZ); dlg.addColLinePicker("CL1",22,35,-1,-1,"","Zig-Zag Line",zigzagCol,zigzagStyle,zigzagWidth); dlg.addTickBox("TB3",8,57,10,-1,"",showPeak); dlg.addColLinePicker("CL2",22,55,-1,-1,"","Peak Line",peakCol,peakStyle,peakWidth); dlg.addTickBox("TB4",8,77,10,-1,"",showTrough); dlg.addColLinePicker("CL3",22,75,-1,-1,"","Trough Line",troughCol,troughStyle,troughWidth); if (dlg.show()==Dialog.Cancel) return false; zigzagPerc = dlg.getValue("NUM1"); patternDataType = dlg.getValue("TB1"); zigzagCol = dlg.getValue("CL1").colour; zigzagStyle = dlg.getValue("CL1").pen; zigzagWidth = dlg.getValue("CL1").width; peakCol = dlg.getValue("CL2").colour; peakStyle = dlg.getValue("CL2").pen; peakWidth = dlg.getValue("CL2").width; troughCol = dlg.getValue("CL3").colour; troughStyle = dlg.getValue("CL3").pen; troughWidth = dlg.getValue("CL3").width; showZZ = dlg.getValue("TB2"); showPeak = dlg.getValue("TB3"); showTrough = dlg.getValue("TB4"); storage.setAt(0, zigzagPerc); storage.setAt(1, patternDataType); storage.setAt(2, zigzagCol); storage.setAt(3, zigzagStyle); storage.setAt(4, zigzagWidth); storage.setAt(5, peakCol); storage.setAt(6, peakStyle); storage.setAt(7, peakWidth); storage.setAt(8, troughCol); storage.setAt(9, troughStyle); storage.setAt(10, troughWidth); storage.setAt(11, showZZ); storage.setAt(12, showPeak); storage.setAt(13, showTrough); } } function onNewChart() { clearDisplay(); var share = getCurrentShare(); if (patternDataType) { var data = share.getCloseArray(); zz = zigZagCalcClose(data,zigzagPerc/100); } else { var data = share.getPriceArray(); zz = zigZagCalcHighLow(data,zigzagPerc/100); } draw(zz); } function onZoom() { draw(zz); } function draw(zz,patternStartIndex,patternEndIndex) { clearDisplay(); setLayer(Layer.Bottom); var s = getMinVisibleBarIndex(); //start drawing the zig-zag line setPenStyle(zigzagStyle,zigzagWidth,zigzagCol); for (var i=1;is) { i--; break; } } moveTo(zz[i].index, zz[i].value); for (i++;izz[i-1].value) { setPenStyle(peakStyle,peakWidth,peakCol); lineTo(bars.length+50,zz[i].value); } if (showTrough && zz[i].valuedata[i]) ll = data[i]; if (hh/zz[0].value-1>=zzPerc || 1-ll/zz[0].value>=zzPerc) { zz[1] = {index:i,value:data[i]}; continue; } } else { if (zz[zz.length-1].value>zz[zz.length-2].value) { if (data[i]>zz[zz.length-1].value) { zz[zz.length-1].value = data[i]; zz[zz.length-1].index = i; continue; } else if (1-data[i]/zz[zz.length-1].value>=zzPerc) { zz[zz.length] = {index:i,value:data[i]}; } } else { if (data[i]=zzPerc) { zz[zz.length] = {index:i,value:data[i]}; } } } } if (zz[zz.length-1].indexdata[i].low) ll = data[i].low; if (hh/zz[0].value-1>=zzPerc) { zz[1] = {index:i,value:data[i].high}; continue; } else if (1-ll/zz[0].value>=zzPerc) { zz[1] = {index:i,value:data[i].low}; continue; } } else { //if the line is moving up if (zz[zz.length-1].value>zz[zz.length-2].value) { if (1-data[i].low/zz[zz.length-1].value>=zzPerc) //check for reversals { zz[zz.length] = {index:i,value:data[i].low}; continue; } else if (data[i].high>zz[zz.length-1].value) //otherwise check for higher highs { zz[zz.length-1].value = data[i].high; zz[zz.length-1].index = i; } } else //if the line is moving down { if (data[i].high/zz[zz.length-1].value-1>=zzPerc) //check for reversals { zz[zz.length] = {index:i,value:data[i].high}; continue; } else if (data[i].low