snowseed-iClv





#property copyright "Copyright S.Projects"
#property link      "http://trader.snowseed.com"

#property indicator_separate_window
#property indicator_buffers 1
#property indicator_color1 Red
#property indicator_minimum 0
#property indicator_maximum 1

// indicator parameters
extern int nClvPeriod = 27;
extern int nClvMa = 7;

// At the very beginning of the chart, before the MA 
// had enough data to draw itself properly, do not display

int nDrawBeginBar;

// indicator buffers
double arrExtMapBuffer[];

// We are using this variable to store the number of bars
// for which the chart is already drawn. The difference
// between the total number of bars and this number is
// the number of bars to draw (usually, 1)

int nExtCountedBars = 0;

////////////////////////
int init()
{
	string strIndicatorShortName;
	strIndicatorShortName = "CLV(" + nClvPeriod + 
		", " + nClvMa + ")";  
	IndicatorShortName(strIndicatorShortName);

	// drawing settings
	SetIndexStyle(0, DRAW_LINE);
	SetIndexShift(0, 0);
		
	IndicatorDigits(4);
		
	// Skip drawing at the beginning of a chart
	nDrawBeginBar = MathMax(nClvPeriod, nClvMa);
	SetIndexDrawBegin(0, nDrawBeginBar);

	// indicator buffers mapping
	SetIndexBuffer(0, arrExtMapBuffer);
		
	return(0);
}
///////////////////////////
int start()
{
	// Not enough points on a chart
	if(Bars <= nDrawBeginBar) 
		return(0);
		
	// See if we have new data to plot (if a new tick came,
	// and it is the first tick of a new bar

	nExtCountedBars = IndicatorCounted();
	if(nExtCountedBars < 0) 
		return(-1);

	// Last counted bar will be recounted
	// Note, that here we force the last bar to be recounted.
	// You may comment this code, if you only want to do it
	// at the beginning of a new bar. I only keep this code
	// for compatibility with a little mess created by official
	// tutorials: see comment below (*)
	if(nExtCountedBars > 0) 
		nExtCountedBars--;
		
	Clv();  

	return(0);
}
///////////////////
// For the selected period:
// CLV = ((Close - Low) - (High - Close)) / (High - Low) 
void Clv()
{
	// (*) Note the line below. If we use 
	// "int nPos = Bars - nExtCountedBars;" the last bar 
	// will be recounted every tick. If there is no "- 1",
	// only the beginning of a new bar triggers the code. 

	int nPos = Bars - nExtCountedBars;

	// Note, that nPos is always > 0. It means, that Close[nPos]
	// is never Close[0], so we don't make a mistake by "looking
	// into the future". Note also, that we assign the value
	// to the arrExtMapBuffer[nPos]. It means, that when calling
	// this indicator from the expert, we need to use shift
	// >= 1. If we want to be able to call it with shift == 0,
	// we need to rewrite the code below, using 
	// arrExtMapBuffer[nPos - 1]. The Close[...] and all other
	// functions obtaining data, should still use [nPos].

	while(nPos > 0 && nPos < ArraySize(Low))
	{
		double dClose = Close[nPos];
		double dLow = Low[ArrayMinimum(Low, nClvPeriod, nPos)]; 
		double dHigh = High[ArrayMaximum(High, nClvPeriod, nPos)]; 

		arrExtMapBuffer[nPos] = 0;

		if(dHigh - dLow != 0)
			arrExtMapBuffer[nPos] = 
				(((dClose - dLow) - (dHigh - dClose)) 
					/ (dHigh - dLow)) / 2 + 0.5; 
		else
			arrExtMapBuffer[nPos] = 0;

		nPos--;
	}
	
	if(nClvMa > 1)
		Ema(arrExtMapBuffer);
}
///////////////////
void Ema(double& arr[])
{
	double dPr = 2.0 / (nClvMa + 1);

	int nPos = Bars - nExtCountedBars;
	
	while(nPos > 0)
	{
		if(nPos == Bars - 2) 
			arrExtMapBuffer[nPos + 1] = arr[nPos + 1];

		arrExtMapBuffer[nPos] = arr[nPos] * dPr + 
			arrExtMapBuffer[nPos + 1] * (1 - dPr);
		nPos--;
	}
}
///////////////////



Sample





Analysis



Market Information Used:

Series array that contains close prices for each bar
Series array that contains the lowest prices of each bar
Series array that contains the highest prices of each bar


Indicator Curves created:

Implements a curve of type DRAW_LINE


Indicators Used:



Custom Indicators Used:

Order Management characteristics:

Other Features: