2014 June: Slope Divergence: Capitalizing On Uncertainty by Perry Kaufman

ICE Data Services -

TheThreePeriodDivergence.efs  

EFSLibrary - Discussion Board  

File Name: TheThreePeriodDivergence.efs

Description:
Slope Divergence: Capitalizing On Uncertainty by Perry Kaufman

Formula Parameters:

TheThreePeriodDivergence.efs

  • Fast Mom: true
  • Mom Period: 10
  • Dvg Period1: 5
  • Dvg Period2: 8
  • Dvg Period3: 13
  • Entry Number: 1
  • Big Point Value: 1
  • Long Only: false
  • Variable Size: false
  • Futures: false
  • Long Position Color: aqua
  • Short Position Color: purple
  • Exit Position Color: grey

Notes:
The related article is copyrighted material. If you are not a subscriber of Stocks & Commodities, please visit www.traders.com.

Download File:
TheThreePeriodDivergence.efs

TheThreePeriodDivergence.efs

EFS Code:
TheThreePeriodDivergence.efs

/*********************************
Provided By:  
    Interactive Data Corporation (Copyright В© 2014) 
    All rights reserved. This sample eSignal Formula Script (EFS)
    is for educational purposes only. Interactive Data Corporation
    reserves the right to modify and overwrite this EFS file with 
    each new release. 

Description:        
    Slope Divergence: Capitalizing On Uncertainty by Perry Kaufman

Formula Parameters:                     Default:
Fast Mom                                true
Mom Period                              10
Dvg Period1                             5
Dvg Period2                             8
Dvg Period3                             13
Entry Number                            1
Big Point Value                         1
Long Only                               false
Variable Size                           false
Futures                                 false
Long Position Color                     aqua
Short Position Color                    purple 
Exit Position Color                     grey

Version:            1.00  04/04/2014

Notes:
    The related article is copyrighted material. If you are not a subscriber
    of Stocks & Commodities, please visit www.traders.com.

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

var fpArray = new Array();

function preMain()
{   
    setStudyTitle("TheThreePeriodDivergence");
    setPriceStudy(true);

    var x = 0;

    fpArray[x] = new FunctionParameter("fpFastMom", FunctionParameter.BOOLEAN);
    with(fpArray[x++])
    {
        setName("Fast Mom");
        setDefault(true);
    }

    fpArray[x] = new FunctionParameter("fpMomPeriod", FunctionParameter.NUMBER);
    with(fpArray[x++])
    {
        setName("Mom Period");
        setDefault(10);
        setLowerLimit(1);
    }

    fpArray[x] = new FunctionParameter("fpDvgPeriod1", FunctionParameter.NUMBER);
    with(fpArray[x++])
    {
        setName("Dvg Period1");    
        setDefault(5);
        setLowerLimit(1);
    }

    fpArray[x] = new FunctionParameter("fpDvgPeriod2", FunctionParameter.NUMBER);
    with(fpArray[x++])
    {
        setName("Dvg Period2");    
        setDefault(8);
        setLowerLimit(1);
    }

    fpArray[x] = new FunctionParameter("fpDvgPeriod3", FunctionParameter.NUMBER);
    with(fpArray[x++])
    {
        setName("Dvg Period3");    
        setDefault(13);
        setLowerLimit(1);
    }

    fpArray[x] = new FunctionParameter("fpEntryNumber", FunctionParameter.NUMBER);
    with(fpArray[x++])
    {
        setName("Entry Number");    
        setDefault(1);
        setLowerLimit(1);
        setUpperLimit(3);
    }

    fpArray[x] = new FunctionParameter("fpBPValue", FunctionParameter.NUMBER);
    with(fpArray[x++])
    {
        setName("Big Point Value");    
        setDefault(1);
        setLowerLimit(1);
    }
    
    fpArray[x] = new FunctionParameter("fpLongOnly", FunctionParameter.BOOLEAN);
    with(fpArray[x++])
    {
        setName("Long Only");
        setDefault(false);
    }

    fpArray[x] = new FunctionParameter("fpVariableSize", FunctionParameter.BOOLEAN);
    with(fpArray[x++])
    {
        setName("Variable Size");
        setDefault(false);
    }

    fpArray[x] = new FunctionParameter("fpFutures", FunctionParameter.BOOLEAN);
    with(fpArray[x++])
    {
        setName("Futures");
        setDefault(false);
    }
    
    fpArray[x] = new FunctionParameter("fpLongColor", FunctionParameter.COLOR);
    with(fpArray[x++])
    {
        setName("Long Position Color");    
        setDefault(Color.cyan);
    } 
    
    fpArray[x] = new FunctionParameter("fpShortColor", FunctionParameter.COLOR);
    with(fpArray[x++])
    {
        setName("Short Position Color");    
        setDefault(Color.magenta);
    } 
    
    fpArray[x] = new FunctionParameter("fpExitColor", FunctionParameter.COLOR);
    with(fpArray[x++])
    {
        setName("Exit Position Color");    
        setDefault(Color.grey);
    } 
}

var bInit = false;
var bVersion = null;

var xClose = null;
var xOpen = null;
var xDay = null;
var xMonth = null;
var xYear = null;

var xATR = null;
var nATRperiod = 20;

var xMom = null;

var xMomSlope1 = 0;
var xPriceSlope1 = 0;
var xMomSlope2 = 0;
var xPriceSlope2 = 0; 
var xMomSlope3 = 0;
var xPriceSlope3 = 0;

var nMaxDivergences = 3;
var nInvestment = 25000;
var nSize = 1;

var nFuturesInvest = 25000;
var nStockInvest = 10000;

var bTrend1Up = false;
var bTrend2Up = false;
var bTrend3Up = false;
var bTrend1Down = false;
var bTrend2Down = false;
var bTrend3Down = false;

var nEntrySize = 0;

var nTotalPL  = 0;
var nLongPL = 0;
var nShortPL = 0;

var nPrevPosition = 0;

var fLog = new File("divergence_PL.csv");

function main(fpFastMom,
              fpMomPeriod,
              fpDvgPeriod1,
              fpDvgPeriod2,
              fpDvgPeriod3,
              fpEntryNumber,
              fpBPValue,
              fpLongOnly,
              fpVariableSize,
              fpFutures,
              fpLongColor,
              fpShortColor,
              fpExitColor) 
{
    if (bVersion == null) bVersion = verify();
    if (bVersion == false) return;
    
    if (!bInit)
    {   
        xClose = close();
        xOpen = open();

        xDay = day();
        xMonth = month();
        xYear = year();
        
        xATR = atr(nATRperiod);
    
        if (fpFastMom) xMom = stochK(fpMomPeriod, 1, 3)
        else xMom = stochD(fpMomPeriod, 1, 3)

        xPriceSlope1 = efsInternal("LinearRegression_Slope", xClose, fpDvgPeriod1);
        xMomSlope1 = efsInternal("LinearRegression_Slope", xMom, fpDvgPeriod1);

        xPriceSlope2 = efsInternal("LinearRegression_Slope", xClose, fpDvgPeriod2);
        xMomSlope2 = efsInternal("LinearRegression_Slope", xMom, fpDvgPeriod2);

        xPriceSlope3 = efsInternal("LinearRegression_Slope", xClose, fpDvgPeriod3);
        xMomSlope3 = efsInternal("LinearRegression_Slope", xMom, fpDvgPeriod3);
     
        bInit = true;
    }

    if (getBarState() == BARSTATE_ALLBARS)
    {
        fLog.open("wt");
        fLog.writeln("Date, TotalPL, LongPL, ShortPL");
        fLog.close();
        
        nInvestment = 25000;
        nEntrySize = 0;
        nSize = 1;
        
        if (fpFutures) nInvestment = nFuturesInvest
        else nInvestment = nStockInvest;
        nLongPL = nInvestment;
        nShortPL = nInvestment;
        nTotalPL = nInvestment;
        
        nPrevPosition = 0;
    }

    if (getCurrentBarIndex() == 0) return;

    var nNextClose = xClose.getValue(1);
    var nClose = xClose.getValue(0);
    var nNextOpen = xOpen.getValue(1);

    var nDay = xDay.getValue(0);
    var nMonth = xMonth.getValue(0);
    var nYear = xYear.getValue(0);
    
    var nATR = xATR.getValue(0);

    var nPriceSlope1 = xPriceSlope1.getValue(0);
    var nMomSlope1 = xMomSlope1.getValue(0);

    var nPriceSlope2 = xPriceSlope2.getValue(0);
    var nMomSlope2 = xMomSlope2.getValue(0);

    var nPriceSlope3 = xPriceSlope3.getValue(0);
    var nMomSlope3 = xMomSlope3.getValue(0);
        
    if (nPriceSlope1 == null || nMomSlope1 == null || 
        nPriceSlope2 == null || nMomSlope2 == null || 
        nPriceSlope3 == null || nMomSlope3 == null ||
        nATR == null)
        return;
        
    if (fpVariableSize)
        if (fpFutures) nSize = nInvestment / (nATR * fpBPValue)
        else nSize = nInvestment / nClose;
    
    var bEnterToday = false;
    var bExitToday = false;
    
    var bDvgBuy1 = false;
    var bDvgSell1 = false;
    
    if (nPriceSlope1 > 0 && nMomSlope1 < 0) bDvgBuy1 = true;
    if (nPriceSlope1 < 0 && nMomSlope1 > 0) bDvgSell1 = true;
    
    var bDvgBuy2 = false;
    var bDvgSell2 = false;

    if (nPriceSlope2 > 0 && nMomSlope2 < 0) bDvgBuy2 = true;
    if (nPriceSlope2 < 0 && nMomSlope2 > 0) bDvgSell2 = true;
    
    var bDvgBuy3 = false;
    var bDvgSell3 = false;

    if (nPriceSlope3 > 0 && nMomSlope3 < 0) bDvgBuy3 = true;
    if (nPriceSlope3 < 0 && nMomSlope3 > 0) bDvgSell3 = true;

    var nBuys = 0;

    if (bDvgBuy1) nBuys++;
    if (bDvgBuy2) nBuys++;
    if (bDvgBuy3) nBuys++;

    var nSells = 0;

    if (bDvgSell1) nSells++;
    if (bDvgSell2) nSells++;
    if (bDvgSell3) nSells++;
    
    bTrend1Up = nPriceSlope1 > 0 && nMomSlope1 > 0;
    bTrend2Up = nPriceSlope2 > 0 && nMomSlope2 > 0;
    bTrend3Up = nPriceSlope3 > 0 && nMomSlope3 > 0;
    trend1down = nPriceSlope1 < 0 && nMomSlope1 < 0;
    trend2down = nPriceSlope2 < 0 && nMomSlope2 < 0;
    trend3down = nPriceSlope3 < 0 && nMomSlope3 < 0;

    var nPriceSlopeUp = 0;
    var nPriceSlopeDown = 0;

    if (nPriceSlope1 >= 0) 
        nPriceSlopeUp++;
    else
        nPriceSlopeDown++;

    if (nPriceSlope2 >= 0)
        nPriceSlopeUp++;
    else
        nPriceSlopeDown++;

    if (nPriceSlope3 >= 0)
        nPriceSlopeUp++;
    else
        nPriceSlopeDown++;

    
    var nMomSlopeUp = 0;
    var nMomSlopeDown = 0;

    if (nMomSlope1 >= 0)
       nMomSlopeUp++;
    else
       nMomSlopeDown++;

    if (nMomSlope2 >= 0)
       nMomSlopeUp++;
    else
       nMomSlopeDown++;
       
    if (nMomSlope3 >= 0)
       nMomSlopeUp++;
    else
       nMomSlopeDown++; 

    if (Strategy.isInTrade())
        if ((nPriceSlopeUp == nMaxDivergences && nMomSlopeUp == nMaxDivergences) ||
            (nPriceSlopeDown == nMaxDivergences && nMomSlopeDown == nMaxDivergences))
        {
            if (Strategy.isLong())
            {
                Strategy.doSell("XLall", Strategy.MARKET, Strategy.NEXTBAR, Strategy.ALL);                                                                               
                drawShapeRelative(1, AboveBar1, Shape.DOWNTRIANGLE, null, fpExitColor, Text.PRESET, getCurrentBarIndex()+"XLall_Shape");
                drawTextRelative(1, AboveBar2, "XLall", fpExitColor, null, Text.PRESET|Text.CENTER, null, null, getCurrentBarIndex()+"XLall_Text");
                drawTextRelative(1, AboveBar3, "0", fpExitColor, null, Text.PRESET|Text.CENTER, null, null, getCurrentBarIndex()+"XLall_Size"); 
            }
            else if (Strategy.isShort())
            {
                Strategy.doCover("XSall", Strategy.MARKET, Strategy.NEXTBAR, Strategy.ALL);                                                                               
                drawShapeRelative(1, BelowBar1, Shape.UPTRIANGLE, null, fpExitColor, Text.PRESET, getCurrentBarIndex()+"XSall_Shape");
                drawTextRelative(1, BelowBar2, "XSall", fpExitColor, null, Text.PRESET|Text.CENTER, null, null, getCurrentBarIndex()+"XSall_Text");
                drawTextRelative(1, BelowBar3, "0", fpExitColor, null, Text.PRESET|Text.CENTER, null, null, getCurrentBarIndex()+"XSall_Size"); 
            }
            
            bExitToday = true; 
        }    
                    
    if ((!Strategy.isInTrade() || Strategy.isShort()) && (nBuys >= fpEntryNumber))
    {
        if (Strategy.isShort())
        {
            Strategy.doCover("RevShort", Strategy.CLOSE, Strategy.THISBAR, Strategy.ALL);                                                                               
            drawShapeRelative(0, BelowBar1, Shape.UPTRIANGLE, null, fpExitColor, Text.PRESET, getCurrentBarIndex()+"RevShort_Shape");
            drawTextRelative(0, BelowBar2, "RevShort", fpExitColor, null, Text.PRESET|Text.CENTER, null, null, getCurrentBarIndex()+"RevShort_Text");
            drawTextRelative(0, BelowBar3, "0", fpExitColor, null, Text.PRESET|Text.CENTER, null, null, getCurrentBarIndex()+"RevShort_Size");
        }
        
        if (nSize >= 1)
        {
            Strategy.doLong("NewBuy", Strategy.MARKET, Strategy.NEXTBAR, nSize);                                                                               
            drawShapeRelative(1, BelowBar1, Shape.UPTRIANGLE, null, fpLongColor, Text.PRESET, getCurrentBarIndex()+"NewBuy_Shape");
            drawTextRelative(1, BelowBar2, "NewBuy", fpLongColor, null, Text.PRESET|Text.CENTER, null, null, getCurrentBarIndex()+"NewBuy_Text");
            drawTextRelative(1, BelowBar3, nSize.toFixed(), fpLongColor, null, Text.PRESET|Text.CENTER, null, null, getCurrentBarIndex()+"NewBuy_Size"); 
                
            nEntrySize = nSize;
            bEnterToday = true;
        }   
    }
    else if ((!Strategy.isInTrade() || Strategy.isLong()) && (!fpLongOnly) &&  (nSells >= fpEntryNumber))
    {
        if (Strategy.isLong())
        {
            Strategy.doSell("RevLong", Strategy.CLOSE, Strategy.THISBAR, Strategy.ALL);                                                                               
            drawShapeRelative(0, AboveBar1, Shape.DOWNTRIANGLE, null, fpExitColor, Text.PRESET, getCurrentBarIndex()+"RevLong_Shape");
            drawTextRelative(0, AboveBar2, "RevLong", fpExitColor, null, Text.PRESET|Text.CENTER, null, null, getCurrentBarIndex()+"RevLong_Text");
            drawTextRelative(0, AboveBar3, "0", fpExitColor, null, Text.PRESET|Text.CENTER, null, null, getCurrentBarIndex()+"RevLong_Size");
        }

        if (nSize >= 1)
        {
            Strategy.doShort("NewSell", Strategy.MARKET, Strategy.NEXTBAR, nSize);                                                                               
            drawShapeRelative(1, AboveBar1, Shape.DOWNTRIANGLE, null, fpShortColor, Text.PRESET, getCurrentBarIndex()+"NewSell_Shape");
            drawTextRelative(1, AboveBar2, "NewSell", fpShortColor, null, Text.PRESET|Text.CENTER, null, null, getCurrentBarIndex()+"NewSell_Text");
            drawTextRelative(1, AboveBar3, nSize.toFixed(), fpShortColor, null, Text.PRESET|Text.CENTER, null, null, getCurrentBarIndex()+"NewSell_Size"); 
            
            nEntrySize = nSize;
            bEnterToday = true;
        }     
    }
    
    var nTodayLongPL = 0;
    var nTodayShortPL = 0;

    if (Strategy.isLong())
        if (bEnterToday)
        {
            nTodayLongPL = 1 * nEntrySize * (nNextClose - nNextOpen) * fpBPValue; 
            nLongPL += nTodayLongPL;
        }
        else
        {
            nTodayLongPL = 1 * nEntrySize * (nNextClose - nClose) * fpBPValue; 
            nLongPL += nTodayLongPL;
        }
    else if (Strategy.isShort())
        if (bEnterToday)
        {
            nTodayShortPL = -1 * nEntrySize * (nNextClose - nNextOpen) * fpBPValue; 
            nShortPL += nTodayShortPL;
        }
        else
        {
            nTodayShortPL = -1 * nEntrySize * (nNextClose - nClose) * fpBPValue; 
            nShortPL += nTodayShortPL;
        }
    
    if (!Strategy.isInTrade() && bExitToday)
        if (nPrevPosition > 0)
        {
            nTodayLongPL = nPrevPosition * nEntrySize * (nNextOpen - nClose) * fpBPValue; 
            nLongPL += nTodayLongPL;
        }
        else
        {
            nTodayShortPL = nPrevPosition * nEntrySize * (nNextOpen - nClose) * fpBPValue; 
            nShortPL += nTodayShortPL
        }
    
    var nTodayPL = nTodayLongPL + nTodayShortPL;
    
    nTotalPL += nTodayPL;
    nInvestment += nTodayPL;

    if (Strategy.isLong()) nPrevPosition = 1;
    if (Strategy.isShort()) nPrevPosition = -1;

    var sADate = nMonth + "/" + nDay + "/" + nYear;

    fLog.open("at");
    fLog.writeln(sADate + ", " + formatPriceNumber(nTotalPL) + ", " + formatPriceNumber(nLongPL) + ", " + formatPriceNumber(nShortPL)); 
    fLog.close();
     
    return;
}

function LinearRegression_Slope(xSourse, nPeriod)
{
    if (getCurrentBarCount() < nPeriod) 
        return;
    
    var nPer = 1;
    var nTime = 0;
    var nTSq = 0;
    var nPrice = 0;
    var nTimePrice = 0;
    var nVal = 0;
    var nSlope = 0;
       
    for (var i = 0; i < nPeriod; i++)
    {
       nTime += nPer;
       nVal = xSourse.getValue(-(nPeriod - 1) + i);  
       nPrice += nVal;
       nTimePrice += (nVal * nPer);
       nTSq += (nPer * nPer);
       nPer++;
    }  
    
    nPer--;
    
    nSlope = ((nPer * nTimePrice) - (nTime * nPrice)) / ((nPer * nTSq) - (nTime * nTime));
       
    return nSlope;
}

function verify() 
{
    var b = false;
    if (getBuildNumber() < 779) 
    {
        drawTextAbsolute(5, 35, "This study requires version 8.0 or later.", 
            Color.white, Color.blue, Text.RELATIVETOBOTTOM|Text.RELATIVETOLEFT|Text.BOLD|Text.LEFT,
            null, 13, "error");
        drawTextAbsolute(5, 20, "Click HERE to upgrade.@URL=http://www.esignal.com/download/default.asp", 
            Color.white, Color.blue, Text.RELATIVETOBOTTOM|Text.RELATIVETOLEFT|Text.BOLD|Text.LEFT,
            null, 13, "upgrade");
        return b;
    } 
    else 
    {
        b = true;
    }

    return b;
}