#include "stdafx.h"		//Precompiled header file

#include "CalcLibSMA.h"

/// <summary>
/// Class:	SimpleMovingAverage 
/// 
/// A simple moving average is formed by finding the average price 
/// of a security over a set number of periods. Most often, the 
/// closing price is used to compute the moving average. For 
/// example: a 5-day moving average would be calculated by adding 
/// the closing prices for the last 5 days and dividing the total 
/// by 5.
/// example:
/// 10 + 11 + 12 + 13 + 14 = 60
/// 60 / 5 = 12
/// 
/// A moving average moves because as the newest period is added, 
/// the oldest period is dropped. If the next closing price in the 
/// average is 15, then this new period would be added and the 
/// oldest day, which is 10, would be dropped. The new 5-day moving 
/// average would be calculated as follows:
/// 
/// 11 + 12 + 13 + 14 + 15 = 65
/// 65 / 5 = 13
/// 
/// Over the last 2 days, the moving average moved from 12 to 13. 
/// As new days are added, the old days will be subtracted and 
/// the moving average will continue to move over time.


CalcLibSMA::CalcLibSMA(DOUBLEVECTOR values, DATEVECTOR dates, int periods)
{
	initValues(values, dates);
	m_period = periods;
}
		

/// <summary>
/// Function:		doCalc() 
/// 
/// Parameters:		None
/// 
/// Description:	Calculates a simple moving average 
/// </summary>

int CalcLibSMA::doCalc()
{
	int retval = getOK();

	int length = m_input.size();

	for (int j = 0; j < length; j++)
	{
		CalcLibData cld = m_input.at(j);

		if (j >= m_period - 1 && cld.getStatus() != cld.getInvalid() )		
		{
			double sum = getSum(j, m_period) / m_period;
			if (sum > 0.0)
			{
				m_output[j].setValue(sum);
				m_output[j].setStatus(cld.getInitialized());
			}
			else
			{
				m_output[j].setValue(0.0);
				m_output[j].setStatus(cld.getUndefined());
			}
		}
		else
		{
			m_output[j].setValue(0.0);
			m_output[j].setStatus(cld.getUndefined());
		}
	}
	return retval;
}


double CalcLibSMA::getSum(int start, int length)
{
	double retval = 0.0;

	for (int i = start, j = 0; j < (length); i--, j++)
	{
		CalcLibData cld = m_input.at(j);

		if (cld.getValue() != cld.getInvalid())		//Hope not status???
		{
			retval += cld.getValue();
		}
	}
	return retval;
}


CalcLibData CalcLibSMA::getOutputPoint(int index)
{
	int length = m_output.size();
	CalcLibData retval = NULL;

	if (index >= 0 && index < length)
	{
		retval = m_output.at(index);
	}

	return retval;
}

