2007 Sep: Trading Trendline Breaks, Part 2

ICE Data Services -


Trendline_Breaks.efs  EFSLibrary - Discussion Board
  

File Name: Trendline_Breaks.efs


Description:
This study is based on the Sept 2007 article, Trading Trendline Breaks, Part 2, by Sylvain Vervoort.


Formula Parameters:
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: False

Display % Retracement Label: False

Number of Historical Labels: 100

Notes:
Study is a modified version of eSignal's RealTimeSwings.efs, which incorporates Vervoort's strategy signals based on ZigZag indicator.
Study provides historical analysis only, see author's notes in the article. The study displays the ZigZag indicator as well as the PU and PD price levels used for the trade signals, which are highlighted on the chart with "Long" and "Short" labels accompanied by up/down arrows. One difference with this EFS study that differs from the logic used in the article is that the forward looking aspect of the signals has been removed. To create realistic signals that may be evaluated in real time, the trade conditions are evaluated on the bars that confirm the previous swing points by the appropriate price action as defined by the formula parameters. The related article is copyrighted material. If you are not a subscriber of Stocks & Commodities, please visit www.traders.com.

Download File:
Trendline_Breaks.efs




EFS Code:






/***************************************Provided By :     eSignal (Copyright ) eSignal), a division of Interactive Data     Corporation. 2007. All rights reserved. This sample eSignal     Formula Script (EFS) is for educational purposes only and may be     modified and saved under a new file name.  eSignal is not responsible    for the functionality once modified.  eSignal reserves the right     to modify and overwrite this EFS file with each new release.    Description:  Trading Trendline Breaks, Part 2              by Sylvain VervoortVersion 1.0  7/9/2007Notes:* Study is a modified version of eSignal's RealTimeSwings.efs,    which incorporates Vervoort's strategy signals based on    ZigZag indicator.* Study provides historical analysis only, see author's notes    in the article.*   Description of Swing Labels:        At Swing Highs -  Points (% Retracement)                          Price (Number of Bars)            At Swing Lows -   Price (Number of Bars)                          Points (% Retracement)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          False    * Display % Retracement Label   False    * Number of Historical Labels   100*****************************************************************/function preMain() {    setPriceStudy(true);    setStudyTitle("Trend Line Breaks ");    //setShowCursorLabel(false);    setShowTitleParameters(false);        //TASC mod    setCursorLabelName("PD", 0);    setCursorLabelName("PU", 1);    setDefaultBarFgColor(Color.red, 0);     //PD    setDefaultBarFgColor(Color.green, 1);   //PU    setDefaultBarThickness(2, 0);    setDefaultBarThickness(2, 1);    setPlotType(PLOTTYPE_FLATLINES, 0);    setPlotType(PLOTTYPE_FLATLINES, 1);            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("% Change in Price");        var fp2 = new FunctionParameter("nRet", FunctionParameter.NUMBER);    fp2.setName("Swing: Wave Percentage");    fp2.setLowerLimit(0);    fp2.setDefault(7);    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("Close");    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("Close");    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("False");        var fp9 = new FunctionParameter("bRetLabel", FunctionParameter.STRING);    fp9.setName("Display \% Retracement Label");    fp9.addOption("True");    fp9.addOption("False");    fp9.setDefault("False");        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 inputsvar cntr = 0;           // image counter for swing linesvar bInit = false;      // initialization routine completionvar nNumBars = null;    // number of bars for defining swingsvar sWaveTypeG = null;  // wave type for confirming swingsvar nRetpcnt = null;    // percent retracement for defining swingsvar nThicknessG = null; // line thicknessvar cColorcon = null;   // confirmed swing colorvar cColordev1 = null;  // developing swing colorvar sHSource = null;    // price source for high swingsvar sLSource = null;    // price source for low swingsvar x1a = null;         // x-coordinate for point a of developing line 1var x1b = null;         // x-coordinate for point b of developing line 1var x2a = null;         // x-coordinate for point a of developing line 2var x2b = null;         // x-coordinate for point b of developing line 2var y1a = null;         // y-coordinate for point a of developing line 1var y1b = null;         // y-coordinate for point b of developing line 1var y2a = null;         // y-coordinate for point a of developing line 2var y2b = null;         // y-coordinate for point b of developing line 2var vLastSwing = null;  // tracking swing type of last confirmed swing (H or L)var nScntr = 0;         // bar counter for swing confirmationvar nLcntr = 0;         // label counter for swing labelsvar aSwingsIndex = new Array(4); // tracks current swings indexes for last 4 swingsvar aSwingsPrice = new Array(4); // tracks current swing prices for last 4 swingsvar nNumLabelsG = null; // max number of swing labelsvar bSwingLabelsG = null;  // controls swing labels displayvar vSpace = null;      // spacer for Labels//TASC modvar bBT = true;     // back test flagvar vPosition = 0;  // 0=flat, 1=long, -1=shortvar nPD = null;var nPU = null;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;                //TASC mod        setDefaultBarThickness(nThickness, 0);        setDefaultBarThickness(nThickness, 1);                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");    }    //TASC mod - back testing conditions    if (nIndex == 0) bBT = false;    if (nState == BARSTATE_NEWBAR) {        if (vPosition != 1 && nPU != null && close(-1) >= nPU && vLastSwing == "L") { // long signal            if (bBT == true) Strategy.doLong("long", Strategy.MARKET, Strategy.THISBAR);            vPosition = 1;            drawShape(Shape.UPARROW, BelowBar1, Color.green);            drawText("Long", BelowBar2, Color.green, Text.FRAME|Text.BOLD, rawtime(0));        } else if (vPosition != -1 && nPD != null && close(-1) <= nPD && vLastSwing == "H") { // short signal            if (bBT == true) Strategy.doShort("short", Strategy.MARKET, Strategy.THISBAR);            vPosition = -1;            drawShape(Shape.DOWNARROW, AboveBar1, Color.red);            drawText("Short", AboveBar2, Color.red, Text.FRAME|Text.BOLD, rawtime(0));        }    }        return new Array(nPD, nPU);}/******  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);        //TASC mod        if (aSwingsPrice[0] != null && vLastSwing != null) {            if (vLastSwing == "H") {                nPD = aSwingsPrice[1] - (aSwingsPrice[1]*0.05);            } else if (vLastSwing == "L") {                nPU = aSwingsPrice[1] + (aSwingsPrice[1]*0.05);            }                    }    }    // 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;}