2004 Oct: SwingPrediction.efs

ICE Data Services -

SwingPrediction.efs  
EFSLibrary - Discussion Board  

File Name: SwingPrediction.efs

Description:
This formula is based on Fibonacci And Gann Projections by Dennis Peterson, which appeared in the October 2004 issue of Stocks & Commodities.

Formula Parameters:

  • Swing # of Bars - 1
    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 - % Change in Price
    (% Retracement, % Change in Price)
  • Swing Wave Percentage - 5
    The number 5 will be treated as 5.0%. The number 0.05 will be treated as 0.0005%.
  • Swing High Price Source - Close
  • Swing Low Price Source - Close
  • Line Thickness - 2
  • Confirmed Swing Line Color - Blue
  • Developing Swing Line Color - Yellow
  • Number of Swings for Gann - 1
    The number of previous swings points to be included in the Gann projections
  • Gann Increment - 0.25
    The +/- increment for Gann calculation above and below the base calculation for Gann.
  • Number of Gann Increments - 2
    The number of Gann increments to be calculated above and below the Gann basis calculation. 2 will draw one above and one low the basis.
  • Fibonacci: DR 1 - 0.382
  • Fibonacci: DR 2 - 1.618
  • Fibonacci: A1 1 - 0.5
  • Fibonacci: A1 2 - 1.732
  • Fibonacci: A2 1 - 0.618
  • Fibonacci: A2 2 - 2.0
  • Fibonacci: C 1 - 0.707
  • Fibonacci: C 2 - 2.618
  • Fibonacci: DC 1 - 1.0
  • Fibonacci: DC 2 - 3.0

Notes:
The current version has one added modification since the formula went into publication. Per Dennis Peterson's request, a third label has been added to show a second percent retracement figure. The top %Rtmt label is the percent retracement of the developing swing (green Sept peak) to the second previous confirmed swing (blue June peak). The second %Rtmt label is the percent retracement of the right-most developing swing line (current bar) to the previous confirmed swing (Aug valley). The last %Chg label is the percent change in price of the righ-most developing swing line (current bar) from the developing swing (green Sept peak). The related article is copyrighted material. If you are not a subscriber of Stocks & Commodities, please visit www.traders.com.

Download File:
SwingPrediction.efs


EFS Code:

/*****************************************************************
Provided By : eSignal. (c) Copyright 2004
Study:        Swing Prediction
Version:      1.0

Formula Parameters:                 Default:
    * Swing: # of Bars              1
        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              % Change in Price
        (% Retracement, % Change in Price)
    * Swing: Wave Percentage        5
        The number 5 will be treated as 5.0%.  The number 0.05 will 
        be treated as 0.0005%.
    * Swing High Price Source       Close
    * Swing Low Price Source        Close
    * Line Thickness                2
    * Confirmed Swing Line Color    Blue
    * Developing Swing Line Color   Yellow
    * Number of Swings for Gann     1
        The number of previous swings points to be included in the
        Gann projections
    * Gann Increment                0.25
        The +/- increment for Gann calculation above and below the base
        calculation for Gann.
    * Number of Gann Increments     2
        The number of Gann increments to be calculated above and below
        the Gann basis calculation.  2 will draw one above and one below
        the basis.
    * Fibonacci: DR 1               0.382
    * Fibonacci: DR 2               1.618
    * Fibonacci: A1 1               0.5
    * Fibonacci: A1 2               1.732
    * Fibonacci: A2 1               0.618
    * Fibonacci: A2 2               2.0
    * Fibonacci: C 1                0.707
    * Fibonacci: C 2                2.618
    * Fibonacci: DC 1               1.0
    * Fibonacci: DC 2               3.0

*****************************************************************/

function preMain() {
    setPriceStudy(true);
    setStudyTitle("Swing Prediction ");
    setShowCursorLabel(false);
    setShowTitleParameters(false);
    
    var fp1 = new FunctionParameter("nNum", FunctionParameter.NUMBER);
    fp1.setName("Swing: # of Bars");
    fp1.setLowerLimit(1);
    fp1.setDefault(1);
    
    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(5);

    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.yellow);
    
    var fp19 = new FunctionParameter("nGann", FunctionParameter.NUMBER);
    fp19.setName("Number of Swings for Gann");
    fp19.setLowerLimit(1);
    fp19.setUpperLimit(6);
    fp19.setDefault(1);
    
    var fp19b = new FunctionParameter("nGannInc", FunctionParameter.NUMBER);
    fp19b.setName("Gann Increment");
    fp19b.setLowerLimit(0);
    fp19b.setDefault(0.25);

    var fp19c = new FunctionParameter("nGannNum", FunctionParameter.NUMBER);
    fp19c.setName("Number of Gann Increments");
    fp19c.setLowerLimit(0);
    fp19c.setDefault(2);

    var fp20 = new FunctionParameter("fib0", FunctionParameter.NUMBER);
    fp20.setName("Fibonacci: DR 1");
    fp20.setLowerLimit(0);
    fp20.setDefault(0.382);

    var fp21 = new FunctionParameter("fib1", FunctionParameter.NUMBER);
    fp21.setName("Fibonacci: DR 2");
    fp21.setLowerLimit(0);
    fp21.setDefault(1.618);

    var fp22 = new FunctionParameter("fib2", FunctionParameter.NUMBER);
    fp22.setName("Fibonacci: A1 1");
    fp22.setLowerLimit(0);
    fp22.setDefault(0.5);

    var fp23 = new FunctionParameter("fib3", FunctionParameter.NUMBER);
    fp23.setName("Fibonacci: A1 2");
    fp23.setLowerLimit(0);
    fp23.setDefault(1.732);

    var fp24 = new FunctionParameter("fib4", FunctionParameter.NUMBER);
    fp24.setName("Fibonacci: A2 1");
    fp24.setLowerLimit(0);
    fp24.setDefault(0.618);

    var fp25 = new FunctionParameter("fib5", FunctionParameter.NUMBER);
    fp25.setName("Fibonacci: A2 2");
    fp25.setLowerLimit(0);
    fp25.setDefault(2);

    var fp26 = new FunctionParameter("fib6", FunctionParameter.NUMBER);
    fp26.setName("Fibonacci: C 1");
    fp26.setLowerLimit(0);
    fp26.setDefault(0.707);

    var fp27 = new FunctionParameter("fib7", FunctionParameter.NUMBER);
    fp27.setName("Fibonacci: C 2");
    fp27.setLowerLimit(0);
    fp27.setDefault(2.618);

    var fp28 = new FunctionParameter("fib8", FunctionParameter.NUMBER);
    fp28.setName("Fibonacci: DC 1");
    fp28.setLowerLimit(0);
    fp28.setDefault(1.0);

    var fp29 = new FunctionParameter("fib9", FunctionParameter.NUMBER);
    fp29.setName("Fibonacci: DC 2");
    fp29.setLowerLimit(0);
    fp29.setDefault(3.0);
}

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 cColorDev = null;   // developing swing color
var nGannG = 1;         // number of swings for Gann calculations
var nGannIncG = null;   // increment value for Gann calculations
var nGannNumG = null;   // number of increments for Gann calculations
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 aY2A = new Array(7);// array of current 7 swing prices 
var vLastSwing = null;  // tracking swing type of last confirmed swing
var nScntr = 0;         // bar counter for swing confirmation
var aSwingsIndex = new Array(7); // tracks current swings for DR, C, DC, A1, A2 periods
var aSwingsPrice = new Array(7); // tracks current swing prices for Gann projections
var aFibs = new Array(10);       // Fibonacci numbers for Swing Predictions
var bProjCon = false;
var bProjDev = false;

var tCntr = 0;

function main(nNum, sWaveType, nRet, sHighSource, sLowSource, nThickness, cColor1, cColor2,
              nGann, nGannInc, nGannNum, fib0, fib1, fib2, fib3, fib4, fib5, fib6, fib7, fib8, fib9) {
    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 < 7; ++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 (cColorDev == null) cColorDev = cColor2;
        if (nGann != null) nGannG = nGann;
        if (nGannIncG == null) nGannIncG = nGannInc;
        if (nGannNumG == null) nGannNumG = Math.round(nGannNum);
        if (sHSource == null) sHSource = sHighSource;
        if (sLSource == null) sLSource = sLowSource;
        if (x1a == null) x1a = 0;
        if (y1a == null) y1a = c;
        i = 0;
        for (i = 0; i < 10; ++i) {
            aFibs[i] = eval("fib"+i);
        }
        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 (bProjCon == true) {
        bProjCon = false;
        doProjections("con");
    }
    if (bProjDev == true) {
        bProjDev = false;
        doProjections("dev1");
    }

    if (nIndex >= -1) {
        var nWaveRet = (Math.abs(aSwingsPrice[0]-aSwingsPrice[1]) / Math.abs(aSwingsPrice[1]-aSwingsPrice[2]))*100;
        var sWaveRetText = " \%Rtmt: " + nWaveRet.toFixed(2) + " ";
        var nWaveRet2 = (Math.abs(y2b-aSwingsPrice[0]) / Math.abs(aSwingsPrice[0]-aSwingsPrice[1]))*100;
        var sWaveRetText2 = " \%Rtmt: " + nWaveRet2.toFixed(2) + " ";
        var nWaveChg = (Math.abs(y2a-y2b) / y1b)*100;
        var sWaveChgText = " \%Chg: " +  nWaveChg.toFixed(2) + " ";
        drawTextRelative(2, 45, sWaveRetText, cColor1, Color.lightgrey,
            Text.BOLD|Text.LEFT|Text.VCENTER|Text.FRAME|Text.RELATIVETOBOTTOM, 
            null, 12, "Ret");   // Developing peak/valley %Ret of previous confirmed peak/valley
        drawTextRelative(2, 25, sWaveRetText2, cColor2, Color.lightgrey,
            Text.BOLD|Text.LEFT|Text.VCENTER|Text.FRAME|Text.RELATIVETOBOTTOM, 
            null, 12, "Ret2");  // Current bar %Ret of current developing peak/valley
        drawTextRelative(2, 5, sWaveChgText, cColor2, Color.lightgrey,
            Text.BOLD|Text.LEFT|Text.VCENTER|Text.FRAME|Text.RELATIVETOBOTTOM, 
            null, 12, "Chg");  // %Change in price of current bar from current developing peak/valley
    }

    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);
        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);
        aY2A.pop();
        aY2A.unshift(y2a);
        if (aSwingsIndex[6] != null) {
            bProjCon = true;
        }
    }

    // dev1
    if (sType == "dev1") {
        drawLineRelative(x1a, y1a, x1b, y1b, PS_SOLID, 
            nThicknessG, cColorDev, sType);
        aSwingsIndex[0] = x1b;
        aSwingsPrice[0] = y1b;
        if (aSwingsIndex[6] != null && getCurrentBarIndex() >= -1) {
            bProjDev = true;
        }
    }
    
    // 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, cColorDev, sType);
        } else {
            removeLine(sType);
        }
    }

    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;
        }
    }
    doLine("dev2");
    return;
}

function doProjections(sName) {
    var i = 0;
    var j = 0;
    var k = 0;
    var nGannTot = (nGannNumG*2) + 1; // total number of Gann rows
    var aX = new Array(10);
    var aY = new Array(10);
    var aSwingPeriods = new Array(10);
    var nOffset = 0;  // 0 for developing swings, 1 for confirmed swings
    
    if (sName == "con") nOffset = 1;

    var DR = aSwingsIndex[0+nOffset] - aSwingsIndex[1+nOffset];
    aSwingPeriods[0] = DR;
    aSwingPeriods[1] = DR;
    var C  = aSwingsIndex[1+nOffset] - aSwingsIndex[3+nOffset];
    aSwingPeriods[2] = C;
    aSwingPeriods[3] = C;
    var DC = aSwingsIndex[1+nOffset] - aSwingsIndex[5+nOffset];
    aSwingPeriods[4] = DC;
    aSwingPeriods[5] = DC;
    var A1 = aSwingsIndex[1+nOffset] - aSwingsIndex[2+nOffset];
    aSwingPeriods[6] = A1;
    aSwingPeriods[7] = A1;
    var A2 = aSwingsIndex[3+nOffset] - aSwingsIndex[4+nOffset];
    aSwingPeriods[8] = A2;
    aSwingPeriods[9] = A2;
    
    if (sName == "con") {
        i = 0;
        for (i = 0; i < nGannG; ++i) {
            for (k = 0; k < 10; ++k) {
                for (j = 0; j < nGannTot; ++j) {
                    removeShape("dev1Proj"+i+k+j);
                }
            }
        }
    }
    
    // X - Projections
    // anchor is from end of DR wave for DR, A1 and A2
    // anchor is from beginning of DR wave for C and DC
    i = 0;
    for (i = 0; i < 10; ++i) {
        if (i >= 2 && i <= 5) { // C and DC
            aX[i] = Math.round((aSwingPeriods[i] * aFibs[i]) + aSwingsIndex[1+nOffset]);
        } else { // DR, A1 and A2
            aX[i] = Math.round((aSwingPeriods[i] * aFibs[i]) + aSwingsIndex[0+nOffset]);
        }
    }
    
    // Y - Projections
    var aY = new Array(nGannG); // number of swings
    i = 0;
    for (i = 0; i < nGannG; ++i) {
        aY[i] = new Array(nGannTot);    // number of rows per swing
    }
    i = 0;
    for (i = 0; i < nGannG; ++i) {
        var nBasis = Math.sqrt(aSwingsPrice[i+nOffset]);
        var nNum = (nGannIncG * nGannNumG);
        for (j = 0; j < nGannTot; ++j) {
            aY[i][j] = (nBasis + nNum) * (nBasis + nNum);
            nNum -= nGannIncG;
        }
    }
    
    // plot Swing Predictions
    i = 0;
    for (i = 0; i < nGannG; ++i) {  // number of swings
        for (k = 0; k < 10; ++k) {  // 10 swing periods (5 waves * 2 fibs for each)
            for (j = 0; j < nGannTot; ++j) {  // total rows per swing
                var ShapeFlags = null;
                if (sName == "con") {
                    var ProjColor = cColorDev;
                    var vShape = "Shape.CIRCLE";
                } else {
                    var ProjColor = Color.red;
                    var vShape = "Shape.DIAMOND";
                }
                if (j == ((nGannTot/2)-.5) ) {
                    if (sName == "con") {
                        ProjColor = cColorCon;
                        vShape = "Shape.CIRCLE";
                    } else {
                        ProjColor = Color.green;
                        vShape = "Shape.DIAMOND";
                    }
                    ShapeFlags = "Shape.ONTOP";
                }
                drawShapeRelative(aX[k], aY[i][j], eval(vShape), null, ProjColor,
                    eval(ShapeFlags), sName + "Proj"+i+k+j);
            }
        }
    }
    
    return;
}