2013 July: The Step Candle Pattern by Sylvain Vervoort

ICE Data Services -

SVEHLZZCandlePattern.efs  
EFSLibrary - Discussion Board  

File Name: SVEHLZZCandlePattern.efs

Description:
The Step Candle Pattern by Sylvain Vervoort

Formula Parameters:

SVEHLZZCandlePattern

  • ZigZag percent : 5
  • ATR Look back Period : 5
  • ZigZag ATR factor: 1.5
  • Color of ZigZag lines: blue
  • Lines Width: 1
  • Candle Pattern: Up/Down patterns

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

Download File:
SVEHLZZCandlePattern.efs

SVEHLZZCandlePattern.efs

EFS Code:
SVEHLZZCandlePattern.efs

/*********************************
Provided By:  
    Interactive Data Corporation (Copyright © 2013) 
    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:        
    The Step Candle Pattern, by Sylvain Vervoort
    
Version:            1.00  05/07/2013

Formula Parameters:                     Default:
ZigZag percent                          5
ATR Look back Period                    5
ZigZag ATR factor                       1.5
Color of ZigZag lines                   blue
Lines Width                             1
Candle Pattern                          Up/Down patterns

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

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


var pArray = new Array();

function preMain()
{

    setStudyTitle("Candle Pattern Indicator"); 
    setComputeOnClose();
    setPriceStudy(true);

    var x = 0;

    pArray[x] = new FunctionParameter("fpZigZagPercentage", FunctionParameter.NUMBER);
    with(pArray[x++])
    {
      setName("ZigZag percent");
      setLowerLimit(0);
      setDefault(5);
    }

    pArray[x] = new FunctionParameter("fpATRPeriod", FunctionParameter.NUMBER);
    with(pArray[x++])
    {
      setName("ATR Look back Period");
      setLowerLimit(1);
      setDefault(5);
    }

    pArray[x] = new FunctionParameter("fpATRFactor", FunctionParameter.NUMBER);
    with(pArray[x++])
    {
      setName("ZigZag ATR factor");
      setLowerLimit(0);
      setDefault(1.5);
    }

    pArray[x] = new FunctionParameter("fpZigZagColor", FunctionParameter.COLOR);
    with(pArray[x++])
    {
      setName("Color of ZigZag lines");
      setDefault(Color.blue);
    }

    pArray[x] = new FunctionParameter("fpLineWidth", FunctionParameter.NUMBER);
    with(pArray[x++])
    {
      setName("Lines Width");
      setLowerLimit(1);
      setDefault(1);
    }

    pArray[x] = new FunctionParameter("fpCandlePattern", FunctionParameter.STRING);
    with(pArray[x++])
    {
        setName("Candle Pattern");
        addOption("None");
        addOption("Up/Down patterns");
        addOption("Bullish/Bearish engulfing patterns");
        addOption("Bullish/Bearish harami (cross) patterns");
        addOption("All");        
        setDefault("Up/Down patterns");
    }
}

var nTrend = 0;      

var nLHb = 0;        
var nLLb = 0;        

var nHH = 0;     
var bLL = 0;   

var nDownlineID = 0;   
var nUplineID = 0;  

var nHLPivot = 0;     

var xATR = null;
var xOpen = null;
var xClose = null;
var xHigh = null;
var xLow = null;

var bInit = false;
var bVersion = null;

var nBarNumber = 0;
var nPatternCnt = 0;

function main(
    fpZigZagPercentage,
    fpATRPeriod,
    fpATRFactor,
    fpZigZagColor,
    fpLineWidth,
    fpCandlePattern
)
{
    if (bVersion == null) bVersion = verify();
    if (bVersion == false) return;

    if(!bInit)
    {
        xATR = atr(fpATRPeriod);
        xOpen = open();
        xClose = close();
        xHigh = high();
        xLow = low();

        bInit = true;
    }
    if (getBarState()==BARSTATE_ALLBARS)
        nPatternCnt=0;

    nBarNumber = getCurrentBarCount();    

    if(nBarNumber < 2)  
    { 
        bLL = xLow.getValue(0); 
        nHH = xHigh.getValue(0);
        nLLb = nLHb = 1;
        nUplineID = nDownlineID = nBarNumber;
        nTrend = 1;
        return;
    }

    var nATR = xATR.getValue(0);

    if (nATR == null)
        return;

    if(fpATRFactor == 0)
    { 
        nHLPivot = fpZigZagPercentage * 0.01;
    }
    else
    { 
        if (fpZigZagPercentage == 0)
        { 
            nHLPivot = nATR / xClose.getValue(0) * fpATRFactor;
        }
        else
        { 
            nHLPivot = fpZigZagPercentage * 0.01 + nATR / xClose.getValue(0) * fpATRFactor;
        }
    }

    if (nTrend > 0)    
    { 
        if (xHigh.getValue(0) >= nHH) 
        { 
            nHH = xHigh.getValue(0);
            nLHb = nBarNumber;

            drawLineRelative(-(nBarNumber - nLLb), bLL, 0, nHH, PS_SOLID, fpLineWidth, fpZigZagColor, nUplineID);
        }
        else if (xLow.getValue(0) < nHH - nHH * nHLPivot) 
        { 
            bLL = xLow.getValue(0);
            nLLb = nBarNumber;
            nDownlineID = nBarNumber;
            nTrend = -1;

            drawLineRelative(-(nBarNumber - nLHb), nHH, 0, bLL, PS_SOLID, fpLineWidth, fpZigZagColor, nDownlineID);
            
            
            if (fpCandlePattern!="None")
            {
                if (fpCandlePattern=="Up/Down patterns" || fpCandlePattern=="All")    
                {            
                   var nStepDown =  StepDown();                   
                                
                   if (nStepDown==0) nStepDown = BodyGapDown();
                   if (nStepDown==1) 
                   {
                      drawTextRelative(-(nBarNumber - nLHb),AboveBar1,"D",Color.red,null,Text.BOLD | Text.PRESET | Text.CENTER, null, 12);
                      nPatternCnt++;
                      removeText("PatternCount");
                      drawTextPixel( 1, 13, nPatternCnt, fpZigZagColor, null, Text.RELATIVETOLEFT | Text.RELATIVETOBOTTOM | Text.BOLD, null, 12, "PatternCount" );                      
                      return;
                   } 
                }
                
               
                if (fpCandlePattern=="Bullish/Bearish engulfing patterns" || fpCandlePattern=="All")                
                   var nBearishEngulfing = BearishEngulfing(); 
                    if (nBearishEngulfing==1)
                    {
                      drawTextRelative(-(nBarNumber - nLHb),AboveBar1,"E",Color.red,null,Text.BOLD | Text.PRESET | Text.CENTER, null, 12);
                      nPatternCnt++;
                      removeText("PatternCount");
                      drawTextPixel( 1, 13, nPatternCnt, fpZigZagColor, null, Text.RELATIVETOLEFT | Text.RELATIVETOBOTTOM | Text.BOLD, null, 12, "PatternCount" );
                      return;
                    }                
            
                if (fpCandlePattern=="Bullish/Bearish harami (cross) patterns" || fpCandlePattern=="All")                
                    var nBearishHaram = BearishHarami();
                
                    if (nBearishHaram==1)
                    {
                      drawTextRelative(-(nBarNumber - nLHb),AboveBar1,"H",Color.red,null,Text.BOLD | Text.PRESET | Text.CENTER, null, 12);
                      nPatternCnt++;
                      removeText("PatternCount");
                      drawTextPixel( 1, 13, nPatternCnt, fpZigZagColor, null, Text.RELATIVETOLEFT | Text.RELATIVETOBOTTOM | Text.BOLD, null, 12, "PatternCount" );
                        return;
                    }                                                    
            }
        }
    }
    else 
    {
        if (xLow.getValue(0) <= bLL)  
        {
            bLL = xLow.getValue(0);
            nLLb = nBarNumber;

            drawLineRelative(-(nBarNumber - nLHb), nHH, 0, bLL, PS_SOLID, fpLineWidth, fpZigZagColor, nDownlineID);
        }
        else if (xHigh.getValue(0) > bLL + bLL * nHLPivot)  
        {
            nHH = xHigh.getValue(0);
            nLHb = nBarNumber;
            nUplineID = nBarNumber;
            nTrend = 1;

            drawLineRelative(-(nBarNumber - nLLb), bLL, 0, nHH, PS_SOLID, fpLineWidth, fpZigZagColor, nUplineID);
            
            
            if (fpCandlePattern!="None")
            {
                if (fpCandlePattern=="Up/Down patterns" || fpCandlePattern=="All")    
                {            
                   var nStepUp =  StepUp();                   
                   
                   if (nStepUp==0) nStepUp = BodyGapUp();
                   if (nStepUp==1) 
                   {
                      drawTextRelative(-(nBarNumber - nLLb),BelowBar1,"U",Color.blue,null,Text.BOLD | Text.PRESET | Text.CENTER, null, 12);
                      nPatternCnt++;
                      removeText("PatternCount");
                      drawTextPixel( 1, 13, nPatternCnt, fpZigZagColor, null, Text.RELATIVETOLEFT | Text.RELATIVETOBOTTOM | Text.BOLD, null, 12, "PatternCount" );                      
                       return;
                   } 
                }
                
               
                if (fpCandlePattern=="Bullish/Bearish engulfing patterns" || fpCandlePattern=="All")                
                   var nBullishEngulfing = BullishEngulfing(); 
                    if (nBullishEngulfing==1)
                    {
                      drawTextRelative(-(nBarNumber - nLLb),BelowBar1,"E",Color.blue,null,Text.BOLD | Text.PRESET | Text.CENTER, null, 12);
                      nPatternCnt++;
                      removeText("PatternCount");
                      drawTextPixel( 1, 13, nPatternCnt, fpZigZagColor, null, Text.RELATIVETOLEFT | Text.RELATIVETOBOTTOM | Text.BOLD, null, 12, "PatternCount" );
                        return;
                    }                
            
                if (fpCandlePattern=="Bullish/Bearish harami (cross) patterns" || fpCandlePattern=="All")                
                    var nBullishHaram = BullishHarami();
                
                    if (nBullishHaram==1)
                    {
                      drawTextRelative(-(nBarNumber - nLLb),BelowBar1,"H",Color.blue,null,Text.BOLD | Text.PRESET | Text.CENTER, null, 12);
                      nPatternCnt++;
                      removeText("PatternCount");
                      drawTextPixel( 1, 13, nPatternCnt, fpZigZagColor, null, Text.RELATIVETOLEFT | Text.RELATIVETOBOTTOM | Text.BOLD, null, 12, "PatternCount" );
                        return;
                    }                                                    
            }
        
        }
    }
}

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;
}

function StepUp()
{
    var nOpen0 = xOpen.getValue(-(nBarNumber-nLLb));
    var nOpen1 = xOpen.getValue(-(nBarNumber-nLLb+1));
    var nOpen_1 = xOpen.getValue(-(nBarNumber-nLLb-1));
    
    var nClose0 = xClose.getValue(-(nBarNumber-nLLb));
    var nClose1 = xClose.getValue(-(nBarNumber-nLLb+1));
    var nClose_1 = xClose.getValue(-(nBarNumber-nLLb-1));
    
    // Black body before last low bar and a step up white body at last low bar
    if (
    (nClose1 < nOpen1 &&
    nClose0 > nOpen0 &&
    nOpen0 >= nClose1 &&
    nOpen0 <= nOpen1 &&
    nClose0 > nOpen1) ||
    // Black body at the last low bar and step up white body after last low bar
    (nClose0 < nOpen0 &&
    nClose_1 > nOpen_1 &&
    nOpen_1 >= nClose0 &&
    nOpen_1 <= nOpen0 &&
    nClose_1 > nOpen0) ||
    // White body before last low bar and step up white body at last low bar
    (nClose1 > nOpen1 &&
    nClose0 > nOpen0 &&
    nOpen0 >= nOpen1 &&
    nOpen0 <= nClose1 &&
    nClose0 > nClose1) ||
    // White body at last low bar and a step up white body after last low bar
    (nClose0 > nOpen0 &&
    nClose_1 > nOpen_1 &&
    nOpen_1 >= nOpen0 &&
    nOpen_1 <= nClose0 &&
    nClose_1 > nClose0)
    ) return 1;
    else return 0;
}

function StepDown()
{
    var nOpen0 = xOpen.getValue(-(nBarNumber-nLHb));
    var nOpen1 = xOpen.getValue(-(nBarNumber-nLHb+1));
    var nOpen_1 = xOpen.getValue(-(nBarNumber-nLHb-1));
    
    var nClose0 = xClose.getValue(-(nBarNumber-nLHb));
    var nClose1 = xClose.getValue(-(nBarNumber-nLHb+1));
    var nClose_1 = xClose.getValue(-(nBarNumber-nLHb-1));
    
    // Black body before last high bar and a step down black body at last high bar
    if (
    (nClose1 < nOpen1 &&
    nClose0 < nOpen0 &&
    nOpen0 <= nOpen1 &&
    nOpen0 >= nClose1 &&
    nClose0 < nClose1) ||
    // Black body at the last high bar and step down black body after last high bar
    (nClose0 < nOpen0 &&
    nClose_1 < nOpen_1 &&
    nOpen_1 <= nOpen0 &&
    nOpen_1 >= nClose0 &&
    nClose_1 < nClose0) ||
    // White body before last high bar and a step down black body at last high bar
    (nClose1 > nOpen1 &&
    nClose0 < nOpen0 &&
    nOpen0 <= nClose1 &&
    nOpen0 >= nOpen1 &&
    nClose0 < nOpen1) ||
    // White body at last high bar and a step down black body after last high bar
    (nClose0 > nOpen0 &&
    nClose_1 < nOpen_1 &&
    nOpen_1 <= nClose0 &&
    nOpen_1 >= nOpen0 &&
    nClose_1 < nOpen0)
    ) return 1;
    else return 0;
}

function BodyGapUp()
{
    var nOpen0 = xOpen.getValue(-(nBarNumber-nLLb));    
    var nOpen_1 = xOpen.getValue(-(nBarNumber-nLLb-1));
    
    var nClose0 = xClose.getValue(-(nBarNumber-nLLb));    
    var nClose_1 = xClose.getValue(-(nBarNumber-nLLb-1));
    
    // Black body at the last low bar followed by a bar with a gap up or equal value
    if(
    (nClose0<= nOpen0 &&
    nOpen_1 >= nOpen0 &&
    nClose_1 >= nOpen0) ||
    // White body at last low bar followed by a bar with a gap up or equal value
    (nClose0 >= nOpen0 &&
    nOpen_1 >= nClose0 &&
    nClose_1 >= nClose0)
    ) return 1;
    else return 0;
}

function BodyGapDown()
{
    var nOpen0 = xOpen.getValue(-(nBarNumber-nLHb));    
    var nOpen_1 = xOpen.getValue(-(nBarNumber-nLHb-1));
    
    var nClose0 = xClose.getValue(-(nBarNumber-nLHb));    
    var nClose_1 = xClose.getValue(-(nBarNumber-nLHb-1));
    
    // White body at last high bar followed by a bar with a gap down or equal value
    if (
    (nClose0>=nOpen0 &&
    nOpen_1<= nOpen0 &&
    nClose_1<=nOpen0) ||
    // Black body at last high bar followed by a bar with a gap down or equal value
    (nClose0<=nOpen0 &&
    nOpen_1<= nClose0 &&
    nClose_1 <= nClose0)
    ) return 1;
    else return 0;
}

function BullishEngulfing()
{
    var nOpen0 = xOpen.getValue(-(nBarNumber-nLLb));
    var nOpen1 = xOpen.getValue(-(nBarNumber-nLLb+1));
    var nOpen_1 = xOpen.getValue(-(nBarNumber-nLLb-1));
    
    var nClose0 = xClose.getValue(-(nBarNumber-nLLb));
    var nClose1 = xClose.getValue(-(nBarNumber-nLLb+1));
    var nClose_1 = xClose.getValue(-(nBarNumber-nLLb-1));
    
    // Black small body or doji before last low bar and larger white at last low bar
    if (
    (nClose1 <= nOpen1 &&
    nClose0 > nOpen0 &&
    nOpen0<=nClose1 &&
    nClose0>= nOpen1) ||
    // Black small body or doji at the last low bar and larger white after last low bar
    (nClose0<= nOpen0 &&
    nClose_1> nOpen_1 &&
    nOpen_1<= nClose0 &&
    nClose_1>= nOpen0) ||
    // White small body or doji before last low bar and larger white at last low bar
    (nClose1>= nOpen1 &&
    nClose0 > nOpen0 &&
    nOpen0 <= nOpen1 &&
    nClose0>=nClose1) ||
    // White small body or doji at last low bar and larger white after last low bar
    (nClose0 >= nOpen0 &&
    nClose_1>nOpen_1 &&
    nOpen_1<=nOpen0 &&
    nClose_1>=nClose0)
    ) return 1;
    else return 0;
}

function BearishEngulfing()
{
    var nOpen0 = xOpen.getValue(-(nBarNumber-nLHb));
    var nOpen1 = xOpen.getValue(-(nBarNumber-nLHb+1));
    var nOpen_1 = xOpen.getValue(-(nBarNumber-nLHb-1));
    
    var nClose0 = xClose.getValue(-(nBarNumber-nLHb));
    var nClose1 = xClose.getValue(-(nBarNumber-nLHb+1));
    var nClose_1 = xClose.getValue(-(nBarNumber-nLHb-1));
    
    // White small body or doji before last high bar and larger black body at last high
    if (
    (nClose1 >= nOpen1 &&
    nClose0 < nOpen0 &&
    nOpen0 >= nClose1 &&
    nClose0 <= nOpen1) ||
    // White small body or doji at last high bar and larger black body after last high bar
    (nClose0 >= nOpen0 &&
    nClose_1 < nOpen_1 &&
    nOpen_1 >= nClose0 &&
    nClose_1 <= nOpen0) ||
    // Black small body or doji before last high bar and larger Black body at last high bar
    nClose1 <= nOpen1 &&
    nClose0 < nOpen0 &&
    nOpen0 >= nOpen1 &&
    nClose0 <= nClose1 ||
    // Black small body or doji at last high bar and larger Black body after last high bar
    nClose0 <= nOpen0 &&
    nClose_1 < nOpen_1 &&
    nOpen_1 >= nOpen0 &&
    nClose_1 <= nClose0
    ) return 1;
    else return 0;
}

function BearishHarami()
{
    var nOpen0 = xOpen.getValue(-(nBarNumber-nLHb));
    var nOpen1 = xOpen.getValue(-(nBarNumber-nLHb+1));
    var nOpen_1 = xOpen.getValue(-(nBarNumber-nLHb-1));
    
    var nClose0 = xClose.getValue(-(nBarNumber-nLHb));
    var nClose1 = xClose.getValue(-(nBarNumber-nLHb+1));
    var nClose_1 = xClose.getValue(-(nBarNumber-nLHb-1));
    
    // Black body at the last high bar and small white OR black body after last high bar
    if (
    (nClose0 < nOpen0 &&
    nOpen_1 >= nClose0 &&
    nOpen_1 <= nOpen0 &&
    nClose_1 >= nClose0 &&
    nClose_1 <= nOpen0) ||
    // White body at the last high bar and small white OR black body after last high bar
    (nClose0 > nOpen0 &&
    nOpen_1 <= nClose0 &&
    nOpen_1 >= nOpen0 &&
    nClose_1 <= nClose0 &&
    nClose_1 >= nOpen0) ||
    // Black body before the last high bar and small white OR black body at last high bar
    (nClose1 < nOpen1 &&
    nOpen0 >= nClose1 &&
    nOpen0 <= nOpen1 &&
    nClose0 >= nClose1 &&
    nClose0 <= nOpen1) ||
    // White body before the last high bar and small white OR black body at last high bar
    (nClose1 > nOpen1 &&
    nOpen0 <= nClose1 &&
    nOpen0 >= nOpen1 &&
    nClose0 <= nClose1 &&
    nClose0 >= nOpen1)
    ) return 1;
    else return 0;
}

function BullishHarami()
{
    var nOpen0 = xOpen.getValue(-(nBarNumber-nLLb));
    var nOpen1 = xOpen.getValue(-(nBarNumber-nLLb+1));
    var nOpen_1 = xOpen.getValue(-(nBarNumber-nLLb-1));
    
    var nClose0 = xClose.getValue(-(nBarNumber-nLLb));
    var nClose1 = xClose.getValue(-(nBarNumber-nLLb+1));
    var nClose_1 = xClose.getValue(-(nBarNumber-nLLb-1));
    
    // Black body at the last low bar and small white OR black body after last low bar
    if (
    (nClose0 < nOpen0 &&
    nOpen_1 >= nClose0 &&
    nOpen_1 <= nOpen0 &&
    nClose_1 >= nClose0 &&
    nClose_1 <= nOpen0) ||
    // White body at the last low bar and small white OR black body after last low bar
    (nClose0 > nOpen0 &&
    nOpen_1 <= nClose0 &&
    nOpen_1 >= nOpen0 &&
    nClose_1 <= nClose0 &&
    nClose_1 >= nOpen0) ||
    // Black body before the last low bar and small white OR black body at last low bar
    (nClose1 < nOpen1 &&    
    nOpen0 >= nClose1 &&
    nOpen0 <= nOpen1 &&
    nClose0 >= nClose1 &&
    nClose0 <= nOpen1) ||
    // White body before the last low bar and small white OR black body at last low bar
    (nClose1 > nOpen1 &&
    nOpen0 <= nClose1 &&
    nOpen0 >= nOpen1 &&
    nClose0 <= nClose1 &&
    nClose0 >= nOpen1)
    ) return 1;
    else return 0;
}