#include "sierrachart.h"

#include "scstudyfunctions.h"

/***********************************************************************/
SCSFExport scsf_ChaikinOsc(SCStudyInterfaceRef sc)
{
	SCSubgraphRef Subgraph_Oscillator = sc.Subgraph[0];
	SCSubgraphRef Subgraph_Overbought = sc.Subgraph[2];
	SCSubgraphRef Subgraph_Oversold = sc.Subgraph[3];


	SCInputRef Input_LongMALength = sc.Input[2];
	SCInputRef Input_ShortMALength = sc.Input[3];
	SCInputRef Input_Divisor = sc.Input[4];
	SCInputRef Input_OverboughtValue = sc.Input[5];
	SCInputRef Input_OversoldValue = sc.Input[6];
	
	if(sc.SetDefaults)
	{
		sc.GraphName = "Chaikin Oscillator";
		
		Subgraph_Oscillator.Name = "Oscillator";
		Subgraph_Oscillator.DrawStyle = DRAWSTYLE_LINE;
		Subgraph_Oscillator.PrimaryColor = RGB(0,255,0);

		Subgraph_Overbought.Name = "Overbought";
		Subgraph_Overbought.DrawStyle = DRAWSTYLE_LINE;
		Subgraph_Overbought.PrimaryColor = RGB(255,255,0);
		Subgraph_Overbought.DrawZeros = false;

		Subgraph_Oversold.Name = "Oversold";
		Subgraph_Oversold.DrawStyle = DRAWSTYLE_LINE;
		Subgraph_Oversold.PrimaryColor = RGB(255,127,0);
		Subgraph_Oversold.DrawZeros = false;

		Input_LongMALength.Name = "Long MovAvg Length";
		Input_LongMALength.SetInt(10);
		Input_LongMALength.SetIntLimits(1,MAX_STUDY_LENGTH);

		Input_ShortMALength.Name = "Short MovAvg Length";
		Input_ShortMALength.SetInt(3);
		Input_ShortMALength.SetIntLimits(1,MAX_STUDY_LENGTH);

		Input_Divisor.Name = "Divisor";
		Input_Divisor.SetFloat(1);
		Input_Divisor.SetFloatLimits(.00001f, (float)MAX_STUDY_LENGTH);

		Input_OverboughtValue.Name = "Overbought";
		Input_OverboughtValue.SetInt(0);

		Input_OversoldValue.Name = "Oversold";
		Input_OversoldValue.SetInt(0);

		

		sc.AutoLoop = 1;

		return;
	}
	
	sc.DataStartIndex = max(Input_LongMALength.GetInt(),Input_ShortMALength.GetInt()) - 1;


	sc.AccumulationDistribution(sc.BaseDataIn, Subgraph_Oscillator.Arrays[0], sc.Index);
	sc.ExponentialMovAvg(Subgraph_Oscillator.Arrays[0], Subgraph_Oscillator.Arrays[1], sc.Index, Input_LongMALength.GetInt());
	sc.ExponentialMovAvg(Subgraph_Oscillator.Arrays[0], Subgraph_Oscillator.Arrays[2], sc.Index, Input_ShortMALength.GetInt());

	Subgraph_Oscillator[sc.Index] = (Subgraph_Oscillator.Arrays[2][sc.Index] - Subgraph_Oscillator.Arrays[1][sc.Index]) / Input_Divisor.GetInt();
	Subgraph_Overbought[sc.Index] = (float)Input_OverboughtValue.GetInt();
	Subgraph_Oversold[sc.Index] = (float)Input_OversoldValue.GetInt();
}

/*==========================================================================*/
SCSFExport scsf_HistoricalVolatilityRatio(SCStudyInterfaceRef sc)
{
	SCSubgraphRef Subgraph_HVR = sc.Subgraph[0];
	SCFloatArrayRef Array_TempLog = sc.Subgraph[0].Arrays[0];
	SCFloatArrayRef Array_TempShort = sc.Subgraph[0].Arrays[1];
	SCFloatArrayRef Array_TempLong = sc.Subgraph[0].Arrays[2];

	SCInputRef Input_ShortLength = sc.Input[2];
	SCInputRef Input_LongLength = sc.Input[3];

	SCFloatArrayRef Array_Close = sc.Close;

	// Configuration
	if (sc.SetDefaults)
	{
		sc.GraphName = "Historical Volatility Ratio";
		
		Subgraph_HVR.Name = "HVR";
		Subgraph_HVR.DrawStyle = DRAWSTYLE_LINE;
		Subgraph_HVR.PrimaryColor = RGB(0,255,0);
		
		Input_ShortLength.Name = "Short Length";
		Input_ShortLength.SetInt(6);
		Input_ShortLength.SetIntLimits(1, INT_MAX);
		
		Input_LongLength.Name = "Long Length";
		Input_LongLength.SetInt(100);
		Input_LongLength.SetIntLimits(1, INT_MAX);

		
		

		sc.AutoLoop = 1;
		
		return;
	}
	

	// Data Processing
		
	sc.DataStartIndex = max(Input_LongLength.GetInt(), Input_ShortLength.GetInt());

	if (sc.Index == 0)
		return;
	
	if (Array_Close[sc.Index - 1] != 0.0)
		Array_TempLog[sc.Index] = logf(Array_Close[sc.Index] / Array_Close[sc.Index - 1]);
	else
		Array_TempLog[sc.Index] = 0;

	sc.StdDeviation(Array_TempLog, Array_TempShort, sc.Index, Input_ShortLength.GetInt());
	sc.StdDeviation(Array_TempLog, Array_TempLong, sc.Index, Input_LongLength.GetInt());

	if (Array_TempLog[sc.Index] != 0)
		Subgraph_HVR[sc.Index] = Array_TempShort[sc.Index] / Array_TempLong[sc.Index];
	else
		Subgraph_HVR[sc.Index] = Subgraph_HVR[sc.Index-1];
}

/*==========================================================================*/
SCSFExport scsf_CurrentPriceLine(SCStudyInterfaceRef sc)
{
	SCSubgraphRef Subgraph_CurrentPriceLine = sc.Subgraph[0];

	SCInputRef Input_NumberOfBarsBack = sc.Input[0];
	SCInputRef Input_InputData = sc.Input[1];
	SCInputRef Input_Version = sc.Input[2];
	SCInputRef Input_DisplayCPLOnBars = sc.Input[3];
	SCInputRef Input_ProjectForward = sc.Input[4];
	SCInputRef UseLastFromCurrentQuoteData = sc.Input [5];
	SCInputRef NumberOfForwardProjectionBars = sc.Input[6];
	SCInputRef Input_NumberOfBarsBackToReference = sc.Input[7];
	
	if(sc.SetDefaults)
	{
		sc.GraphName = "Current Price Line";

		Subgraph_CurrentPriceLine.Name = "CPL";
		Subgraph_CurrentPriceLine.DrawStyle = DRAWSTYLE_LINE;
		Subgraph_CurrentPriceLine.PrimaryColor = RGB(0,255,0);
		Subgraph_CurrentPriceLine.DrawZeros = false;
		Subgraph_CurrentPriceLine.LineStyle = LINESTYLE_DOT;
		
		sc.ScaleRangeType =  SCALE_SAMEASREGION;
		sc.GraphRegion = 0;

		Input_NumberOfBarsBack.Name = "Number of Bars to Display On. 0 = Current Day";
		Input_NumberOfBarsBack.SetInt(0);
		Input_NumberOfBarsBack.SetIntLimits(0,MAX_STUDY_LENGTH);

		Input_InputData.Name = "Input Data";
		Input_InputData.SetInputDataIndex(SC_LAST);
		
		Input_DisplayCPLOnBars.Name = "Display Current Price Line on Chart Bars";
		Input_DisplayCPLOnBars.SetYesNo(true);

		Input_ProjectForward.Name = "Forward Project Current Price Line";
		Input_ProjectForward.SetYesNo(false);

		UseLastFromCurrentQuoteData.Name = "Use Last Trade Price From Current Quote Data";
		UseLastFromCurrentQuoteData.SetYesNo(false);

		NumberOfForwardProjectionBars.Name = "Number of Forward Projection Bars";
		NumberOfForwardProjectionBars.SetInt(10);

		Input_NumberOfBarsBackToReference.Name = "Number of Bars Back to Reference";
		Input_NumberOfBarsBackToReference.SetInt(0);
		Input_NumberOfBarsBackToReference.SetIntLimits(0, MAX_STUDY_LENGTH);
		
		Input_Version.SetInt(2);

		sc.AutoLoop = 0; //Manual looping	
		return;
	}

	if (NumberOfForwardProjectionBars.GetInt() == 0)
		NumberOfForwardProjectionBars.SetInt(10);
	
	SCFloatArrayRef InputDataArray = sc.BaseData[Input_InputData.GetInputDataIndex()];

	float LineValue = 0;

	if(UseLastFromCurrentQuoteData.GetYesNo())
		LineValue = sc.LastTradePrice;
	else
	{
		LineValue = InputDataArray[sc.ArraySize - 1 - Input_NumberOfBarsBackToReference.GetInt()];
	}

	int &r_PriorLineStartIndex = sc.GetPersistentInt(1);
	float &r_PriorValue = sc.GetPersistentFloat(2);
	int &r_PriorArraySize = sc.GetPersistentInt(3);

	if (sc.IsFullRecalculation)
	{
		r_PriorValue = 0;
		r_PriorArraySize = 0;
	}

	bool LineNeedsUpdating = false;
	if (LineValue != r_PriorValue || sc.ArraySize != r_PriorArraySize)
		LineNeedsUpdating = true;

	r_PriorValue = LineValue;
	r_PriorArraySize = sc.ArraySize;

	if (!LineNeedsUpdating)//for efficiency
		return;
	
	if(Input_DisplayCPLOnBars.GetYesNo())
	{		
		int BarsBack = Input_NumberOfBarsBack.GetInt();
		
		if (BarsBack == 0)// Current Day
		{
				SCDateTime TradingDayStartDateTime = sc.GetTradingDayStartDateTimeOfBar(sc.BaseDateTimeIn[sc.ArraySize - 1]);

				int BarIndex = 0;
				for (BarIndex = sc.ArraySize - 1;
					sc.BaseDateTimeIn[BarIndex] >= TradingDayStartDateTime && BarIndex >= 0; BarIndex--)
				{
					Subgraph_CurrentPriceLine[BarIndex] = LineValue;

					sc.EarliestUpdateSubgraphDataArrayIndex = BarIndex;
				}
		}
		else
		{
			int StartingIndex = max(0, sc.ArraySize - BarsBack);

			sc.EarliestUpdateSubgraphDataArrayIndex = sc.UpdateStartIndex;

			for (int Index = max(0, sc.UpdateStartIndex - BarsBack); Index < sc.ArraySize; ++Index)
			{
				if(Index >= StartingIndex)
					break;

				Subgraph_CurrentPriceLine[Index] = 0;

				if (Index < sc.EarliestUpdateSubgraphDataArrayIndex)
					sc.EarliestUpdateSubgraphDataArrayIndex = Index;

			}

			for (int Index = sc.ArraySize - 1; BarsBack > 0 && Index >= 0; Index--)
			{
				Subgraph_CurrentPriceLine[Index] = LineValue;
				BarsBack--;

				if (Index < sc.EarliestUpdateSubgraphDataArrayIndex)
					sc.EarliestUpdateSubgraphDataArrayIndex = Index;
			}
		}

	}
	else if (r_PriorLineStartIndex != 0)
	{
		//Clear prior array elements for when projecting forward
		for(int Index = r_PriorLineStartIndex; Index < sc.ArraySize; Index++)
			Subgraph_CurrentPriceLine[Index] = 0.0;
	}

	// Zero out prior values
	int StartClearIndex = 0;
	if (Input_DisplayCPLOnBars.GetYesNo())
		StartClearIndex = sc.EarliestUpdateSubgraphDataArrayIndex - 1;
	else
		StartClearIndex = sc.ArraySize - 1;

	for (int BarIndex = StartClearIndex; BarIndex >= 0; --BarIndex)
	{
		if (Subgraph_CurrentPriceLine[BarIndex] == 0.0f)
			break;

		Subgraph_CurrentPriceLine[BarIndex] = 0.0f;
		sc.EarliestUpdateSubgraphDataArrayIndex = BarIndex;
	}

	if (Input_ProjectForward.GetYesNo())
	{
		int NumberOfBars = NumberOfForwardProjectionBars.GetInt();
		Subgraph_CurrentPriceLine.ExtendedArrayElementsToGraph = NumberOfBars;
		for(int Index = 0; Index < NumberOfBars; Index++)
		{
			Subgraph_CurrentPriceLine[sc.ArraySize + Index] = LineValue;
		}

		r_PriorLineStartIndex = sc.ArraySize;
	}
	else
		Subgraph_CurrentPriceLine.ExtendedArrayElementsToGraph = 0;

}

/*==========================================================================*/
SCSFExport scsf_CurrentBidAskLines(SCStudyInterfaceRef sc)
{
	SCSubgraphRef Subgraph_CurrentBidLine = sc.Subgraph[0];
	SCSubgraphRef Subgraph_CurrentAskLine = sc.Subgraph[1];

	SCInputRef Input_NumberOfBarsBack = sc.Input[0];
	SCInputRef Input_DisplayLinesOnBars = sc.Input[1];
	SCInputRef Input_ProjectForward = sc.Input[2];
	SCInputRef Input_NumberOfForwardProjectionBars = sc.Input[3];

	if (sc.SetDefaults)
	{
		sc.GraphName = "Current Bid Ask Lines";

		Subgraph_CurrentBidLine.Name = "Bid";
		Subgraph_CurrentBidLine.DrawStyle = DRAWSTYLE_LINE;
		Subgraph_CurrentBidLine.PrimaryColor = RGB(255, 0, 0);
		Subgraph_CurrentBidLine.DrawZeros = false;
		Subgraph_CurrentBidLine.LineStyle = LINESTYLE_SOLID;
		Subgraph_CurrentBidLine.LineWidth = 2;

		Subgraph_CurrentAskLine.Name = "Ask";
		Subgraph_CurrentAskLine.DrawStyle = DRAWSTYLE_LINE;
		Subgraph_CurrentAskLine.PrimaryColor = RGB(0, 255, 0);
		Subgraph_CurrentAskLine.DrawZeros = false;
		Subgraph_CurrentAskLine.LineStyle = LINESTYLE_SOLID;
		Subgraph_CurrentAskLine.LineWidth = 2;

		sc.ScaleRangeType = SCALE_SAMEASREGION;
		sc.GraphRegion = 0;

		Input_NumberOfBarsBack.Name = "Number of Bars to Display On. 0 = Current Day";
		Input_NumberOfBarsBack.SetInt(0);
		Input_NumberOfBarsBack.SetIntLimits(0, MAX_STUDY_LENGTH);
		
		Input_DisplayLinesOnBars.Name = "Display Current Lines on Chart Bars";
		Input_DisplayLinesOnBars.SetYesNo(true);

		Input_ProjectForward.Name = "Forward Project Bid and Ask Lines";
		Input_ProjectForward.SetYesNo(false);

		Input_NumberOfForwardProjectionBars.Name = "Number of Forward Projection Bars";
		Input_NumberOfForwardProjectionBars.SetInt(10);

		sc.AutoLoop = 0;

		
		return;
	}

	if (Input_NumberOfForwardProjectionBars.GetInt() == 0)
		Input_NumberOfForwardProjectionBars.SetInt(10);

	float BidLineValue = sc.Bid;
	float AskLineValue = sc.Ask;

	int &PriorLineStartIndex = sc.GetPersistentInt(1);

	if (Input_DisplayLinesOnBars.GetYesNo())
	{
		int BarsBack = Input_NumberOfBarsBack.GetInt();

		if (BarsBack == 0)
		{
			SCDateTime TradingDayStartDateTime = sc.GetTradingDayStartDateTimeOfBar(sc.BaseDateTimeIn[sc.ArraySize - 1]);

			int BarIndex = 0;
			for (BarIndex = sc.ArraySize - 1;
				sc.BaseDateTimeIn[BarIndex] >= TradingDayStartDateTime && BarIndex >= 0; BarIndex--)
			{
				Subgraph_CurrentBidLine[BarIndex] = BidLineValue;
				Subgraph_CurrentAskLine[BarIndex] = AskLineValue;

				sc.EarliestUpdateSubgraphDataArrayIndex = BarIndex;
			}


		}
		else
		{
			int StartingIndex = sc.ArraySize - BarsBack;

			sc.EarliestUpdateSubgraphDataArrayIndex = sc.UpdateStartIndex;

			for (int Index = sc.UpdateStartIndex - BarsBack; Index < sc.ArraySize; ++Index)
			{
				if (Index >= StartingIndex)
					break;

				Subgraph_CurrentBidLine[Index] = 0;
				Subgraph_CurrentAskLine[Index] = 0;
			}

			for (int Index = sc.ArraySize - 1; BarsBack > 0 && Index >= 0; Index--)
			{
				Subgraph_CurrentBidLine[Index] = BidLineValue;
				Subgraph_CurrentAskLine[Index] = AskLineValue;
				BarsBack--;

				if (Index < sc.EarliestUpdateSubgraphDataArrayIndex)
					sc.EarliestUpdateSubgraphDataArrayIndex = Index;
			}
		}

	}
	else if (PriorLineStartIndex != 0)
	{
		//Clear prior array elements for when projecting forward
		for (int Index = PriorLineStartIndex; Index < sc.ArraySize; ++Index)
		{
			Subgraph_CurrentBidLine[Index] = 0.0;
			Subgraph_CurrentAskLine[Index] = 0.0;
		}
	}

	// Zero out prior values
	int StartClearIndex = 0;
	if (Input_DisplayLinesOnBars.GetYesNo())
		StartClearIndex = sc.EarliestUpdateSubgraphDataArrayIndex - 1;
	else
		StartClearIndex = sc.ArraySize - 1;

	for (int BarIndex = StartClearIndex; BarIndex >= 0; --BarIndex)
	{
		if (Subgraph_CurrentBidLine[BarIndex] == 0.0f
			&& Subgraph_CurrentAskLine[BarIndex] == 0.0f)
			break;

		Subgraph_CurrentBidLine[BarIndex] = 0.0f;
		Subgraph_CurrentAskLine[BarIndex] = 0.0f;
		sc.EarliestUpdateSubgraphDataArrayIndex = BarIndex;
	}


	if (Input_ProjectForward.GetYesNo())
	{
		int NumberOfBars = Input_NumberOfForwardProjectionBars.GetInt();
		Subgraph_CurrentBidLine.ExtendedArrayElementsToGraph = NumberOfBars;
		Subgraph_CurrentAskLine.ExtendedArrayElementsToGraph = NumberOfBars;

		for (int Index = 0; Index < NumberOfBars; Index++)
		{
			Subgraph_CurrentBidLine[sc.ArraySize + Index] = BidLineValue;
			Subgraph_CurrentAskLine[sc.ArraySize + Index] = AskLineValue;
		}

		PriorLineStartIndex = sc.ArraySize;
	}
	else
	{
		Subgraph_CurrentBidLine.ExtendedArrayElementsToGraph = 0;
		Subgraph_CurrentAskLine.ExtendedArrayElementsToGraph = 0;
	}
}

/*==========================================================================*/
SCSFExport scsf_OutOfSequence(SCStudyInterfaceRef sc) 
{	
	SCSubgraphRef Subgraph_OOOT = sc.Subgraph[0];

	if(sc.SetDefaults)
	{
		sc.GraphName = "Out of Order Timestamps Detector";

		Subgraph_OOOT.Name = "OoOT";
		Subgraph_OOOT.PrimaryColor = RGB(255,64,32);
		Subgraph_OOOT.DrawStyle = DRAWSTYLE_BACKGROUND;
		Subgraph_OOOT.LineWidth = 5;
		Subgraph_OOOT.DrawZeros = false;

		sc.GraphRegion = 0;
		
		sc.DisplayStudyInputValues= false;

		sc.ScaleRangeType = SCALE_INDEPENDENT;

		sc.DrawStudyUnderneathMainPriceGraph;

		
		

		sc.AutoLoop = 1;

		return;
	}
	
	sc.DataStartIndex = 0;
	if (sc.Index <= 0)
		return;

	double prevDateTime = sc.BaseDateTimeIn[sc.Index-1];
	double curDateTime = sc.BaseDateTimeIn[sc.Index];

	if(curDateTime < prevDateTime)
		Subgraph_OOOT.Data[sc.Index] = 1;
	else 
		Subgraph_OOOT.Data[sc.Index] = 0;
	
	return;
}

/************************************************************
*  MoneyFlowIndex
*
*		typical price:			(high + low + close )/3
*		money flow:				typical price * volume
*		money ratio:			positive money flow / negative money flow
************************************************************/
SCSFExport scsf_MoneyFlowIndex(SCStudyInterfaceRef sc)
{
	SCSubgraphRef Subgraph_MFI = sc.Subgraph[0];

	SCInputRef Input_Length = sc.Input[2];
		
	if (sc.SetDefaults)
	{
		sc.GraphName = "Money Flow Index";
		sc.GraphRegion = 1;
		sc.ValueFormat = 3;

		Subgraph_MFI.DrawStyle = DRAWSTYLE_LINE;	
		Subgraph_MFI.Name = "MFI";
		Subgraph_MFI.PrimaryColor = RGB(0, 255, 0);
		Subgraph_MFI.DrawZeros = true;
		
		Input_Length.Name = "Length";
		Input_Length.SetInt(14); 
		Input_Length.SetIntLimits(1, MAX_STUDY_LENGTH);

		sc.AutoLoop = 1;

		return;
	}
	
	const double BIAS_DIVISION_DOUBLE = (double)10e-20;

	double typ_price = 0.0, prev_typ_price = 0.0, money_flow = 0.0, volume = 0.0, N_pos_mon_flow = 0.0, N_neg_mon_flow = 0.0, MoneyFlowIndex = 0.0, money_ratio = 0.0;

	sc.DataStartIndex = Input_Length.GetInt();

	if ((sc.Index - Input_Length.GetInt() + 1) != 0)
		prev_typ_price = sc.HLCAvg[sc.Index - Input_Length.GetInt()];

	for(int IndexOffset= 0; IndexOffset < Input_Length.GetInt(); IndexOffset++)
	{
		volume			= sc.Volume[sc.Index - Input_Length.GetInt() + 1 + IndexOffset];
		typ_price		= sc.HLCAvg[sc.Index - Input_Length.GetInt() + 1 + IndexOffset];
		money_flow		= typ_price * volume;
		N_pos_mon_flow += typ_price > prev_typ_price ? money_flow : 0;
		N_neg_mon_flow += typ_price < prev_typ_price ? money_flow : 0;
		prev_typ_price	= typ_price;
	}

	money_ratio = N_pos_mon_flow / (N_neg_mon_flow + BIAS_DIVISION_DOUBLE);

	MoneyFlowIndex = 100.0 - (100.0 / (1.0 + money_ratio));

	Subgraph_MFI[sc.Index] = (float)MoneyFlowIndex;		
}


/*============================================================================*/
SCSFExport scsf_VolumeWeightedAveragePrice(SCStudyInterfaceRef sc)
{
	SCSubgraphRef   Subgraph_VWAPSubgraph = sc.Subgraph[0];
	SCFloatArrayRef Array_BarSumPriceTimesVolume = Subgraph_VWAPSubgraph.Arrays[0];  
	SCFloatArrayRef Array_BarSumPriceSquaredTimesVolume = Subgraph_VWAPSubgraph.Arrays[1];
	SCFloatArrayRef Array_StandardDeviationArray = Subgraph_VWAPSubgraph.Arrays[2];
	SCFloatArrayRef Array_BarSumPriceVWAPDifferenceSquaredTimesVolume = Subgraph_VWAPSubgraph.Arrays[3];
	SCFloatArrayRef Array_CalculatedBarVolume = Subgraph_VWAPSubgraph.Arrays[4];

	SCSubgraphRef   Subgraph_SD1Top    = sc.Subgraph[1];
	SCSubgraphRef   Subgraph_SD1Bottom = sc.Subgraph[2];
	SCSubgraphRef   Subgraph_SD2Top    = sc.Subgraph[3];
	SCSubgraphRef   Subgraph_SD2Bottom = sc.Subgraph[4];
	SCSubgraphRef   Subgraph_SD3Top    = sc.Subgraph[5];
	SCSubgraphRef   Subgraph_SD3Bottom = sc.Subgraph[6];
	SCSubgraphRef   Subgraph_SD4Top    = sc.Subgraph[7];
	SCSubgraphRef   Subgraph_SD4Bottom = sc.Subgraph[8];

	SCInputRef Input_InputData              = sc.Input[0];
	SCInputRef Input_BandCalculationMethod	= sc.Input[1];
	SCInputRef Input_VolumeTypeToUse		= sc.Input[2];
	SCInputRef Input_TimePeriodType         = sc.Input[3];	
	SCInputRef Input_TimePeriodLength       = sc.Input[4];	
	SCInputRef Input_Version                = sc.Input[5];	
	SCInputRef Input_DistanceMultiplier_V3  = sc.Input[6];
	SCInputRef Input_IgnoreTimePeriodTypeAndLength = sc.Input[7];
	SCInputRef Input_BaseOnUnderlyingData   = sc.Input[9];
	SCInputRef Input_UseFixedOffset         = sc.Input[10];
	SCInputRef Input_StartDateTime			= sc.Input[11];
	SCInputRef Input_Band1OffsetMultiplier  = sc.Input[12];
	SCInputRef Input_Band2OffsetMultiplier  = sc.Input[13];
	SCInputRef Input_Band3OffsetMultiplier  = sc.Input[14];
	SCInputRef Input_Band4OffsetMultiplier  = sc.Input[15];
	

	if(sc.SetDefaults)
	{
		sc.GraphName = "Volume Weighted Average Price";
		sc.GraphRegion = 0;
		sc.ValueFormat = VALUEFORMAT_INHERITED;
		sc.AutoLoop = 1;
		sc.ScaleRangeType=SCALE_SAMEASREGION;
		
		Subgraph_VWAPSubgraph.Name = "VWAP";
		Subgraph_VWAPSubgraph.DrawStyle = DRAWSTYLE_DASH;
		Subgraph_VWAPSubgraph.LineWidth = 2;
		Subgraph_VWAPSubgraph.PrimaryColor = RGB (237, 13, 255);
		Subgraph_VWAPSubgraph.DrawZeros = false;

		Subgraph_SD1Top.Name = "Top Band 1";
		Subgraph_SD1Top.DrawStyle = DRAWSTYLE_DASH;
		Subgraph_SD1Top.LineWidth = 2;
		Subgraph_SD1Top.PrimaryColor = RGB (192, 192, 192);
		Subgraph_SD1Top.DrawZeros = false;

		Subgraph_SD1Bottom.Name = "Bottom Band 1";
		Subgraph_SD1Bottom.DrawStyle = DRAWSTYLE_DASH;
		Subgraph_SD1Bottom.LineWidth = 2;
		Subgraph_SD1Bottom.PrimaryColor = RGB (192, 192, 192);
		Subgraph_SD1Bottom.DrawZeros = false;

		Subgraph_SD2Top.Name = "Top Band 2";
		Subgraph_SD2Top.DrawStyle = DRAWSTYLE_IGNORE;
		Subgraph_SD2Top.LineWidth = 2;
		Subgraph_SD2Top.PrimaryColor = RGB (192, 192, 192);
		Subgraph_SD2Top.DrawZeros = false;

		Subgraph_SD2Bottom.Name = "Bottom Band 2";
		Subgraph_SD2Bottom.DrawStyle = DRAWSTYLE_IGNORE;
		Subgraph_SD2Bottom.LineWidth = 2;
		Subgraph_SD2Bottom.PrimaryColor = RGB (192, 192, 192);
		Subgraph_SD2Bottom.DrawZeros = false;

		Subgraph_SD3Top.Name = "Top Band 3";
		Subgraph_SD3Top.DrawStyle = DRAWSTYLE_IGNORE;
		Subgraph_SD3Top.LineWidth = 2;
		Subgraph_SD3Top.PrimaryColor = RGB (192, 192, 192);
		Subgraph_SD3Top.DrawZeros = false;

		Subgraph_SD3Bottom.Name = "Bottom Band 3";
		Subgraph_SD3Bottom.DrawStyle = DRAWSTYLE_IGNORE;
		Subgraph_SD3Bottom.LineWidth = 2;
		Subgraph_SD3Bottom.PrimaryColor = RGB (192, 192, 192);
		Subgraph_SD3Bottom.DrawZeros = false;

		Subgraph_SD4Top.Name = "Top Band 4";
		Subgraph_SD4Top.DrawStyle = DRAWSTYLE_IGNORE;
		Subgraph_SD4Top.LineWidth = 2;
		Subgraph_SD4Top.PrimaryColor = RGB (192, 192, 192);
		Subgraph_SD4Top.DrawZeros = false;

		Subgraph_SD4Bottom.Name = "Bottom Band 4";
		Subgraph_SD4Bottom.DrawStyle = DRAWSTYLE_IGNORE;
		Subgraph_SD4Bottom.LineWidth = 2;
		Subgraph_SD4Bottom.PrimaryColor = RGB (192, 192, 192);
		Subgraph_SD4Bottom.DrawZeros = false;

		int DisplayOrder = 1;

		Input_InputData.Name = "Input Data";
		Input_InputData.SetInputDataIndex(SC_LAST);  
		Input_InputData.DisplayOrder = DisplayOrder++;

		Input_VolumeTypeToUse.Name = "Volume Type to Use";
		Input_VolumeTypeToUse.SetCustomInputStrings("Total Volume;Bid Volume;Ask Volume");
		Input_VolumeTypeToUse.SetCustomInputIndex(0);
		Input_VolumeTypeToUse.DisplayOrder = DisplayOrder++;

		Input_BaseOnUnderlyingData.Name = "Base On Underlying Data";
		Input_BaseOnUnderlyingData.SetYesNo(0);
		Input_BaseOnUnderlyingData.DisplayOrder = DisplayOrder++;

		Input_TimePeriodType.Name = "Time Period Type";
		Input_TimePeriodType.SetTimePeriodType(TIME_PERIOD_LENGTH_UNIT_DAYS);
		Input_TimePeriodType.DisplayOrder = DisplayOrder++;
		
		Input_TimePeriodLength.Name = "Time Period Length";
		Input_TimePeriodLength.SetInt(1);
		Input_TimePeriodLength.DisplayOrder = DisplayOrder++;

		Input_StartDateTime.Name = "Start Date-Time";
		Input_StartDateTime.SetDateTime(0.0);
		Input_StartDateTime.DisplayOrder = DisplayOrder++;

		Input_IgnoreTimePeriodTypeAndLength.Name = "Ignore Time Period Type And Length";
		Input_IgnoreTimePeriodTypeAndLength.SetYesNo(false);
		Input_IgnoreTimePeriodTypeAndLength.DisplayOrder = DisplayOrder++;

		Input_DistanceMultiplier_V3.SetFloat(0.5);

		//UseFixedOffset.Name = "Use Fixed Offset Instead of Std. Deviation";
		Input_UseFixedOffset.SetYesNo(0);
		//UseFixedOffset.DisplayOrder = DisplayOrder++;

		Input_BandCalculationMethod.Name = "Std. Deviation Band Calculation Method";
		Input_BandCalculationMethod.SetCustomInputStrings("VWAP Variance;Fixed Offset;Standard Deviation;Percentage");
		Input_BandCalculationMethod.SetCustomInputIndex(0);
		Input_BandCalculationMethod.DisplayOrder = DisplayOrder++;

		Input_Band1OffsetMultiplier.Name = "Band 1 Std. Deviation Multiplier/Fixed Offset";
		Input_Band1OffsetMultiplier.SetFloat(0.5);
		Input_Band1OffsetMultiplier.DisplayOrder = DisplayOrder++;

		Input_Band2OffsetMultiplier.Name = "Band 2 Std. Deviation Multiplier/Fixed Offset";
		Input_Band2OffsetMultiplier.SetFloat(1.0);
		Input_Band2OffsetMultiplier.DisplayOrder = DisplayOrder++;

		Input_Band3OffsetMultiplier.Name = "Band 3 Std. Deviation Multiplier/Fixed Offset";
		Input_Band3OffsetMultiplier.SetFloat(1.5);
		Input_Band3OffsetMultiplier.DisplayOrder = DisplayOrder++;

		Input_Band4OffsetMultiplier.Name = "Band 4 Std. Deviation Multiplier/Fixed Offset";
		Input_Band4OffsetMultiplier.SetFloat(2.0);
		Input_Band4OffsetMultiplier.DisplayOrder = DisplayOrder++;

		Input_Version.SetInt(6);

		return;
	}

	if(Input_Version.GetInt() < 2)
	{
		Input_TimePeriodType.SetTimePeriodType(TIME_PERIOD_LENGTH_UNIT_DAYS);
		Input_TimePeriodLength.SetInt(1);

		Input_Version.SetInt(2);
	}

	if(Input_Version.GetInt() < 3)
	{
		Input_DistanceMultiplier_V3.SetFloat(0.5);

		Input_Version.SetInt(3);
	}
	
	if (Input_Version.GetInt() < 4)
	{
		Input_Band1OffsetMultiplier.SetFloat(Input_DistanceMultiplier_V3.GetFloat());
		Input_Band2OffsetMultiplier.SetFloat(Input_DistanceMultiplier_V3.GetFloat()*2.0f);
		Input_Band3OffsetMultiplier.SetFloat(Input_DistanceMultiplier_V3.GetFloat()*3.0f);
		Input_Band4OffsetMultiplier.SetFloat(Input_DistanceMultiplier_V3.GetFloat()*4.0f);

		Input_Version.SetInt(4);
	}

	if (Input_Version.GetInt() < 5)
	{
		Input_BandCalculationMethod.SetCustomInputIndex(Input_UseFixedOffset.GetYesNo() ? 1 : 0);
		Input_Version.SetInt(5);
	}

	if (Input_Version.GetInt() < 6)
	{
		Input_IgnoreTimePeriodTypeAndLength.SetYesNo(false);
		Input_Version.SetInt(6);
	}

	sc.DataStartIndex = 1;

	int& r_LastIndexProcessed = sc.GetPersistentInt(1);
	int& r_StartIndexOfCurrentPeriod = sc.GetPersistentInt(3);
	
	double& r_PriorSumPriceTimesVolume        = sc.GetPersistentDouble(1);
	double& r_PriorSumPriceSquaredTimesVolume = sc.GetPersistentDouble(2);
	double& r_PriorCumulativeVolume           = sc.GetPersistentDouble(3);

	if (sc.Index == 0)
	{
		Array_BarSumPriceTimesVolume[sc.Index] = 0;
		Array_BarSumPriceSquaredTimesVolume[sc.Index] = 0;

		if (Input_BaseOnUnderlyingData.GetYesNo())
		{
			if (sc.MaintainVolumeAtPriceData == 0)
			{
				sc.MaintainVolumeAtPriceData = 1;
				sc.FlagToReloadChartData = 1;
			}
		}
		else
			sc.MaintainVolumeAtPriceData = 0;
	}

	if (Input_StartDateTime.GetDate() != 0 
		&&  sc.BaseDateTimeIn[sc.Index] < Input_StartDateTime.GetDateTime())
		return;

	bool PriorBarIndexExcludedBasedOnDateTime = sc.Index > 0
		&& Input_StartDateTime.GetDate() != 0 
		&&  sc.BaseDateTimeIn[sc.Index - 1] < Input_StartDateTime.GetDateTime();

	SCDateTime PriorCurrentPeriodStartDateTime;

	SCDateTime CurrentPeriodStartDateTime;

	if(!Input_IgnoreTimePeriodTypeAndLength.GetYesNo())
	{
		CurrentPeriodStartDateTime = sc.GetStartOfPeriodForDateTime(sc.BaseDateTimeIn[sc.Index], Input_TimePeriodType.GetTimePeriodType(), Input_TimePeriodLength.GetInt(), 0);
		PriorCurrentPeriodStartDateTime = sc.GetStartOfPeriodForDateTime(sc.BaseDateTimeIn[sc.Index - 1], Input_TimePeriodType.GetTimePeriodType(), Input_TimePeriodLength.GetInt(), 0);
	}

	bool IsStartOfNewPeriod = false;

	//Reset at start of new period
	if (sc.Index == 0 
		|| CurrentPeriodStartDateTime != PriorCurrentPeriodStartDateTime 
		|| PriorBarIndexExcludedBasedOnDateTime)
	{

		r_PriorSumPriceTimesVolume = 0;
		r_PriorSumPriceSquaredTimesVolume = 0;
		r_PriorCumulativeVolume = 0;

		r_LastIndexProcessed = sc.Index;

		r_StartIndexOfCurrentPeriod = sc.Index;
		IsStartOfNewPeriod = true;
	}
	else if (sc.Index != r_LastIndexProcessed)
	{
		// add in last values
		for (; r_LastIndexProcessed < sc.Index; ++r_LastIndexProcessed)
		{
			r_PriorSumPriceTimesVolume += Array_BarSumPriceTimesVolume[r_LastIndexProcessed];
			r_PriorSumPriceSquaredTimesVolume += Array_BarSumPriceSquaredTimesVolume[r_LastIndexProcessed];
			r_PriorCumulativeVolume += Array_CalculatedBarVolume[r_LastIndexProcessed];
		}
	}

	double BarVolume = 0;

	float CurrentPrice = sc.BaseDataIn[Input_InputData.GetInputDataIndex()][sc.Index];

	if (Input_BaseOnUnderlyingData.GetYesNo())
	{
		Array_BarSumPriceTimesVolume[sc.Index] = 0;
		Array_BarSumPriceSquaredTimesVolume[sc.Index] = 0;

		if ((int)sc.VolumeAtPriceForBars->GetNumberOfBars() < sc.ArraySize)
			return;

		const s_VolumeAtPriceV2 *p_VolumeAtPrice = nullptr;

		const int NumVAPElementsAtBarIndex = sc.VolumeAtPriceForBars->GetSizeAtBarIndex(sc.Index);
		for (int VAPIndex = 0; VAPIndex < NumVAPElementsAtBarIndex; VAPIndex++)
		{
			sc.VolumeAtPriceForBars->GetVAPElementAtIndex(sc.Index, VAPIndex, &p_VolumeAtPrice);

			float Price = p_VolumeAtPrice->PriceInTicks * sc.TickSize;

			uint32_t VolumeToUse = 0;
			if (Input_VolumeTypeToUse.GetIndex() == 1)
				VolumeToUse = p_VolumeAtPrice->BidVolume;
			else if (Input_VolumeTypeToUse.GetIndex() == 2)
				VolumeToUse = p_VolumeAtPrice->AskVolume;
			else
				VolumeToUse = p_VolumeAtPrice->Volume;

			Array_BarSumPriceTimesVolume[sc.Index] += (Price * VolumeToUse);
			Array_BarSumPriceSquaredTimesVolume[sc.Index] += (Price * Price * VolumeToUse);
			BarVolume += VolumeToUse;
		}
	}
	else
	{

		Array_BarSumPriceTimesVolume[sc.Index] = CurrentPrice * sc.Volume[sc.Index];
		Array_BarSumPriceSquaredTimesVolume[sc.Index] = CurrentPrice * CurrentPrice * sc.Volume[sc.Index];
		BarVolume = sc.Volume[sc.Index];
	}

	Array_CalculatedBarVolume[sc.Index] = static_cast <float> (BarVolume);

	double PriceTimesVolume = r_PriorSumPriceTimesVolume + Array_BarSumPriceTimesVolume[sc.Index];
	double PriceSquaredTimesVolume = r_PriorSumPriceSquaredTimesVolume + Array_BarSumPriceSquaredTimesVolume[sc.Index];
	double CumulativeVolume = r_PriorCumulativeVolume + BarVolume;

	double VolumeWeightedAveragePrice = 0;
	if (CumulativeVolume != 0)
		VolumeWeightedAveragePrice = PriceTimesVolume / CumulativeVolume;

	Subgraph_VWAPSubgraph[sc.Index] = (float)VolumeWeightedAveragePrice;

	float BandDistance = 1.0f;
	if (Input_BandCalculationMethod.GetIndex() == 1)//Fixed offset
	{
		BandDistance = 1.0f;
	}
	else if (Input_BandCalculationMethod.GetIndex() == 0)//VWAP variance
	{

		double PriceVWAPDifferenceSquaredTimesVolume = (CurrentPrice - Subgraph_VWAPSubgraph[sc.Index])*(CurrentPrice - Subgraph_VWAPSubgraph[sc.Index])* sc.Volume[sc.Index];
		if (IsStartOfNewPeriod)
		{
			Array_BarSumPriceVWAPDifferenceSquaredTimesVolume[sc.Index] = (float)PriceVWAPDifferenceSquaredTimesVolume;
		}
		else
		{
			Array_BarSumPriceVWAPDifferenceSquaredTimesVolume[sc.Index] =
				(float)(Array_BarSumPriceVWAPDifferenceSquaredTimesVolume[sc.Index - 1] + PriceVWAPDifferenceSquaredTimesVolume);
		}
		
		if (CumulativeVolume != 0)
			BandDistance = (float)sqrt(Array_BarSumPriceVWAPDifferenceSquaredTimesVolume[sc.Index]/CumulativeVolume);
		else
			BandDistance = 1.0f;

	}
	else if (Input_BandCalculationMethod.GetIndex() == 2)//VWAP variance//Standard deviation
	{
		sc.StdDeviation(Subgraph_VWAPSubgraph, Array_StandardDeviationArray, sc.Index - r_StartIndexOfCurrentPeriod + 1);
		BandDistance = Array_StandardDeviationArray[sc.Index];
	}
	else //Percentage
	{
		BandDistance = (float)VolumeWeightedAveragePrice / 100.0f;
	}
	
	Subgraph_SD1Top[sc.Index]    = Subgraph_VWAPSubgraph[sc.Index] + Input_Band1OffsetMultiplier.GetFloat() * BandDistance;
	Subgraph_SD1Bottom[sc.Index] = Subgraph_VWAPSubgraph[sc.Index] - Input_Band1OffsetMultiplier.GetFloat() * BandDistance;

	Subgraph_SD2Top[sc.Index]    = Subgraph_VWAPSubgraph[sc.Index] + Input_Band2OffsetMultiplier.GetFloat() * BandDistance;
	Subgraph_SD2Bottom[sc.Index] = Subgraph_VWAPSubgraph[sc.Index] - Input_Band2OffsetMultiplier.GetFloat() * BandDistance;

	Subgraph_SD3Top[sc.Index]    = Subgraph_VWAPSubgraph[sc.Index] + Input_Band3OffsetMultiplier.GetFloat() * BandDistance;
	Subgraph_SD3Bottom[sc.Index] = Subgraph_VWAPSubgraph[sc.Index] - Input_Band3OffsetMultiplier.GetFloat() * BandDistance;

	Subgraph_SD4Top[sc.Index]    = Subgraph_VWAPSubgraph[sc.Index] + Input_Band4OffsetMultiplier.GetFloat() * BandDistance;
	Subgraph_SD4Bottom[sc.Index] = Subgraph_VWAPSubgraph[sc.Index] - Input_Band4OffsetMultiplier.GetFloat() * BandDistance;
}

/*===========================================================================*/
void GetIndexForStartofDayPeriodForDaysBack
( SCStudyInterfaceRef sc
, const SCDateTime InitialStartDateTime
, const int NumDaysToInclude
, const bool ExcludeWeekends
, const int MinimumRequiredTimePeriodInDayAsPercent
, int& r_InitialBarIndex
)
{
	int DaysBack = -1;

	for (int DaysCount = 0; DaysCount < NumDaysToInclude; ++DaysCount)
	{
		for (int Iterations = 10; Iterations > 0; --Iterations)
		{
			DaysBack++;

			SCDateTime PriorPeriodStartDateTime = InitialStartDateTime - DaysBack * DAYS;
			SCDateTime PriorPeriodEndDateTime = PriorPeriodStartDateTime + 1 * DAYS - 1 * SECONDS;

			r_InitialBarIndex = sc.GetNearestMatchForSCDateTime(sc.ChartNumber, PriorPeriodStartDateTime);

			const SCDateTime TradingDayDate = sc.GetTradingDayDate(PriorPeriodStartDateTime);

			if (ExcludeWeekends && TradingDayDate.IsWeekend())
				continue;

			// for the current day, do not do any check to see if there is sufficient data because there may not be if the day is not complete.
			if (NumDaysToInclude == 1)
				break;

			const int PriorPeriodLastIndex = sc.GetNearestMatchForSCDateTime(sc.ChartNumber, PriorPeriodEndDateTime);

			const double ActualTimeSpan
				= sc.CalculateTimeSpanAcrossChartBars
					( r_InitialBarIndex
					, PriorPeriodLastIndex
					);

			//If there is a sufficient amount of data in this time period
			if (ActualTimeSpan > 1*DAYS * (MinimumRequiredTimePeriodInDayAsPercent * 0.01))
				break;
		}
	} 
}

/*============================================================================*/
SCSFExport scsf_RollingVolumeWeightedAveragePrice(SCStudyInterfaceRef sc)
{
	SCSubgraphRef   Subgraph_VWAPSubgraph = sc.Subgraph[0];
	SCFloatArrayRef Array_BarSumPriceTimesVolume = Subgraph_VWAPSubgraph.Arrays[0];
	SCFloatArrayRef Array_StandardDeviationArray = Subgraph_VWAPSubgraph.Arrays[1];
	SCFloatArrayRef Array_PriceTimesVolumeArray = Subgraph_VWAPSubgraph.Arrays[2];
	SCSubgraphRef Subgraph_BackgroundVWAPForCurrentPeriod = sc.Subgraph[9];
	SCSubgraphRef Subgraph_PriceVWAPDifferenceSquaredTimesVolume = sc.Subgraph[10];
	SCSubgraphRef Subgraph_BarSumPriceVWAPDifferenceSquaredTimesVolumeArray = sc.Subgraph[11];
	SCSubgraphRef Subgraph_CumulativeVolumeForPeriodArray = sc.Subgraph[12];
	SCSubgraphRef Subgraph_BandDistance = sc.Subgraph[13];

	SCSubgraphRef   Subgraph_SD1Top = sc.Subgraph[1];
	SCSubgraphRef   Subgraph_SD1Bottom = sc.Subgraph[2];
	SCSubgraphRef   Subgraph_SD2Top = sc.Subgraph[3];
	SCSubgraphRef   Subgraph_SD2Bottom = sc.Subgraph[4];
	SCSubgraphRef   Subgraph_SD3Top = sc.Subgraph[5];
	SCSubgraphRef   Subgraph_SD3Bottom = sc.Subgraph[6];
	SCSubgraphRef   Subgraph_SD4Top = sc.Subgraph[7];
	SCSubgraphRef   Subgraph_SD4Bottom = sc.Subgraph[8];

	SCInputRef Input_InputData = sc.Input[0];
	SCInputRef Input_BandCalculationMethod = sc.Input[1];
	SCInputRef Input_MinimumRequiredTimePeriodAsPercentForSkipDays = sc.Input[2];
	SCInputRef Input_TimePeriodType = sc.Input[3];
	SCInputRef Input_TimePeriodLength = sc.Input[4];
	SCInputRef Input_Version = sc.Input[5];
	SCInputRef Input_DistanceMultiplier_V3 = sc.Input[6];
	SCInputRef Input_NumberOfDaysToCalculate = sc.Input[7];
	SCInputRef Input_BaseOnUnderlyingData = sc.Input[9];
	SCInputRef Input_UseFixedOffset = sc.Input[10];
	SCInputRef Input_Band1OffsetMultiplier = sc.Input[12];
	SCInputRef Input_Band2OffsetMultiplier = sc.Input[13];
	SCInputRef Input_Band3OffsetMultiplier = sc.Input[14];
	SCInputRef Input_Band4OffsetMultiplier = sc.Input[15];
	SCInputRef Input_ExcludeWeekendInDateCalc = sc.Input[16];


	if (sc.SetDefaults)
	{
		sc.GraphName = "Volume Weighted Average Price - Rolling";
		sc.GraphRegion = 0;
		sc.ValueFormat = VALUEFORMAT_INHERITED;
		sc.AutoLoop = 0;//Manual looping
		sc.MaintainVolumeAtPriceData = 1;

		sc.ScaleRangeType = SCALE_SAMEASREGION;

		Subgraph_VWAPSubgraph.Name = "VWAP";
		Subgraph_VWAPSubgraph.DrawStyle = DRAWSTYLE_DASH;
		Subgraph_VWAPSubgraph.LineWidth = 2;
		Subgraph_VWAPSubgraph.PrimaryColor = RGB(237, 13, 255);
		Subgraph_VWAPSubgraph.DrawZeros = false;

		Subgraph_SD1Top.Name = "Top Band 1";
		Subgraph_SD1Top.DrawStyle = DRAWSTYLE_DASH;
		Subgraph_SD1Top.LineWidth = 2;
		Subgraph_SD1Top.PrimaryColor = RGB(192, 192, 192);
		Subgraph_SD1Top.DrawZeros = false;

		Subgraph_SD1Bottom.Name = "Bottom Band 1";
		Subgraph_SD1Bottom.DrawStyle = DRAWSTYLE_DASH;
		Subgraph_SD1Bottom.LineWidth = 2;
		Subgraph_SD1Bottom.PrimaryColor = RGB(192, 192, 192);
		Subgraph_SD1Bottom.DrawZeros = false;

		Subgraph_SD2Top.Name = "Top Band 2";
		Subgraph_SD2Top.DrawStyle = DRAWSTYLE_IGNORE;
		Subgraph_SD2Top.LineWidth = 2;
		Subgraph_SD2Top.PrimaryColor = RGB(192, 192, 192);
		Subgraph_SD2Top.DrawZeros = false;

		Subgraph_SD2Bottom.Name = "Bottom Band 2";
		Subgraph_SD2Bottom.DrawStyle = DRAWSTYLE_IGNORE;
		Subgraph_SD2Bottom.LineWidth = 2;
		Subgraph_SD2Bottom.PrimaryColor = RGB(192, 192, 192);
		Subgraph_SD2Bottom.DrawZeros = false;

		Subgraph_SD3Top.Name = "Top Band 3";
		Subgraph_SD3Top.DrawStyle = DRAWSTYLE_IGNORE;
		Subgraph_SD3Top.LineWidth = 2;
		Subgraph_SD3Top.PrimaryColor = RGB(192, 192, 192);
		Subgraph_SD3Top.DrawZeros = false;

		Subgraph_SD3Bottom.Name = "Bottom Band 3";
		Subgraph_SD3Bottom.DrawStyle = DRAWSTYLE_IGNORE;
		Subgraph_SD3Bottom.LineWidth = 2;
		Subgraph_SD3Bottom.PrimaryColor = RGB(192, 192, 192);
		Subgraph_SD3Bottom.DrawZeros = false;

		Subgraph_SD4Top.Name = "Top Band 4";
		Subgraph_SD4Top.DrawStyle = DRAWSTYLE_IGNORE;
		Subgraph_SD4Top.LineWidth = 2;
		Subgraph_SD4Top.PrimaryColor = RGB(192, 192, 192);
		Subgraph_SD4Top.DrawZeros = false;

		Subgraph_SD4Bottom.Name = "Bottom Band 4";
		Subgraph_SD4Bottom.DrawStyle = DRAWSTYLE_IGNORE;
		Subgraph_SD4Bottom.LineWidth = 2;
		Subgraph_SD4Bottom.PrimaryColor = RGB(192, 192, 192);
		Subgraph_SD4Bottom.DrawZeros = false;

		Subgraph_BackgroundVWAPForCurrentPeriod.Name = "BackgroundVWAPForCurrentPeriod";
		Subgraph_BackgroundVWAPForCurrentPeriod.DrawStyle = DRAWSTYLE_IGNORE;
		Subgraph_BackgroundVWAPForCurrentPeriod.DisplayNameValueInWindowsFlags = 1;

		Subgraph_PriceVWAPDifferenceSquaredTimesVolume.Name = "PriceVWAPDifferenceSquaredTimesVolume";
		Subgraph_PriceVWAPDifferenceSquaredTimesVolume.DrawStyle = DRAWSTYLE_IGNORE;
		Subgraph_PriceVWAPDifferenceSquaredTimesVolume.DisplayNameValueInWindowsFlags = 1;

		Subgraph_BarSumPriceVWAPDifferenceSquaredTimesVolumeArray.Name = "BarSumPriceVWAPDifferenceSquaredTimesVolumeArray";
		Subgraph_BarSumPriceVWAPDifferenceSquaredTimesVolumeArray.DrawStyle = DRAWSTYLE_IGNORE;
		Subgraph_BarSumPriceVWAPDifferenceSquaredTimesVolumeArray.DisplayNameValueInWindowsFlags = 1;

		Subgraph_CumulativeVolumeForPeriodArray.Name = "CumulativeVolumeForPeriodArray";
		Subgraph_CumulativeVolumeForPeriodArray.DrawStyle = DRAWSTYLE_IGNORE;
		Subgraph_CumulativeVolumeForPeriodArray.DisplayNameValueInWindowsFlags = 1;

		Subgraph_BandDistance.Name = "BandDistance";
		Subgraph_BandDistance.DrawStyle = DRAWSTYLE_IGNORE;
		Subgraph_BandDistance.DisplayNameValueInWindowsFlags = 1;

		int DisplayOrder = 1;

		Input_InputData.Name = "Input Data";
		Input_InputData.SetInputDataIndex(SC_LAST);
		Input_InputData.DisplayOrder = DisplayOrder++;

		Input_BaseOnUnderlyingData.Name = "Base On Underlying Data";
		Input_BaseOnUnderlyingData.SetYesNo(0);
		Input_BaseOnUnderlyingData.DisplayOrder = DisplayOrder++;

		Input_TimePeriodType.Name = "Time Period Type";
		Input_TimePeriodType.SetCustomInputStrings("Days - Trading Days;Days - 24 Hour Period;Minutes;Bars");
		Input_TimePeriodType.SetCustomInputIndex(0);
		Input_TimePeriodType.DisplayOrder = DisplayOrder++;

		Input_TimePeriodLength.Name = "Time Period Length";
		Input_TimePeriodLength.SetInt(1);
		Input_TimePeriodLength.DisplayOrder = DisplayOrder++;

		Input_NumberOfDaysToCalculate.Name = "Number of Days to Calculate";
		Input_NumberOfDaysToCalculate.SetInt(10);
		Input_NumberOfDaysToCalculate.DisplayOrder = DisplayOrder++;

		Input_DistanceMultiplier_V3.SetFloat(0.5);

		Input_ExcludeWeekendInDateCalc.Name = "Exclude Weekends In Date Look Back";
		Input_ExcludeWeekendInDateCalc.SetYesNo(1);
		Input_ExcludeWeekendInDateCalc.DisplayOrder = DisplayOrder++;

		Input_MinimumRequiredTimePeriodAsPercentForSkipDays.Name = "Minimum Required Time Period as Percent for Skip Days";
		Input_MinimumRequiredTimePeriodAsPercentForSkipDays.SetInt(0);
		Input_MinimumRequiredTimePeriodAsPercentForSkipDays.DisplayOrder = DisplayOrder++;

		//UseFixedOffset.Name = "Use Fixed Offset Instead of Std. Deviation";
		Input_UseFixedOffset.SetYesNo(0);
		//UseFixedOffset.DisplayOrder = DisplayOrder++;

		Input_BandCalculationMethod.Name = "Std. Deviation Band Calculation Method";
		Input_BandCalculationMethod.SetCustomInputStrings("VWAP Variance;Fixed Offset;Standard Deviation;Percentage");
		Input_BandCalculationMethod.SetCustomInputIndex(0);
		Input_BandCalculationMethod.DisplayOrder = DisplayOrder++;

		Input_Band1OffsetMultiplier.Name = "Band 1 Std. Deviation Multiplier/Fixed Offset";
		Input_Band1OffsetMultiplier.SetFloat(0.5);
		Input_Band1OffsetMultiplier.DisplayOrder = DisplayOrder++;

		Input_Band2OffsetMultiplier.Name = "Band 2 Std. Deviation Multiplier/Fixed Offset";
		Input_Band2OffsetMultiplier.SetFloat(1.0);
		Input_Band2OffsetMultiplier.DisplayOrder = DisplayOrder++;

		Input_Band3OffsetMultiplier.Name = "Band 3 Std. Deviation Multiplier/Fixed Offset";
		Input_Band3OffsetMultiplier.SetFloat(1.5);
		Input_Band3OffsetMultiplier.DisplayOrder = DisplayOrder++;

		Input_Band4OffsetMultiplier.Name = "Band 4 Std. Deviation Multiplier/Fixed Offset";
		Input_Band4OffsetMultiplier.SetFloat(2.0);
		Input_Band4OffsetMultiplier.DisplayOrder = DisplayOrder++;

		Input_Version.SetInt(8);

		return;
	}

	if (Input_NumberOfDaysToCalculate.GetInt() == 0)
		Input_NumberOfDaysToCalculate.SetInt(10);


	// calculate the period start index
	const int PeriodType = Input_TimePeriodType.GetIndex();

	if (PeriodType == 0 || PeriodType == 1)
	{
		int DaysRequired = Input_TimePeriodLength.GetInt();

		if (Input_NumberOfDaysToCalculate.GetInt() < DaysRequired)
			Input_NumberOfDaysToCalculate.SetInt(DaysRequired);
	}

	int& r_LastIndexProcessed = sc.GetPersistentInt(1);
	int& r_FirstIndexIncluded = sc.GetPersistentInt(2);
	int& r_PriorFirstIndexIncluded = sc.GetPersistentInt(3);

	int& r_LastExcludedIndex = sc.GetPersistentInt(4);

	SCDateTime& r_PriorTradeDate = sc.GetPersistentSCDateTime(1);

	if (sc.IsFullRecalculation)//reset
	{
		r_LastIndexProcessed = -1;
		r_FirstIndexIncluded = 0;
		r_PriorFirstIndexIncluded = -1;
		r_LastExcludedIndex = -1;

		if (Input_BaseOnUnderlyingData.GetYesNo())
		{
			if (sc.MaintainVolumeAtPriceData == 0)
			{
				sc.MaintainVolumeAtPriceData = 1;
				sc.FlagToReloadChartData = 1;
			}
		}
		else
			sc.MaintainVolumeAtPriceData = 0;
	}

	if (Input_BaseOnUnderlyingData.GetYesNo() &&
		(int)sc.VolumeAtPriceForBars->GetNumberOfBars() < sc.ArraySize)
		return;

	const SCDateTime TradingDayDateForLastBar = sc.GetTradingDayDate(sc.BaseDateTimeIn[sc.ArraySize - 1]);


	for (int Index = sc.UpdateStartIndex; Index < sc.ArraySize; ++Index)
	{
		bool NewBar = Index != r_LastIndexProcessed;

		r_LastIndexProcessed = Index;

		Array_BarSumPriceTimesVolume[Index] = 0;

		const SCDateTime TradingDayDateForBar = sc.GetTradingDayDate(sc.BaseDateTimeIn[Index]);

		if ((TradingDayDateForLastBar.GetDate() - TradingDayDateForBar.GetDate() + 1)
	> Input_NumberOfDaysToCalculate.GetInt())
		{
			r_LastExcludedIndex = Index;
			continue;
		}

		float CurrentPrice = sc.BaseDataIn[Input_InputData.GetInputDataIndex()][Index];

		// Calculate bar values
		if (Input_BaseOnUnderlyingData.GetYesNo())
		{

			const s_VolumeAtPriceV2 *p_VolumeAtPrice = nullptr;
			int NumberOfPrices = sc.VolumeAtPriceForBars->GetSizeAtBarIndex(Index);

			for (int VAPIndex = 0; VAPIndex < NumberOfPrices; VAPIndex++)
			{
				sc.VolumeAtPriceForBars->GetVAPElementAtIndex(Index, VAPIndex, &p_VolumeAtPrice);

				float Price = p_VolumeAtPrice->PriceInTicks * sc.TickSize;
				float PriceTimesVolume = Price * p_VolumeAtPrice->Volume;

				Array_BarSumPriceTimesVolume[Index] += PriceTimesVolume;
			}
#ifdef _DEBUG

			if (Index == sc.ArraySize - 1)
			{
				float  BarSumPriceTimesVolumeValue = Array_BarSumPriceTimesVolume[Index];
				SCString Message;
				Message.Format("%f", BarSumPriceTimesVolumeValue);
				sc.AddMessageToLog(Message, 0);
			}

#endif // _DEBUG

		}
		else
		{
			Array_BarSumPriceTimesVolume[Index] = CurrentPrice * sc.Volume[Index];
		}

		if (NewBar)
		{

			if (PeriodType == 0)  // Days - trading days
			{
				int TradeDate = sc.GetTradingDayDate(sc.BaseDateTimeIn[Index]);

				SCDateTime CurrentDayStartDateTime = sc.GetStartDateTimeForTradingDate(TradeDate);

				r_PriorTradeDate = TradeDate;

				r_FirstIndexIncluded = sc.GetContainingIndexForSCDateTime(sc.ChartNumber, CurrentDayStartDateTime);

				GetIndexForStartofDayPeriodForDaysBack
				(sc
					, CurrentDayStartDateTime
					, Input_TimePeriodLength.GetInt()
					, Input_ExcludeWeekendInDateCalc.GetYesNo() != 0
					, Input_MinimumRequiredTimePeriodAsPercentForSkipDays.GetInt()
					, r_FirstIndexIncluded
				);
			}
			else if (PeriodType == 1)  // Days - 24 hour periods
			{
				SCDateTime CurrentPeriodStartDateTime = sc.BaseDateTimeIn[Index] - 1 * DAYS + 1 * SECONDS;
				r_FirstIndexIncluded = sc.GetContainingIndexForSCDateTime(sc.ChartNumber, CurrentPeriodStartDateTime);

				GetIndexForStartofDayPeriodForDaysBack
				(sc
					, CurrentPeriodStartDateTime
					, Input_TimePeriodLength.GetInt()
					, Input_ExcludeWeekendInDateCalc.GetYesNo() != 0
					, Input_MinimumRequiredTimePeriodAsPercentForSkipDays.GetInt()
					, r_FirstIndexIncluded
				);
			}
			else if (PeriodType == 2)  // Minutes
			{
				SCDateTime RollingStartDateTime = 0;

				if (sc.AreTimeSpecificBars() && sc.SecondsPerBar != 0)
				{
					RollingStartDateTime = sc.BaseDateTimeIn[Index] + (sc.SecondsPerBar - 1) * SECONDS;
					RollingStartDateTime -= Input_TimePeriodLength.GetInt() * MINUTES;
				}
				else
				{
					if (Index == sc.ArraySize - 1)
						RollingStartDateTime = sc.LatestDateTimeForLastBar;
					else
						RollingStartDateTime = sc.BaseDateTimeIn[Index + 1] - 1 * SECONDS;

					RollingStartDateTime -= Input_TimePeriodLength.GetInt() * MINUTES;
				}

				for (; r_FirstIndexIncluded <= Index; ++r_FirstIndexIncluded)
				{
					if (sc.BaseDateTimeIn[r_FirstIndexIncluded] < RollingStartDateTime)
						continue;

					break;
				}
			}
			else  // Bars
			{
				r_FirstIndexIncluded = max(0, Index - Input_TimePeriodLength.GetInt() + 1);
			}

#ifdef _DEBUG
			SCString MessageText;
			SCString IndexDateTime = sc.DateTimeToString(sc.BaseDateTimeIn[Index], FLAG_DT_COMPLETE_DATETIME);
			SCString FirstIndexIncludedDateTime = sc.DateTimeToString(sc.BaseDateTimeIn[r_FirstIndexIncluded], FLAG_DT_COMPLETE_DATETIME);
			SCString IndexTradingDate = sc.DateTimeToString(sc.GetTradingDayDate(sc.BaseDateTimeIn[Index]), FLAG_DT_COMPLETE_DATE);
			MessageText.Format("NewBar. FirstIndexIncluded: %d, CurrentIndex: %d, FirstIndexIncluded_DateTime: %s, CurrentIndex_DateTime: %s, CurrentIndex_TradingDate: %s"
				, r_FirstIndexIncluded, Index, FirstIndexIncludedDateTime.GetChars(), IndexDateTime.GetChars(), IndexTradingDate.GetChars());
			sc.AddMessageToLog(MessageText, 0);

#endif

		}

		if (r_FirstIndexIncluded <= r_LastExcludedIndex)
			r_FirstIndexIncluded = r_LastExcludedIndex + 1;

		int CalculationStartIndex = Index;
		bool ResetCalculation = false;
		if (r_PriorFirstIndexIncluded != r_FirstIndexIncluded
			|| r_FirstIndexIncluded == Index)
		{
			CalculationStartIndex = r_FirstIndexIncluded;
			ResetCalculation = true;
		}

		r_PriorFirstIndexIncluded = r_FirstIndexIncluded;

		bool TempResetCalculation = ResetCalculation;
		for (int AvgIndex = CalculationStartIndex; AvgIndex <= Index; ++AvgIndex)
		{
			if (TempResetCalculation)
			{
				TempResetCalculation = false;
				Array_PriceTimesVolumeArray[AvgIndex] = Array_BarSumPriceTimesVolume[AvgIndex];
				Subgraph_CumulativeVolumeForPeriodArray[AvgIndex] = sc.Volume[AvgIndex];
			}
			else
			{

				Array_PriceTimesVolumeArray[AvgIndex] = Array_PriceTimesVolumeArray[AvgIndex - 1] + Array_BarSumPriceTimesVolume[AvgIndex];
				Subgraph_CumulativeVolumeForPeriodArray[AvgIndex] = Subgraph_CumulativeVolumeForPeriodArray[AvgIndex - 1] + sc.Volume[AvgIndex];
			}

			if (Subgraph_CumulativeVolumeForPeriodArray[AvgIndex] != 0)
				Subgraph_BackgroundVWAPForCurrentPeriod[AvgIndex] = Array_PriceTimesVolumeArray[AvgIndex] / Subgraph_CumulativeVolumeForPeriodArray[AvgIndex];
			else
				Subgraph_BackgroundVWAPForCurrentPeriod[AvgIndex] = 0;
		}


		if (Subgraph_CumulativeVolumeForPeriodArray[Index] != 0)
			Subgraph_VWAPSubgraph[Index] = Array_PriceTimesVolumeArray[Index] / Subgraph_CumulativeVolumeForPeriodArray[Index];


		if (Input_BandCalculationMethod.GetIndex() == 1)//Fixed offset
		{
			Subgraph_BandDistance[Index] = 1.0f;
		}
		else if (Input_BandCalculationMethod.GetIndex() == 0)//VWAP variance
		{
			for (int BarIndex = CalculationStartIndex; BarIndex <= Index; ++BarIndex)
			{
				Subgraph_PriceVWAPDifferenceSquaredTimesVolume[BarIndex] =
					(sc.BaseDataIn[Input_InputData.GetInputDataIndex()][BarIndex] - Subgraph_BackgroundVWAPForCurrentPeriod[BarIndex])
					* (sc.BaseDataIn[Input_InputData.GetInputDataIndex()][BarIndex] - Subgraph_BackgroundVWAPForCurrentPeriod[BarIndex])
					* sc.Volume[BarIndex];

				if (ResetCalculation)
				{
					ResetCalculation = false;
					Subgraph_BarSumPriceVWAPDifferenceSquaredTimesVolumeArray[BarIndex] = Subgraph_PriceVWAPDifferenceSquaredTimesVolume[BarIndex];
				}
				else
				{
					Subgraph_BarSumPriceVWAPDifferenceSquaredTimesVolumeArray[BarIndex] = Subgraph_BarSumPriceVWAPDifferenceSquaredTimesVolumeArray[BarIndex - 1] + Subgraph_PriceVWAPDifferenceSquaredTimesVolume[BarIndex];

				}

				//float CheckValue1 = BarSumPriceVWAPDifferenceSquaredTimesVolumeArray[BarIndex];
				//float CheckValue2 = PriceVWAPDifferenceSquaredTimesVolume[BarIndex];
				//float CheckValue3 = 0;
			}

			if (Subgraph_CumulativeVolumeForPeriodArray[Index] != 0)
			{
				Subgraph_BandDistance[Index] = (float)sqrt(Subgraph_BarSumPriceVWAPDifferenceSquaredTimesVolumeArray[Index] / Subgraph_CumulativeVolumeForPeriodArray[Index]);
			}
			else
				Subgraph_BandDistance[Index] = 1.0f;

		}
		else if (Input_BandCalculationMethod.GetIndex() == 2) //Standard deviation
		{
			sc.StdDeviation(Subgraph_VWAPSubgraph, Array_StandardDeviationArray, Index, Index - r_FirstIndexIncluded + 1);
			Subgraph_BandDistance[Index] = Array_StandardDeviationArray[Index];
		}
		else //Percentage
		{
			Subgraph_BandDistance[Index] = Subgraph_VWAPSubgraph[Index] / 100.0f;
		}

		Subgraph_SD1Top[Index] = Subgraph_VWAPSubgraph[Index] + Input_Band1OffsetMultiplier.GetFloat() * Subgraph_BandDistance[Index];
		Subgraph_SD1Bottom[Index] = Subgraph_VWAPSubgraph[Index] - Input_Band1OffsetMultiplier.GetFloat() * Subgraph_BandDistance[Index];

		Subgraph_SD2Top[Index] = Subgraph_VWAPSubgraph[Index] + Input_Band2OffsetMultiplier.GetFloat() * Subgraph_BandDistance[Index];
		Subgraph_SD2Bottom[Index] = Subgraph_VWAPSubgraph[Index] - Input_Band2OffsetMultiplier.GetFloat() * Subgraph_BandDistance[Index];

		Subgraph_SD3Top[Index] = Subgraph_VWAPSubgraph[Index] + Input_Band3OffsetMultiplier.GetFloat() * Subgraph_BandDistance[Index];
		Subgraph_SD3Bottom[Index] = Subgraph_VWAPSubgraph[Index] - Input_Band3OffsetMultiplier.GetFloat() * Subgraph_BandDistance[Index];

		Subgraph_SD4Top[Index] = Subgraph_VWAPSubgraph[Index] + Input_Band4OffsetMultiplier.GetFloat() * Subgraph_BandDistance[Index];
		Subgraph_SD4Bottom[Index] = Subgraph_VWAPSubgraph[Index] - Input_Band4OffsetMultiplier.GetFloat() * Subgraph_BandDistance[Index];
	}
}

/*============================================================================*/
SCSFExport scsf_RollingHighAccuracyMovingAverage(SCStudyInterfaceRef sc)
{
	SCSubgraphRef   Subgraph_MovingAverage = sc.Subgraph[0];
	SCFloatArrayRef Array_PriceSum = Subgraph_MovingAverage.Arrays[0];
	SCFloatArrayRef Array_PriceCount = Subgraph_MovingAverage.Arrays[1];
	SCFloatArrayRef Array_StandardDeviation = Subgraph_MovingAverage.Arrays[2];

	SCSubgraphRef   Subgraph_SD1Top    = sc.Subgraph[1];
	SCSubgraphRef   Subgraph_SD1Bottom = sc.Subgraph[2];
	SCSubgraphRef   Subgraph_SD2Top    = sc.Subgraph[3];
	SCSubgraphRef   Subgraph_SD2Bottom = sc.Subgraph[4];
	SCSubgraphRef   Subgraph_SD3Top    = sc.Subgraph[5];
	SCSubgraphRef   Subgraph_SD3Bottom = sc.Subgraph[6];
	SCSubgraphRef   Subgraph_SD4Top    = sc.Subgraph[7];
	SCSubgraphRef   Subgraph_SD4Bottom = sc.Subgraph[8];

	SCInputRef Input_InputData              = sc.Input[0];
	SCInputRef Input_BandCalculationMethod  = sc.Input[1];
	SCInputRef Input_MinimumRequiredTimePeriodAsPercentForSkipDays = sc.Input[2];
	SCInputRef Input_TimePeriodType         = sc.Input[3];	
	SCInputRef Input_TimePeriodLength       = sc.Input[4];	
	SCInputRef Input_Version                = sc.Input[5];	
	SCInputRef Input_NumberOfDaysToCalculate  = sc.Input[7];
	SCInputRef Input_BaseOnUnderlyingData   = sc.Input[8];
	SCInputRef Input_Band1OffsetMultiplier  = sc.Input[9];
	SCInputRef Input_Band2OffsetMultiplier  = sc.Input[10];
	SCInputRef Input_Band3OffsetMultiplier  = sc.Input[11];
	SCInputRef Input_Band4OffsetMultiplier  = sc.Input[12];
	SCInputRef Input_ExcludeWeekendInDateCalc = sc.Input[13];


	if(sc.SetDefaults)
	{
		sc.GraphName = "Moving Average - Rolling High Accuracy";
		sc.GraphRegion = 0;
		sc.ValueFormat = VALUEFORMAT_INHERITED;
		sc.AutoLoop = 0;//Manual looping
		sc.MaintainVolumeAtPriceData = 1;

		Subgraph_MovingAverage.Name = "Moving Average";
		Subgraph_MovingAverage.DrawStyle = DRAWSTYLE_LINE;
		Subgraph_MovingAverage.LineWidth = 2;
		Subgraph_MovingAverage.PrimaryColor = RGB(237, 13, 255);
		Subgraph_MovingAverage.DrawZeros = false;
		
		Subgraph_SD1Top.Name = "Top Band 1";
		Subgraph_SD1Top.DrawStyle = DRAWSTYLE_DASH;
		Subgraph_SD1Top.LineWidth = 2;
		Subgraph_SD1Top.PrimaryColor = RGB (192, 192, 192);
		Subgraph_SD1Top.DrawZeros = false;

		Subgraph_SD1Bottom.Name = "Bottom Band 1";
		Subgraph_SD1Bottom.DrawStyle = DRAWSTYLE_DASH;
		Subgraph_SD1Bottom.LineWidth = 2;
		Subgraph_SD1Bottom.PrimaryColor = RGB (192, 192, 192);
		Subgraph_SD1Bottom.DrawZeros = false;

		Subgraph_SD2Top.Name = "Top Band 2";
		Subgraph_SD2Top.DrawStyle = DRAWSTYLE_IGNORE;
		Subgraph_SD2Top.LineWidth = 2;
		Subgraph_SD2Top.PrimaryColor = RGB (192, 192, 192);
		Subgraph_SD2Top.DrawZeros = false;

		Subgraph_SD2Bottom.Name = "Bottom Band 2";
		Subgraph_SD2Bottom.DrawStyle = DRAWSTYLE_IGNORE;
		Subgraph_SD2Bottom.LineWidth = 2;
		Subgraph_SD2Bottom.PrimaryColor = RGB (192, 192, 192);
		Subgraph_SD2Bottom.DrawZeros = false;

		Subgraph_SD3Top.Name = "Top Band 3";
		Subgraph_SD3Top.DrawStyle = DRAWSTYLE_IGNORE;
		Subgraph_SD3Top.LineWidth = 2;
		Subgraph_SD3Top.PrimaryColor = RGB (192, 192, 192);
		Subgraph_SD3Top.DrawZeros = false;

		Subgraph_SD3Bottom.Name = "Bottom Band 3";
		Subgraph_SD3Bottom.DrawStyle = DRAWSTYLE_IGNORE;
		Subgraph_SD3Bottom.LineWidth = 2;
		Subgraph_SD3Bottom.PrimaryColor = RGB (192, 192, 192);
		Subgraph_SD3Bottom.DrawZeros = false;

		Subgraph_SD4Top.Name = "Top Band 4";
		Subgraph_SD4Top.DrawStyle = DRAWSTYLE_IGNORE;
		Subgraph_SD4Top.LineWidth = 2;
		Subgraph_SD4Top.PrimaryColor = RGB (192, 192, 192);
		Subgraph_SD4Top.DrawZeros = false;

		Subgraph_SD4Bottom.Name = "Bottom Band 4";
		Subgraph_SD4Bottom.DrawStyle = DRAWSTYLE_IGNORE;
		Subgraph_SD4Bottom.LineWidth = 2;
		Subgraph_SD4Bottom.PrimaryColor = RGB (192, 192, 192);
		Subgraph_SD4Bottom.DrawZeros = false;

		int DisplayOrder = 1;

		Input_InputData.Name = "Input Data";
		Input_InputData.SetCustomInputStrings("Price;Volume;Number of Trades;AskVolume-BidVolume");
		Input_InputData.SetCustomInputIndex(0);
		Input_InputData.DisplayOrder = DisplayOrder++;

		Input_TimePeriodType.Name = "Time Period Type";
		Input_TimePeriodType.SetCustomInputStrings("Days - Trading Days;Days - 24 Hour Period;Minutes;Bars");
		Input_TimePeriodType.SetCustomInputIndex(0);
		Input_TimePeriodType.DisplayOrder = DisplayOrder++;

		Input_TimePeriodLength.Name = "Time Period Length";
		Input_TimePeriodLength.SetInt(1);
		Input_TimePeriodLength.DisplayOrder = DisplayOrder++;

		Input_NumberOfDaysToCalculate.Name = "Number of Days to Calculate";
		Input_NumberOfDaysToCalculate.SetInt(10);
		Input_NumberOfDaysToCalculate.DisplayOrder = DisplayOrder++;

		Input_ExcludeWeekendInDateCalc.Name = "Exclude Weekends In Date Look Back";
		Input_ExcludeWeekendInDateCalc.SetYesNo(1);
		Input_ExcludeWeekendInDateCalc.DisplayOrder = DisplayOrder++;

		Input_MinimumRequiredTimePeriodAsPercentForSkipDays.Name = "Minimum Required Time Period as Percent for Skip Days";
		Input_MinimumRequiredTimePeriodAsPercentForSkipDays.SetInt(25);
		Input_MinimumRequiredTimePeriodAsPercentForSkipDays.DisplayOrder = DisplayOrder++;

		Input_BandCalculationMethod.Name = "Std. Deviation Band Calculation Method";
		Input_BandCalculationMethod.SetCustomInputStrings("Standard Deviation;Fixed Offset");
		Input_BandCalculationMethod.SetCustomInputIndex(1);
		Input_BandCalculationMethod.DisplayOrder = DisplayOrder++;

		Input_Band1OffsetMultiplier.Name = "Band 1 Std. Deviation Multiplier/Fixed Offset";
		Input_Band1OffsetMultiplier.SetFloat(0.5);
		Input_Band1OffsetMultiplier.DisplayOrder = DisplayOrder++;

		Input_Band2OffsetMultiplier.Name = "Band 2 Std. Deviation Multiplier/Fixed Offset";
		Input_Band2OffsetMultiplier.SetFloat(1.0);
		Input_Band2OffsetMultiplier.DisplayOrder = DisplayOrder++;

		Input_Band3OffsetMultiplier.Name = "Band 3 Std. Deviation Multiplier/Fixed Offset";
		Input_Band3OffsetMultiplier.SetFloat(1.5);
		Input_Band3OffsetMultiplier.DisplayOrder = DisplayOrder++;

		Input_Band4OffsetMultiplier.Name = "Band 4 Std. Deviation Multiplier/Fixed Offset";
		Input_Band4OffsetMultiplier.SetFloat(2.0);
		Input_Band4OffsetMultiplier.DisplayOrder = DisplayOrder++;

		Input_Version.SetInt(2);

		

		return;
	}

	if(Input_Version.GetInt() < 2)
	{
		Input_Version.SetInt(2);
		Input_InputData.SetCustomInputIndex(0);
	}

	if ((int)sc.VolumeAtPriceForBars->GetNumberOfBars() < sc.ArraySize)
		return;

	if (Input_NumberOfDaysToCalculate.GetInt() == 0)
		Input_NumberOfDaysToCalculate.SetInt(10);


	// calculate the period start index
	int PeriodType = Input_TimePeriodType.GetIndex();

	if (PeriodType == 0 || PeriodType == 1)
	{
		int DaysRequired = Input_TimePeriodLength.GetInt();

		if (Input_NumberOfDaysToCalculate.GetInt() < DaysRequired)
			Input_NumberOfDaysToCalculate.SetInt(DaysRequired);
	}


	int& LastIndexProcessed = sc.GetPersistentInt(1);
	int& FirstIndexIncluded = sc.GetPersistentInt(2);
	int& LastExcludedIndex = sc.GetPersistentInt(3);


	if (sc.IsFullRecalculation)//reset
	{
		LastIndexProcessed = -1;
		FirstIndexIncluded = 0;
		LastExcludedIndex = -1;


		if (sc.MaintainVolumeAtPriceData == 0)
		{
			sc.MaintainVolumeAtPriceData = 1;
			sc.FlagToReloadChartData = 1;
		}

	}

	for (int Index = sc.UpdateStartIndex; Index < sc.ArraySize; ++Index)
	{
		bool NewBar = Index != LastIndexProcessed;

		LastIndexProcessed = Index;

		SCDateTime TradingDayDateForBar = sc.GetTradingDayDate( sc.BaseDateTimeIn[Index]);
		SCDateTime TradingDayDateForLastBar = sc.GetTradingDayDate( sc.BaseDateTimeIn[sc.ArraySize - 1]);

		if ((TradingDayDateForLastBar.GetDate() - TradingDayDateForBar.GetDate() + 1)
	> Input_NumberOfDaysToCalculate.GetInt())
		{
			LastExcludedIndex = Index;
			continue;
		}

		Array_PriceSum[Index] = 0;
		Array_PriceCount[Index] = 0;

		// calculate bar summation

		const s_VolumeAtPriceV2* p_VolumeAtPrice = NULL;

		int NumVAPElementsAtBarIndex = sc.VolumeAtPriceForBars->GetSizeAtBarIndex(Index);
		for (int VAPIndex = 0; VAPIndex < NumVAPElementsAtBarIndex; VAPIndex++)
		{
			sc.VolumeAtPriceForBars->GetVAPElementAtIndex(Index, VAPIndex, &p_VolumeAtPrice);

			int InputDataIndex = Input_InputData.GetIndex();
			if (InputDataIndex == 0)
			{
				float Price = p_VolumeAtPrice->PriceInTicks * sc.TickSize;
				float PriceTimeTrades = Price * p_VolumeAtPrice->NumberOfTrades;

				Array_PriceSum[Index] += PriceTimeTrades;
				Array_PriceCount[Index] += p_VolumeAtPrice->NumberOfTrades;
			}
			else if (InputDataIndex == 1)
			{
				Array_PriceSum[Index] += p_VolumeAtPrice->Volume;
				Array_PriceCount[Index] += 1;

			}
			else if (InputDataIndex == 2)
			{
				Array_PriceSum[Index] += p_VolumeAtPrice->NumberOfTrades;
				Array_PriceCount[Index] += 1;
			}
			else if (InputDataIndex == 3)
			{
				Array_PriceSum[Index] += labs(p_VolumeAtPrice->AskVolume - p_VolumeAtPrice->BidVolume);
				Array_PriceCount[Index] += 1;
			}
		}

		if (NewBar)
		{

			if (PeriodType == 0)  // Days - trading days
			{
				int TradeDate = sc.GetTradingDayDate(sc.BaseDateTimeIn[Index]);

				SCDateTime CurrentDayStartDateTime = sc.GetStartDateTimeForTradingDate(TradeDate);
				FirstIndexIncluded = sc.GetContainingIndexForSCDateTime(sc.ChartNumber, CurrentDayStartDateTime);

				GetIndexForStartofDayPeriodForDaysBack
					( sc
					, CurrentDayStartDateTime
					, Input_TimePeriodLength.GetInt()
					, Input_ExcludeWeekendInDateCalc.GetYesNo() != 0
					, Input_MinimumRequiredTimePeriodAsPercentForSkipDays.GetInt()
					, FirstIndexIncluded
					);
			}
			else if (PeriodType == 1)  // Days - 24 hour periods
			{
				SCDateTime CurrentPeriodStartDateTime = sc.BaseDateTimeIn[Index] - 1*DAYS + 1*SECONDS;
				FirstIndexIncluded = sc.GetContainingIndexForSCDateTime(sc.ChartNumber, CurrentPeriodStartDateTime);

				GetIndexForStartofDayPeriodForDaysBack
					( sc
					, CurrentPeriodStartDateTime
					, Input_TimePeriodLength.GetInt()
					, Input_ExcludeWeekendInDateCalc.GetYesNo() != 0
					, Input_MinimumRequiredTimePeriodAsPercentForSkipDays.GetInt()
					, FirstIndexIncluded
					);
			}
			else if (PeriodType == 2)  // Minutes
			{
				SCDateTime RollingStartDateTime = 0;

				if (sc.AreTimeSpecificBars() && sc.SecondsPerBar != 0)
				{
					RollingStartDateTime  = sc.BaseDateTimeIn[Index] + (sc.SecondsPerBar - 1) * SECONDS;
					RollingStartDateTime -= Input_TimePeriodLength.GetInt() * MINUTES;
				}
				else
				{
					if (Index == sc.ArraySize - 1)
						RollingStartDateTime = sc.LatestDateTimeForLastBar;
					else
						RollingStartDateTime = sc.BaseDateTimeIn[Index+1] - 1*SECONDS;

					RollingStartDateTime -= Input_TimePeriodLength.GetInt() * MINUTES;
				}

				for (; FirstIndexIncluded <= Index; ++FirstIndexIncluded)
				{
					if (sc.BaseDateTimeIn[FirstIndexIncluded] < RollingStartDateTime)
						continue;

					break;
				}
			}
			else  // Bars
			{
				FirstIndexIncluded = max(0, Index - Input_TimePeriodLength.GetInt()+1);
			}


		}

		if (FirstIndexIncluded <= LastExcludedIndex)
			FirstIndexIncluded = LastExcludedIndex + 1;


		// calculate average
		double CumulativePriceSum = 0;
		double CumulativePriceCount = 0;

		for (int AvgIndex=FirstIndexIncluded; AvgIndex <= Index; ++AvgIndex)
		{
			CumulativePriceSum += Array_PriceSum[AvgIndex];
			CumulativePriceCount += Array_PriceCount[AvgIndex];
		}

		if (CumulativePriceCount != 0)
			Subgraph_MovingAverage[Index] = (float)(CumulativePriceSum / CumulativePriceCount);
		else
			Subgraph_MovingAverage[Index] = Subgraph_MovingAverage[Index - 1];


		float BandDistance = 1.0f;
		
		//Standard deviation
		if (Input_BandCalculationMethod.GetInt() == 0)
		{
			const int StandardDeviationLength = Index - FirstIndexIncluded + 1;
			if (Index - StandardDeviationLength + 1 > LastExcludedIndex)
			{
				sc.StdDeviation(Subgraph_MovingAverage, Array_StandardDeviation, Index, StandardDeviationLength);
				BandDistance = Array_StandardDeviation[Index];
			}
		}


		Subgraph_SD1Top[Index]    = Subgraph_MovingAverage[Index] + Input_Band1OffsetMultiplier.GetFloat() * BandDistance;
		Subgraph_SD1Bottom[Index] = Subgraph_MovingAverage[Index] - Input_Band1OffsetMultiplier.GetFloat() * BandDistance;

		Subgraph_SD2Top[Index]    = Subgraph_MovingAverage[Index] + Input_Band2OffsetMultiplier.GetFloat() * BandDistance;
		Subgraph_SD2Bottom[Index] = Subgraph_MovingAverage[Index] - Input_Band2OffsetMultiplier.GetFloat() * BandDistance;

		Subgraph_SD3Top[Index]    = Subgraph_MovingAverage[Index] + Input_Band3OffsetMultiplier.GetFloat() * BandDistance;
		Subgraph_SD3Bottom[Index] = Subgraph_MovingAverage[Index] - Input_Band3OffsetMultiplier.GetFloat() * BandDistance;

		Subgraph_SD4Top[Index]    = Subgraph_MovingAverage[Index] + Input_Band4OffsetMultiplier.GetFloat() * BandDistance;
		Subgraph_SD4Bottom[Index] = Subgraph_MovingAverage[Index] - Input_Band4OffsetMultiplier.GetFloat() * BandDistance;
	}
}

/*============================================================================*/

SCSFExport scsf_TrueBarAverage(SCStudyInterfaceRef sc)
{
	SCSubgraphRef   Subgraph_Average = sc.Subgraph[0];

	if(sc.SetDefaults)
	{
		sc.ScaleRangeType = SCALE_SAMEASREGION;

		sc.GraphName = "True Bar Average";
		sc.GraphRegion = 0;
		sc.ValueFormat = VALUEFORMAT_INHERITED;
		sc.AutoLoop = 1;
		sc.MaintainVolumeAtPriceData = 1;

		Subgraph_Average.Name = "Average";
		Subgraph_Average.DrawStyle = DRAWSTYLE_LINE;
		Subgraph_Average.LineWidth = 2;
		Subgraph_Average.PrimaryColor = RGB(237, 13, 255);
		Subgraph_Average.DrawZeros = false;


		

		return;
	}


	int PriceCount = 0;
	float Sum = 0.0;

	const s_VolumeAtPriceV2 *p_VolumeAtPrice = NULL;

	int NumVAPElementsAtBarIndex = sc.VolumeAtPriceForBars->GetSizeAtBarIndex(sc.Index);
	for (int VAPIndex = 0; VAPIndex < NumVAPElementsAtBarIndex; VAPIndex++)
	{
		sc.VolumeAtPriceForBars->GetVAPElementAtIndex(sc.Index, VAPIndex, &p_VolumeAtPrice);

		Sum += p_VolumeAtPrice->PriceInTicks * sc.TickSize;
		++PriceCount;
	}

	if (PriceCount != 0)
		Subgraph_Average[sc.Index] = Sum / PriceCount;		 

}

/*============================================================================*/
SCSFExport scsf_MovingLinearRegressionLine(SCStudyInterfaceRef sc)
{
	SCSubgraphRef Subgraph_MLR = sc.Subgraph[0];

	SCInputRef Input_InputData = sc.Input[0];
	SCInputRef Input_Length = sc.Input[2];

	if(sc.SetDefaults)
	{
		sc.GraphName = "Moving Linear Regression";

		sc.GraphRegion = 0;
		sc.ValueFormat = 3;  
		sc.AutoLoop = 1;

		Subgraph_MLR.Name = "MLR";
		Subgraph_MLR.DrawStyle = DRAWSTYLE_LINE;
		Subgraph_MLR.PrimaryColor = RGB(0,255,0);
		Subgraph_MLR.DrawZeros = false;
		
		Input_InputData.Name = "Input Data";
		Input_InputData.SetInputDataIndex(SC_LAST); 
		
		Input_Length.Name     = "Length";
		Input_Length.SetInt(14);
		Input_Length.SetIntLimits(1, MAX_STUDY_LENGTH);


		
		

		return;
	}

	sc.DataStartIndex = Input_Length.GetInt()-1;	
	
	sc.LinearRegressionIndicator(sc.BaseDataIn[Input_InputData.GetInputDataIndex()], Subgraph_MLR,  Input_Length.GetInt());		
}
/*============================================================================*/

SCSFExport scsf_MACD(SCStudyInterfaceRef sc)
{
	SCSubgraphRef Subgraph_MACD			= sc.Subgraph[0];
	SCSubgraphRef Subgraph_MovAvgOfMACD	= sc.Subgraph[1];
	SCSubgraphRef Subgraph_MACDDiff		= sc.Subgraph[2];
	SCSubgraphRef Subgraph_RefLine		= sc.Subgraph[3];

	SCInputRef Input_InputData				= sc.Input[0];
	SCInputRef Input_FastLength				= sc.Input[3];
	SCInputRef Input_SlowLength				= sc.Input[4];
	SCInputRef Input_MACDLength				= sc.Input[5];
	SCInputRef Input_MovingAverageType		= sc.Input[6];


	if(sc.SetDefaults)
	{
		sc.GraphName = "MACD";
		sc.AutoLoop					= 1;

		sc.GraphRegion				= 1;
		sc.ValueFormat				= 3;
		
		Subgraph_MACD.Name = "MACD";
		Subgraph_MACD.DrawStyle = DRAWSTYLE_LINE;
		Subgraph_MACD.DrawZeros = true;
		Subgraph_MACD.PrimaryColor = RGB(0,255,0);

		Subgraph_MovAvgOfMACD.Name	= "MA of MACD";
		Subgraph_MovAvgOfMACD.DrawStyle = DRAWSTYLE_LINE;
		Subgraph_MovAvgOfMACD.DrawZeros = true;
		Subgraph_MovAvgOfMACD.PrimaryColor = RGB(255,0,255);

		Subgraph_MACDDiff.Name = "MACD Diff";
		Subgraph_MACDDiff.DrawStyle = DRAWSTYLE_BAR;
		Subgraph_MACDDiff.DrawZeros = true;
		Subgraph_MACDDiff.PrimaryColor = RGB(255,255,0);

		Subgraph_RefLine.Name = "Line";
		Subgraph_RefLine.DrawStyle = DRAWSTYLE_LINE;
		Subgraph_RefLine.DrawZeros = true;
		Subgraph_RefLine.PrimaryColor = RGB(255,127,0);

		Input_InputData.Name = "Input Data";
		Input_InputData.SetInputDataIndex(SC_LAST); 

		Input_FastLength.Name ="Fast Moving Average Length";
		Input_FastLength.SetInt(12);  
		Input_FastLength.SetIntLimits(1,MAX_STUDY_LENGTH);

		Input_SlowLength.Name = "Slow Moving Average Length";
		Input_SlowLength.SetInt(26);  
		Input_SlowLength.SetIntLimits(1,MAX_STUDY_LENGTH);

		Input_MACDLength.Name = "MACD Moving Average Length";
		Input_MACDLength.SetInt(9);   
		Input_MACDLength.SetIntLimits(1,MAX_STUDY_LENGTH);

		Input_MovingAverageType.Name = "Moving Average Type";
		Input_MovingAverageType.SetMovAvgType(MOVAVGTYPE_EXPONENTIAL);

		return;
	}

	if (Input_MovingAverageType.GetMovAvgType()==MOVAVGTYPE_EXPONENTIAL)
		sc.DataStartIndex = 2;
	else
		sc.DataStartIndex = Input_MACDLength.GetInt() + max(Input_FastLength.GetInt(), Input_SlowLength.GetInt());

	sc.MACD(sc.BaseDataIn[Input_InputData.GetInputDataIndex()], Subgraph_MACD, sc.Index, Input_FastLength.GetInt(), Input_SlowLength.GetInt(), Input_MACDLength.GetInt(), Input_MovingAverageType.GetInt()); 

	Subgraph_MovAvgOfMACD[sc.Index]	= Subgraph_MACD.Arrays[2][sc.Index];
	Subgraph_MACDDiff[sc.Index]	= Subgraph_MACD.Arrays[3][sc.Index];
	Subgraph_RefLine[sc.Index]	= 0;	
}


/*============================================================================*/

SCSFExport scsf_3_10_Oscillator(SCStudyInterfaceRef sc)
{
	SCSubgraphRef Subgraph_MACD = sc.Subgraph[0];
	SCSubgraphRef Subgraph_MovAvgOfMACD = sc.Subgraph[1];
	SCSubgraphRef Subgraph_MACDDiff = sc.Subgraph[2];
	SCSubgraphRef Subgraph_RefLine = sc.Subgraph[3];

	SCInputRef Input_InputData = sc.Input[0];
	SCInputRef Input_FastLength = sc.Input[1];
	SCInputRef Input_SlowLength = sc.Input[2];
	SCInputRef Input_MACDLength = sc.Input[3];


	if (sc.SetDefaults)
	{
		sc.GraphName = "3/10 Oscillator";
		sc.AutoLoop = 1;

		sc.GraphRegion = 1;
		sc.ValueFormat = 3;

		Subgraph_MACD.Name = "3/10";
		Subgraph_MACD.DrawStyle = DRAWSTYLE_LINE;
		Subgraph_MACD.DrawZeros = true;
		Subgraph_MACD.PrimaryColor = RGB(0, 255, 0);

		Subgraph_MovAvgOfMACD.Name = "Mov Avg 3/10";
		Subgraph_MovAvgOfMACD.DrawStyle = DRAWSTYLE_LINE;
		Subgraph_MovAvgOfMACD.DrawZeros = true;
		Subgraph_MovAvgOfMACD.PrimaryColor = RGB(255, 0, 255);

		Subgraph_MACDDiff.Name = "3/10 Diff";
		Subgraph_MACDDiff.DrawStyle = DRAWSTYLE_BAR;
		Subgraph_MACDDiff.DrawZeros = true;
		Subgraph_MACDDiff.PrimaryColor = RGB(255, 255, 0);

		Subgraph_RefLine.Name = "Line";
		Subgraph_RefLine.DrawStyle = DRAWSTYLE_LINE;
		Subgraph_RefLine.DrawZeros = true;
		Subgraph_RefLine.PrimaryColor = RGB(255, 127, 0);

		Input_InputData.Name = "Input Data";
		Input_InputData.SetInputDataIndex(SC_LAST);

		Input_FastLength.Name = "Fast Moving Average Length";
		Input_FastLength.SetInt(3);
		Input_FastLength.SetIntLimits(1, MAX_STUDY_LENGTH);

		Input_SlowLength.Name = "Slow Moving Average Length";
		Input_SlowLength.SetInt(10);
		Input_SlowLength.SetIntLimits(1, MAX_STUDY_LENGTH);

		Input_MACDLength.Name = "3/10 Moving Average Length";
		Input_MACDLength.SetInt(16);
		Input_MACDLength.SetIntLimits(1, MAX_STUDY_LENGTH);
		
		return;
	}

	sc.DataStartIndex = Input_MACDLength.GetInt() + max(Input_FastLength.GetInt(), Input_SlowLength.GetInt());

	sc.MACD(sc.BaseDataIn[Input_InputData.GetInputDataIndex()], Subgraph_MACD, sc.Index, Input_FastLength.GetInt(), Input_SlowLength.GetInt(), Input_MACDLength.GetInt(), MOVAVGTYPE_SIMPLE);

	Subgraph_MovAvgOfMACD[sc.Index] = Subgraph_MACD.Arrays[2][sc.Index];
	Subgraph_MACDDiff[sc.Index] = Subgraph_MACD.Arrays[3][sc.Index];
	Subgraph_RefLine[sc.Index] = 0;
}

/*============================================================================*/

SCSFExport scsf_MACDLeader(SCStudyInterfaceRef sc)
{
	SCSubgraphRef Subgraph_MACD = sc.Subgraph[0];
	SCFloatArrayRef Array_FastExponential = sc.Subgraph[0].Arrays[0];
	SCFloatArrayRef Array_SlowExponential = sc.Subgraph[0].Arrays[1];
	SCFloatArrayRef  Array_InputDataMinusFastAverage = sc.Subgraph[0].Arrays[2];
	SCFloatArrayRef  Array_InputDataMinusSlowAverage = sc.Subgraph[0].Arrays[3];

	SCFloatArrayRef  Array_AvgInputDataMinusFastAverage = sc.Subgraph[0].Arrays[4];
	SCFloatArrayRef  Array_AvgInputDataMinusSlowAverage = sc.Subgraph[0].Arrays[5];

	SCSubgraphRef Subgraph_MovAvgOfMACD = sc.Subgraph[1];
	SCSubgraphRef Subgraph_MACDLeader = sc.Subgraph[2];
	SCSubgraphRef Subgraph_RefLine = sc.Subgraph[3];

	SCInputRef Input_InputData = sc.Input[0];
	SCInputRef Input_FastLength = sc.Input[1];
	SCInputRef Input_SlowLength = sc.Input[2];
	SCInputRef Input_MACDMovingAverageLength = sc.Input[3];
	SCInputRef Input_MovingAverageType = sc.Input[4];
	SCInputRef Input_MACDMovingAverageType = sc.Input[5];


	if (sc.SetDefaults)
	{
		sc.GraphName = "MACD Leader";
		sc.AutoLoop = 1;

		sc.GraphRegion = 1;
		sc.ValueFormat = 3;

		Subgraph_MACD.Name = "MACD";
		Subgraph_MACD.DrawStyle = DRAWSTYLE_LINE;
		Subgraph_MACD.DrawZeros = true;
		Subgraph_MACD.PrimaryColor = RGB(0, 255, 0);

		Subgraph_MovAvgOfMACD.Name = "MA of MACD";
		Subgraph_MovAvgOfMACD.DrawStyle = DRAWSTYLE_LINE;
		Subgraph_MovAvgOfMACD.DrawZeros = true;
		Subgraph_MovAvgOfMACD.PrimaryColor = RGB(255, 0, 255);

		Subgraph_MACDLeader.Name = "MACD Leader";
		Subgraph_MACDLeader.DrawStyle = DRAWSTYLE_LINE;
		Subgraph_MACDLeader.LineWidth = 2;
		Subgraph_MACDLeader.DrawZeros = true;
		Subgraph_MACDLeader.PrimaryColor = RGB(255, 128, 0);

		Subgraph_RefLine.Name = "Line";
		Subgraph_RefLine.DrawStyle = DRAWSTYLE_LINE;
		Subgraph_RefLine.DrawZeros = true;
		Subgraph_RefLine.PrimaryColor = RGB(255, 127, 0);

		Input_InputData.Name = "Input Data";
		Input_InputData.SetInputDataIndex(SC_LAST);

		Input_FastLength.Name = "Fast Moving Average Length";
		Input_FastLength.SetInt(12);
		Input_FastLength.SetIntLimits(1, MAX_STUDY_LENGTH);

		Input_SlowLength.Name = "Slow Moving Average Length";
		Input_SlowLength.SetInt(26);
		Input_SlowLength.SetIntLimits(1, MAX_STUDY_LENGTH);

		Input_MACDMovingAverageLength.Name = "MACD Moving Average Length";
		Input_MACDMovingAverageLength.SetInt(9);
		Input_MACDMovingAverageLength.SetIntLimits(1, MAX_STUDY_LENGTH);

		Input_MovingAverageType.Name = "Moving Average Type";
		Input_MovingAverageType.SetMovAvgType(MOVAVGTYPE_EXPONENTIAL);

		Input_MACDMovingAverageType.Name = "MACD Moving Average Type";
		Input_MACDMovingAverageType.SetMovAvgType(MOVAVGTYPE_SIMPLE);

		return;
	}

	sc.DataStartIndex = Input_MACDMovingAverageLength.GetInt() + max(Input_FastLength.GetInt(), Input_SlowLength.GetInt());

	int InputData = Input_InputData.GetInputDataIndex();
	sc.MovingAverage(sc.BaseDataIn[InputData], Array_FastExponential, Input_MovingAverageType.GetInt(), Input_FastLength.GetInt() );
	sc.MovingAverage(sc.BaseDataIn[InputData], Array_SlowExponential, Input_MovingAverageType.GetInt(), Input_SlowLength.GetInt());

	Subgraph_MACD[sc.Index] = Array_FastExponential[sc.Index] - Array_SlowExponential[sc.Index];

	sc.MovingAverage(Subgraph_MACD, Subgraph_MovAvgOfMACD, Input_MACDMovingAverageType.GetInt(), Input_MACDMovingAverageLength.GetInt());

	Array_InputDataMinusFastAverage[sc.Index] = sc.BaseDataIn[InputData][sc.Index] - Array_FastExponential[sc.Index];

	Array_InputDataMinusSlowAverage[sc.Index] = sc.BaseDataIn[InputData][sc.Index] - Array_SlowExponential[sc.Index];

	sc.MovingAverage(Array_InputDataMinusFastAverage, Array_AvgInputDataMinusFastAverage, Input_MovingAverageType.GetInt(), Input_FastLength.GetInt());
	sc.MovingAverage(Array_InputDataMinusSlowAverage, Array_AvgInputDataMinusSlowAverage, Input_MovingAverageType.GetInt(), Input_SlowLength.GetInt());

	Subgraph_MACDLeader[sc.Index] = Subgraph_MACD[sc.Index] + Array_AvgInputDataMinusFastAverage[sc.Index] - Array_AvgInputDataMinusSlowAverage[sc.Index];

	Subgraph_RefLine[sc.Index] = 0;
}

/*============================================================================*/

SCSFExport scsf_StandardErrorBands(SCStudyInterfaceRef sc)
{
	SCSubgraphRef Subgraph_UpperBand = sc.Subgraph[0];
	SCSubgraphRef Subgraph_MidBand = sc.Subgraph[1];
	SCSubgraphRef Subgraph_LowerBand = sc.Subgraph[2];
	

	SCInputRef Input_InputData = sc.Input[0];
	SCInputRef Input_Length = sc.Input[2];
	SCInputRef Input_StandardDeviations = sc.Input[3];

	if(sc.SetDefaults)
	{
		sc.GraphName = "Standard Error Bands";

		sc.AutoLoop = 1;
		sc.GraphRegion = 0;
		sc.ValueFormat = 3;  
		
		Subgraph_MidBand.Name = "Middle Band";
		Subgraph_MidBand.DrawStyle = DRAWSTYLE_LINE;
		Subgraph_MidBand.DrawZeros = false;
		Subgraph_MidBand.PrimaryColor = RGB(255,0,255);

		Subgraph_LowerBand.Name = "Bottom Band";
		Subgraph_LowerBand.DrawStyle = DRAWSTYLE_LINE;
		Subgraph_LowerBand.DrawZeros = false;
		Subgraph_LowerBand.PrimaryColor = RGB(255,255,0);

		Subgraph_UpperBand.Name = "Top Band";
		Subgraph_UpperBand.DrawStyle = DRAWSTYLE_LINE;
		Subgraph_UpperBand.DrawZeros = false;
		Subgraph_UpperBand.PrimaryColor = RGB(0,255,0);
		
		Input_InputData.Name = "Input Data";
		Input_InputData.SetInputDataIndex(SC_LAST);  
		
		Input_Length.Name = "Length";
		Input_Length.SetInt(14);
		Input_Length.SetIntLimits(1,MAX_STUDY_LENGTH);
		
		Input_StandardDeviations.Name = "Standard Deviations";
		Input_StandardDeviations.SetFloat(2.0f);
		Input_StandardDeviations.SetFloatLimits(.001f,(float)MAX_STUDY_LENGTH);	

		return;
	}

	sc.DataStartIndex = Input_Length.GetInt()-1;	



	sc.LinearRegressionIndicator(sc.BaseDataIn[Input_InputData.GetInputDataIndex()], Subgraph_MidBand, Input_Length.GetInt());		

	double StandardErrorValue = sc.GetStandardError(sc.BaseDataIn[Input_InputData.GetInputDataIndex()], Input_Length.GetInt());

	Subgraph_UpperBand[sc.Index] = (float)(Subgraph_MidBand[sc.Index] + StandardErrorValue * Input_StandardDeviations.GetFloat());

	Subgraph_LowerBand[sc.Index] = (float)(Subgraph_MidBand[sc.Index] - StandardErrorValue * Input_StandardDeviations.GetFloat());
}

/*===========================================================================*/
SCSFExport scsf_BollingerBands(SCStudyInterfaceRef sc)
{
	SCSubgraphRef Subgraph_UpperBand = sc.Subgraph[0];
	SCSubgraphRef Subgraph_MidBand = sc.Subgraph[1];
	SCSubgraphRef Subgraph_LowerBand = sc.Subgraph[2];

	SCInputRef Input_InputData = sc.Input[0];
	SCInputRef Input_Length = sc.Input[3];
	SCInputRef Input_StandardDeviations = sc.Input[4];
	SCInputRef Input_Version = sc.Input[5];
	SCInputRef Input_MAType = sc.Input[6];

	if(sc.SetDefaults)
	{
		sc.GraphName = "Bollinger Bands";
		sc.GraphRegion = 0;
		sc.ValueFormat = 3;  
		sc.AutoLoop = true;
		
		Subgraph_MidBand.Name = "Middle Band";
		Subgraph_MidBand.DrawStyle = DRAWSTYLE_LINE;
		Subgraph_MidBand.PrimaryColor = RGB(255,0,255);

		Subgraph_UpperBand.Name = "Top Band";
		Subgraph_UpperBand.DrawStyle = DRAWSTYLE_LINE;
		Subgraph_UpperBand.PrimaryColor = RGB(0,255,0);

		Subgraph_LowerBand.Name = "Bottom Band";
		Subgraph_LowerBand.DrawStyle = DRAWSTYLE_LINE;
		Subgraph_LowerBand.PrimaryColor = RGB(255,255,0);
		
		Input_InputData.Name = "Input Data";
		Input_InputData.SetInputDataIndex(SC_HLC_AVG);
		
		Input_Length.Name = "Length";
		Input_Length.SetInt(10);
		Input_Length.SetIntLimits(1,MAX_STUDY_LENGTH);
		
		Input_StandardDeviations.Name = "Standard Deviations";
		Input_StandardDeviations.SetFloat(2.0f);
		Input_StandardDeviations.SetFloatLimits(.0001f,(float)MAX_STUDY_LENGTH);

		Input_Version.SetInt(2);

		Input_MAType.Name = "Moving Average Type";
		Input_MAType.SetMovAvgType(MOVAVGTYPE_SIMPLE);


		

		return;
	}


	sc.DataStartIndex = Input_Length.GetInt()-1; 
	
	sc.BollingerBands(sc.BaseDataIn[Input_InputData.GetInputDataIndex()],Subgraph_MidBand,Input_Length.GetInt(),Input_StandardDeviations.GetFloat(),Input_MAType.GetMovAvgType());

	Subgraph_UpperBand[sc.Index] = Subgraph_MidBand.Arrays[0][sc.Index];
	Subgraph_LowerBand[sc.Index] = Subgraph_MidBand.Arrays[1][sc.Index];
}
/*===========================================================================*/


SCSFExport scsf_BollingerBands_StandardDeviationOfAverage(SCStudyInterfaceRef sc)
{
	SCSubgraphRef Subgraph_UpperBand = sc.Subgraph[0];
	SCSubgraphRef Subgraph_MidBand = sc.Subgraph[1];
	SCSubgraphRef Subgraph_LowerBand = sc.Subgraph[2];

	SCInputRef Input_InputData = sc.Input[0];
	SCInputRef Input_Length = sc.Input[1];
	SCInputRef Input_StandardDeviations = sc.Input[2];
	SCInputRef Input_MAType = sc.Input[3];

	if(sc.SetDefaults)
	{
		sc.GraphName = "Bollinger Bands - StandardDeviationOfAverage";
		sc.GraphRegion = 0;
		sc.ValueFormat = VALUEFORMAT_INHERITED;
		sc.AutoLoop = true;

		Subgraph_MidBand.Name = "Middle Band";
		Subgraph_MidBand.DrawStyle = DRAWSTYLE_LINE;
		Subgraph_MidBand.PrimaryColor = RGB(255,0,255);

		Subgraph_UpperBand.Name = "Top Band";
		Subgraph_UpperBand.DrawStyle = DRAWSTYLE_LINE;
		Subgraph_UpperBand.PrimaryColor = RGB(0,255,0);

		Subgraph_LowerBand.Name = "Bottom Band";
		Subgraph_LowerBand.DrawStyle = DRAWSTYLE_LINE;
		Subgraph_LowerBand.PrimaryColor = RGB(255,255,0);

		Input_InputData.Name = "Input Data";
		Input_InputData.SetInputDataIndex(SC_HLC_AVG);

		Input_Length.Name = "Length";
		Input_Length.SetInt(10);
		Input_Length.SetIntLimits(1,MAX_STUDY_LENGTH);

		Input_StandardDeviations.Name = "Standard Deviations";
		Input_StandardDeviations.SetFloat(2.0f);
		Input_StandardDeviations.SetFloatLimits(.0001f, (float)MAX_STUDY_LENGTH);


		Input_MAType.Name = "Moving Average Type";
		Input_MAType.SetMovAvgType(MOVAVGTYPE_SIMPLE);


		

		return;
	}


	sc.DataStartIndex = Input_Length.GetInt()-1; 

	BollingerBands_StandardDeviationOfAverage_S(sc.BaseDataIn[Input_InputData.GetInputDataIndex()],
		Subgraph_MidBand,
		Subgraph_UpperBand,
		Subgraph_LowerBand,
		Subgraph_MidBand.Arrays[0],
		sc.Index,
		Input_Length.GetInt(),
		Input_StandardDeviations.GetFloat(),
		Input_MAType.GetMovAvgType());

}

/*===========================================================================*/
SCSFExport scsf_PositiveVolumeIndex(SCStudyInterfaceRef sc)
{
	SCSubgraphRef Subgraph_PVI = sc.Subgraph[0];

	SCInputRef Input_InputData = sc.Input[0];
	SCInputRef Input_InitialValue = sc.Input[2];
	
	if(sc.SetDefaults)
	{
		sc.GraphName = "Positive Volume Index";
		sc.GraphRegion = 1;
		sc.ValueFormat = 3;
		sc.AutoLoop = 1; // true
		
		Subgraph_PVI.Name = "PVI"; 
		Subgraph_PVI.DrawStyle = DRAWSTYLE_LINE;
		Subgraph_PVI.PrimaryColor = RGB(0,255,0);
		Subgraph_PVI.DrawZeros = false;

		Input_InputData.Name = "Input Data";
		Input_InputData.SetInputDataIndex(SC_LAST);
		
		Input_InitialValue.Name = "Initial Value";
		Input_InitialValue.SetFloat(2.5f);
		Input_InitialValue.SetFloatLimits(.01f,(float)MAX_STUDY_LENGTH);

		

		return;
	}
	
	float prev_PVI;
	float prev_data;
	float data;
	float PVIval;
	float volume;
	float prev_volume;

	sc.DataStartIndex = 0;
	
	int pos = sc.Index;
	if(pos == 0)// We are starting a new PVI study
	{
		Subgraph_PVI[0] = Input_InitialValue.GetFloat();
		pos++;
	}

	volume = sc.Volume[pos]; 
	prev_volume = sc.Volume[pos-1];
	prev_PVI = Subgraph_PVI[pos-1];
	if(volume > prev_volume) // current volume less than equal to previous volume. 
	{
		data = sc.BaseDataIn[Input_InputData.GetInputDataIndex()][pos]; 
		prev_data = sc.BaseDataIn[Input_InputData.GetInputDataIndex()][pos-1];							
		PVIval = prev_PVI + ((data-prev_data) / prev_data * prev_PVI );
	}
	else
	{
		PVIval = prev_PVI;				
	}

	Subgraph_PVI[pos] = PVIval;
}
/************************************************************************************************************************/
SCSFExport scsf_NegativeVolumeIndex(SCStudyInterfaceRef sc)
{
	SCSubgraphRef Subgraph_NVI = sc.Subgraph[0];

	SCInputRef Input_InputData = sc.Input[0];
	SCInputRef Input_InitialValue = sc.Input[2];

	if(sc.SetDefaults)
	{
		sc.GraphName = "Negative Volume Index";

		sc.GraphRegion = 1;
		sc.ValueFormat = 3;
		sc.AutoLoop= true;

		Subgraph_NVI.Name = "NVI";
		Subgraph_NVI.DrawStyle = DRAWSTYLE_LINE;
		Subgraph_NVI.PrimaryColor = RGB(0,255,0);
		Subgraph_NVI.DrawZeros = false;

		Input_InputData.Name = "Input Data";
		Input_InputData.SetInputDataIndex(SC_LAST);  

		Input_InitialValue.Name = "Initial Value";
		Input_InitialValue.SetFloat(2.5f);
		Input_InitialValue.SetFloatLimits(0.01f,(float)MAX_STUDY_LENGTH);

		
		

		return;
	}

	sc.DataStartIndex = 0;

	float prev_NVI;
	float prev_data;
	float data;
	float NVIval;
	float volume;
	float prev_volume;

	int pos = sc.Index;
	if(pos == 0)// We are starting a new NVI study
	{
		Subgraph_NVI[0] = Input_InitialValue.GetFloat();
		pos++;
	}

	volume = sc.Volume[pos]; 
	prev_volume	= sc.Volume[pos-1];
	prev_NVI = Subgraph_NVI[pos-1];
	if(volume < prev_volume) // current volume greater then equal to previous volume. 
	{
		data = sc.BaseDataIn[Input_InputData.GetInputDataIndex()][pos]; 
		prev_data = sc.BaseDataIn[Input_InputData.GetInputDataIndex()][pos-1];							
		NVIval = prev_NVI + ((data-prev_data) / prev_data * prev_NVI);
	}
	else
	{
		NVIval	= prev_NVI;
	}

	Subgraph_NVI[pos] = NVIval;
}
/************************************************************************************************************************/
SCSFExport scsf_DoubleStochasticNew(SCStudyInterfaceRef sc)
{
	SCSubgraphRef Subgraph_DS = sc.Subgraph[0];
	SCSubgraphRef Subgraph_Line1 = sc.Subgraph[5];
	SCSubgraphRef Subgraph_Line2 = sc.Subgraph[6];
		
	SCInputRef Input_Length = sc.Input[0];
	SCInputRef Input_EMALength = sc.Input[2];
	SCInputRef Input_MovAvgType = sc.Input[3];
	SCInputRef Input_Line1Value = sc.Input[4];
	SCInputRef Input_Line2Value = sc.Input[5];

	if(sc.SetDefaults)
	{
		sc.GraphName = "Double Stochastic";
		sc.GraphRegion = 1;
		sc.ValueFormat = 3;  
		sc.AutoLoop = true;

		Subgraph_DS.Name = "DS";
		Subgraph_DS.DrawStyle = DRAWSTYLE_LINE;
		Subgraph_DS.PrimaryColor = RGB(0,255,0);
		Subgraph_DS.DrawZeros = false;
		
		Subgraph_Line1.Name = "Line 1";
		Subgraph_Line1.DrawStyle = DRAWSTYLE_LINE;
		Subgraph_Line1.PrimaryColor = RGB(0,255,0);
		Subgraph_Line1.DrawZeros = false;
		
		Subgraph_Line2.Name = "Line 2";
		Subgraph_Line2.DrawStyle = DRAWSTYLE_LINE;
		Subgraph_Line2.PrimaryColor = RGB(0,255,0);
		Subgraph_Line2.DrawZeros = false;

		Input_Length.Name = "Length";
		Input_Length.SetInt(10);
		Input_Length.SetIntLimits(1,MAX_STUDY_LENGTH);
		
		Input_EMALength.Name = "Moving Average Length";
		Input_EMALength.SetInt(3);
		Input_EMALength.SetIntLimits(1,MAX_STUDY_LENGTH);

		Input_MovAvgType.Name = "Moving Average Type";
		Input_MovAvgType.SetMovAvgType(MOVAVGTYPE_EXPONENTIAL);
		
		Input_Line1Value.Name = "Line 1";
		Input_Line1Value.SetInt(10);
		
		Input_Line2Value.Name = "Line 2";
		Input_Line2Value.SetInt(85);

		
		
		
		return;
	}

	sc.DoubleStochastic(sc.BaseDataIn, Subgraph_DS, Input_Length.GetInt(), Input_EMALength.GetInt(), Input_MovAvgType.GetMovAvgType());

	Subgraph_Line1[sc.Index] = (float)Input_Line1Value.GetInt();
	Subgraph_Line2[sc.Index] = (float)Input_Line2Value.GetInt();
}

/*==========================================================================*/
SCSFExport scsf_CandlesNoTails(SCStudyInterfaceRef sc)
{
	SCSubgraphRef Subgraph_Open = sc.Subgraph[0];
	SCSubgraphRef Subgraph_Last = sc.Subgraph[3];
	SCSubgraphRef Subgraph_Volume = sc.Subgraph[4];
	SCSubgraphRef Subgraph_NumTrades = sc.Subgraph[5];
	SCSubgraphRef Subgraph_OHLCAvg = sc.Subgraph[6];
	SCSubgraphRef Subgraph_HLCAvg = sc.Subgraph[7];
	SCSubgraphRef Subgraph_HLAvg = sc.Subgraph[8];
	SCSubgraphRef Subgraph_BidVol = sc.Subgraph[9];
	SCSubgraphRef Subgraph_AskVol = sc.Subgraph[10];

	if (sc.SetDefaults)
	{
		// Set the configuration and defaults
		
		sc.GraphName = "Candles without Tails";
	
		sc.GraphDrawType = GDT_CANDLESTICK;
		sc.StandardChartHeader = 1;
		sc.DisplayAsMainPriceGraph = 1;
		sc.GraphRegion = 0;
			
		Subgraph_Open.Name = "Open";
		Subgraph_Open.DrawStyle = DRAWSTYLE_LINE;
		Subgraph_Open.PrimaryColor = RGB(0,255,0);
		Subgraph_Open.DrawZeros = false;
		
		Subgraph_Last.Name = "Last";
		Subgraph_Last.DrawStyle = DRAWSTYLE_LINE;
		Subgraph_Last.PrimaryColor = RGB(255,127,0);
		Subgraph_Last.DrawZeros = false;

		Subgraph_Volume.Name = "Volume";
		Subgraph_Volume.DrawStyle = DRAWSTYLE_LINE;
		Subgraph_Volume.PrimaryColor = RGB(255,0,0);
		Subgraph_Volume.DrawZeros = false;

		Subgraph_NumTrades.Name = "# of Trades / OI";
		Subgraph_NumTrades.DrawStyle = DRAWSTYLE_IGNORE;
		Subgraph_NumTrades.PrimaryColor = RGB(0,0,255);
		Subgraph_NumTrades.DrawZeros = false;

		Subgraph_OHLCAvg.Name = "OHLC Avg";
		Subgraph_OHLCAvg.DrawStyle = DRAWSTYLE_IGNORE;
		Subgraph_OHLCAvg.PrimaryColor = RGB(127,0,255);
		Subgraph_OHLCAvg.DrawZeros = false;

		Subgraph_HLCAvg.Name = "HLC Avg";
		Subgraph_HLCAvg.DrawStyle = DRAWSTYLE_IGNORE;
		Subgraph_HLCAvg.PrimaryColor = RGB(0,255,255);
		Subgraph_HLCAvg.DrawZeros = false;

		Subgraph_HLAvg.Name = "HL Avg";
		Subgraph_HLAvg.DrawStyle = DRAWSTYLE_IGNORE;
		Subgraph_HLAvg.PrimaryColor = RGB(0,127,255);
		Subgraph_HLAvg.DrawZeros = false;

		Subgraph_BidVol.Name = "Bid Vol";
		Subgraph_BidVol.DrawStyle = DRAWSTYLE_IGNORE;
		Subgraph_BidVol.PrimaryColor = RGB(0,255,0);
		Subgraph_BidVol.DrawZeros = false;

		Subgraph_AskVol.Name = "Ask Vol";
		Subgraph_AskVol.DrawStyle = DRAWSTYLE_IGNORE;
		Subgraph_AskVol.PrimaryColor = RGB(0,255,0);
		Subgraph_AskVol.DrawZeros = false;

		
		

		sc.AutoLoop = 1;
		
		return;
	}
	//create a new name that includes the base graph name.
	sc.GraphName.Format("%s No Tails", sc.GetStudyName(0).GetChars());
	
	// Do data processing
	
	Subgraph_Open[sc.Index] = sc.Open[sc.Index];
	Subgraph_Last[sc.Index] = sc.Close[sc.Index];
	Subgraph_Volume[sc.Index] = sc.Volume[sc.Index];
	Subgraph_NumTrades[sc.Index] = sc.NumberOfTrades[sc.Index];
}

/**************************************************************************************************/
SCSFExport scsf_KiwisTrailingStop(SCStudyInterfaceRef sc)
{	
	SCSubgraphRef Subgraph_TSUp = sc.Subgraph[0];
	SCSubgraphRef Subgraph_TSDown = sc.Subgraph[1];	

	SCSubgraphRef Subgraph_direction = sc.Subgraph[3];
	SCSubgraphRef Subgraph_hiclose = sc.Subgraph[4];
	SCSubgraphRef Subgraph_loclose = sc.Subgraph[5];

	SCFloatArrayRef Array_e1 = sc.Subgraph[6];
	SCFloatArrayRef Array_e2 = sc.Subgraph[7];
	SCFloatArrayRef Array_e3 = sc.Subgraph[8];
	SCFloatArrayRef Array_e4 = sc.Subgraph[9];
	SCFloatArrayRef Array_e5 = sc.Subgraph[10];
	SCFloatArrayRef Array_e6 = sc.Subgraph[11];

	SCSubgraphRef Subgraph_TempRange = sc.Subgraph[6];
	SCSubgraphRef Subgraph_TempAvgRange = sc.Subgraph[7];
	SCSubgraphRef Subgraph_diff2 = sc.Subgraph[8];
	SCSubgraphRef Subgraph_atrmod = sc.Subgraph[9];

	SCInputRef Input_Use2Subgraphs = sc.Input[0];
	SCInputRef Input_ATRLength = sc.Input[2];
	SCInputRef Input_ATRFactor = sc.Input[3];
	SCInputRef Input_Vervoort = sc.Input[4];
	SCInputRef Input_ATRMax = sc.Input[5];



	if(sc.SetDefaults)
	{
		sc.GraphName="Kiwi's Trailing Stop";
		sc.StudyDescription = "Kiwi's Trailing Stop (Chandelier) plus Sylvain Vervoort variation";

		Subgraph_TSUp.Name="TS";
		Subgraph_TSUp.DrawStyle = DRAWSTYLE_LINE_SKIP_ZEROS;
		Subgraph_TSUp.SecondaryColorUsed = 1;
		Subgraph_TSUp.PrimaryColor = RGB(0,255,0);
		Subgraph_TSUp.SecondaryColor = RGB(255,0,0);
		Subgraph_TSUp.DrawZeros = false;

		Subgraph_TSDown.Name = "TS";
		Subgraph_TSDown.DrawStyle = DRAWSTYLE_LINE_SKIP_ZEROS;
		Subgraph_TSDown.PrimaryColor = RGB(255,0,0);
		Subgraph_TSDown.DrawZeros = false;

		Subgraph_TempRange.Name = "TR";
		Subgraph_TempRange.DrawStyle = DRAWSTYLE_IGNORE;
		Subgraph_TempRange.PrimaryColor = RGB(127,0,255);
		Subgraph_TempRange.DrawZeros = false;

		Subgraph_TempAvgRange.Name = "TAR";
		Subgraph_TempAvgRange.DrawStyle = DRAWSTYLE_IGNORE;
		Subgraph_TempAvgRange.PrimaryColor = RGB(0,255,255);
		Subgraph_TempAvgRange.DrawZeros = false;

		Subgraph_diff2.Name = "diff2";
		Subgraph_diff2.DrawStyle = DRAWSTYLE_IGNORE;
		Subgraph_diff2.PrimaryColor = RGB(0,127,255);
		Subgraph_diff2.DrawZeros = false;

		Subgraph_atrmod.Name = "atrmod";
		Subgraph_atrmod.DrawStyle = DRAWSTYLE_IGNORE;
		Subgraph_atrmod.PrimaryColor = RGB(0,255,0);
		Subgraph_atrmod.DrawZeros = false;

		sc.AutoLoop = 0;

		Input_ATRLength.Name="ATR Length";
		Input_ATRLength.SetFloat(9.0);

		Input_ATRFactor.Name="ATR Factor";
		Input_ATRFactor.SetFloat(2.5);

		Input_Vervoort.Name="Vervoort Variation?";
		Input_Vervoort.SetYesNo(false);

		Input_ATRMax.Name="Vervoort Maximum Range";
		Input_ATRMax.SetFloat(1.5);

		Input_Use2Subgraphs.Name="Use 2 subgraphs";
		Input_Use2Subgraphs.SetYesNo(true);

		sc.GraphRegion = 0;

		return;
	}

	int 	pos;
	float 	Ave;
	float  	b,b2,b3,c1,c2,c3,c4,w1=0,w2=0;

	sc.DataStartIndex=10;

	if(Input_Use2Subgraphs.GetYesNo())
	{
		Subgraph_TSUp.Name = "TS Up";
		Subgraph_TSDown.Name = "TS Down";

		Subgraph_TSUp.SecondaryColorUsed = false;
	}
	else
	{
		Subgraph_TSUp.Name="TS";

		Subgraph_TSUp.SecondaryColorUsed = 1;
	}


	if (sc.UpdateStartIndex == 0)
	{
		Subgraph_direction[sc.UpdateStartIndex] = 1;
		Subgraph_loclose[sc.UpdateStartIndex] = sc.Close[sc.UpdateStartIndex]; 
		Subgraph_hiclose[sc.UpdateStartIndex] = Subgraph_loclose[sc.UpdateStartIndex];

		Array_e1[sc.UpdateStartIndex]=sc.High[sc.UpdateStartIndex]-sc.Low[sc.UpdateStartIndex]; 
		Array_e2[sc.UpdateStartIndex]=Array_e1[sc.UpdateStartIndex]; 
		Array_e3[sc.UpdateStartIndex]=Array_e1[sc.UpdateStartIndex]; 
		Array_e4[sc.UpdateStartIndex]=Array_e1[sc.UpdateStartIndex]; 
		Array_e5[sc.UpdateStartIndex]=Array_e1[sc.UpdateStartIndex]; 
		Array_e6[sc.UpdateStartIndex]=Array_e1[sc.UpdateStartIndex];
	}

	if(!Input_Vervoort.GetYesNo()) 
	{
		b=0.5;					// 0.5
		b2=(b*b);				// 0.25
		b3=(b2*b);				// 0.125

		c1=-b3;					// - 0.125
		c2=(3*(b2+b3));			// 0.45
		c3=(-3*(2*b2+b+b3)); 
		c4=(1+3*b+b3+3*b2);
		w1 = 2/(Input_ATRLength.GetFloat()+1);  
		w2 = 1-w1;

		for (pos=max(sc.UpdateStartIndex, 1); pos < sc.ArraySize; pos++)
		{
			float temp = max(sc.High[pos]-sc.Low[pos], sc.High[pos]-sc.Close[pos-1]);
			float P   = max(temp,sc.Close[pos-1]-sc.Low[pos]);

			Array_e1[pos] = w1*P + w2*Array_e1[pos - 1];
			Array_e2[pos] = w1*Array_e1[pos] + w2*Array_e2[pos - 1];
			Array_e3[pos] = w1*Array_e2[pos] + w2*Array_e3[pos - 1];
			Array_e4[pos] = w1*Array_e3[pos] + w2*Array_e4[pos - 1];
			Array_e5[pos] = w1*Array_e4[pos] + w2*Array_e5[pos - 1];
			Array_e6[pos] = w1*Array_e5[pos] + w2*Array_e6[pos - 1];

			Ave = c1*Array_e6[pos] + c2*Array_e5[pos] + c3*Array_e4[pos] + c4*Array_e3[pos];

			if((Subgraph_direction[pos-1]==1 && sc.Close[pos]<(Subgraph_loclose[pos-1]))
				|| 
				(Subgraph_direction[pos-1]==-1 && sc.Close[pos]>(Subgraph_hiclose[pos-1])))
			{
				if(Subgraph_direction[pos-1]==1)
				{
					Subgraph_direction[pos] = -1; //reverse short
					Subgraph_hiclose[pos] = sc.Close[pos]+(Ave*Input_ATRFactor.GetFloat());
					Subgraph_loclose[pos] = 0;
				} 
				else
				{
					Subgraph_direction[pos] = 1; //reverse long
					Subgraph_loclose[pos] = sc.Close[pos]-(Ave*Input_ATRFactor.GetFloat());
					Subgraph_hiclose[pos] = 0;
				}
			} 
			else
			{
				if(Subgraph_direction[pos-1]==1)
				{
					if(sc.Close[pos]-(Ave*Input_ATRFactor.GetFloat())>Subgraph_loclose[pos-1])
					{
						Subgraph_loclose[pos] = sc.Close[pos]-(Ave*Input_ATRFactor.GetFloat());
						Subgraph_hiclose[pos] = Subgraph_hiclose[pos-1];
					}
					else
					{
						Subgraph_loclose[pos] = Subgraph_loclose[pos-1];
						Subgraph_hiclose[pos] = Subgraph_hiclose[pos-1];
					}
				} 
				else
				{
					if(sc.Close[pos]+(Ave*Input_ATRFactor.GetFloat())<Subgraph_hiclose[pos-1])
					{
						Subgraph_loclose[pos] = Subgraph_loclose[pos-1];
						Subgraph_hiclose[pos] = sc.Close[pos]+(Ave*Input_ATRFactor.GetFloat());
					}
					else
					{
						Subgraph_loclose[pos] = Subgraph_loclose[pos-1];
						Subgraph_hiclose[pos] = Subgraph_hiclose[pos-1];
					}
				};

				Subgraph_direction[pos] = Subgraph_direction[pos-1]; // no change
			};

			if(Subgraph_direction[pos]==1) 
			{
				if(Input_Use2Subgraphs.GetYesNo() == false)
				{
					Subgraph_TSUp[pos] = (Subgraph_loclose[pos]); 
					Subgraph_TSUp.DataColor[pos] = Subgraph_TSUp.PrimaryColor;
				}
				else
				{
					Subgraph_TSUp[pos] = (Subgraph_loclose[pos]); 
					Subgraph_TSDown[pos] = 0;
				}
			} 
			else
			{
				if(Input_Use2Subgraphs.GetYesNo() == false)
				{
					Subgraph_TSUp[pos] = (Subgraph_hiclose[pos]); 
					Subgraph_TSUp.DataColor[pos] =  Subgraph_TSUp.SecondaryColor;
				}
				else
				{
					Subgraph_TSDown[pos] = (Subgraph_hiclose[pos]);  
					Subgraph_TSUp[pos] = 0;
				}
			}	
		}
	} else
	{

		/*	
		HiLo:=If(H-L<1.5*Mov(H-L,period,S),H-L, 1.5*Mov
		(H-L,period,S));
		Href:=If(L<=Ref(H,-1),H-Ref(C,-1),(H-Ref(C,-1))-(L-Ref(H,-1))/2);
		Lref:=If(H>=Ref(L,-1),Ref(C,-1)-L,(Ref(C,-1)-L)-(Ref(L,-1)-H)/2);
		diff1:=Max(HiLo,Href);
		diff2:=Max(diff1,Lref);
		atrmod:=Wilders(diff2,period);
		loss:=atrfact*atrmod;
		trail:= 
		If(C>PREV AND Ref(C,-1)>PREV,
		Max(PREV,C-loss),
		If(C<PREV AND Ref(C,-1)<PREV,
		Min(PREV,C+loss),
		If(C>PREV,C-loss,C+loss)));
		*/	


		for (pos=max(sc.UpdateStartIndex, 1); pos < sc.ArraySize; pos++)
		{
			float HiLo,Href,Lref;
			int period = (int)Input_ATRLength.GetFloat();
			Subgraph_TempRange[pos] = sc.High[pos]-sc.Low[pos];
			sc.MovingAverage(Subgraph_TempRange, Subgraph_TempAvgRange, MOVAVGTYPE_SIMPLE, pos, period);

			HiLo=min(Subgraph_TempRange[pos],Input_ATRMax.GetFloat()*Subgraph_TempAvgRange[pos]);
			if(sc.Low[pos]<=sc.High[pos-1]) Href=sc.High[pos]-sc.Close[pos-1]; else Href=(sc.High[pos]-sc.Close[pos-1])-(sc.Low[pos]-sc.High[pos-1])/2;
			if(sc.High[pos]>=sc.Low[pos-1]) Lref=sc.Close[pos-1]-sc.Low[pos];  else Lref=(sc.Close[pos-1]-sc.Low[pos])- (sc.Low[pos-1]-sc.High[pos])/2;

			Subgraph_diff2[pos] = max(Lref,max(HiLo,Href));
			sc.MovingAverage(Subgraph_diff2, Subgraph_atrmod, MOVAVGTYPE_WILDERS, pos, period);

			Ave = Subgraph_atrmod[pos];

			if((Subgraph_direction[pos-1]==1 && sc.Close[pos]<(Subgraph_loclose[pos-1]))
				|| 
				(Subgraph_direction[pos-1]==-1 && sc.Close[pos]>(Subgraph_hiclose[pos-1])))
			{
				if(Subgraph_direction[pos-1]==1)
				{
					Subgraph_direction[pos] = -1; //reverse short
					Subgraph_hiclose[pos] = sc.Close[pos]+(Ave*Input_ATRFactor.GetFloat());
					Subgraph_loclose[pos] = 0;
				} 
				else
				{
					Subgraph_direction[pos] = 1; //reverse long
					Subgraph_loclose[pos] = sc.Close[pos]-(Ave*Input_ATRFactor.GetFloat());
					Subgraph_hiclose[pos] = 0;
				}
			} 
			else
			{
				if(Subgraph_direction[pos-1]==1)
				{
					if(sc.Close[pos]-(Ave*Input_ATRFactor.GetFloat())>Subgraph_loclose[pos-1])
					{
						Subgraph_loclose[pos] = sc.Close[pos]-(Ave*Input_ATRFactor.GetFloat());
						Subgraph_hiclose[pos] = Subgraph_hiclose[pos-1];
					}
					else
					{
						Subgraph_loclose[pos] = Subgraph_loclose[pos-1];
						Subgraph_hiclose[pos] = Subgraph_hiclose[pos-1];
					}
				} 
				else
				{
					if(sc.Close[pos]+(Ave*Input_ATRFactor.GetFloat())<Subgraph_hiclose[pos-1])
					{
						Subgraph_loclose[pos] = Subgraph_loclose[pos-1];
						Subgraph_hiclose[pos] = sc.Close[pos]+(Ave*Input_ATRFactor.GetFloat());
					}
					else
					{
						Subgraph_loclose[pos] = Subgraph_loclose[pos-1];
						Subgraph_hiclose[pos] = Subgraph_hiclose[pos-1];
					}
				};

				Subgraph_direction[pos] = Subgraph_direction[pos-1]; // no change
			};

			if(Subgraph_direction[pos]==1) 
			{
				if(Input_Use2Subgraphs.GetYesNo() == false)
				{
					Subgraph_TSUp[pos] = (Subgraph_loclose[pos]); 
					Subgraph_TSUp.DataColor[pos] = Subgraph_TSUp.PrimaryColor;
				}
				else
				{
					Subgraph_TSUp[pos] = (Subgraph_loclose[pos]); 
					Subgraph_TSDown[pos] = 0;
				}
			} 
			else
			{
				if(Input_Use2Subgraphs.GetYesNo() == false)
				{
					Subgraph_TSUp[pos] = (Subgraph_hiclose[pos]); 
					Subgraph_TSUp.DataColor[pos] =  Subgraph_TSUp.SecondaryColor;
				}
				else
				{
					Subgraph_TSDown[pos] = (Subgraph_hiclose[pos]);  
					Subgraph_TSUp[pos] = 0;
				}
			}
		}
	}
}

/*============================================================================*/
SCSFExport scsf_LargeTextDisplayForStudyFromChart(SCStudyInterfaceRef sc)
{
	SCSubgraphRef Subgraph_TextDisplay = sc.Subgraph[0];

	SCInputRef Input_HorizontalPosition = sc.Input[0];
	SCInputRef Input_VerticalPosition = sc.Input[1];
	SCInputRef Input_StudySubgraphReference = sc.Input[3];
	SCInputRef Input_DisplaySubgraphName = sc.Input[4];
	SCInputRef Input_SubgraphOffset = sc.Input[5];
	SCInputRef Input_UseTextForNonZeroValue = sc.Input[6];
	SCInputRef Input_NonZeroValueText = sc.Input[7];
	
	if (sc.SetDefaults)
	{
		// Set the configuration and defaults
		
		sc.GraphName = "Text Display For Study from Chart";
		
		sc.AutoLoop = 0;
		sc.GraphRegion = 0;

		Subgraph_TextDisplay.Name = "Text Display";
		Subgraph_TextDisplay.LineWidth = 20;
		Subgraph_TextDisplay.DrawStyle = DRAWSTYLE_CUSTOM_TEXT;
		Subgraph_TextDisplay.PrimaryColor = RGB(0, 0, 0); //black
		Subgraph_TextDisplay.SecondaryColor = RGB(128, 255, 255);
		Subgraph_TextDisplay.SecondaryColorUsed = true;
		Subgraph_TextDisplay.DisplayNameValueInWindowsFlags = 0;

		Input_HorizontalPosition.Name.Format("Horizontal Position From Left (1-%d)", (int)CHART_DRAWING_MAX_HORIZONTAL_AXIS_RELATIVE_POSITION);
		Input_HorizontalPosition.SetInt(20);
		Input_HorizontalPosition.SetIntLimits(1, (int)CHART_DRAWING_MAX_HORIZONTAL_AXIS_RELATIVE_POSITION);

		Input_VerticalPosition.Name.Format("Vertical Position From Bottom (1-%d)", (int)CHART_DRAWING_MAX_VERTICAL_AXIS_RELATIVE_POSITION);
		Input_VerticalPosition.SetInt(90);
		Input_VerticalPosition.SetIntLimits(1, (int)CHART_DRAWING_MAX_VERTICAL_AXIS_RELATIVE_POSITION);

		Input_StudySubgraphReference.Name = "Study And Subgraph To Display";
		Input_StudySubgraphReference.SetChartStudySubgraphValues(1, 1, 0);

		Input_DisplaySubgraphName.Name = "Display Subgraph Name";
		Input_DisplaySubgraphName.SetYesNo(false);

		Input_SubgraphOffset.Name = "Subgraph Columns Back";
		Input_SubgraphOffset.SetInt(0);

		Input_UseTextForNonZeroValue.Name = "Use Text for Non-Zero Value";
		Input_UseTextForNonZeroValue.SetYesNo(false);

		Input_NonZeroValueText.Name = "Non-Zero Value Text";
		Input_NonZeroValueText.SetString("");

		sc.TextInputName = "Prefix Text for Display Value";

		
		return;
	}
	
	// Do data processing


	SCFloatArray StudyReference;

	sc.GetStudyArrayFromChartUsingID(Input_StudySubgraphReference.GetChartNumber(), Input_StudySubgraphReference.GetStudyID(), Input_StudySubgraphReference.GetSubgraphIndex(), StudyReference);
	
	
	SCString ValueText;
	if (sc.TextInput.GetLength()>0)
	{
		ValueText += sc.TextInput;
		ValueText += " ";
	}

	int ColumnsBack = Input_SubgraphOffset.GetInt();
	float StudyValue = StudyReference[StudyReference.GetArraySize() - 1 - ColumnsBack];

	//Patch for when referencing data from the Numbers Bars Calculated Values study. This value could be used.
	if (StudyValue == -FLT_MAX)
		StudyValue = 0;

	if (Input_UseTextForNonZeroValue.GetYesNo())
	{
		if (StudyValue != 0)
			ValueText += Input_NonZeroValueText.GetString();
		else
			ValueText += " ";
	}
	else
		ValueText += sc.FormatGraphValue(StudyValue, sc.GetValueFormat());

	sc.AddAndManageSingleTextDrawingForStudy
	(sc
		, false
		, Input_HorizontalPosition.GetInt()
		, Input_VerticalPosition.GetInt()
		, Subgraph_TextDisplay
		, false
		, ValueText
		, true
	);
}


/*============================================================================*/
SCSFExport scsf_LargeTextDisplayForStudy(SCStudyInterfaceRef sc)
{
	SCSubgraphRef Subgraph_TextDisplay = sc.Subgraph[0];

	SCInputRef Input_HorizontalPosition = sc.Input[0];
	SCInputRef Input_VerticalPosition = sc.Input[1];
	SCInputRef Input_StudySubgraphReference = sc.Input[3];
	SCInputRef Input_DisplaySubgraphName = sc.Input[4];
	SCInputRef Input_SubgraphOffset = sc.Input[5];
	SCInputRef Input_PrefixTextForDisplayValue = sc.Input[6];
	SCInputRef Input_SuffixTextForDisplayValue = sc.Input[7];
	SCInputRef Input_UseTextForNonZeroValue = sc.Input[8];
	SCInputRef Input_NonZeroValueText = sc.Input[9];

	if (sc.SetDefaults)
	{
		// Set the configuration and defaults

		sc.GraphName = "Text Display For Study";

		sc.AutoLoop = 0;
		sc.GraphRegion = 0;

		Subgraph_TextDisplay.Name = "Text Display";
		Subgraph_TextDisplay.LineWidth = 20;
		Subgraph_TextDisplay.DrawStyle = DRAWSTYLE_CUSTOM_TEXT;
		Subgraph_TextDisplay.PrimaryColor = RGB(0, 0, 0); //black
		Subgraph_TextDisplay.SecondaryColor = RGB(128, 255, 255);
		Subgraph_TextDisplay.SecondaryColorUsed = true;
		Subgraph_TextDisplay.DisplayNameValueInWindowsFlags = 0;

		Input_HorizontalPosition.Name.Format("Horizontal Position From Left (1-%d)", (int)CHART_DRAWING_MAX_HORIZONTAL_AXIS_RELATIVE_POSITION);
		Input_HorizontalPosition.SetInt(20);
		Input_HorizontalPosition.SetIntLimits(1, (int)CHART_DRAWING_MAX_HORIZONTAL_AXIS_RELATIVE_POSITION);

		Input_VerticalPosition.Name.Format("Vertical Position From Bottom (1-%d)", (int)CHART_DRAWING_MAX_VERTICAL_AXIS_RELATIVE_POSITION);
		Input_VerticalPosition.SetInt(90);
		Input_VerticalPosition.SetIntLimits(1, (int)CHART_DRAWING_MAX_VERTICAL_AXIS_RELATIVE_POSITION);

		Input_StudySubgraphReference.Name = "Study and Subgraph to Display";
		Input_StudySubgraphReference.SetStudySubgraphValues(1, 0);

		Input_DisplaySubgraphName.Name = "Display Subgraph Name";
		Input_DisplaySubgraphName.SetYesNo(false);

		Input_SubgraphOffset.Name = "Subgraph Columns Back";
		Input_SubgraphOffset.SetInt(0);

		Input_PrefixTextForDisplayValue.Name = "Prefix Text for Display Value";
		Input_PrefixTextForDisplayValue.SetString("");

		Input_SuffixTextForDisplayValue.Name = "Suffix Text for Display Value";
		Input_SuffixTextForDisplayValue.SetString("");

		Input_UseTextForNonZeroValue.Name = "Use Text for Non-Zero Value";
		Input_UseTextForNonZeroValue.SetYesNo(false);

		Input_NonZeroValueText.Name = "Non-Zero Value Text";
		Input_NonZeroValueText.SetString("");

		
		return;
	}

	// Do data processing

	SCFloatArray StudyReference;
	sc.GetStudyArrayUsingID(Input_StudySubgraphReference.GetStudyID(), Input_StudySubgraphReference.GetSubgraphIndex(), StudyReference);


	int ColumnsBack = Input_SubgraphOffset.GetInt();
	SCString ValueText;
	if (Input_PrefixTextForDisplayValue.GetString()[0] != '\0')
	{
		ValueText += Input_PrefixTextForDisplayValue.GetString();
		ValueText += " ";
	}

	if (Input_DisplaySubgraphName.GetYesNo())
	{
		const char* SubgraphName = sc.GetStudySubgraphName(Input_StudySubgraphReference.GetStudyID(), Input_StudySubgraphReference.GetSubgraphIndex());

		if (SubgraphName != NULL)
		{
			ValueText += SubgraphName;
			ValueText += ": ";
		}
	}

	float StudyValue = StudyReference[StudyReference.GetArraySize() - 1 - ColumnsBack];

	if (StudyValue == -FLT_MAX)//Patch for when referencing data from the Numbers Bars Calculated Values study. This value could be used.
		StudyValue = 0;

	if(Input_UseTextForNonZeroValue.GetYesNo() )
	{
		if (StudyValue != 0)
			ValueText += Input_NonZeroValueText.GetString();
		else
			ValueText += " ";
	}
	else
		ValueText += sc.FormatGraphValue(StudyValue, sc.GetValueFormat());

	ValueText += Input_SuffixTextForDisplayValue.GetString();

	sc.AddAndManageSingleTextDrawingForStudy
		( sc
		, false
		, Input_HorizontalPosition.GetInt()
		, Input_VerticalPosition.GetInt()
		, Subgraph_TextDisplay
		, false
		, ValueText
		, true
		);

}

/*============================================================================ */
SCSFExport scsf_ProfitLossTextStudy(SCStudyInterfaceRef sc)
{
	SCInputRef Input_HorizontalPosition = sc.Input[0];
	SCInputRef Input_VerticalPosition   = sc.Input[1];
	SCInputRef Input_DisplayInFillSpace = sc.Input[2];
	SCInputRef Input_ProfitLossFormat   = sc.Input[3];
	SCInputRef Input_RTCommission       = sc.Input[4];

	SCInputRef Input_ShowOpenPL			    = sc.Input[5];
	SCInputRef Input_ShowClosedPL		    = sc.Input[6];
	SCInputRef Input_ShowDailyPL		    = sc.Input[7];
	SCInputRef Input_IncludeOpenPLInDailyPL = sc.Input[8];

	SCInputRef Input_TextSize                = sc.Input[10];
	SCInputRef Input_TextColor               = sc.Input[11];
	SCInputRef Input_TextBackColor           = sc.Input[12];
	SCInputRef Input_ShowTotalTrades         = sc.Input[13];
	SCInputRef Input_ShowTotalQuantityFilled = sc.Input[14];
	SCInputRef Input_ShowDailyTotalTrades    = sc.Input[15];
	SCInputRef Input_ShowDailyTotalQuantityFilled = sc.Input[16];
	SCInputRef Input_ShowMaximumOpenPositionProfit = sc.Input[17];
	SCInputRef Input_ShowMaximumOpenPositionLoss = sc.Input[18];
	SCInputRef Input_ShowFlatToFlatClosedProfitLoss = sc.Input[19];

	if (sc.SetDefaults)
	{
		// Set the configuration and defaults
		sc.GraphName = "Trading: Profit/Loss Text";

		sc.AutoLoop = 0;
		sc.GraphRegion = 0;
		sc.MaintainTradeStatisticsAndTradesData = 1;

		Input_HorizontalPosition.Name.Format("Horizontal Position From Left (1-%d)", (int)CHART_DRAWING_MAX_HORIZONTAL_AXIS_RELATIVE_POSITION);
		Input_HorizontalPosition.SetInt(20);
		Input_HorizontalPosition.SetIntLimits(1, (int)CHART_DRAWING_MAX_HORIZONTAL_AXIS_RELATIVE_POSITION);

		Input_VerticalPosition.Name.Format("Vertical Position From Bottom (1-%d)", (int)CHART_DRAWING_MAX_VERTICAL_AXIS_RELATIVE_POSITION);
		Input_VerticalPosition.SetInt(90);
		Input_VerticalPosition.SetIntLimits(1, (int)CHART_DRAWING_MAX_VERTICAL_AXIS_RELATIVE_POSITION);

		Input_DisplayInFillSpace.Name = "Display in Fill Space";
		Input_DisplayInFillSpace.SetYesNo(false);

		Input_ShowOpenPL.Name = "Show Open Profit/Loss";
		Input_ShowOpenPL.SetYesNo(1);

		Input_ShowClosedPL.Name = "Show Closed Profit/Loss";
		Input_ShowClosedPL.SetYesNo(1);

		Input_ShowDailyPL.Name = "Show Daily Profit/Loss";
		Input_ShowDailyPL.SetYesNo(1);

		Input_IncludeOpenPLInDailyPL.Name = "Include Open Profit/Loss in Daily Profit/Loss";
		Input_IncludeOpenPLInDailyPL.SetYesNo(0);

		Input_TextSize.Name = "Text Size";
		Input_TextSize.SetInt(14);
		Input_TextSize.SetIntLimits(3, 50);

		Input_TextColor.Name = "Text Color";
		Input_TextColor.SetColor(0,0,0);  // black

		Input_TextBackColor.Name = "Text Background Color";
		Input_TextBackColor.SetColor(128,255,255);

		Input_ShowTotalTrades.Name = "Show Total Trades";
		Input_ShowTotalTrades.SetYesNo(0);

		Input_ShowTotalQuantityFilled.Name = "Show Total Quantity Filled";
		Input_ShowTotalQuantityFilled.SetYesNo(0);

		Input_ShowDailyTotalTrades.Name = "Show Daily Total Trades";
		Input_ShowDailyTotalTrades.SetYesNo(0);

		Input_ShowDailyTotalQuantityFilled.Name = "Show Daily Total Quantity Filled";
		Input_ShowDailyTotalQuantityFilled.SetYesNo(0);

		Input_ShowMaximumOpenPositionProfit.Name = "Show Maximum Open Position Profit";
		Input_ShowMaximumOpenPositionProfit.SetYesNo(0);

		Input_ShowMaximumOpenPositionLoss.Name = "Show Maximum Open Position Loss";
		Input_ShowMaximumOpenPositionLoss.SetYesNo(0);

		Input_ShowFlatToFlatClosedProfitLoss.Name = "Show Flat to Flat Closed Profit Loss";
		Input_ShowFlatToFlatClosedProfitLoss.SetYesNo(0);

		Input_ProfitLossFormat.Name = "Profit/Loss Display Format";
		Input_ProfitLossFormat.SetCustomInputStrings("Currency Value;Points (P);Points - Ignore Quantity (p);Ticks (T);Ticks - Ignore Quantity (t);Currency Value & Points (P);Currency Value & Points - Ignore Quantity (p);Currency Value & Ticks (T);Currency Value & Ticks - Ignore Quantity (t)");
		Input_ProfitLossFormat.SetCustomInputIndex(0);

		Input_RTCommission.Name = "Round Turn Commission To Include";
		Input_RTCommission.SetFloat(0);

		
		return;
	}

	// This is to ensure that we access the trade data that matches the simulation mode setting.
	sc.SendOrdersToTradeService = !sc.GlobalTradeSimulationIsOn;

	if (sc.HideStudy)
		return;

	int& r_TextDrawingLineNumber = sc.GetPersistentInt(1);

	// Do data processing
	s_UseTool Tool;

	Tool.Clear(); // Reset tool structure for our next use. Unnecessary in this case, but good practice.
	Tool.DrawingType = DRAWING_TEXT;
	Tool.ChartNumber = sc.ChartNumber;
	Tool.Region = sc.GraphRegion;

	if (r_TextDrawingLineNumber != 0)
		Tool.LineNumber = r_TextDrawingLineNumber;

	Tool.AddMethod = UTAM_ADD_OR_ADJUST;

	if(Input_DisplayInFillSpace.GetYesNo())
		Tool.BeginDateTime = -3;
	else
		Tool.BeginDateTime = Input_HorizontalPosition.GetInt();

	Tool.BeginValue = (float)Input_VerticalPosition.GetInt();
	Tool.UseRelativeVerticalValues = true;
	Tool.Color = Input_TextColor.GetColor();
	Tool.FontFace = sc.ChartTextFont;
	Tool.FontBackColor = Input_TextBackColor.GetColor();
	Tool.FontSize = Input_TextSize.GetInt();
	Tool.FontBold = true;
	Tool.ReverseTextColor = false;
	Tool.MultiLineLabel = true;
	Tool.TextAlignment = DT_LEFT;

	ProfitLossDisplayFormatEnum ProfitLossDisplayFormat = (ProfitLossDisplayFormatEnum)(Input_ProfitLossFormat.GetIndex()+1);

	s_SCPositionData PositionData;
	sc.GetTradePosition(PositionData) ;

	double RoundTurnCommissionRate = sc.CurrencyValuePerTick == 0 ? 0 : Input_RTCommission.GetFloat();

	SCString Text;

	n_ACSIL::s_TradeStatistics AllStats;
	n_ACSIL::s_TradeStatistics DailyStats;

	sc.GetTradeStatisticsForSymbolV2(n_ACSIL::STATS_TYPE_ALL_TRADES, AllStats);
	sc.GetTradeStatisticsForSymbolV2(n_ACSIL::STATS_TYPE_DAILY_ALL_TRADES, DailyStats);

	if (Input_ShowOpenPL.GetYesNo())
	{
		SCString PLString;
		double Commission = RoundTurnCommissionRate * PositionData.PositionQuantity / 2.0;
		sc.CreateProfitLossDisplayString(PositionData.OpenProfitLoss-Commission, PositionData.PositionQuantity, ProfitLossDisplayFormat, PLString);
		Text.Format("Open PL: %s", PLString.GetChars());
	}

	if (Input_ShowClosedPL.GetYesNo())
	{
		if (Text != "")
			Text.Append("\n");

		SCString PLString;
		double Commission = RoundTurnCommissionRate * AllStats.TotalQuantity;
		sc.CreateProfitLossDisplayString(AllStats.ClosedTradesProfitLoss - Commission, AllStats.TotalQuantity, ProfitLossDisplayFormat, PLString);
		
		SCString ClosedPLText;
		ClosedPLText.Format("Closed PL: %s", PLString.GetChars());

		Text.Append(ClosedPLText);
	}

	if (Input_ShowDailyPL.GetYesNo())
	{
		if (Text != "")
			Text.Append("\n");

		double DailyPL = DailyStats.ClosedTradesProfitLoss;
		t_OrderQuantity32_64  DailyClosedQuantity = DailyStats.TotalQuantity;
		double Commission = RoundTurnCommissionRate * DailyClosedQuantity;

		if (Input_IncludeOpenPLInDailyPL.GetYesNo())
		{
			DailyPL += PositionData.OpenProfitLoss;
			t_OrderQuantity32_64 OpenQuantity = abs(PositionData.PositionQuantity);
			DailyClosedQuantity += OpenQuantity;
			Commission += (RoundTurnCommissionRate * OpenQuantity / 2.0);
			Text.Append("Daily Net PL: ");
		}
		else
			Text.Append("Daily PL: ");

		SCString PLString;
		sc.CreateProfitLossDisplayString(DailyPL-Commission, DailyClosedQuantity, ProfitLossDisplayFormat, PLString);

		Text.Append(PLString);
	}

	if (Input_ShowTotalTrades.GetYesNo())
	{
		if (Text != "")
			Text.Append("\n");

		SCString TotalTradesText;
		TotalTradesText.Format("Total Trades: %i", AllStats.TotalTrades);

		Text.Append(TotalTradesText);
	}

	if (Input_ShowTotalQuantityFilled.GetYesNo())
	{
		if (Text != "")
			Text.Append("\n");

		SCString TotalFilledText("Total Filled Qty: ");
		SCString QuantityString;
		sc.OrderQuantityToString(AllStats.TotalFilledQuantity, QuantityString);
		TotalFilledText += QuantityString;

		Text.Append(TotalFilledText);
	}

	if (Input_ShowDailyTotalTrades.GetYesNo())
	{
		if (Text != "")
			Text.Append("\n");

		SCString TotalTradesText;
		TotalTradesText.Format("Daily Trades: %i", DailyStats.TotalTrades);

		Text.Append(TotalTradesText);
	}

	if (Input_ShowDailyTotalQuantityFilled.GetYesNo())
	{
		if (Text != "")
			Text.Append("\n");

		SCString TotalFilledText("Daily Filled Qty: ");
		SCString QuantityString;
		sc.OrderQuantityToString(DailyStats.TotalFilledQuantity, QuantityString);
		TotalFilledText += QuantityString;

		Text.Append(TotalFilledText);
	}

	if (Input_ShowMaximumOpenPositionProfit.GetYesNo())
	{
		if (Text != "")
			Text.Append("\n");

		SCString PLString;
		sc.CreateProfitLossDisplayString(PositionData.MaximumOpenPositionProfit, PositionData.PositionQuantity, ProfitLossDisplayFormat, PLString);
		Text.AppendFormat("Max Open Profit: %s", PLString.GetChars());
	}

	if (Input_ShowMaximumOpenPositionLoss.GetYesNo())
	{
		if (Text != "")
			Text.Append("\n");

		SCString PLString;
		sc.CreateProfitLossDisplayString(PositionData.MaximumOpenPositionLoss, PositionData.PositionQuantity, ProfitLossDisplayFormat, PLString);
		Text.AppendFormat("Max Open Loss: %s", PLString.GetChars());
	}

	if (Input_ShowFlatToFlatClosedProfitLoss.GetYesNo())
	{
		if (Text != "")
			Text.Append("\n");

		SCString PLString;
		sc.CreateProfitLossDisplayString(DailyStats.ClosedFlatToFlatTradesProfitLoss, 0, ProfitLossDisplayFormat, PLString);
		Text.AppendFormat("FTF P/L: %s", PLString.GetChars());

	}

	Tool.Text = Text;

	sc.UseTool(Tool);

	r_TextDrawingLineNumber = Tool.LineNumber;
}


/*==========================================================================*/
SCSFExport scsf_UpDownVolumeRatio(SCStudyInterfaceRef sc)
{
	SCSubgraphRef Subgraph_UpDownVolumeRatio = sc.Subgraph[0];
	SCSubgraphRef Subgraph_ZeroLine = sc.Subgraph[1];

	SCInputRef Input_MovingAverageLength = sc.Input[0];
	SCInputRef Input_VolumeOrTrades = sc.Input[1];
	SCInputRef Input_MovingAverageType = sc.Input [2];


	if (sc.SetDefaults)
	{
		// Set the configuration and defaults

		sc.GraphName = "Up/Down Volume Ratio";
		sc.MaintainAdditionalChartDataArrays = 1;

		sc.GraphRegion =1;

		Subgraph_UpDownVolumeRatio.Name = "VR";
		Subgraph_UpDownVolumeRatio.DrawStyle = DRAWSTYLE_BAR;
		Subgraph_UpDownVolumeRatio.PrimaryColor = RGB(0, 255, 0);
		Subgraph_UpDownVolumeRatio.SecondaryColor = RGB(255, 0, 0);
		Subgraph_UpDownVolumeRatio.LineWidth = 3;
		Subgraph_UpDownVolumeRatio.AutoColoring = AUTOCOLOR_POSNEG;
		Subgraph_UpDownVolumeRatio.DrawZeros = false;  // false

		Subgraph_ZeroLine.Name = "Zero";
		Subgraph_ZeroLine.DrawStyle = DRAWSTYLE_LINE;
		Subgraph_ZeroLine.PrimaryColor = RGB(128, 128,128);
		Subgraph_ZeroLine.LineWidth = 2;
		Subgraph_ZeroLine.DrawZeros = true;  // true

		Input_MovingAverageLength.Name = "Moving Average Length";
		Input_MovingAverageLength.SetInt(14);
		Input_MovingAverageLength.SetIntLimits(1, INT_MAX);

		Input_VolumeOrTrades.Name = "Calculation Based On";
		Input_VolumeOrTrades.SetCustomInputStrings("Up/Down Volume;Ask/Bid Volume;Up/Down Trades");
		Input_VolumeOrTrades.SetCustomInputIndex(0);

		Input_MovingAverageType.Name = "Moving Average Type";
		Input_MovingAverageType.SetMovAvgType(MOVAVGTYPE_EXPONENTIAL);
		
		

		sc.AutoLoop = 1;

		return;
	}
	
	
	// Do data processing
	int Up = SC_UPVOL;
	int Down = SC_DOWNVOL;

	if(Input_VolumeOrTrades.GetIndex() == 0)
	{	
		Up = SC_UPVOL;
		Down = SC_DOWNVOL;
	}
	else if(Input_VolumeOrTrades.GetIndex() == 1)
	{	
		Up = SC_ASKVOL;
		Down = SC_BIDVOL;
	}
	else
	{
		Up = SC_ASKNT;
		Down = SC_BIDNT;
	}

	float TotalTrades = sc.BaseData[Up][sc.Index] + sc.BaseData[Down][sc.Index];
	
	if (TotalTrades > 0)
		Subgraph_UpDownVolumeRatio.Arrays[0][sc.Index] = 100 * (sc.BaseData[Up][sc.Index] - sc.BaseData[Down][sc.Index]) / TotalTrades;
	else
		Subgraph_UpDownVolumeRatio.Arrays[0][sc.Index] = 0.0f;
	
	sc.MovingAverage(Subgraph_UpDownVolumeRatio.Arrays[0], Subgraph_UpDownVolumeRatio, Input_MovingAverageType.GetMovAvgType(), Input_MovingAverageLength.GetInt());
}

/*==========================================================================*/

SCSFExport scsf_MovAvgCross(SCStudyInterfaceRef sc)
{ 
	SCInputRef Input_MA1Price = sc.Input[0];
	SCInputRef Input_MA1Type = sc.Input[1];
	SCInputRef Input_MA1Length = sc.Input[2];
	SCInputRef Input_MA2Price = sc.Input[3];
	SCInputRef Input_MA2Type = sc.Input[4];
	SCInputRef Input_MA2Length = sc.Input[5];
	SCInputRef Input_DotsSpacing = sc.Input[6];

	if (sc.SetDefaults)
	{
		// Set the configuration and defaults

		sc.GraphName = "Moving Average Crossover";

		sc.AutoLoop = 1;

		sc.GraphRegion = 0;

		sc.Subgraph[0].Name = "Moving Average 1";
		sc.Subgraph[0].DrawStyle = DRAWSTYLE_LINE;
		sc.Subgraph[0].PrimaryColor = RGB(0,255,0);

		sc.Subgraph[1].Name = "Moving Average 2";
		sc.Subgraph[1].DrawStyle = DRAWSTYLE_LINE;
		sc.Subgraph[1].PrimaryColor = RGB(255,0,255);

		sc.Subgraph[2].Name = "Buy/Sell";
		sc.Subgraph[2].SecondaryColorUsed = 1;
		sc.Subgraph[2].PrimaryColor = RGB(0,255,0);
		sc.Subgraph[2].SecondaryColor = RGB(255,0,0);
		sc.Subgraph[2].DrawStyle = DRAWSTYLE_POINT;
		sc.Subgraph[2].LineWidth = 4;

		Input_MA1Price.Name = "Moving Average 1 Input Data";
		Input_MA1Price.SetInputDataIndex(SC_LAST);
		Input_MA1Type.Name = "MA1.Type";
		Input_MA1Type.SetMovAvgType(MOVAVGTYPE_EXPONENTIAL);
		Input_MA1Length.Name = "MA1.Length";
		Input_MA1Length.SetInt(5);
		Input_MA1Length.SetIntLimits(1,MAX_STUDY_LENGTH);

		Input_MA2Price.Name = "Moving Average 2 Input Data";
		Input_MA2Price.SetInputDataIndex(SC_OPEN);
		Input_MA2Type.Name = "MA2.Type";
		Input_MA2Type.SetMovAvgType(MOVAVGTYPE_WEIGHTED);
		Input_MA2Length.Name = "MA2.Length";
		Input_MA2Length.SetInt(6);
		Input_MA2Length.SetIntLimits(1,MAX_STUDY_LENGTH);


		return;
	}

	// Do data processing
	sc.MovingAverage(sc.BaseData[Input_MA1Price.GetInputDataIndex()], sc.Subgraph[0],Input_MA1Type.GetMovAvgType(),Input_MA1Length.GetInt());

	sc.MovingAverage(sc.BaseData[Input_MA2Price.GetInputDataIndex()], sc.Subgraph[1],Input_MA2Type.GetMovAvgType(),Input_MA2Length.GetInt());

	int direction = sc.CrossOver(sc.Subgraph[0],sc.Subgraph[1]);
	if (direction == CROSS_FROM_TOP)
	{
		sc.Subgraph[2][sc.Index] = sc.BaseData[SC_HIGH][sc.Index];
		sc.Subgraph[2].DataColor[sc.Index] = sc.Subgraph[2].SecondaryColor;
	}
	else if (direction == CROSS_FROM_BOTTOM)
	{	
		sc.Subgraph[2][sc.Index] = sc.BaseData[SC_LOW][sc.Index];
		sc.Subgraph[2].DataColor[sc.Index] = sc.Subgraph[2].PrimaryColor;
	}
	else
	{
		sc.Subgraph[2][sc.Index] = 0;
	}
}


/*==========================================================================*/
SCSFExport scsf_BillWilliamsAC(SCStudyInterfaceRef sc)
{
	SCSubgraphRef Subgraph_Up = sc.Subgraph[0];
	SCSubgraphRef Subgraph_Down = sc.Subgraph[1];
	SCSubgraphRef Subgraph_Flat = sc.Subgraph[2];
	SCSubgraphRef Subgraph_All = sc.Subgraph[3];
	SCSubgraphRef Subgraph_Temp4 = sc.Subgraph[4];
	SCSubgraphRef Subgraph_Sum1 = sc.Subgraph[5];
	SCSubgraphRef Subgraph_Avg1 = sc.Subgraph[6];
	SCSubgraphRef Subgraph_Sum2 = sc.Subgraph[7];
	SCSubgraphRef Subgraph_Avg2 = sc.Subgraph[8];
	SCSubgraphRef Subgraph_Sum4 = sc.Subgraph[9];
	SCSubgraphRef Subgraph_Avg4 = sc.Subgraph[10];

	SCInputRef Input_LongMaLength = sc.Input[0];
	SCInputRef Input_ShortMaLength = sc.Input[1];
	SCInputRef Input_SignalMaLength = sc.Input[2];
	SCInputRef Input_MaType = sc.Input[3];

	if (sc.SetDefaults)
	{
		sc.GraphName = "Bill Williams AC";

		sc.StudyDescription = "";

		

		Subgraph_Up.Name = "Up";
		Subgraph_Up.DrawStyle = DRAWSTYLE_DASH;
		Subgraph_Up.PrimaryColor = RGB( 0, 255, 0);
		Subgraph_Up.DrawZeros = false;

		Subgraph_Down.Name = "Down";
		Subgraph_Down.DrawStyle = DRAWSTYLE_DASH;
		Subgraph_Down.PrimaryColor = RGB( 255, 0, 255);
		Subgraph_Down.DrawZeros = false;

		Subgraph_Flat.Name = "Flat";
		Subgraph_Flat.DrawStyle = DRAWSTYLE_DASH;
		Subgraph_Flat.PrimaryColor = RGB( 192, 192, 192);
		Subgraph_Flat.DrawZeros = false;

		Subgraph_All.Name = "All";
		Subgraph_All.DrawStyle = DRAWSTYLE_IGNORE;
		Subgraph_All.PrimaryColor = RGB( 255, 127, 0);
		Subgraph_All.DrawZeros = false;

		Input_LongMaLength.Name = "Long Moving Average Length";
		Input_LongMaLength.SetInt(34);
		Input_LongMaLength.SetIntLimits(1, INT_MAX);

		Input_ShortMaLength.Name = "Short Moving Average Length";
		Input_ShortMaLength.SetInt(5);
		Input_ShortMaLength.SetIntLimits(1, INT_MAX);

		Input_SignalMaLength.Name = "Signal Moving Average Length";
		Input_SignalMaLength.SetInt(5);
		Input_SignalMaLength.SetIntLimits(1, INT_MAX);

		Input_MaType.Name = "Moving Average Type";
		Input_MaType.SetCustomInputStrings("Bill Williams Smoothed;Exponential;Simple");
		Input_MaType.SetCustomInputIndex(0);


		sc.AutoLoop = 1;

		return;
	}

	// Do data processing

	const float cfactor1 = 2.0f / (Input_LongMaLength.GetInt() + 1);		const float cinvfactor1 = 1.0f - cfactor1;
	const float cfactor2 = 2.0f / (Input_ShortMaLength.GetInt() + 1);	const float cinvfactor2 = 1.0f - cfactor2;
	const float cfactor4 = 2.0f / (Input_SignalMaLength.GetInt() + 1);	const float cinvfactor4 = 1.0f - cfactor4;

	sc.DataStartIndex = 50;

	int pos = sc.Index;
	if (pos < 50)
		return;

	int j;
	float avg3, avg4;

	switch (Input_MaType.GetInt())
	{
	case 0:
		{
			Subgraph_Sum1[pos] = Subgraph_Sum1[pos - 1] + sc.Close[pos];
			if (pos >= 50 + Input_LongMaLength.GetInt())
				Subgraph_Sum1[pos] = Subgraph_Sum1[pos] - Subgraph_Avg1[pos - 1];
			Subgraph_Avg1[pos] = Subgraph_Sum1[pos] / Input_LongMaLength.GetInt();

			Subgraph_Sum2[pos] = Subgraph_Sum2[pos - 1] + sc.Close[pos];
			if (pos >= 50 + Input_ShortMaLength.GetInt())
				Subgraph_Sum2[pos] = Subgraph_Sum2[pos] - Subgraph_Avg2[pos - 1];
			Subgraph_Avg2[pos] = Subgraph_Sum2[pos] / Input_ShortMaLength.GetInt();

			avg3 = Subgraph_Avg2[pos] - Subgraph_Avg1[pos];

			Subgraph_Temp4.Data[pos] = avg3;
			Subgraph_Sum4[pos] = Subgraph_Sum4[pos - 1] + avg3;
			avg4 = Subgraph_Sum4[pos] / Input_SignalMaLength.GetInt();
			j = pos - Input_SignalMaLength.GetInt() + 1;
			if (pos > 50 + Input_SignalMaLength.GetInt() - 2)
				Subgraph_Sum4[pos] = Subgraph_Sum4[pos] - Subgraph_Temp4.Data[j];
		}
		break;

	case 1:
		{
			Subgraph_Avg1[pos] = Subgraph_Avg1[pos - 1] * cinvfactor1 + sc.Close[pos] * cfactor1;
			Subgraph_Avg2[pos] = Subgraph_Avg2[pos - 1] * cinvfactor2 + sc.Close[pos] * cfactor2;
			avg3 = Subgraph_Avg2[pos] - Subgraph_Avg1[pos];
			//Temp4.Data[pos] = avg3;
			avg4 = Subgraph_Avg4[pos] = Subgraph_Avg4[pos - 1] * cinvfactor4 + avg3 * cfactor4;
		}
		break;

	case 2:
	default:
		{
			Subgraph_Sum1[pos] = Subgraph_Sum1[pos - 1] + sc.Close[pos];
			float avg1 = Subgraph_Sum1[pos] / Input_LongMaLength.GetInt();
			j = pos - Input_LongMaLength.GetInt() + 1;
			if (pos > 50 + Input_LongMaLength.GetInt() - 2)
				Subgraph_Sum1[pos] = Subgraph_Sum1[pos] - sc.Close[j];

			Subgraph_Sum2[pos] = Subgraph_Sum2[pos - 1] + sc.Close[pos];
			float avg2 = Subgraph_Sum2[pos] / Input_ShortMaLength.GetInt();
			j = pos - Input_ShortMaLength.GetInt() + 1;
			if (pos > 50 + Input_ShortMaLength.GetInt() - 2)
				Subgraph_Sum2[pos] = Subgraph_Sum2[pos] - sc.Close[j];

			avg3 = avg2 - avg1;

			Subgraph_Temp4.Data[pos] = avg3;
			Subgraph_Sum4[pos] = Subgraph_Sum4[pos - 1] + avg3;
			avg4 = Subgraph_Sum4[pos] / Input_SignalMaLength.GetInt();
			j = pos - Input_SignalMaLength.GetInt() + 1;
			if (pos > 50 + Input_SignalMaLength.GetInt() - 2)
				Subgraph_Sum4[pos] = Subgraph_Sum4[pos] - Subgraph_Temp4.Data[j];
		}
		break;
	}


	Subgraph_All.Data[pos] = avg3 - avg4;

	if (Subgraph_All.Data[pos] > Subgraph_All.Data[pos - 1])
	{
		Subgraph_Up.Data[pos] = Subgraph_All.Data[pos];
		Subgraph_Down.Data[pos] = 0;
		Subgraph_Flat.Data[pos] = 0;
	}
	else if(Subgraph_All.Data[pos] < Subgraph_All.Data[pos - 1])
	{
		Subgraph_Up.Data[pos] = 0;
		Subgraph_Down.Data[pos] = Subgraph_All.Data[pos];
		Subgraph_Flat.Data[pos] = 0;
	}
	else
	{
		Subgraph_Up.Data[pos] = 0;
		Subgraph_Down.Data[pos] = 0;
		Subgraph_Flat.Data[pos] = Subgraph_All.Data[pos];
	}
}

/*==========================================================================*/
SCSFExport scsf_BillWilliamsAO(SCStudyInterfaceRef sc)
{
	SCSubgraphRef Subgraph_AO = sc.Subgraph[0];
	SCSubgraphRef Subgraph_ZeroLine = sc.Subgraph[1];

	SCInputRef Input_InputData = sc.Input[0];
	SCInputRef Input_MA1Length = sc.Input[2];
	SCInputRef Input_MA2Length = sc.Input[3];
	SCInputRef Input_MAType = sc.Input[4];

	if (sc.SetDefaults)
	{
		sc.GraphName = "Bill Williams Awesome Oscillator";

		sc.GraphRegion = 1;
		sc.ValueFormat = 3;
		sc.AutoLoop = 1;

		Subgraph_AO.Name = "AO";
		Subgraph_AO.DrawStyle = DRAWSTYLE_BAR;
		Subgraph_AO.LineWidth = 2;
		Subgraph_AO.SecondaryColor = RGB(255,0,0);
		Subgraph_AO.AutoColoring = AUTOCOLOR_SLOPE;
		Subgraph_AO.DrawZeros = false;

		Subgraph_ZeroLine.Name ="Zero Line";
		Subgraph_ZeroLine.DrawStyle = DRAWSTYLE_LINE;
		Subgraph_ZeroLine.LineWidth =1;
		Subgraph_ZeroLine.PrimaryColor = RGB(255,0,255);
		Subgraph_ZeroLine.DrawZeros = true;

		Input_InputData.SetInputDataIndex(SC_HL_AVG);

		Input_MA1Length.Name = "Moving Average 1 Length";
		Input_MA1Length.SetInt(34);
		Input_MA1Length.SetIntLimits(1, MAX_STUDY_LENGTH);

		Input_MA2Length.Name = "Moving Average 2 Length";
		Input_MA2Length.SetInt(5);
		Input_MA2Length.SetIntLimits(1, MAX_STUDY_LENGTH);

		Input_MAType.Name = "Moving Average Type";
		Input_MAType.SetMovAvgType(MOVAVGTYPE_SIMPLE);


		return;
	}

	sc.DataStartIndex = max(Input_MA1Length.GetInt(), Input_MA2Length.GetInt());



	sc.MovingAverage(sc.BaseDataIn[Input_InputData.GetInputDataIndex()], Subgraph_AO.Arrays[0], Input_MAType.GetMovAvgType(), Input_MA1Length.GetInt());
	sc.MovingAverage(sc.BaseDataIn[Input_InputData.GetInputDataIndex()], Subgraph_AO.Arrays[1], Input_MAType.GetMovAvgType(), Input_MA2Length.GetInt());

	Subgraph_AO.Data[sc.Index] = Subgraph_AO.Arrays[1][sc.Index] - Subgraph_AO.Arrays[0][sc.Index];

}

/*==========================================================================*/
SCSFExport scsf_BillWilliamsMA(SCStudyInterfaceRef sc)
{
	SCSubgraphRef Subgraph_MovAvg = sc.Subgraph[0];

	SCInputRef Input_InputData = sc.Input[0];
	SCInputRef Input_MovingAverageLength = sc.Input[2];
	SCInputRef Input_MovingAverageType = sc.Input[4];
	SCInputRef Input_Version = sc.Input[5];

	if (sc.SetDefaults)
	{
		sc.GraphName = "Bill Williams Moving Average";

		sc.StudyDescription = "To offset the moving average, use the Displacement setting for the MovAvg Subgraph.";
		sc.GraphRegion= 0;

		Subgraph_MovAvg.Name = "MovAvg";
		Subgraph_MovAvg.DrawStyle = DRAWSTYLE_LINE;
		Subgraph_MovAvg.PrimaryColor = RGB(0,255,0);

		Input_InputData.Name = "Input Data";
		Input_InputData.SetInputDataIndex(SC_LAST);

		Input_MovingAverageLength.Name = "MovAvg Length";
		Input_MovingAverageLength.SetInt(34);
		Input_MovingAverageLength.SetIntLimits(1, INT_MAX);

		Input_MovingAverageType.Name = "Moving Average Type";
		Input_MovingAverageType.SetCustomInputStrings(";Bill Willams EMA;Smoothed Moving Average");
		Input_MovingAverageType.SetCustomInputIndex(2);

		Input_Version.SetInt(1);

		sc.AutoLoop = 1;

		return;
	}

	// Do data processing

	sc.DataStartIndex = 0;

	if (Input_Version.GetInt() < 1)
	{
		Input_InputData.SetInputDataIndex(SC_LAST);
		Input_Version.SetInt(1);
	}

	if (Input_MovingAverageType.GetIndex() == 0)
		Input_MovingAverageType.SetCustomInputIndex(1);

	uint32_t InputIndex = Input_InputData.GetInputDataIndex();

	if (Input_MovingAverageType.GetIndex() == 1)
	{
		if (sc.Index == 0)
		{
			Subgraph_MovAvg[0] = sc.BaseData[InputIndex][0];
			Subgraph_MovAvg.Arrays[4][sc.Index] = sc.BaseData[InputIndex][0]*Input_MovingAverageLength.GetInt();
		}
		else
		{
			Subgraph_MovAvg.Arrays[4][sc.Index] = Subgraph_MovAvg.Arrays[4][sc.Index - 1] + sc.BaseData[InputIndex][sc.Index];
			Subgraph_MovAvg.Arrays[4][sc.Index] -=  Subgraph_MovAvg[sc.Index - 1];
			Subgraph_MovAvg[sc.Index] = Subgraph_MovAvg.Arrays[4][sc.Index] / Input_MovingAverageLength.GetInt();
		}
	}
	else
	{
		sc.SmoothedMovingAverage(sc.BaseData[InputIndex], Subgraph_MovAvg, sc.Index, Input_MovingAverageLength.GetInt());
	}
}

/*==========================================================================*/
SCSFExport scsf_BillWilliamsAlligator(SCStudyInterfaceRef sc)
{
	const int jaw = 0;
	const int teeth = 1;
	const int lips = 2;

	SCSubgraphRef Subgraph_Jaw = sc.Subgraph[0];
	SCSubgraphRef Subgraph_Teeth = sc.Subgraph[1];
	SCSubgraphRef Subgraph_Lips = sc.Subgraph[2];

	SCInputRef Input_InputData = sc.Input[0];
	SCInputRef Input_JawLength = sc.Input[1];
	SCInputRef Input_TeethLength = sc.Input[3];
	SCInputRef Input_LipsLength = sc.Input[5];
	SCInputRef Input_VersionUpdate1 = sc.Input[7];
	SCInputRef Input_MovAvgType = sc.Input[8];
	SCInputRef Input_VersionUpdate2 = sc.Input[9];

	if (sc.SetDefaults)
	{
		sc.GraphName = "Bill Williams Alligator";

		sc.StudyDescription = "";

		// Set the region to draw the graph in.  Region zero is the main
		// price graph region.
		sc.GraphRegion = 0;
		

		// Set the name of the first subgraph
		// Set the color and style of the graph line.  If these are not set
		// the default will be used.
		Subgraph_Jaw.Name = "Jaw";		
		Subgraph_Jaw.PrimaryColor = RGB(0,0,255);  // Blue
		Subgraph_Jaw.DrawStyle = DRAWSTYLE_LINE;
		Subgraph_Jaw.GraphicalDisplacement = 8;
		Subgraph_Jaw.DrawZeros = false;

		// Set the color and style of the graph line.  If these are not set
		// the default will be used.
		Subgraph_Teeth.Name = "Teeth";
		Subgraph_Teeth.PrimaryColor = RGB(255,0,0);  // Red
		Subgraph_Teeth.DrawStyle = DRAWSTYLE_LINE;
		Subgraph_Teeth.GraphicalDisplacement = 5;
		Subgraph_Teeth.DrawZeros = false;

		// Set the color and style of the graph line.  If these are not set
		// the default will be used.
		Subgraph_Lips.Name = "Lips";		
		Subgraph_Lips.PrimaryColor = RGB(0, 255, 0);  // Red
		Subgraph_Lips.DrawStyle = DRAWSTYLE_LINE;
		Subgraph_Lips.GraphicalDisplacement = 3;
		Subgraph_Lips.DrawZeros = false;

		sc.AutoLoop = 1;

		Input_InputData.Name = "Input Data";
		Input_InputData.SetInputDataIndex(SC_HL_AVG);

		Input_JawLength.Name = "Jaw Length";
		Input_JawLength.SetIntLimits(1,MAX_STUDY_LENGTH);
		Input_JawLength.SetInt(13);

		Input_TeethLength.Name = "Teeth Length";
		Input_TeethLength.SetIntLimits(1,MAX_STUDY_LENGTH);
		Input_TeethLength.SetInt(8);

		Input_LipsLength.Name = "Lips Length";
		Input_LipsLength.SetIntLimits(1,MAX_STUDY_LENGTH);
		Input_LipsLength.SetInt(5);

		Input_VersionUpdate1.SetYesNo(true); //Used For Settings Updating

		Input_MovAvgType.Name = "Moving Average Type";
		Input_MovAvgType.SetMovAvgType(MOVAVGTYPE_SMOOTHED);

		Input_VersionUpdate2.SetYesNo(true);
		return;
	}

	// data processing

	if (Input_VersionUpdate2.GetYesNo() == false)
		Input_MovAvgType.SetMovAvgType(MOVAVGTYPE_SMOOTHED);

	if (Input_VersionUpdate1.GetYesNo() == false)
	{
		Subgraph_Jaw.GraphicalDisplacement = 8;
		Subgraph_Teeth.GraphicalDisplacement = 5;
		Subgraph_Lips.GraphicalDisplacement = 3;
	}

	// calculate jaw, teeth and lips

	sc.MovingAverage(sc.BaseData[Input_InputData.GetInputDataIndex()], Subgraph_Jaw, Input_MovAvgType.GetMovAvgType(), Input_JawLength.GetInt());
	sc.MovingAverage(sc.BaseData[Input_InputData.GetInputDataIndex()], Subgraph_Teeth, Input_MovAvgType.GetMovAvgType(), Input_TeethLength.GetInt());
	sc.MovingAverage(sc.BaseData[Input_InputData.GetInputDataIndex()], Subgraph_Lips, Input_MovAvgType.GetMovAvgType(), Input_LipsLength.GetInt());
}



/*==========================================================================*/

SCSFExport scsf_AverageOfAverage(SCStudyInterfaceRef sc)
{
	SCSubgraphRef Subgraph_Avg = sc.Subgraph[0];
	SCSubgraphRef Subgraph_Temp1 = sc.Subgraph[1];

	SCInputRef Input_Length = sc.Input[0];
	SCInputRef Input_EmaLength = sc.Input[1];

	if (sc.SetDefaults)
	{
		// Set the configuration and defaults
		
		sc.GraphName = "Average of Average";
		
		sc.StudyDescription = "";

		sc.AutoLoop = 1;  // true
		
		Subgraph_Avg.Name = "Avg";
		Subgraph_Avg.DrawStyle = DRAWSTYLE_LINE;
		Subgraph_Avg.PrimaryColor = RGB(0,255,0);
		
		Input_Length.Name = "Length";
		Input_Length.SetInt(10);
		Input_Length.SetIntLimits(1, INT_MAX);
		
		Input_EmaLength.Name = "ExpMA Length";
		Input_EmaLength.SetInt(10);
		Input_EmaLength.SetIntLimits(1, INT_MAX);
		
		return;
	}
	
	
	// Do data processing
	
	
	/* This calculates the Exponential Moving Average of a Linear Regression Indicator
		by passing the output array from the Linear Regression Indicator function to the
		Input data parameter of Exponential Moving Average function.*/
	
	sc.LinearRegressionIndicator(sc.Close, Subgraph_Temp1, sc.Index, Input_Length.GetInt());
	sc.ExponentialMovAvg(Subgraph_Temp1, Subgraph_Avg, sc.Index, Input_EmaLength.GetInt());
}



/*==========================================================================*/
SCSFExport scsf_WoodiesEMA(SCStudyInterfaceRef sc)
{
	SCSubgraphRef Subgraph_EMA = sc.Subgraph[0];
	SCSubgraphRef Subgraph_UpDownColors = sc.Subgraph[1];
	SCSubgraphRef Subgraph_EMAOutput = sc.Subgraph[2];

	SCInputRef Input_NumberOfBars = sc.Input[0];
	SCInputRef Input_PriceChange = sc.Input[1];
	SCInputRef Input_EMALength = sc.Input[2];
	SCInputRef Input_FixedValue = sc.Input[4];
	SCInputRef Input_InputData = sc.Input[6];

	if(sc.SetDefaults)
	{
		sc.GraphName="Woodies EMA";

		sc.AutoLoop = 1;

		sc.GraphRegion = 0;

		Subgraph_EMA.Name = "EMA";
		Subgraph_EMA.DrawStyle = DRAWSTYLE_LINE;
		Subgraph_EMA.PrimaryColor = RGB(0,255,0);
		Subgraph_EMA.DrawZeros = false;

		Subgraph_UpDownColors.Name = "Up / Down Color";
		Subgraph_UpDownColors.DrawStyle = DRAWSTYLE_IGNORE;
		Subgraph_UpDownColors.PrimaryColor = RGB(0,255,0);
		Subgraph_UpDownColors.SecondaryColor = RGB(255,0,0);
		Subgraph_UpDownColors.SecondaryColorUsed = 1;
		Subgraph_UpDownColors.DrawZeros = false;

		Input_InputData.Name = "Input Data";
		Input_InputData.SetInputDataIndex(SC_HLC_AVG);

		Input_NumberOfBars.Name = "Number of Bars for Angle";
		Input_NumberOfBars.SetInt(4);
		Input_NumberOfBars.SetIntLimits(1,MAX_STUDY_LENGTH);

		Input_PriceChange.Name = "Price Change for Angle";
		Input_PriceChange.SetFloat(0.000001f);


		Input_EMALength.Name = "EMA Length";
		Input_EMALength.SetInt(34);
		Input_EMALength.SetIntLimits(1,MAX_STUDY_LENGTH);

		Input_FixedValue.Name = "Fixed Value to Use";
		Input_FixedValue.SetFloat(0);

		return;
	}


	sc.DataStartIndex = Input_EMALength.GetInt() + Input_NumberOfBars.GetInt();

	sc.ExponentialMovAvg(sc.BaseData[Input_InputData.GetInputDataIndex()], Subgraph_EMAOutput, Input_EMALength.GetInt());

	if (sc.Index < Input_NumberOfBars.GetInt())
		return;

	int BarIndex = sc.Index;

	if(Input_FixedValue.GetFloat() == 0.0f) 
		Subgraph_EMA[BarIndex] = Subgraph_EMAOutput[BarIndex];
	else 
		Subgraph_EMA[BarIndex] = Input_FixedValue.GetFloat();

	if (Subgraph_EMAOutput[BarIndex] - Subgraph_EMAOutput[BarIndex-Input_NumberOfBars.GetInt()] >= Input_PriceChange.GetFloat())
	{
		Subgraph_EMA.DataColor[BarIndex] = Subgraph_UpDownColors.PrimaryColor;  
	}
	else if (Subgraph_EMAOutput[BarIndex] - Subgraph_EMAOutput[BarIndex-Input_NumberOfBars.GetInt()] <= -Input_PriceChange.GetFloat())
	{
		Subgraph_EMA.DataColor[BarIndex] = Subgraph_UpDownColors.SecondaryColor; 
	}
	else
	{
		Subgraph_EMA.DataColor[BarIndex] = Subgraph_EMA.PrimaryColor;
	}

}

/*==========================================================================*/
SCSFExport scsf_WoodieCCITrend(SCStudyInterfaceRef sc)
{
	SCSubgraphRef Subgraph_Above = sc.Subgraph[0];
	SCSubgraphRef Subgraph_Below = sc.Subgraph[1];
	SCSubgraphRef Subgraph_AboveColorValues = sc.Subgraph[2];
	SCSubgraphRef Subgraph_DoNotDraw1 = sc.Subgraph[3];
	SCSubgraphRef Subgraph_DoNotDraw2 = sc.Subgraph[4];
	SCSubgraphRef Subgraph_CCI = sc.Subgraph[5];

	SCInputRef Input_WarningBar = sc.Input[0];
	SCInputRef Input_AlternateColor = sc.Input[1];
	SCInputRef Input_CCILength = sc.Input[2];
	SCInputRef Input_NumberOfBars = sc.Input[3];
	SCInputRef Input_BarsIntertrendState = sc.Input[4];
	SCInputRef Input_BarsFixPos = sc.Input[5];

	if(sc.SetDefaults)
	{
		sc.GraphName="Woodies CCI Trend - Old";

		sc.AutoLoop = 0;

		Subgraph_Above.Name = "Above";
		Subgraph_Above.DrawStyle = DRAWSTYLE_BAR;
		Subgraph_Above.PrimaryColor = RGB(0,0,255);
		Subgraph_Above.DrawZeros = false;

		Subgraph_Below.Name = "Below";
		Subgraph_Below.DrawStyle = DRAWSTYLE_BAR;
		Subgraph_Below.PrimaryColor = RGB(255,0,0);
		Subgraph_Below.DrawZeros = false;

		Subgraph_AboveColorValues.Name = "Color Value Output";
		Subgraph_AboveColorValues.PrimaryColor = RGB(255, 255, 255);
		Subgraph_AboveColorValues.DrawStyle = DRAWSTYLE_IGNORE;
		Subgraph_AboveColorValues.DrawZeros = false;

		Subgraph_DoNotDraw1.DrawStyle = DRAWSTYLE_HIDDEN;
		Subgraph_DoNotDraw1.PrimaryColor = RGB(255,255,0);
		Subgraph_DoNotDraw1.DrawZeros = false;

		Subgraph_DoNotDraw2.DrawStyle = DRAWSTYLE_HIDDEN;
		Subgraph_DoNotDraw2.PrimaryColor = RGB(98,98,98);
		Subgraph_DoNotDraw2.DrawZeros = false;

		Subgraph_CCI.Name = "CCI";
		Subgraph_CCI.DrawStyle = DRAWSTYLE_IGNORE;
		Subgraph_CCI.PrimaryColor = RGB(0,0,255);
		Subgraph_CCI.DrawZeros = false;


		Input_WarningBar.Name = "Use a Warning Bar";
		Input_WarningBar.SetYesNo(false);		

		Input_AlternateColor.Name = "Alternate Colour for uncertain trend states 0, 1, 2 or 4";
		Input_AlternateColor.SetInt(0);
		Input_AlternateColor.SetIntLimits(0,4);

		Input_CCILength.Name = "CCI Length";
		Input_CCILength.SetInt(14);
		Input_CCILength.SetIntLimits(1,MAX_STUDY_LENGTH);

		Input_NumberOfBars.Name = "Number of Bars";
		Input_NumberOfBars.SetInt(6);
		Input_NumberOfBars.SetIntLimits(1,MAX_STUDY_LENGTH);

		Input_BarsIntertrendState.Name = "# of Bars for Intertrend State";
		Input_BarsIntertrendState.SetInt(1);
		Input_BarsIntertrendState.SetIntLimits(1,MAX_STUDY_LENGTH);

		Input_BarsFixPos.Name = "0 = Bars or n = Fixed Position (n/1000)";
		Input_BarsFixPos.SetFloat(0);	

		return;
	}
	

	Subgraph_AboveColorValues.DrawStyle = DRAWSTYLE_IGNORE;
	Subgraph_DoNotDraw1.DrawStyle = DRAWSTYLE_HIDDEN;
	Subgraph_DoNotDraw2.DrawStyle = DRAWSTYLE_HIDDEN;

	COLORREF Color0 = Subgraph_Above.PrimaryColor;
	COLORREF Color1 = Subgraph_Below.PrimaryColor;
	COLORREF Color2 = Subgraph_DoNotDraw1.PrimaryColor;
	COLORREF Color3 = Subgraph_DoNotDraw2.PrimaryColor;

	int ArraySize = sc.ArraySize;

	switch (Input_AlternateColor.GetInt())
	{
	case 4:
	case 2:
		Subgraph_DoNotDraw1.Name ="Change on Next Bar";
		Subgraph_DoNotDraw2.Name ="Trend & Position Confused";
		break;
	case 1:
		Subgraph_DoNotDraw1.Name = "Trend Up but below Zero";
		Subgraph_DoNotDraw2.Name = "Trend Dn but above Zero";
		break;
	case 0:
	default:
		Subgraph_DoNotDraw1.Name = "Change on Next Bar";
	}

	int ud = -2, goingpos = 0, goingneg = 0, posbar = 0, negbar = 0, up = 0, 
		dn = 0, next = 0;


	for(int i = sc.UpdateStartIndex; i < ArraySize;i++)
	{
		sc.CCI(sc.HLCAvg, Subgraph_CCI.Arrays[0], Subgraph_CCI, i, Input_CCILength.GetInt(), 0.015f);
	}

	int Start = max (sc.UpdateStartIndex, Input_CCILength.GetInt()*2 - 1);

	float cci0;
	for (int i = Start-1; i >= Input_CCILength.GetInt()*2; i--)
	{
		cci0 = sc.Subgraph[5][i];
		if (cci0 > 0)
		{
			dn = 0;
			up++;
		}

		else if (cci0 < 0)
		{
			up = 0;
			dn++;
		}

		if(up >= Input_NumberOfBars.GetInt()) 
		{
			Start = i + Input_NumberOfBars.GetInt();
			ud=2;
			break;
		}		
		else if(dn >= Input_NumberOfBars.GetInt()) 
		{
			ud=-2;
			Start = i + Input_NumberOfBars.GetInt();
			break;
		}
	}

	sc.DataStartIndex = Input_CCILength.GetInt()*2 - 1;

	for (int pos=Start; pos < ArraySize; pos++)
	{
		cci0 = Subgraph_CCI[pos];

		if (cci0>0) 
		{
			if(Input_AlternateColor.GetInt() == 4 && Input_BarsIntertrendState.GetInt() <= up+1) 
				dn = 0;

			if(ud <= 0)
			{
				if (goingpos == 0)
				{
					goingpos = 1;
					up = 1;
					dn = 0; 
					negbar = 0; 
					if(Input_AlternateColor.GetInt() == 4 && Input_BarsIntertrendState.GetInt() == 1) 
						ud=0;
				}
				else
				{
					up++; 
					if(up == Input_NumberOfBars.GetInt()) 
						dn = 0;

					if(Input_AlternateColor.GetInt() == 4 && Input_BarsIntertrendState.GetInt() <= up) 
						ud = 0;
				}
			} 
			else	if(ud >= 2)
			{
				if (goingneg == 1) 
				{
					posbar++; 
					if(posbar >= 2) 
					{
						goingneg = 0; 
						dn = 0;
					} 
				}
				else
					up++;
			} 
		}

		if (cci0<0) 
		{
			if(Input_AlternateColor.GetInt()==4 && Input_BarsIntertrendState.GetInt()<=dn+1)
				up=0;

			if(ud>= 0) 
			{
				if (goingneg==0)
				{
					goingneg=1;
					dn=1; 
					up=0; 
					posbar=0; 
					if(Input_AlternateColor.GetInt()==4 && Input_BarsIntertrendState.GetInt()==1) 
						ud=0;
				}
				else
				{
					dn++; 
					if(dn==Input_NumberOfBars.GetInt()) 
						up=0;

					if(Input_AlternateColor.GetInt()==4 && Input_BarsIntertrendState.GetInt()<=dn) 
						ud=0;
				}
			} 
			else	if(ud <= -2) 
			{
				if (goingpos == 1)
				{
					negbar++; 
					if(negbar>=2) 
					{
						goingpos=0; 
						up=0;
					} 
				}
				else
					dn++;
			} 
		};


		next=0;
		if(up==(Input_NumberOfBars.GetInt()-1) && (ud<=-2 || (ud==0 && Input_AlternateColor.GetInt()==4)) && Input_WarningBar.GetYesNo()!=0) 
			next=1; 

		else	if(dn==(Input_NumberOfBars.GetInt()-1) && (ud>= 2 || (ud==0 && Input_AlternateColor.GetInt()==4)) && Input_WarningBar.GetYesNo()!=0) 
			next=1;

		if(up>=Input_NumberOfBars.GetInt()) 
			ud=2;

		if(dn>=Input_NumberOfBars.GetInt()) 
			ud=-2;

		if (Input_BarsFixPos.GetFloat())
			Subgraph_Above[pos] = Input_BarsFixPos.GetFloat()/1000;
		else
			Subgraph_Above[pos] = cci0; 

		if (next==1)
		{
			if(Input_AlternateColor.GetInt()==0 || Input_AlternateColor.GetInt()==2 || Input_AlternateColor.GetInt()==4)
			{
				Subgraph_Above.DataColor[pos] = Color2;
			} 
			else	if(Input_AlternateColor.GetInt()==1)
			{ 
				if(Input_BarsFixPos.GetFloat()==0) 
				{ 
					Subgraph_Above.DataColor[pos] = Color0; 
					Subgraph_Below[pos]=cci0/2; 
				};
			};
		} 
		else
		{
			if (ud==0 && Input_AlternateColor.GetInt()==4)
			{ 
				Subgraph_Above.DataColor[pos] = Color3;
			} 
			else if (ud>=2)
			{
				if(Input_AlternateColor.GetInt()==0 || cci0>=0)
				{ 
					Subgraph_Above.DataColor[pos] = Color0;
				} 
				else	if(Input_AlternateColor.GetInt()==1)
				{ 
					Subgraph_Above.DataColor[pos] = Color2;
				} 
				else if(Input_AlternateColor.GetInt()==2 || Input_AlternateColor.GetInt()==4)
				{ 
					Subgraph_Above.DataColor[pos] = Color3;
				}
			} 
			else if (ud<=-2)
			{
				if(Input_AlternateColor.GetInt()==0 || cci0<=0)
				{ 
					Subgraph_Above.DataColor[pos] = Color1;
				} 
				else
				{
					Subgraph_Above.DataColor[pos] = Color3;
				}
			}
		}

		if (Subgraph_Above.DataColor[pos] == Color0)
		{
			Subgraph_AboveColorValues[pos] = 1;
		}
		else if (Subgraph_Above.DataColor[pos] == Color1)
		{
			Subgraph_AboveColorValues[pos] = 2;
		}
		else if (Subgraph_Above.DataColor[pos] == Color2)
		{
			Subgraph_AboveColorValues[pos] = 3;
		}
		else if (Subgraph_Above.DataColor[pos] == Color3)
		{
			Subgraph_AboveColorValues[pos] = 4;
		}
	}
}

/*==========================================================================*/
SCSFExport scsf_Sidewinder(SCStudyInterfaceRef sc)
{
	SCSubgraphRef Subgraph_SwTop = sc.Subgraph[0];
	SCSubgraphRef Subgraph_SwBottom = sc.Subgraph[1];
	SCSubgraphRef Subgraph_FlatColor = sc.Subgraph[2];
	SCSubgraphRef Subgraph_OutWorksheet = sc.Subgraph[3];
	SCSubgraphRef Subgraph_Lsma = sc.Subgraph[4];
	SCSubgraphRef Subgraph_LsmaAngle = sc.Subgraph[5];
	SCSubgraphRef Subgraph_Ema = sc.Subgraph[6];
	SCSubgraphRef Subgraph_EmaAngle = sc.Subgraph[7];

	SCInputRef Input_LsmaLength = sc.Input[0];
	SCInputRef Input_EmaLength = sc.Input[1];
	SCInputRef Input_TrendingThreshold = sc.Input[3];
	SCInputRef Input_NormalThreshold = sc.Input[4];
	SCInputRef Input_LineValue = sc.Input[5];
	SCInputRef Input_TickValueOverride = sc.Input[6];

	if(sc.SetDefaults)
	{
		sc.GraphName="Sidewinder";
		sc.StudyDescription="Sidewinder";

		sc.AutoLoop = 0;

		Subgraph_SwTop.Name = "SW Top";
		Subgraph_SwTop.DrawStyle = DRAWSTYLE_LINE;
		Subgraph_SwTop.LineWidth = 2;
		Subgraph_SwTop.PrimaryColor = RGB(255,255,0);
		Subgraph_SwTop.SecondaryColor = RGB(0,255,0);
		Subgraph_SwTop.SecondaryColorUsed = 1;  // true
		Subgraph_SwTop.DrawZeros = false;

		Subgraph_SwBottom.Name = "SW Bottom";
		Subgraph_SwBottom.DrawStyle = DRAWSTYLE_LINE;
		Subgraph_SwBottom.LineWidth = 2;
		Subgraph_SwBottom.PrimaryColor = RGB(255,255,0);
		Subgraph_SwBottom.SecondaryColor = RGB(0,255,0);
		Subgraph_SwBottom.SecondaryColorUsed = 1;  // true
		Subgraph_SwBottom.DrawZeros = false;

		Subgraph_FlatColor.Name = "Flat Color";
		Subgraph_FlatColor.DrawStyle = DRAWSTYLE_IGNORE;
		Subgraph_FlatColor.PrimaryColor = RGB(255,0,0);
		Subgraph_FlatColor.DrawZeros = false;

		Subgraph_OutWorksheet.Name = "Output for Spreadsheets";
		Subgraph_OutWorksheet.DrawStyle = DRAWSTYLE_IGNORE;
		Subgraph_OutWorksheet.PrimaryColor = RGB(255,255,255);
		Subgraph_OutWorksheet.DrawZeros = false;

		Subgraph_Lsma.DrawStyle = DRAWSTYLE_IGNORE;
		Subgraph_Lsma.DrawZeros = false;

		Subgraph_LsmaAngle.DrawStyle = DRAWSTYLE_IGNORE;
		Subgraph_LsmaAngle.DrawZeros = false;

		Subgraph_Ema.DrawStyle = DRAWSTYLE_IGNORE;
		Subgraph_Ema.DrawZeros = false;

		Subgraph_EmaAngle.DrawStyle = DRAWSTYLE_IGNORE;
		Subgraph_EmaAngle.DrawZeros = false;

		Input_LsmaLength.Name = "LSMA Length";
		Input_LsmaLength.SetInt(25);
		Input_LsmaLength.SetIntLimits(1,MAX_STUDY_LENGTH);

		Input_EmaLength.Name = "EMA Length";
		Input_EmaLength.SetInt(34);
		Input_EmaLength.SetIntLimits(1,MAX_STUDY_LENGTH);

		Input_TrendingThreshold.Name = "Trending Threshold";
		Input_TrendingThreshold.SetFloat(100.0f);

		Input_NormalThreshold.Name = "Normal Threshold";
		Input_NormalThreshold.SetFloat(30.0f);

		Input_LineValue.Name = "Line Value";
		Input_LineValue.SetFloat(200.0f);

		Input_TickValueOverride.Name = "Tick Value (Enter number to override default)";
		Input_TickValueOverride.SetFloat(0.0f);

		sc.AutoLoop = 1;

		return;
	}

	Subgraph_OutWorksheet.DrawStyle = DRAWSTYLE_IGNORE;
	Subgraph_OutWorksheet.PrimaryColor = RGB(255,255,255);

	const float RAD_TO_DEG = (180.0f/3.14159265358979f);

	// Colors
	COLORREF colorFlat = Subgraph_FlatColor.PrimaryColor;
	COLORREF colorNormalUp = Subgraph_SwTop.PrimaryColor;
	COLORREF colorTrendingUp = Subgraph_SwTop.SecondaryColor;
	COLORREF colorNormalDown = Subgraph_SwBottom.PrimaryColor;
	COLORREF colorTrendingDown = Subgraph_SwBottom.SecondaryColor;

	if (Input_TickValueOverride.GetFloat() == 1)
		Input_TickValueOverride.SetFloat(0);

	float inTickSize = sc.TickSize;

	if(Input_TickValueOverride.GetFloat() != 0)
		inTickSize = Input_TickValueOverride.GetFloat();

	float &PriorTickSize = sc.GetPersistentFloat(1);

	if(PriorTickSize != inTickSize)
	{
		sc.UpdateStartIndex = 0;
		PriorTickSize = inTickSize;
	}


	float InverseTickSize = 1/inTickSize;


	sc.DataStartIndex = Input_LsmaLength.GetInt() - 1;

	// Determine the input array element to begin calculation at
	int Pos = sc.Index;
	if (Pos < 2)
		return;

	// Calculate the EMA
	sc.ExponentialMovAvg(sc.Close, Subgraph_Ema, Pos, Input_EmaLength.GetInt());

	// Calculate the LSMA
	sc.LinearRegressionIndicator(sc.Close,Subgraph_Lsma,Pos, Input_LsmaLength.GetInt());

	// Calculate the LSMA angle
	float lsma_Angle = (float)sc.SlopeToAngleInDegrees((Subgraph_Lsma[Pos]-((Subgraph_Lsma[Pos-1]+Subgraph_Lsma[Pos-2])/2.0f))*InverseTickSize);
	Subgraph_LsmaAngle[Pos] = lsma_Angle;

	// Calculate the EMA angle
	float ema_Angle	= (float)sc.SlopeToAngleInDegrees((Subgraph_Ema[Pos]-((Subgraph_Ema[Pos-1]+Subgraph_Ema[Pos-2])/2.0f))*InverseTickSize);

	Subgraph_EmaAngle[Pos] = ema_Angle;

	// Calculate SW
	COLORREF color;
	float worksheetValue;

	if (fabs(Subgraph_EmaAngle[Pos]) >= 15.0f
		&& (Subgraph_EmaAngle[Pos] + Subgraph_LsmaAngle[Pos]) >= Input_TrendingThreshold.GetFloat())
	{
		color = colorTrendingUp; 
		worksheetValue = 2;
	}
	else if (fabs(Subgraph_EmaAngle[Pos]) >= 15.0f
		&& (Subgraph_EmaAngle[Pos] + Subgraph_LsmaAngle[Pos]) <= -Input_TrendingThreshold.GetFloat())
	{
		color = colorTrendingDown; 
		worksheetValue = -2;
	}
	else if (Subgraph_EmaAngle[Pos] > 5.0f && Subgraph_LsmaAngle[Pos] > 0.0f
		&& (Subgraph_EmaAngle[Pos] + Subgraph_LsmaAngle[Pos]) >= Input_NormalThreshold.GetFloat())
	{
		color = colorNormalUp;
		worksheetValue = 1;
	}
	else if (Subgraph_EmaAngle[Pos] < 5.0f && Subgraph_LsmaAngle[Pos] < 0.0f
		&& (Subgraph_EmaAngle[Pos] + Subgraph_LsmaAngle[Pos]) <= -Input_NormalThreshold.GetFloat())
	{
		color = colorNormalDown;
		worksheetValue = -1;
	}
	else
	{
		color = colorFlat;
		worksheetValue = 0;
	}

	Subgraph_SwTop[Pos] = Input_LineValue.GetFloat();
	Subgraph_SwBottom[Pos] = -Input_LineValue.GetFloat();

	Subgraph_SwTop.DataColor[Pos] = color;
	Subgraph_SwBottom.DataColor[Pos] = color;

	Subgraph_OutWorksheet[Pos] = worksheetValue;
}


/*==========================================================================*/
SCSFExport scsf_LSMAAboveBelowCCI(SCStudyInterfaceRef sc)
{
	SCSubgraphRef Subgraph_LsmaCCI = sc.Subgraph[0];
	SCSubgraphRef Subgraph_DoNotDraw1 = sc.Subgraph[1];
	SCSubgraphRef Subgraph_DoNotDraw2 = sc.Subgraph[2];
	SCSubgraphRef Subgraph_DoNotDraw3 = sc.Subgraph[3];
	SCSubgraphRef Subgraph_DoNotDraw4 = sc.Subgraph[4];

	SCInputRef Input_LsmaLength = sc.Input[0];
	SCInputRef Input_CCILength = sc.Input[2];
	SCInputRef Input_BarsPointsLsma = sc.Input[3];
	

	if (sc.SetDefaults)
	{
		// Set the configuration and defaults
		sc.GraphName ="LSMA Above/Below CCI";
		sc.GraphRegion = 1;	

		Subgraph_LsmaCCI.DrawStyle = DRAWSTYLE_BAR;
		Subgraph_LsmaCCI.Name = "LSMA Above/Below CCI";
		Subgraph_LsmaCCI.PrimaryColor = RGB(0, 255, 0);
		Subgraph_LsmaCCI.SecondaryColorUsed = 1;
		Subgraph_LsmaCCI.SecondaryColor = RGB(255, 0, 255);
		Subgraph_LsmaCCI.DrawZeros = false;

		Subgraph_DoNotDraw4.DrawStyle = DRAWSTYLE_IGNORE;
		Subgraph_DoNotDraw4.Name = "Spreadsheet Output";
		Subgraph_DoNotDraw4.PrimaryColor = RGB(255,0,0);
		Subgraph_DoNotDraw4.DrawZeros = false;

		Input_LsmaLength.Name = "MA Length";
		Input_LsmaLength.SetInt(25);
		Input_LsmaLength.SetIntLimits(1,MAX_STUDY_LENGTH);

		Input_CCILength.Name = "CCI Length";
		Input_CCILength.SetInt(14);
		Input_CCILength.SetIntLimits(1,MAX_STUDY_LENGTH);

		Input_BarsPointsLsma.Name = "Bars (0) or Points (n/1000) or LSMA (9999)";
		Input_BarsPointsLsma.SetInt(0);
		Input_BarsPointsLsma.SetIntLimits(0, 9999);

		//MovAvgType.Name = "Moving Average Type";
		//MovAvgType.SetMovAvgType(MOVAVGTYPE_LINEARREGRESSION);

		sc.AutoLoop = 1;

		return;
	}

	COLORREF color0 = Subgraph_LsmaCCI.PrimaryColor;
	COLORREF color1 = Subgraph_LsmaCCI.SecondaryColor;

	sc.DataStartIndex = max(Input_LsmaLength.GetInt(), Input_CCILength.GetInt());

	int MAType = MOVAVGTYPE_LINEARREGRESSION;


	sc.MovingAverage(sc.Close, Subgraph_DoNotDraw1, MAType,sc.Index, Input_LsmaLength.GetInt());
	sc.CCI(sc.HLCAvg, Subgraph_DoNotDraw2, Subgraph_DoNotDraw3, sc.Index, Input_CCILength.GetInt(), 0.015f);

	float fLSMA = Subgraph_DoNotDraw1[sc.Index];
	float fCCI = Subgraph_DoNotDraw3[sc.Index];

	if (Input_BarsPointsLsma.GetInt() == 0) 
		Subgraph_LsmaCCI[sc.Index] = fCCI; 
	else if (Input_BarsPointsLsma.GetInt() == 9999) 
		Subgraph_LsmaCCI[sc.Index] = fLSMA; 
	else
		Subgraph_LsmaCCI[sc.Index] = (float)Input_BarsPointsLsma.GetInt() / 1000.0f;

	if (sc.Close[sc.Index] > fLSMA)
	{
		Subgraph_LsmaCCI.DataColor[sc.Index] = color0;
		Subgraph_DoNotDraw4[sc.Index] = 1;
	}
	else if (sc.Close[sc.Index] < fLSMA)
	{
		Subgraph_LsmaCCI.DataColor[sc.Index] = color1;
		Subgraph_DoNotDraw4[sc.Index] = -1;
	}
}

/*==========================================================================*/
SCSFExport scsf_LSMAAboveBelow(SCStudyInterfaceRef sc)
{
	SCSubgraphRef Subgraph_Lsma = sc.Subgraph[0];
	SCSubgraphRef Subgraph_DoNotDraw1 = sc.Subgraph[1];
	SCSubgraphRef Subgraph_WorksheetOutput = sc.Subgraph[2];

	SCInputRef Input_LsmaLength = sc.Input[0];

	if (sc.SetDefaults)
	{
		// Set the configuration and defaults
		sc.GraphName ="LSMA Above/Below Last";
		sc.GraphRegion = 1;	

		Subgraph_Lsma.DrawStyle = DRAWSTYLE_SQUARE;
		Subgraph_Lsma.LineWidth = 2;
		Subgraph_Lsma.Name = "Above/Below";
		Subgraph_Lsma.PrimaryColor = RGB(0, 255, 0);
		Subgraph_Lsma.SecondaryColorUsed = 1;
		Subgraph_Lsma.SecondaryColor = RGB(255, 0, 0);
		Subgraph_Lsma.DrawZeros = true;

		Subgraph_WorksheetOutput.Name = "Spreadsheet Output";
		Subgraph_WorksheetOutput.DrawStyle = DRAWSTYLE_IGNORE;
		Subgraph_WorksheetOutput.PrimaryColor = RGB(255,255,0);
		Subgraph_WorksheetOutput.DrawZeros = true;

		Input_LsmaLength.Name = "MovAvg Length";
		Input_LsmaLength.SetInt(25);
		Input_LsmaLength.SetIntLimits(1,MAX_STUDY_LENGTH);

		sc.AutoLoop = 1;

		return;
	}

	COLORREF color0 = Subgraph_Lsma.PrimaryColor;
	COLORREF color1 = Subgraph_Lsma.SecondaryColor;

	sc.DataStartIndex = Input_LsmaLength.GetInt();

	int index = sc.Index;

	sc.MovingAverage(sc.Close, Subgraph_DoNotDraw1, MOVAVGTYPE_LINEARREGRESSION, index, Input_LsmaLength.GetInt());

	float fLSMA = Subgraph_DoNotDraw1[index];

	if (sc.Close[index] > fLSMA)
	{
		Subgraph_Lsma.DataColor[index] = color0;
		Subgraph_WorksheetOutput[index] = 1;

	}
	else if (sc.Close[index] < fLSMA)
	{
		Subgraph_Lsma.DataColor[index] = color1;
		Subgraph_WorksheetOutput[index] = -1;

	}
	else 
	{
		Subgraph_Lsma.DataColor[index] = 0;
		Subgraph_WorksheetOutput[index] = 0;
	}
}
/*==========================================================================*/
SCSFExport scsf_EMAAboveBelow(SCStudyInterfaceRef sc)
{
	SCSubgraphRef Subgraph_ExponentialMovingAverage = sc.Subgraph[0];
	SCSubgraphRef Subgraph_DoNotDraw1 = sc.Subgraph[1];
	SCSubgraphRef Subgraph_WorksheetOutput = sc.Subgraph[2];

	SCInputRef Subgraph_MovingAverageLength = sc.Input[0];

	if (sc.SetDefaults)
	{
		// Set the configuration and defaults
		sc.GraphName ="EMA Above/Below Last";
		sc.GraphRegion = 1;

		Subgraph_ExponentialMovingAverage.DrawStyle = DRAWSTYLE_SQUARE;
		Subgraph_ExponentialMovingAverage.LineWidth = 2;
		Subgraph_ExponentialMovingAverage.Name = "Above/Below";
		Subgraph_ExponentialMovingAverage.PrimaryColor = RGB(0, 255, 0);
		Subgraph_ExponentialMovingAverage.SecondaryColorUsed = 1;
		Subgraph_ExponentialMovingAverage.SecondaryColor = RGB(255, 0, 0);
		Subgraph_ExponentialMovingAverage.DrawZeros = true;

		Subgraph_WorksheetOutput.Name = "Spreadsheet Output";
		Subgraph_WorksheetOutput.DrawStyle= DRAWSTYLE_IGNORE;
		Subgraph_WorksheetOutput.PrimaryColor = RGB(255, 255, 0);
		Subgraph_WorksheetOutput.DrawZeros = true;

		Subgraph_MovingAverageLength.Name = "Moving Average Length";
		Subgraph_MovingAverageLength.SetInt(25);
		Subgraph_MovingAverageLength.SetIntLimits(1,MAX_STUDY_LENGTH);

		sc.AutoLoop = 1;

		return;
	}

	COLORREF color0 = Subgraph_ExponentialMovingAverage.PrimaryColor;
	COLORREF color1 = Subgraph_ExponentialMovingAverage.SecondaryColor;

	sc.DataStartIndex = Subgraph_MovingAverageLength.GetInt();

	sc.MovingAverage(sc.Close, Subgraph_DoNotDraw1, MOVAVGTYPE_EXPONENTIAL, sc.Index, Subgraph_MovingAverageLength.GetInt());

	if (sc.Close[sc.Index] > Subgraph_DoNotDraw1[sc.Index])
	{
		Subgraph_ExponentialMovingAverage.DataColor[sc.Index] = color0;
		Subgraph_WorksheetOutput[sc.Index] = 1;

	}
	else if (sc.Close[sc.Index] < Subgraph_DoNotDraw1[sc.Index])
	{
		Subgraph_ExponentialMovingAverage.DataColor[sc.Index] = color1;
		Subgraph_WorksheetOutput[sc.Index] = -1;

	}
	else 
	{
		Subgraph_ExponentialMovingAverage.DataColor[sc.Index] = 0;
		Subgraph_WorksheetOutput[sc.Index] = 0;
	}
}

/*==========================================================================*/
SCSFExport scsf_MurreyMath(SCStudyInterfaceRef sc)
{
	const int NumberOfVisibleLines = 25;

	SCInputRef Input_SquareWidth = sc.Input[0];
	SCInputRef Input_UseLastBarAsEndDateTime = sc.Input[1];
	SCInputRef Input_EndDateTime = sc.Input[2];
	SCInputRef Input_SquareWidthNew = sc.Input[3];
	SCInputRef Input_Version = sc.Input[4];
	SCInputRef Input_SquareWidthMultiplier = sc.Input[5];
	SCInputRef Input_RoundToTickSize = sc.Input[6];
	SCInputRef Input_CustomSquareWidth = sc.Input[7];


	// Configuration
	if (sc.SetDefaults)
	{   
		sc.GraphName = "Murrey Math"; 
		sc.AutoLoop = 0;  
		sc.GraphRegion = 0; 
		sc.ScaleRangeType = SCALE_SAMEASREGION;

		for (int SubgraphIndex = 0; SubgraphIndex < NumberOfVisibleLines; SubgraphIndex++)
		{
			SCString SubgraphString;

			if(SubgraphIndex <= 16)
				SubgraphString.Format("%d/8", SubgraphIndex-8);
			else
				SubgraphString.Format("+%d/8", SubgraphIndex-16);

			sc.Subgraph[SubgraphIndex].Name = SubgraphString;
			sc.Subgraph[SubgraphIndex].DrawStyle = DRAWSTYLE_DASH;
			sc.Subgraph[SubgraphIndex].LineWidth = 1;


			sc.Subgraph[SubgraphIndex].PrimaryColor = RGB(0, 255, 0);
			sc.Subgraph[SubgraphIndex].LineLabel |= LL_NAME_ALIGN_LEFT | LL_DISPLAY_NAME | LL_NAME_ALIGN_CENTER;

		}

		//SquareWidth.Name = "Square Width";
		Input_SquareWidth.SetInt(64);  
		Input_SquareWidth.SetIntLimits(1, MAX_STUDY_LENGTH);

		Input_SquareWidthNew.Name = "Square Width";
		Input_SquareWidthNew.SetCustomInputStrings("4;8;16;32;64;128;256;512");  
		Input_SquareWidthNew.SetCustomInputIndex(0);

		Input_UseLastBarAsEndDateTime.Name = "Use Last Bar as End Date-Time";
		Input_UseLastBarAsEndDateTime.SetYesNo(true);

		Input_EndDateTime.Name = "End Date-Time";
		Input_EndDateTime.SetDateTime(0);

		Input_Version.SetInt(1);

		Input_SquareWidthMultiplier.Name = "Square Width Multiplier";
		Input_SquareWidthMultiplier.SetFloat(1.5);
		Input_SquareWidthMultiplier.SetFloatLimits(1.0, 100);

		Input_RoundToTickSize.Name = "Round to Tick Size";
		Input_RoundToTickSize.SetYesNo(false);

		Input_CustomSquareWidth.Name = "Custom Square Width";
		Input_CustomSquareWidth.SetInt(0);
		Input_CustomSquareWidth.SetIntLimits(0, MAX_STUDY_LENGTH);

		return;
	}   


	if(Input_Version.GetInt() < 1)
	{
		Input_Version.SetInt(1);
		int OldSquareWidth = Input_SquareWidth.GetInt();

		switch(OldSquareWidth)
		{
			case 4:
				Input_SquareWidthNew.SetCustomInputIndex(0);
			break;

			case 8:
				Input_SquareWidthNew.SetCustomInputIndex(1);
			break;

			case 16:
				Input_SquareWidthNew.SetCustomInputIndex(2);
			break;

			case 32:
				Input_SquareWidthNew.SetCustomInputIndex(3);
			break;

			default:
			case 64:
				Input_SquareWidthNew.SetCustomInputIndex(4);
			break;

			case 128:
				Input_SquareWidthNew.SetCustomInputIndex(5);
			break;

			case 256:
				Input_SquareWidthNew.SetCustomInputIndex(6);
			break;

			case 512:
				Input_SquareWidthNew.SetCustomInputIndex(7);
			break;
		}
	}

	int SquareWidthNumber = atoi(Input_SquareWidthNew.GetSelectedCustomString());

	if (Input_CustomSquareWidth.GetInt() > 0)
		SquareWidthNumber = Input_CustomSquareWidth.GetInt();

	int BarsBackToReference = sc.Round(SquareWidthNumber * Input_SquareWidthMultiplier.GetFloat());

	int &PreviousStartOutputBarIndex = sc.GetPersistentInt(1);

	//Clear previously used elements
	for(int BarIndex = PreviousStartOutputBarIndex; BarIndex < sc.ArraySize; BarIndex++)
	{
		for (int LineIndex = 0; LineIndex < NumberOfVisibleLines; LineIndex++)
		{
			sc.Subgraph[LineIndex][BarIndex] = 0;
		}
	}

	//Determine the starting index
	if (Input_UseLastBarAsEndDateTime.GetYesNo())
		PreviousStartOutputBarIndex = sc.ArraySize - BarsBackToReference;
	else
	{
		PreviousStartOutputBarIndex = sc.GetNearestMatchForSCDateTime(sc.ChartNumber, Input_EndDateTime.GetDateTime()) -  BarsBackToReference + 1;
		
	}
	
	double HighestHighOfSquareWidthLength = (double) sc.GetHighest(sc.High, PreviousStartOutputBarIndex + BarsBackToReference - 1, BarsBackToReference);

	double LowestLowOfSquareWidthLength = (double) sc.GetLowest(sc.Low, PreviousStartOutputBarIndex + BarsBackToReference - 1, BarsBackToReference);

	double PriceRange = HighestHighOfSquareWidthLength - LowestLowOfSquareWidthLength;
	double SR = 0.0, OctaveCount = 0.0, Si = 0.0, M = 0.0, B = 0.0, TT = 0.0;
	
	int I = 0;


	if(HighestHighOfSquareWidthLength > 25)
	{
		if(log(0.4*HighestHighOfSquareWidthLength)/log(10.0)-int(log(0.4*HighestHighOfSquareWidthLength)/log(10.0))>0)
			SR = exp(log(10.0)*(int(log(0.4*HighestHighOfSquareWidthLength)/log(10.0))+1));
		else
			SR = exp(log(10.0)*(int(log(0.4*HighestHighOfSquareWidthLength)/log(10.0))));
	}
	else 
	{
		SR = 100*exp(log(8.0)*(int(log(0.005*HighestHighOfSquareWidthLength)/log(8.0))));
	}

	double RangeMMI =  log(SR/PriceRange)/log(8.0);
	if(RangeMMI<=0)
	{
		OctaveCount = 0;
	}
	else
	{
		if(log(SR/PriceRange)/log(8.0)- fmod(log(SR/PriceRange),log(8.0))== 0)
		{
			OctaveCount = int(RangeMMI);
		}
		else
		{
			OctaveCount = int(RangeMMI)+1.0;
		}
	}


	Si = SR *exp(-OctaveCount * log(8.0));
	M = int(((1/log(2.0))*log(PriceRange/Si))+.00001);

	double ValueToRound = (((HighestHighOfSquareWidthLength + LowestLowOfSquareWidthLength) * .5)/(Si* exp((M-1)*log(2.0))));
	I = sc.Round((float)ValueToRound);

	B =(I-1) * Si * exp((M-1)* log(2.0));
	TT =(I+1) * Si * exp((M-1) * log(2.0));

	for (int LineIndex = 0; LineIndex < NumberOfVisibleLines; LineIndex++)
	{
		for(int BarIndex = PreviousStartOutputBarIndex; BarIndex < sc.ArraySize; BarIndex++)
		{
			float MurreyMathValue = (float)(B + ((LineIndex-8) * 0.125 * (TT -B)));

			if (Input_RoundToTickSize.GetYesNo())
				MurreyMathValue = sc.RoundToTickSize(MurreyMathValue);

			sc.Subgraph[LineIndex][BarIndex] = MurreyMathValue;
		}
	}
}




/*==========================================================================*/
SCSFExport scsf_PreviousCloseLine(SCStudyInterfaceRef sc)
{
	SCSubgraphRef Subgraph_PreviousCloseLine = sc.Subgraph[0];
	SCInputRef Input_UsePreviousCloseFromQuoteData = sc.Input[0];

	if(sc.SetDefaults)
	{
		sc.GraphName = "Previous Close Line";

		Subgraph_PreviousCloseLine.Name = "PCL";
		Subgraph_PreviousCloseLine.DrawStyle = DRAWSTYLE_LINE;
		
		Subgraph_PreviousCloseLine.LineStyle = LINESTYLE_DOT;
		Subgraph_PreviousCloseLine.PrimaryColor = RGB(0, 255, 0);
		Subgraph_PreviousCloseLine.LineWidth = 2;
		Subgraph_PreviousCloseLine.DrawZeros = false;

		Input_UsePreviousCloseFromQuoteData.Name = "Use Previous Close From Quote Data";
		Input_UsePreviousCloseFromQuoteData.SetYesNo(0);

		sc.GraphRegion = 0;

		
		return;
	}

	SCDateTime  PriorDayCloseDateTime = sc.GetStartDateTimeForTradingDate(sc.GetTradingDayDate(sc.BaseDateTimeIn[sc.ArraySize - 1]) );

	PriorDayCloseDateTime -= 1 * SECONDS;

	int PriorDayCloseDateTimeIndex = sc.GetContainingIndexForSCDateTime(sc.ChartNumber, PriorDayCloseDateTime);

	float PriorDayCloseValue = 0.0;
	if (Input_UsePreviousCloseFromQuoteData.GetYesNo())
		PriorDayCloseValue = sc.PreviousClose;
	else
		PriorDayCloseValue = sc.BaseData[SC_LAST][PriorDayCloseDateTimeIndex];

	for (int BarIndex = sc.UpdateStartIndex ; BarIndex < sc.ArraySize; ++BarIndex)
	{
		if (BarIndex < PriorDayCloseDateTimeIndex)
			continue;

		Subgraph_PreviousCloseLine[BarIndex] = PriorDayCloseValue;
	}

}

/*==========================================================================*/
SCSFExport scsf_ValueChartLevels(SCStudyInterfaceRef sc)
{
	SCInputRef Input_ModOBLevel = sc.Input[1];
	SCInputRef Input_SigOBLevel = sc.Input[2];

	SCSubgraphRef Subgraph_PlusModerateOverboughtLevel = sc.Subgraph[0];
	SCSubgraphRef Subgraph_PlusSignificantOverboughtLevel = sc.Subgraph[1];
	SCSubgraphRef Subgraph_ZeroLevel= sc.Subgraph[2];
	SCSubgraphRef Subgraph_MinusModerateOverboughtLevel= sc.Subgraph[3];
	SCSubgraphRef Subgraph_MinusSignificantOverboughtLevel= sc.Subgraph[4];

	if (sc.SetDefaults)
	{
		// Set the configuration and defaults
		sc.GraphName ="Value Chart Levels";

		sc.GraphDrawType = GDT_CUSTOM;
		sc.AutoLoop = 1;
		



		Input_ModOBLevel.Name = "Moderately Overbought Level";
		Input_ModOBLevel.SetFloat(4.0f);
		Input_ModOBLevel.SetFloatLimits(0,100.0f);

		Input_SigOBLevel.Name = "Significantly Overbought Level";
		Input_SigOBLevel.SetFloat(8.0f);
		Input_SigOBLevel.SetFloatLimits(0,100.0f);

		Subgraph_PlusModerateOverboughtLevel.Name = "+ Moderate Overbought Level";
		Subgraph_PlusModerateOverboughtLevel.PrimaryColor = RGB(0,255,0);
		Subgraph_PlusModerateOverboughtLevel.DrawStyle = DRAWSTYLE_LINE;
		Subgraph_PlusModerateOverboughtLevel.DisplayNameValueInWindowsFlags= 0;
		
		Subgraph_PlusSignificantOverboughtLevel.Name = "+ Significant Overbought Level";
		Subgraph_PlusSignificantOverboughtLevel.PrimaryColor = RGB(255,0,0);
		Subgraph_PlusSignificantOverboughtLevel.DrawStyle = DRAWSTYLE_LINE;
		Subgraph_PlusSignificantOverboughtLevel.DisplayNameValueInWindowsFlags= 0;
		
		Subgraph_MinusModerateOverboughtLevel.Name = "- Moderate Overbought Level";
		Subgraph_MinusModerateOverboughtLevel.PrimaryColor = RGB(0,255,0);
		Subgraph_MinusModerateOverboughtLevel.DrawStyle = DRAWSTYLE_LINE;
		Subgraph_MinusModerateOverboughtLevel.DisplayNameValueInWindowsFlags= 0;

		Subgraph_MinusSignificantOverboughtLevel.Name = "- Significant Overbought Level";
		Subgraph_MinusSignificantOverboughtLevel.PrimaryColor = RGB(255,0,0);
		Subgraph_MinusSignificantOverboughtLevel.DrawStyle = DRAWSTYLE_LINE;
		Subgraph_MinusSignificantOverboughtLevel.DisplayNameValueInWindowsFlags= 0;

		Subgraph_ZeroLevel.Name = "Zero Level";
		Subgraph_ZeroLevel.PrimaryColor = RGB(128,128,128);
		Subgraph_ZeroLevel.DrawStyle = DRAWSTYLE_LINE;
		Subgraph_ZeroLevel.DisplayNameValueInWindowsFlags= 0;
		Subgraph_ZeroLevel.DrawZeros = 1;
		

	}

	Subgraph_PlusModerateOverboughtLevel[sc.Index] = Input_ModOBLevel.GetFloat();
	Subgraph_PlusSignificantOverboughtLevel[sc.Index] = Input_SigOBLevel.GetFloat();

	Subgraph_MinusModerateOverboughtLevel[sc.Index] = Input_ModOBLevel.GetFloat() * -1.0f;
	Subgraph_MinusSignificantOverboughtLevel[sc.Index] = Input_SigOBLevel.GetFloat() * -1.0f;


}

/*============================================================================*/
SCSFExport scsf_ValueChart(SCStudyInterfaceRef sc)
{
	SCInputRef Input_Length     = sc.Input[0];

	SCSubgraphRef Subgraph_VcOpen  = sc.Subgraph[0];
	SCSubgraphRef Subgraph_VcHigh  = sc.Subgraph[1];
	SCSubgraphRef Subgraph_VcLow   = sc.Subgraph[2];
	SCSubgraphRef Subgraph_VcClose = sc.Subgraph[3];

	SCFloatArrayRef Array_VcHLMA = Subgraph_VcOpen.Arrays[1];
	SCFloatArrayRef Array_TR     = Subgraph_VcOpen.Arrays[2];
	SCFloatArrayRef Array_ATR    = Subgraph_VcOpen.Arrays[3];
	SCFloatArrayRef Array_HH     = Subgraph_VcOpen.Arrays[4];
	SCFloatArrayRef Array_LL     = Subgraph_VcOpen.Arrays[5];


	if (sc.SetDefaults)
	{
		// Set the configuration and defaults
		sc.GraphName ="Value Chart";

		sc.GraphDrawType = GDT_CANDLESTICK;
		sc.AutoLoop = 1;
		

		// Inputs
		Input_Length.Name = "Length";
		Input_Length.SetInt(5);
		Input_Length.SetIntLimits(2,10000);

		// Subgraphs
		Subgraph_VcOpen.Name = "VC Open";
		Subgraph_VcOpen.DrawStyle = DRAWSTYLE_LINE;
		Subgraph_VcOpen.PrimaryColor = RGB(0,255,0);
		Subgraph_VcOpen.SecondaryColorUsed = true;
		Subgraph_VcOpen.SecondaryColor = RGB(0,255,0);
		Subgraph_VcOpen.DrawZeros = 1;

		Subgraph_VcHigh.Name = "VC High";
		Subgraph_VcHigh.DrawStyle = DRAWSTYLE_LINE;
		Subgraph_VcHigh.PrimaryColor = RGB(128,255,128);
		Subgraph_VcHigh.DrawZeros = 1;

		Subgraph_VcLow.Name = "VC Low";
		Subgraph_VcLow.DrawStyle = DRAWSTYLE_LINE;
		Subgraph_VcLow.PrimaryColor = RGB(255,0,0);
		Subgraph_VcLow.SecondaryColor = RGB(255,0,0);
		Subgraph_VcLow.SecondaryColorUsed = true;
		Subgraph_VcLow.DrawZeros = 1;

		Subgraph_VcClose.Name = "VC Close";
		Subgraph_VcClose.DrawStyle = DRAWSTYLE_LINE;
		Subgraph_VcClose.PrimaryColor = RGB(255,128,128);
		Subgraph_VcClose.DrawZeros = 1;

		return;
	}

	
	
	int NumBars = Input_Length.GetInt();
	float LRange = 1;

	if (NumBars > 7)
	{
		int VarNumBars = sc.Round((float)NumBars / 5.0f);

		sc.Highest(sc.High, Array_HH, VarNumBars);
		sc.Lowest(sc.Low, Array_LL, VarNumBars);

		float R1 = Array_HH[sc.Index] - Array_LL[sc.Index];
		if (R1 == 0 && VarNumBars == 1)
			R1 = abs(sc.Close[sc.Index] - sc.Close[sc.Index-VarNumBars]);

		float R2 = Array_HH[sc.Index-VarNumBars-1] - Array_LL[sc.Index-VarNumBars];
		if (R2 == 0 && VarNumBars == 1)
			R2 = abs(sc.Close[sc.Index-VarNumBars] - sc.Close[sc.Index-(VarNumBars*2)]);

		float R3 = Array_HH[sc.Index-(VarNumBars*2)] - Array_LL[sc.Index-(VarNumBars*2)];
		if (R3 == 0 && VarNumBars == 1)
			R3 = abs(sc.Close[sc.Index-(VarNumBars*2)] - sc.Close[sc.Index-(VarNumBars*3)]);

		float R4 = Array_HH[sc.Index-(VarNumBars*3)] - Array_LL[sc.Index-(VarNumBars*3)];
		if (R4 == 0 && VarNumBars == 1)
			R4 = abs(sc.Close[sc.Index-(VarNumBars*3)] - sc.Close[sc.Index-(VarNumBars*4)]);

		float R5 = Array_HH[sc.Index-(VarNumBars*4)] - Array_LL[sc.Index-(VarNumBars*4)];
		if (R5 == 0 && VarNumBars == 1)
			R5 = abs(sc.Close[sc.Index-(VarNumBars*4)] - sc.Close[sc.Index-(VarNumBars*5)]);

		LRange = (R1 + R2 + R3 + R4 + R5) / 5 / 5;
	}
	else
	{
		sc.ATR(sc.BaseDataIn, Array_TR, Array_ATR, 5, MOVAVGTYPE_SIMPLE);
		LRange = Array_ATR[sc.Index] / 5;
	}


	sc.MovingAverage(sc.HLAvg, Array_VcHLMA, MOVAVGTYPE_SIMPLE, Input_Length.GetInt());
	float AvgVcHL = Array_VcHLMA[sc.Index];

	Subgraph_VcOpen[sc.Index]  = (sc.Open[sc.Index]  - AvgVcHL) / LRange;
	Subgraph_VcHigh[sc.Index]  = (sc.High[sc.Index]  - AvgVcHL) / LRange;
	Subgraph_VcLow[sc.Index]   = (sc.Low[sc.Index]   - AvgVcHL) / LRange;
	Subgraph_VcClose[sc.Index] = (sc.Close[sc.Index] - AvgVcHL) / LRange;
}
