RealTimeSwings.efs
File Name: RealTimeSwings.efs
Description:
This formula identifies swing points on a daily or intra-day basis. On intra-day intervals, the developing legs (last two legs) will update in real time. This type of study is also referred to as the Zig Zag. The main difference with this study is that the user can define swing points with a combination of user-defined inputs.
Formula Parameters:
-
Swing: # of Bars - 5
(Number must be greater than 0. Determines the number of bars to either side of the swing point that must not exceed the swing bar's max or min value). -
Swing: Wave Type - % Retracement
(options are: % Retracement or % Change in Price. % Change in Price requires the price to move a minimum percentage from the previously identified swing point. % Retracement requires the price to move a minimum percentage of the distance between the 2 previously identified swing points.) -
Swing: Wave Percentage - 30
(The percentage requirement for the selected wave type.) -
Swing High Price Source - High
(options are: Open, High, Low, Close) -
Swing Low Price Source - Low
(options are: Open, High, Low, Close) - Line Thickness - 2
- Confirmed Swing Line Color - Blue
- Developing Swing Line Color - Red
- Confirmed Swing Line Color - Blue
- Developing Swing Line Color - Red
- Display Swing Labels - True
- Display % Retracement Label - True
- Number of Historical Labels - 100
Notes:
To replicate the more common Zig Zag study on a 30 min chart of INTC for example, enter 1 for # of Bars, select % Change in Price and 1.5 for Wave Percentage. Another combination that works well across various intra-day intervals is a # of Bars of 10 with % Change in Price and a Wave Percentage of 0. The chart image below is using the default values above.
Download File:
RealTimeSwings.efs
EFS Code:
/***************************************************************** Provided By : eSignal. (c) Copyright 2004 Study: Real Time Swings Version: 1.1 Formula Parameters: Default: * Swing: # of Bars 5 This is the minimum number of bars required to define a swing point. This number is for both sides of the swing point (i.e. 5 bars on the left and right of the swing bar). * Swing: Wave Type % Retracement (% Retracement, % Change in Price) * Swing: Wave Percentage 30 The number 5 will be treated as 5.0%. The number 0.05 will be treated as 0.0005%. * Swing High Price Source High * Swing Low Price Source Low * Line Thickness 2 * Confirmed Swing Line Color Blue * Developing Swing Line Color Red * Display Swing Labels True * Display % Retracement Label True * Number of Historical Labels 100 Notes: 1.1 3/24/2004 * Added labels to display point value, % retracement, number of bars and price level of swings. The number of historical labels is set to 100 for performance reasons. Increase this number to view more historical labels. * Added labels to display current swing's % retracement. Description of Swing Labels: At Swing Highs - Points (% Retracement) Price (Number of Bars) At Swing Lows - Price (Number of Bars) Points (% Retracement) *****************************************************************/ function preMain() { setPriceStudy(true); setStudyTitle("Real Time Swings "); setShowCursorLabel(false); setShowTitleParameters(false); var fp1 = new FunctionParameter("nNum", FunctionParameter.NUMBER); fp1.setName("Swing: # of Bars"); fp1.setLowerLimit(1); fp1.setDefault(5); var fp2a = new FunctionParameter("sWaveType", FunctionParameter.STRING); fp2a.setName("Swing: Wave Type"); fp2a.addOption("% Retracement"); fp2a.addOption("% Change in Price"); fp2a.setDefault("% Retracement"); var fp2 = new FunctionParameter("nRet", FunctionParameter.NUMBER); fp2.setName("Swing: Wave Percentage"); fp2.setLowerLimit(0); fp2.setDefault(30); var fp3 = new FunctionParameter("sHighSource", FunctionParameter.STRING); fp3.setName("Swing High Price Source"); fp3.addOption("Open"); fp3.addOption("High"); fp3.addOption("Low"); fp3.addOption("Close"); fp3.setDefault("High"); var fp4 = new FunctionParameter("sLowSource", FunctionParameter.STRING); fp4.setName("Swing Low Price Source"); fp4.addOption("Open"); fp4.addOption("High"); fp4.addOption("Low"); fp4.addOption("Close"); fp4.setDefault("Low"); var fp5 = new FunctionParameter("nThickness", FunctionParameter.NUMBER); fp5.setName("Line Thickness"); fp5.setLowerLimit(1); fp5.setDefault(2); var fp6 = new FunctionParameter("cColor1", FunctionParameter.COLOR); fp6.setName("Confirmed Swing Line Color"); fp6.setDefault(Color.blue); var fp7 = new FunctionParameter("cColor2", FunctionParameter.COLOR); fp7.setName("Developing Swing Line Color"); fp7.setDefault(Color.red); var fp8 = new FunctionParameter("bSwingLabels", FunctionParameter.STRING); fp8.setName("Display Swing Labels"); fp8.addOption("True"); fp8.addOption("False"); fp8.setDefault("True"); var fp9 = new FunctionParameter("bRetLabel", FunctionParameter.STRING); fp9.setName("Display \% Retracement Label"); fp9.addOption("True"); fp9.addOption("False"); fp9.setDefault("True"); var fp10 = new FunctionParameter("nNumLabels", FunctionParameter.NUMBER); fp10.setName("Number of Historical Labels"); fp10.setLowerLimit(1); fp10.setDefault(100); } var bEdit = true; // tracks change of user inputs var cntr = 0; // image counter for swing lines var bInit = false; // initialization routine completion var nNumBars = null; // number of bars for defining swings var sWaveTypeG = null; // wave type for confirming swings var nRetpcnt = null; // percent retracement for defining swings var nThicknessG = null; // line thickness var cColorcon = null; // confirmed swing color var cColordev1 = null; // developing swing color var sHSource = null; // price source for high swings var sLSource = null; // price source for low swings var x1a = null; // x-coordinate for point a of developing line 1 var x1b = null; // x-coordinate for point b of developing line 1 var x2a = null; // x-coordinate for point a of developing line 2 var x2b = null; // x-coordinate for point b of developing line 2 var y1a = null; // y-coordinate for point a of developing line 1 var y1b = null; // y-coordinate for point b of developing line 1 var y2a = null; // y-coordinate for point a of developing line 2 var y2b = null; // y-coordinate for point b of developing line 2 var vLastSwing = null; // tracking swing type of last confirmed swing var nScntr = 0; // bar counter for swing confirmation var nLcntr = 0; // label counter for swing labels var aSwingsIndex = new Array(4); // tracks current swings indexes for last 4 swings var aSwingsPrice = new Array(4); // tracks current swing prices for last 4 swings var nNumLabelsG = null; // max number of swing labels var bSwingLabelsG = null; // controls swing labels display var vSpace = null; // spacer for Labels function main(nNum, sWaveType, nRet, sHighSource, sLowSource, nThickness, cColor1, cColor2, bSwingLabels, bRetLabel, nNumLabels) { var nState = getBarState(); var nIndex = getCurrentBarIndex(); var h = getValue(sHighSource); var l = getValue(sLowSource); var c = close(); var i = 0; // record keeping if (nState == BARSTATE_NEWBAR) { if (cntr > 100) cntr = 0; if (x1a != null) x1a -= 1; if (x1b != null) x1b -= 1; if (x2a != null) x2a -= 1; if (x2b != null) x2b -= 1; i = 0; for (i = 0; i < 3; ++i) { if (aSwingsIndex[i] != null) aSwingsIndex[i] -= 1; } } //Initialization if (bEdit == true) { if (nNumBars == null) nNumBars = nNum; if (sWaveTypeG == null) sWaveTypeG = sWaveType; if (nRetpcnt == null) nRetpcnt = nRet/100; if (nThicknessG == null) nThicknessG = nThickness; if (cColorcon == null) cColorcon = cColor1; if (cColordev1 == null) cColordev1 = cColor2; if (sHSource == null) sHSource = sHighSource; if (sLSource == null) sLSource = sLowSource; if (x1a == null) x1a = 0; if (y1a == null) y1a = c; if (nNumLabelsG == null) nNumLabelsG = nNumLabels; if (bSwingLabelsG == null) bSwingLabelsG = bSwingLabels; nLcntr = nNumLabels; // Initialize vSpace var OM = (close() * 0.005); //offset multiplier var sInterval = getInterval(); if (sInterval == "D") OM = OM*3; if (sInterval == "W") OM = OM*20; if (sInterval == "M") OM = OM*30; var TimeFrame = parseInt(sInterval); if (TimeFrame >= 1 && TimeFrame <= 5) { OM = OM*(TimeFrame/15); } else if (TimeFrame > 5 && TimeFrame <= 15) { OM = OM*(TimeFrame/10); }else if (TimeFrame > 15) { OM = OM*(TimeFrame/5); } if (!isNaN(TimeFrame)) OM = (OM/TimeFrame)*3; vSpace = OM; bEdit = false; } if (bInit == false) { bInit = Init(h,l,c); } // Swings if (nState == BARSTATE_NEWBAR) { nScntr += 1; // confirmed Swings if (nScntr > nNumBars) { confirmSwings(); if (bInit == true) { doLine("dev1"); doLine("dev2"); } } } checkSwings(h, l); if (bInit == true) { doLine("dev1"); doLine("dev2"); } // % Retracement Label var nWaveRet = (Math.abs(y2a-y2b) / Math.abs(y1b-y1a))*100; if (x1b == x2b) nWaveRet = 0.0; if (bRetLabel == "True") { var sWaveRetText = " \%Retraced: " + nWaveRet.toFixed(2) + " "; drawTextRelative(2, y2b, sWaveRetText, cColordev1, null, Text.BOLD|Text.LEFT|Text.VCENTER|Text.FRAME, "Arial", 10, "Ret"); } return; } /****** Functions *****/ /***********************/ function Init(h,l,c) { if (close(-(nNumBars*2)) == null) { return false; } else { // Find initial line. // The initial line will be the first high or low swing, // which has the greater difference of the swing point to // the close of the first bar. var Index = getCurrentBarIndex() var hIndex = Index; var lIndex = Index; var j = nNumBars*2; var aHigh = getValue(sHSource, 0, -j); var aLow = getValue(sLSource, 0, -j); var vHH = aHigh[0]; var vLL = aLow[0]; var tempIndex = Index; var i = 0; for (i = 0; i < j; ++i) { if (aHigh[i] > vHH) { vHH = aHigh[i]; hIndex = tempIndex; } if (aLow[i] < vLL) { vLL = aLow[i]; lIndex = tempIndex; } tempIndex -= 1; } if (vHH - y1a > y1a - vLL) { vLastSwing = "L"; x1b = hIndex - Index; y1b = vHH; doLine("dev1"); x2a = x1b; y2a = vHH; x2b = 0; y2b = c; doLine("dev2"); } else { vLastSwing = "H"; x1b = lIndex - Index; y1b = vLL; doLine("dev1"); x2a = x1b; y2a = vLL; x2b = 0; y2b = c; doLine("dev2"); } } if (vLastSwing != null) { return true; } else { return false; } } function doLine(sType) { //confirmed if (sType == "con") { cntr += 1; drawLineRelative(x1a, y1a, x1b, y1b, PS_SOLID, nThicknessG, cColorcon, sType+cntr); //Swing Labels if (bSwingLabelsG == "True") doSwingLabels(sType); x1a = x2a; y1a = y2a; x1b = x2b; y1b = y2b; x2a = x1b; y2a = y1b; aSwingsIndex.pop(); aSwingsIndex.unshift(x1b); aSwingsPrice.pop(); aSwingsPrice.unshift(y1b); if (vLastSwing == "H") y2b = getValue(sHSource); if (vLastSwing == "L") y2b = getValue(sLSource); } // dev1 if (sType == "dev1") { drawLineRelative(x1a, y1a, x1b, y1b, PS_SOLID, nThicknessG, cColordev1, sType); aSwingsIndex[0] = x1b; aSwingsPrice[0] = y1b; //Swing Labels if (bSwingLabelsG == "True") doSwingLabels(sType); } // dev2 if (sType == "dev2") { if (x2a != 0 && x2a != x2b) { if ( (vLastSwing == "H" && sHSource == "Close") || (vLastSwing == "L" && sLSource == "Close") ) { x2b = 0; y2b = close(); } drawLineRelative(x2a, y2a, x2b, y2b, PS_SOLID, nThicknessG, cColordev1, sType); } else { removeLine(sType); } } return; } function doSwingLabels(sType) { var sTagNamePts = "SwingPtsDev"; var sTagNameRet = "SwingRetDev"; var sTagNamePr = "SwingPrDev"; var sTagNameBars = "SwingBarsDev"; var nWaveRet = ((Math.abs(aSwingsPrice[1]-aSwingsPrice[0]) / Math.abs(aSwingsPrice[1]-aSwingsPrice[2])) * 100); var nBars = (aSwingsIndex[0] - aSwingsIndex[1]); if (sType == "con") { //nWaveRet = (Math.abs(y2a-y2b) / Math.abs(y1b-y1a)); nLcntr += 1; if (nLcntr > nNumLabelsG) nLcntr = 1; sTagNamePts = "SwingPts"+sType+nLcntr; sTagNameRet = "SwingRet"+sType+nLcntr; sTagNamePr = "SwingPr"+sType+nLcntr; sTagNameBars = "SwingBars"+sType+nLcntr; } var pts = (y1b-y1a).toFixed(2); if (y1a < y1b) { // swing high drawTextRelative(x1b, y1b+vSpace, pts + " ", eval("cColor"+sType), null, Text.BOTTOM|Text.RIGHT, "Arial", 10, sTagNamePts); // Points if (!isNaN(nWaveRet)) { drawTextRelative(x1b, y1b+vSpace, "| ("+nWaveRet.toFixed(2)+"\%)", eval("cColor"+sType), null, Text.BOTTOM|Text.LEFT, "Arial", 10, sTagNameRet); // % Retracement } drawTextRelative(x1b, y1b+vSpace, y1b.toFixed(2) + " ", eval("cColor"+sType), null, Text.TOP|Text.RIGHT, "Arial", 10, sTagNamePr); // Price if (!isNaN(nBars)) { drawTextRelative(x1b, y1b+vSpace, "| ("+nBars+" Bars)", eval("cColor"+sType), null, Text.TOP|Text.LEFT, "Arial", 10, sTagNameBars); // Number of Bars } } else { // swing low drawTextRelative(x1b, y1b-vSpace, pts + " ", eval("cColor"+sType), null, Text.TOP|Text.RIGHT, "Arial", 10, sTagNamePts); // Points if (!isNaN(nWaveRet)) { drawTextRelative(x1b, y1b-vSpace, "| ("+nWaveRet.toFixed(2)+"\%)", eval("cColor"+sType), null, Text.TOP|Text.LEFT, "Arial", 10, sTagNameRet); // % Retracement } drawTextRelative(x1b, y1b-vSpace, y1b.toFixed(2) + " ", eval("cColor"+sType), null, Text.BOTTOM|Text.RIGHT, "Arial", 10, sTagNamePr); // Price if (!isNaN(nBars)) { drawTextRelative(x1b, y1b-vSpace, "| ("+nBars+" Bars)", eval("cColor"+sType), null, Text.BOTTOM|Text.LEFT, "Arial", 10, sTagNameBars); // Number of Bars } } return; } function confirmSwings() { if (x1b != x2b) { // underdeveloped dev1 line if (sWaveTypeG == "% Retracement") { var nWave = (Math.abs(y2a-y2b) / Math.abs(y1b-y1a)); } else { var nWave = (Math.abs(y2a-y2b) / y1b); } if (vLastSwing == "L" && nWave >= nRetpcnt ) { // Swing High nScntr = 0; vLastSwing = "H"; doLine("con"); } else if (vLastSwing == "H" && nWave >= nRetpcnt ) { // Swing Low nScntr = 0; vLastSwing = "L"; doLine("con"); } } return; } function checkSwings(h, l) { // dev1 if (vLastSwing == "L") { // find Swing High if (h >= y1b) { // higher high, no swing nScntr = 0; x1b = 0; y1b = h; doLine("dev1"); x2a = 0; y2a = h; } } else if (vLastSwing == "H") { // find Swing Low if (l <= y1b) { // Lower low, no swing nScntr = 0; x1b = 0; y1b = l; doLine("dev1"); x2a = 0; y2a = l; } } // dev2 if (nScntr == 0) { x2b = 0; if (vLastSwing == "H") y2b = h; if (vLastSwing == "L") y2b = l; } else { if (vLastSwing == "H" && h >= y2b) { y2b = h; x2b = 0; } else if (vLastSwing == "L" && l <= y2b) { y2b = l; x2b = 0; } } return; }