File Name: VolumeFlowIndicator.efs
Description:
Based on Using Money Flow to Stay With the Trend by Markos Katsanos. This article appeared in the June 2004 issue of Stock & Commodities.
Formula Parameters:
VFI Length - 30
MA of VFI Length - 50
Notes:
The related article is copyrighted material. If you are not a subscriber of Stocks & Commodities, please visit www.traders.com.
Version 1.1
This formula has been modified 5/4/2004. An input parameter for the VFI length was added and the MA length of volume for volume curtailment is set to the same length.
Download File:
VolumeFlowIndicator.efs
EFS Code:
Description:
Based on Using Money Flow to Stay With the Trend by Markos Katsanos. This article appeared in the June 2004 issue of Stock & Commodities.
Formula Parameters:
VFI Length - 30
MA of VFI Length - 50
Notes:
The related article is copyrighted material. If you are not a subscriber of Stocks & Commodities, please visit www.traders.com.
Version 1.1
This formula has been modified 5/4/2004. An input parameter for the VFI length was added and the MA length of volume for volume curtailment is set to the same length.
Download File:
VolumeFlowIndicator.efs
EFS Code:
PHP Code:
/******************************************
Provided By : eSignal. (c) Copyright 2004
Study: Volume Flow Indicator by Markos Katsanos
Version: 1.1
4/8/2004
Notes: 1.1 5/4/2004
* Added input parameter for VFI length and set MA length of
volume for volume curtailment to the same length.
Formula Parameters: Default:
VFI Length 30
MA of VFI Length 50
*******************************************/
function preMain() {
setStudyTitle("Volume Flow Indicator ");
setShowTitleParameters(false);
setCursorLabelName("VFI", 0);
setCursorLabelName("VFI MA", 1);
setDefaultBarFgColor(Color.green, 0);
setDefaultBarFgColor(Color.blue, 1);
setDefaultBarThickness(2, 0);
setDefaultBarThickness(1, 1);
addBand(0, PS_SOLID, 1, Color.black, "zero");
var fp0 = new FunctionParameter("nVFIlength", FunctionParameter.NUMBER);
fp0.setName("VFI Length");
fp0.setLowerLimit(1);
fp0.setDefault(26);
var fp1 = new FunctionParameter("nVFImaLen", FunctionParameter.NUMBER);
fp1.setName("MA of VFI Length");
fp1.setLowerLimit(1);
fp1.setDefault(50);
}
var nTyp = null; // Current typical price
var nTyp1 = null; // Previous typical price
var nTypChg = 0; // Current typical price change
var vVol = null; // Current volume
var nVolSum = 0; // Cumulative volume sum
var nVolAdj = 0; // Current adjusted volume
var nVolMA = null; // Current Vol MA
var nVolMA1 = null; // Previous Vol MA
var aTypPrice = null; // Array of changes in typical price
var aVolume = null; // Volume array
var VFI = null; // Current VFI
var aVFI = null; // Array of VFI values for EMA calc
var aVFI = new Array(3); // Array of VFI values for EMA calc
var aEMA = null; // Array of VFI 3EMA values
// globals for EMA
var vEMA = null;
var vEMA1 = null;
var dPercent = 0.0;
var bPrimed = false;
var bEdit = false;
function main(nVFIlength, nVFImaLen) {
var nState = getBarState();
var vInter = 0;
var nCutoff = 0;
var vMAofEMA = null;
var dSum = 0;
var i = 0;
if (bEdit == false) {
if (aTypPrice == null) aTypPrice = new Array(nVFIlength);
if (aVolume == null) aVolume = new Array(nVFIlength);
if (aEMA == null) aEMA = new Array(nVFImaLen);
bEdit = true;
}
if (nState == BARSTATE_NEWBAR) {
if (nTyp != null) {
aTypPrice.pop();
aTypPrice.unshift(nTypChg);
nTyp1 = nTyp;
}
if (nVol != null) {
aVolume.pop();
aVolume.unshift(nVol);
}
nVolMA1 = nVolMA;
nVolSum += nVolAdj;
if (VFI != null) {
aVFI.pop();
aVFI.unshift(VFI);
}
if (vEMA != null) {
aEMA.pop();
aEMA.unshift(vEMA);
}
}
nVol = volume();
if (nVol == null) return;
aVolume[0] = nVol;
if (aVolume[nVFIlength-1] != null) {
for (i = 0; i < nVFIlength; ++i) {
dSum += aVolume[i];
}
nVolMA = dSum/nVFIlength;
}
nTyp = (high() + low() + close()) / 3;
if (nTyp1 != null) {
nTypChg = (Math.log(nTyp) - Math.log(nTyp1));
aTypPrice[0] = nTypChg;
}
if (nVolMA == null || nVolMA1 == null) return;
if (aTypPrice[nVFIlength-1] != null) {
vInter = StDev(nVFIlength);
nCutoff = (.2 * vInter * close());
} else {
return;
}
nVolAdj = nVol;
//Minimal Change Cutoff
if ((nTyp - nTyp1) >= 0 && (nTyp - nTyp1) < nCutoff) nVolAdj = 0;
if ((nTyp - nTyp1) < 0 && (nTyp - nTyp1) > -nCutoff) nVolAdj = 0;
// Volume curtailment
if (nVolAdj > (2.5*nVolMA1)) nVolAdj = (2.5*nVolMA1);
if (nTyp - nTyp1 < 0 && nVolAdj > 0) nVolAdj *= -1;
VFI = ((nVolSum + nVolAdj) / nVolMA1);
aVFI[0] = VFI;
if (aVFI[2] != null) {
vEMA = EMA();
aEMA[0] = vEMA;
}
if (aEMA[nVFImaLen-1] != null) {
dSum = 0;
i = 0;
for(i = 0; i < nVFImaLen; ++i) {
dSum += aEMA[i];
}
vMAofEMA = dSum/nVFImaLen;
}
if (vEMA != null) {
if (vEMA >= 0) {
setBarFgColor(Color.green, 0);
} else {
setBarFgColor(Color.red, 0);
}
}
return new Array(vEMA, vMAofEMA);
}
/***** Functions *****/
function StDev(nLength) {
//var nLength = 30;
var sumX = 0;
var sumX2 = 0;
for (i = 0; i < nLength; ++i) {
sumX += aTypPrice[i];
sumX2 += (aTypPrice[i] * aTypPrice[i])
}
var meanX = (sumX/nLength);
var stdev = Math.sqrt((sumX2/nLength) - (meanX*meanX));
return stdev;
}
function EMA() {
var nBarState = getBarState();
var dSum = 0.0;
var nLength = 3;
if(nBarState == BARSTATE_ALLBARS || bPrimed == false) {
dPercent = (2.0 / (nLength + 1.0));
bPrimed = false;
}
if (nBarState == BARSTATE_NEWBAR) {
vEMA1 = vEMA;
}
if(bPrimed == false) {
for(i = 0; i < nLength; i++) {
dSum += aVFI[i];
}
bPrimed = true;
return (dSum / nLength);
} else {
return (((VFI - vEMA1) * dPercent) + vEMA1);
}
}