2007 Nov: Short-Term Volume and Price Oscillator

ICE Data Services -

SVAPO.efs  
EFSLibrary - Discussion Board  

File Name: SVAPO.efs

Description:
This study is based on the November 2007 article, Short-Term Volume and Price Oscillator, by Sylvain Vervoort.

Formula Parameters:

  • SVAPO Period: 8
  • Minimum %o price change: 1
  • Standard Deviation High: 1.5
  • Standard Deviation Low: 1.3
  • Standard Deviation Period: 100
  • Color: green
  • Thickness: 2

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

Download File:
SVAPO.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:  Short-Term Volume And Price Oscillator
              by Sylvain Vervoort

Version 1.0  9/6/2007

Notes:
* Study requires version 8.0 or later.


Formula Parameters:                     Default:
SVAPO Period                            8
Minimum %o price change                 1
Standard Deviation High                 1.5
Standard Deviation Low                  1.3
Standard Deviation Period               100
Color                                   green
Thickness                               2
***************************************/

function preMain() {
    setStudyTitle("Short-Term Vol And Price Osc ");
    setShowTitleParameters(false);
    setCursorLabelName("DevH", 0);
    setCursorLabelName("SVAPO", 1);
    setCursorLabelName("DevL", 2);
    setDefaultBarStyle(PS_DASHDOT, 0);
    setDefaultBarStyle(PS_DASHDOT, 2);
  
    var fp1 = new FunctionParameter("nPeriod", FunctionParameter.NUMBER);
        fp1.setName("SVAPO Period");
        fp1.setLowerLimit(3);
        fp1.setUpperLimit(20);
        fp1.setDefault(8);
    var fp2 = new FunctionParameter("nCutoff", FunctionParameter.NUMBER);
        fp2.setName("Minimum %o price change");
        fp2.setLowerLimit(1);
        fp2.setUpperLimit(10);
        fp2.setDefault(1);
    var fp3 = new FunctionParameter("nDevH", FunctionParameter.NUMBER);
        fp3.setName("Standard Deviation High");
        fp3.setLowerLimit(0.1);
        fp3.setUpperLimit(5);
        fp3.setDefault(1.5);
    var fp4 = new FunctionParameter("nDevL", FunctionParameter.NUMBER);
        fp4.setName("Standard Deviation Low");
        fp4.setLowerLimit(0.1);
        fp4.setUpperLimit(5);
        fp4.setDefault(1.3);
    var fp5 = new FunctionParameter("nStdevPeriod", FunctionParameter.NUMBER);
        fp5.setName("Standard Deviation Period");
        fp5.setLowerLimit(1);
        fp5.setUpperLimit(200);
        fp5.setDefault(100);
    var fp30 = new FunctionParameter("cColor", FunctionParameter.COLOR);
        fp30.setName("Color");
        fp30.setDefault(Color.green);
    var fp40 = new FunctionParameter("nThick", FunctionParameter.NUMBER);
        fp40.setName("Thickness");
        fp40.setLowerLimit(1);
        fp40.setDefault(2);
}

// Global Variables
var bVersion  = null;    // Version flag
var bInit     = false;   // Initialization flag

// globals variables
var xHaOpen     = null;
var xHaClose    = null;
var xHaTema     = null;
var xVolLRSlope = null;
var xVtr        = null;
var xSvapoSum   = null;
var xSvapo      = null;
var xStdev      = null;


function main(nPeriod, nCutoff, nDevH, nDevL, nStdevPeriod, cColor, nThick) {
    if (bVersion == null) bVersion = verify();
    if (bVersion == false) return;    

    //Initialization
    if (bInit == false) {
        setDefaultBarFgColor(cColor, 0);
        setDefaultBarThickness(nThick, 1);
        addBand(0, PS_DASHDOT, 1, cColor, "zero");
        xHaOpen     = efsInternal("calcHaOpen");
        xHaClose    = efsInternal("calcHaClose", xHaOpen);
        xHaTema     = efsInternal("calcTEMA", (nPeriod/1.6), xHaClose);
        xVolLRSlope = efsInternal("calcLinRegSlope", nPeriod, volume());
        xVtr        = efsInternal("calcTEMA", nPeriod, xVolLRSlope);
        xVolAvg     = sma((nPeriod*5), volume());
        xVc         = efsInternal("calcVc", xVolAvg);
        xSvapoSum   = efsInternal("calcSvapoSum", nPeriod, nCutoff, 
                        xHaTema, xVtr, xVolAvg, xVc );
        xSvapo      = efsInternal("calcTEMA", nPeriod, xSvapoSum);
        xStdev      = efsInternal("calcStDev", nStdevPeriod, xSvapo);
        
        bInit = true;
    }

    var nSvapo = xSvapo.getValue(0);
    var nStdev = xStdev.getValue(0);
    if (nSvapo == null || nStdev == null) return;
    
    var nStDevH = nDevH * nStdev;
    var nStDevL = -nDevL * nStdev;
    
    return new Array( nStDevH, nSvapo, nStDevL );
}


// HaOpen globals
var nHaOpen   = null;
var nHaOpen_1 = null;

function calcHaOpen() {
    if (nHaOpen_1 == null && open(-1) != null) {
        nHaOpen_1 = open(-1);
    } else if (nHaOpen != null) {
        nHaOpen_1 = nHaOpen;
    }
    if (nHaOpen_1 == null) return;
    
    var nC_1 = sma(1, ohlc4(), -1);
    if (nC_1 == null) return;
    
    nHaOpen = (nC_1 + nHaOpen_1) / 2;
    
    return nHaOpen;
}


function calcHaClose(xHaO) {
    var n4 = sma(1, ohlc4(), 0);
    var nHaO = xHaO.getValue(0);
    if (n4 == null || nHaO == null) return;

    var nHaCl = (n4 + nHaO +
        Math.max(n4, high(0), nHaO) +
        Math.min(n4, low(0), nHaO )  ) / 4;
    
    return nHaCl;
}


// TEMA globals
var xAvg1 = null;
var xAvg2 = null;
var xAvg3 = null;
var bInit2 = false;

function calcTEMA(nLength,xSource){

    if(bInit2 == false){
        xAvg1 = ema(nLength,xSource);
        xAvg2 = ema(nLength,xAvg1);
        xAvg3 = ema(nLength,xAvg2);
        bInit2 = true;
    }
    
    var nAvg1 = xAvg1.getValue(0);
    var nAvg2 = xAvg2.getValue(0);
    var nAvg3 = xAvg3.getValue(0);
    if (nAvg1 == null || nAvg2 == null || nAvg3 == null) return;

    var nTEMA = (3*nAvg1)-(3*nAvg2)+nAvg3;
    
    return nTEMA;
}


function calcLinRegSlope( nLRlen, xSource) {
    // y = Ax + B;
    // A = SUM( (x-xAVG)*(y-yAVG) ) / SUM( (x-xAVG)^2 )
    // A = slope
    // B = yAVG - (A*xAVG);  // y-intercept

    if (xSource.getValue(-nLRlen) == null || 
        xSource.getValue(0) == 0) return;

    var xSum = 0;
    var ySum = 0;
    var i = 0;
    for (i = 0; i < nLRlen; i++) {
        xSum += i;
        ySum += xSource.getValue(-i);
    }
    var xAvg = xSum/nLRlen;
    var yAvg = ySum/nLRlen;
    var aSum1 = 0;
    var aSum2 = 0;
    i = 0;
    for (i = 0; i < nLRlen; i++) {
        aSum1 += (i-xAvg) * (xSource.getValue(-i)-yAvg); 
        aSum2 += (i-xAvg)*(i-xAvg);
    }
    var A = -(aSum1 / aSum2);  // slope
    //var B = yAvg - (A*xAvg);  // y-intercept
    
    return A;
}


function calcVc( xAvg ) {
    var nVolAvg = xAvg.getValue(-1);
    if (nVolAvg == null) return;
    
    var nVmax = nVolAvg * 2;
    var nVc   = volume(0);
    if (nVc >= nVmax) nVc = nVmax;
    
    return nVc;
}



function calcSvapoSum(nPeriod, nCutoff, xHaC, xvtr, xVAvg, xvc ) {

    nCutoff /= 100;
    var nSvapoSum = null;
    var nSum    = 0;
    var i       = 0;
    var nVave   = xVAvg.getValue(0);    
    if (nVave == null || xvtr.getValue( -(nPeriod+2) ) == null) return;
    
    for (i = 0; i < nPeriod; i++) {
        var b1 = false;
        var b2 = false;
        var nHaC    = xHaC.getValue(-i);
        var nHaC_1  = xHaC.getValue(-(i+1));
        var nVc     = xvc.getValue(-i);
        var nVtr    = xvtr.getValue(-i);
        var nVtr_1  = xvtr.getValue(-(i+1));
        var nVtr_2  = xvtr.getValue(-(i+2));
        
        b1 = (nHaC > (nHaC_1*(1+nCutoff/1000)));
        b2 = (nVtr >= nVtr_1) || (nVtr_1 >= nVtr_2);
        if (b1 == true && b2 == true ) {
            nSum += nVc;
        } else {
            b1 = (nHaC < (nHaC_1*(1-nCutoff/1000)));
            b2 = (nVtr > nVtr_1) || (nVtr_1 > nVtr_2);
            if (b1 == true && b2 == true ) {
                nSum -= nVc;
            }
        }
    }
    
    nSvapoSum = nSum / (nVave+1);
    
    return nSvapoSum;
}


function calcStDev(nLength, xSource) {    
    var sumX = 0;
    var sumX2 = 0;
    
    if (xSource.getValue(-nLength) == null) return;
    
    for (i = 0; i < nLength; i++) {
        var nVal = xSource.getValue(-i);
        sumX += nVal;
        sumX2 += (nVal * nVal);
    }
    var meanX = (sumX/nLength);
    var stdev = Math.sqrt((sumX2/nLength) - (meanX*meanX));

    return stdev;
}


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