    #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, static_cast<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] = static_cast<float>(Input_OverboughtValue.GetInt());
        Subgraph_Oversold[sc.Index] = static_cast<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 Input_UseLastFromCurrentQuoteData = sc.Input [5];
        SCInputRef Input_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);

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

            Input_NumberOfForwardProjectionBars.Name = "Number of Forward Projection Bars";
            Input_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 (Input_NumberOfForwardProjectionBars.GetInt() == 0)
            Input_NumberOfForwardProjectionBars.SetInt(10);

        SCFloatArrayRef InputDataArray = sc.BaseData[Input_InputData.GetInputDataIndex()];

        float LineValue = 0;

        if(Input_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 = Input_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(0, 255, 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(255, 0, 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 &r_PriorLineStartIndex = sc.GetPersistentInt(1);

        int EarliestUpdateSubgraphDataArrayIndex = sc.ArraySize;

        if (Input_DisplayLinesOnBars.GetYesNo())
        {
            const 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;

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

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

                    EarliestUpdateSubgraphDataArrayIndex = Index;
                }
            }

        }

        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;
            }
        }
        else
        {
            Subgraph_CurrentBidLine.ExtendedArrayElementsToGraph = 0;
            Subgraph_CurrentAskLine.ExtendedArrayElementsToGraph = 0;
        }

        for (int Index = r_PriorLineStartIndex; Index < EarliestUpdateSubgraphDataArrayIndex; ++Index)
        {
            Subgraph_CurrentBidLine[Index] = 0.0;
            Subgraph_CurrentAskLine[Index] = 0.0;
        }

        //if (r_PriorLineStartIndex != 0
        //  && r_PriorLineStartIndex < EarliestUpdateSubgraphDataArrayIndex)
        //{
        //  EarliestUpdateSubgraphDataArrayIndex = r_PriorLineStartIndex;
        //}
        //else
            r_PriorLineStartIndex = EarliestUpdateSubgraphDataArrayIndex;

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

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

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

            Subgraph_OutOfOrderTimestamp.Name = "Out of Order Timestamp";
            Subgraph_OutOfOrderTimestamp.PrimaryColor = RGB(255,64,32);
            Subgraph_OutOfOrderTimestamp.DrawStyle = DRAWSTYLE_BACKGROUND;
            Subgraph_OutOfOrderTimestamp.LineWidth = 5;
            Subgraph_OutOfOrderTimestamp.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;

        SCDateTime PreviousBarDateTime = sc.BaseDateTimeIn[sc.Index-1];
        SCDateTime CurrentBarDateTime = sc.BaseDateTimeIn[sc.Index];

        if(CurrentBarDateTime < PreviousBarDateTime)
            Subgraph_OutOfOrderTimestamp.Data[sc.Index] = 1;
        else
            Subgraph_OutOfOrderTimestamp.Data[sc.Index] = 0;

        return;
    }

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

        if (sc.SetDefaults)
        {
            sc.GraphName = "Duplicate Timestamps Detector";

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

            sc.GraphRegion = 0;

            sc.DisplayStudyInputValues = false;

            sc.ScaleRangeType = SCALE_INDEPENDENT;

            sc.DrawStudyUnderneathMainPriceGraph;

            sc.AutoLoop = 0;

            return;
        }

        sc.DataStartIndex = 1;

        int FirstValidIndex = 1;

        for(int BarIndex = max(FirstValidIndex, sc.UpdateStartIndex); BarIndex < sc.ArraySize; BarIndex++)
        {
            SCDateTimeMS PreviousBarDateTime = sc.BaseDateTimeIn[BarIndex -1];
            SCDateTimeMS CurrentBarDateTime = sc.BaseDateTimeIn[BarIndex];

            if (CurrentBarDateTime == PreviousBarDateTime)
                Subgraph_DuplicateTimestamp.Data[BarIndex] = 1;
            else
                Subgraph_DuplicateTimestamp.Data[BarIndex] = 0;
        }

    }

    /************************************************************
    *  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 = static_cast<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] = static_cast<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 (static_cast<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] = static_cast<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 = (static_cast<double>(CurrentPrice) - Subgraph_VWAPSubgraph[sc.Index]) * (static_cast<double>(CurrentPrice) - Subgraph_VWAPSubgraph[sc.Index]) * sc.Volume[sc.Index];
            if (IsStartOfNewPeriod)
            {
                Array_BarSumPriceVWAPDifferenceSquaredTimesVolume[sc.Index] = static_cast<float>(PriceVWAPDifferenceSquaredTimesVolume);
            }
            else
            {
                Array_BarSumPriceVWAPDifferenceSquaredTimesVolume[sc.Index] =
                    static_cast<float>(Array_BarSumPriceVWAPDifferenceSquaredTimesVolume[sc.Index - 1] + PriceVWAPDifferenceSquaredTimesVolume);
            }

            if (CumulativeVolume != 0)
                BandDistance = static_cast<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 = static_cast<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 - SCDateTime::DAYS(DaysBack);
                SCDateTime PriorPeriodEndDateTime = PriorPeriodStartDateTime + SCDateTime::DAYS(1) - SCDateTime::SECONDS(1);

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

                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.GetAsDouble());

                const SCDateTime ActualTimeSpan(sc.CalculateTimeSpanAcrossChartBars
                (r_InitialBarIndex, PriorPeriodLastIndex));

                //If there is a sufficient amount of data in this time period
                if (ActualTimeSpan > SCDateTime::SECONDS_Fraction(MinimumRequiredTimePeriodInDayAsPercent * 0.01 * SECONDS_PER_DAY))
                {
                    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];
        SCInputRef Input_VolumeTypeToUse = sc.Input[17];

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

        n_ACSIL::s_BarPeriod BarPeriod;
        sc.GetBarPeriodParameters(BarPeriod);

        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() &&
            static_cast<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;
            }

            const int VolumeTypeToUse = Input_VolumeTypeToUse.GetIndex();

            const int InputDataIndex = Input_InputData.GetInputDataIndex();

            float CurrentPrice = sc.BaseDataIn[InputDataIndex][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;
                    uint32_t VolumeToUse = 0;

                    if (VolumeTypeToUse == 1)
                        VolumeToUse = p_VolumeAtPrice->BidVolume;
                    else if (VolumeTypeToUse == 2)
                        VolumeToUse = p_VolumeAtPrice->AskVolume;
                    else
                        VolumeToUse = p_VolumeAtPrice->Volume;

                    const float PriceTimesVolume = Price * VolumeToUse;

                    Array_BarSumPriceTimesVolume[Index] += PriceTimesVolume;
                }
            }
            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.GetAsDouble());

                    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] - SCDateTime::DAYS(1) + SCDateTime::SECONDS(1);
                    r_FirstIndexIncluded = sc.GetContainingIndexForSCDateTime(sc.ChartNumber, CurrentPeriodStartDateTime.GetAsDouble());

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

                    if (BarPeriod.IntradayChartBarPeriodType == IBPT_DAYS_MINS_SECS && sc.SecondsPerBar != 0)
                    {
                        RollingStartDateTime = sc.BaseDateTimeIn[Index] + SCDateTime::SECONDS(sc.SecondsPerBar - 1);
                        RollingStartDateTime.SubtractMinutes(Input_TimePeriodLength.GetInt());
                    }
                    else
                    {
                        if (Index == sc.ArraySize - 1)
                            RollingStartDateTime = sc.LatestDateTimeForLastBar;
                        else
                            RollingStartDateTime = sc.BaseDateTimeIn[Index + 1] - SCDateTime::SECONDS(1);

                        RollingStartDateTime.SubtractMinutes(Input_TimePeriodLength.GetInt());
                    }

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

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

                    if (VolumeTypeToUse == 1)
                    {
                        Subgraph_CumulativeVolumeForPeriodArray[AvgIndex] = sc.BidVolume[AvgIndex];
                    }
                    else if (VolumeTypeToUse == 2)
                    {
                        Subgraph_CumulativeVolumeForPeriodArray[AvgIndex] = sc.AskVolume[AvgIndex];
                    }
                    else
                    {
                        Subgraph_CumulativeVolumeForPeriodArray[AvgIndex] = sc.Volume[AvgIndex];
                    }
                }
                else
                {

                    Array_PriceTimesVolumeArray[AvgIndex] = Array_PriceTimesVolumeArray[AvgIndex - 1] + Array_BarSumPriceTimesVolume[AvgIndex];

                    if (VolumeTypeToUse == 1)
                    {
                        Subgraph_CumulativeVolumeForPeriodArray[AvgIndex] = Subgraph_CumulativeVolumeForPeriodArray[AvgIndex - 1] + sc.BidVolume[AvgIndex];
                    }
                    else if (VolumeTypeToUse == 2)
                    {
                        Subgraph_CumulativeVolumeForPeriodArray[AvgIndex] = Subgraph_CumulativeVolumeForPeriodArray[AvgIndex - 1] + sc.AskVolume[AvgIndex];
                    }
                    else//Total volume
                    {
                        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)
                {
                        float VolumeToUseInCalculation = 0;
                        if (VolumeTypeToUse == 1)
                        {
                            VolumeToUseInCalculation = sc.BidVolume[BarIndex];
                        }
                        else if (VolumeTypeToUse == 2)
                        {
                            VolumeToUseInCalculation = sc.AskVolume[BarIndex];
                        }
                        else
                        {
                            VolumeToUseInCalculation= sc.Volume[BarIndex];
                        }

                        Subgraph_PriceVWAPDifferenceSquaredTimesVolume[BarIndex] =
                            (sc.BaseDataIn[InputDataIndex][BarIndex]
                                - Subgraph_BackgroundVWAPForCurrentPeriod[BarIndex])
                            * (sc.BaseDataIn[InputDataIndex][BarIndex]
                                - Subgraph_BackgroundVWAPForCurrentPeriod[BarIndex])
                            * VolumeToUseInCalculation;

                    if (ResetCalculation)
                    {
                        ResetCalculation = false;

                        Subgraph_BarSumPriceVWAPDifferenceSquaredTimesVolumeArray[BarIndex] = Subgraph_PriceVWAPDifferenceSquaredTimesVolume[BarIndex];
                    }
                    else
                    {
                        Subgraph_BarSumPriceVWAPDifferenceSquaredTimesVolumeArray[BarIndex] = Subgraph_BarSumPriceVWAPDifferenceSquaredTimesVolumeArray[BarIndex - 1] + Subgraph_PriceVWAPDifferenceSquaredTimesVolume[BarIndex];

                    }
                }

                if (Subgraph_CumulativeVolumeForPeriodArray[Index] != 0)
                {
                    Subgraph_BandDistance[Index] = static_cast<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;
        }

        n_ACSIL::s_BarPeriod BarPeriod;
        sc.GetBarPeriodParameters(BarPeriod);

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

        if (static_cast<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.GetAsDouble());

                    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] - SCDateTime::DAYS(1) + SCDateTime::SECONDS(1);
                    FirstIndexIncluded = sc.GetContainingIndexForSCDateTime(sc.ChartNumber, CurrentPeriodStartDateTime.GetAsDouble());

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

                    if (BarPeriod.IntradayChartBarPeriodType == IBPT_DAYS_MINS_SECS && BarPeriod.IntradayChartBarPeriodParameter1 != 0)
                    {
                        RollingStartDateTime  = sc.BaseDateTimeIn[Index] + SCDateTime::SECONDS(sc.SecondsPerBar - 1);
                        RollingStartDateTime.SubtractMinutes(Input_TimePeriodLength.GetInt());
                    }
                    else
                    {
                        if (Index == sc.ArraySize - 1)
                            RollingStartDateTime = sc.LatestDateTimeForLastBar;
                        else
                            RollingStartDateTime = sc.BaseDateTimeIn[Index+1] - SCDateTime::SECONDS(1);

                        RollingStartDateTime.SubtractMinutes(Input_TimePeriodLength.GetInt());
                    }

                    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] = static_cast<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, static_cast<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] = static_cast<float>(Subgraph_MidBand[sc.Index] + StandardErrorValue * Input_StandardDeviations.GetFloat());

        Subgraph_LowerBand[sc.Index] = static_cast<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, static_cast<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, static_cast<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, static_cast<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, static_cast<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] = static_cast<float>(Input_Line1Value.GetInt());
        Subgraph_Line2[sc.Index] = static_cast<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 = static_cast<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)", static_cast<int>(CHART_DRAWING_MAX_HORIZONTAL_AXIS_RELATIVE_POSITION));
            Input_HorizontalPosition.SetInt(20);
            Input_HorizontalPosition.SetIntLimits(1, static_cast<int>(CHART_DRAWING_MAX_HORIZONTAL_AXIS_RELATIVE_POSITION));

            Input_VerticalPosition.Name.Format("Vertical Position From Bottom (1-%d)", static_cast<int>(CHART_DRAWING_MAX_VERTICAL_AXIS_RELATIVE_POSITION));
            Input_VerticalPosition.SetInt(90);
            Input_VerticalPosition.SetIntLimits(1, static_cast<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.IsEmpty())
        {
            ValueText += sc.TextInput;
            ValueText += " ";
        }

        if (Input_DisplaySubgraphName.GetYesNo())
        {
            SCString SubgraphNameFromChartStudy;
            sc.GetStudySubgraphNameFromChart(Input_StudySubgraphReference.GetChartNumber(), Input_StudySubgraphReference.GetStudyID(), Input_StudySubgraphReference.GetSubgraphIndex(), SubgraphNameFromChartStudy);
            ValueText += SubgraphNameFromChartStudy;
            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)", static_cast<int>(CHART_DRAWING_MAX_HORIZONTAL_AXIS_RELATIVE_POSITION));
            Input_HorizontalPosition.SetInt(20);
            Input_HorizontalPosition.SetIntLimits(1, static_cast<int>(CHART_DRAWING_MAX_HORIZONTAL_AXIS_RELATIVE_POSITION));

            Input_VerticalPosition.Name.Format("Vertical Position From Bottom (1-%d)", static_cast<int>(CHART_DRAWING_MAX_VERTICAL_AXIS_RELATIVE_POSITION));
            Input_VerticalPosition.SetInt(90);
            Input_VerticalPosition.SetIntLimits(1, static_cast<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
            , sc.DrawStudyUnderneathMainPriceGraph? 0 : 1
            );

    }

    /*============================================================================ */
    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_RoundTurnCommission = 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];
        SCInputRef Input_ShowCurrentTradeTimeDuration = sc.Input[20];
        SCInputRef Input_ShowNetProfitLossForAllSymbolsForTradeAccount = sc.Input[21];

        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)", static_cast<int>(CHART_DRAWING_MAX_HORIZONTAL_AXIS_RELATIVE_POSITION));
            Input_HorizontalPosition.SetInt(20);
            Input_HorizontalPosition.SetIntLimits(1, static_cast<int>(CHART_DRAWING_MAX_HORIZONTAL_AXIS_RELATIVE_POSITION));

            Input_VerticalPosition.Name.Format("Vertical Position From Bottom (1-%d)", static_cast<int>(CHART_DRAWING_MAX_VERTICAL_AXIS_RELATIVE_POSITION));
            Input_VerticalPosition.SetInt(90);
            Input_VerticalPosition.SetIntLimits(1, static_cast<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_RoundTurnCommission.Name = "Round Turn Commission To Include";
            Input_RoundTurnCommission.SetFloat(0);

            Input_ShowCurrentTradeTimeDuration.Name = "Show Current Trade Time Duration";
            Input_ShowCurrentTradeTimeDuration.SetYesNo(0);

            Input_ShowNetProfitLossForAllSymbolsForTradeAccount.Name = "Show Net Profit/Loss for All Symbols for Trade Account";
            Input_ShowNetProfitLossForAllSymbolsForTradeAccount.SetYesNo(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 = static_cast<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 = static_cast<ProfitLossDisplayFormatEnum>(Input_ProfitLossFormat.GetIndex()+1);

        s_SCPositionData PositionData;
        sc.GetTradePosition(PositionData);

        const double RoundTurnCommissionRate = sc.CurrencyValuePerTick == 0 ? 0 : Input_RoundTurnCommission.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 * fabs(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.IsEmpty())
                Text.Append("\n");

            SCString PLString;
            double Commission = RoundTurnCommissionRate * fabs(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.IsEmpty())
                Text.Append("\n");

            double DailyPL = DailyStats.ClosedTradesProfitLoss;
            double  DailyClosedQuantity = DailyStats.TotalQuantity;
            double Commission = RoundTurnCommissionRate * fabs(DailyClosedQuantity);

            if (Input_IncludeOpenPLInDailyPL.GetYesNo())
            {
                DailyPL += PositionData.OpenProfitLoss;
                const double 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.IsEmpty())
                Text.Append("\n");

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

            Text.Append(TotalTradesText);
        }

        if (Input_ShowTotalQuantityFilled.GetYesNo())
        {
            if (!Text.IsEmpty())
                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.IsEmpty())
                Text.Append("\n");

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

            Text.Append(TotalTradesText);
        }

        if (Input_ShowDailyTotalQuantityFilled.GetYesNo())
        {
            if (!Text.IsEmpty())
                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.IsEmpty())
                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.IsEmpty())
                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.IsEmpty())
                Text.Append("\n");

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

        }

        if (Input_ShowCurrentTradeTimeDuration.GetYesNo())
        {
            if (!Text.IsEmpty())
                Text.Append("\n");

            s_ACSTrade TradeEntry;
            int32_t TradesSize = sc.GetFlatToFlatTradeListSize();
            if (TradesSize >= 1)
            {
                const int Result = sc.GetFlatToFlatTradeListEntry(TradesSize - 1, TradeEntry);

                if (TradeEntry.CloseDateTime.IsUnset())
                {
                    SCDateTime TimeDuration = sc.GetCurrentDateTime() - TradeEntry.OpenDateTime;
                    SCString DurationString;
                    DurationString = sc.DateTimeToString(TimeDuration.GetAsDouble(), FLAG_DT_DATE_TIME_AS_TIME_DURATION_FORMAT);
                    Text += DurationString;
                }
            }
        }

        if (Input_ShowNetProfitLossForAllSymbolsForTradeAccount.GetYesNo())
        {
            if (!Text.IsEmpty())
                Text.Append("\n");

            SCString PLString;
            double NetProfitLoss = sc.GetTotalNetProfitLossForAllSymbols(1);
            sc.CreateProfitLossDisplayString(NetProfitLoss, 0, ProfitLossDisplayFormat, PLString);
            Text.AppendFormat("AllSymbols Daily Net 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;

        uint32_t Color0 = Subgraph_Above.PrimaryColor;
        uint32_t Color1 = Subgraph_Below.PrimaryColor;
        uint32_t Color2 = Subgraph_DoNotDraw1.PrimaryColor;
        uint32_t 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
        uint32_t colorFlat = Subgraph_FlatColor.PrimaryColor;
        uint32_t colorNormalUp = Subgraph_SwTop.PrimaryColor;
        uint32_t colorTrendingUp = Subgraph_SwTop.SecondaryColor;
        uint32_t colorNormalDown = Subgraph_SwBottom.PrimaryColor;
        uint32_t 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 = static_cast<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 = static_cast<float>(sc.SlopeToAngleInDegrees((Subgraph_Ema[Pos]-((Subgraph_Ema[Pos-1]+Subgraph_Ema[Pos-2])/2.0f))*InverseTickSize));

        Subgraph_EmaAngle[Pos] = ema_Angle;

        // Calculate SW
        uint32_t color = 0;
        float worksheetValue = 0;

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

            sc.AutoLoop = 1;

            return;
        }

        uint32_t Color0 = Subgraph_LsmaCCI.PrimaryColor;
        uint32_t 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] = static_cast<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;
        }

        uint32_t color0 = Subgraph_Lsma.PrimaryColor;
        uint32_t 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;
        }

        uint32_t color0 = Subgraph_ExponentialMovingAverage.PrimaryColor;
        uint32_t 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().GetAsDouble()) -  BarsBackToReference + 1;

        }

        double HighestHighOfSquareWidthLength = static_cast<double>(sc.GetHighest(sc.High, PreviousStartOutputBarIndex + BarsBackToReference - 1, BarsBackToReference));

        double LowestLowOfSquareWidthLength = static_cast<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));

        if(PriceRange == 0)
            M = 0.0f;
        else
            M = int(((1 / log(2.0)) * log(fabs(PriceRange / Si))) + .00001);

        double ValueToRound = (((HighestHighOfSquareWidthLength + LowestLowOfSquareWidthLength) * .5)/(Si* exp((M-1)*log(2.0))));
        I = sc.Round(static_cast<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 = static_cast<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;
            sc.AutoLoop = 0;

            return;
        }

        SCDateTime  PriorDayCloseDateTime = sc.GetStartDateTimeForTradingDate(sc.GetTradingDayDate(sc.BaseDateTimeIn[sc.ArraySize - 1]) );

        PriorDayCloseDateTime.SubtractSeconds(1);

        int PriorDayCloseDateTimeIndex = sc.GetContainingIndexForSCDateTime(sc.ChartNumber, PriorDayCloseDateTime.GetAsDouble());

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

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

        SCInputRef Input_InputData = sc.Input[0];
        SCInputRef Input_Length = sc.Input[1];
        SCInputRef Input_Multiplier = sc.Input[2];
        SCInputRef Input_GDEMACount = sc.Input[3];

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

            sc.GraphName = "Moving Average - Generalized Double Exponential";
            sc.GraphRegion = 0;

            sc.StudyDescription = "Moving Average - Generalized Double Moving Exponential";

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

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

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

            Input_Multiplier.Name = "Multiplier";
            Input_Multiplier.SetFloat(1.0f);

            Input_GDEMACount.Name = "GDEMA Count";
            Input_GDEMACount.SetInt(1);
            Input_GDEMACount.SetIntLimits(1, SC_SUBGRAPHS_AVAILABLE - 1);

            sc.AutoLoop = 1;

            return;
        }

        int Length = Input_Length.GetInt();
        float Multiplier = Input_Multiplier.GetFloat();
        int Count = Input_GDEMACount.GetInt();

        sc.DataStartIndex = Length * Count;

        if (sc.Index == 0)
        {
            for (int SubgraphIndex = 1; SubgraphIndex <= Count; SubgraphIndex++)
            {
                sc.Subgraph[SubgraphIndex].Name.Format("%d", SubgraphIndex);
                sc.Subgraph[SubgraphIndex].DrawStyle = DRAWSTYLE_IGNORE;
                sc.Subgraph[SubgraphIndex].DisplayNameValueInWindowsFlags = 0;
            }
        }

        sc.ExponentialMovAvg(sc.BaseDataIn[Input_InputData.GetInputDataIndex()], sc.Subgraph[1].Arrays[0], Length);
        sc.ExponentialMovAvg(sc.Subgraph[1].Arrays[0], sc.Subgraph[1].Arrays[1], Length);
        sc.Subgraph[1][sc.Index] = (1 + Multiplier) * sc.Subgraph[1].Arrays[0][sc.Index] - Multiplier * sc.Subgraph[1].Arrays[1][sc.Index];

        for (int SubgraphIndex = 2; SubgraphIndex <= Count; SubgraphIndex++)
        {
            sc.ExponentialMovAvg(sc.Subgraph[SubgraphIndex - 1], sc.Subgraph[SubgraphIndex].Arrays[0], Length);
            sc.ExponentialMovAvg(sc.Subgraph[SubgraphIndex].Arrays[0], sc.Subgraph[SubgraphIndex].Arrays[1], Length);
            sc.Subgraph[SubgraphIndex][sc.Index] = (1 + Multiplier) * sc.Subgraph[SubgraphIndex].Arrays[0][sc.Index] - Multiplier * sc.Subgraph[SubgraphIndex].Arrays[1][sc.Index];
        }

        Subgraph_GDEMA[sc.Index] = sc.Subgraph[Count][sc.Index];
    }

    /*==========================================================================*/
    SCSFExport scsf_SchaffTrendCycle(SCStudyInterfaceRef sc)
    {
        SCSubgraphRef Subgraph_SchaffTrendCycle = sc.Subgraph[0];
        SCSubgraphRef Subgraph_MACD = sc.Subgraph[1];
        SCSubgraphRef Subgraph_FastKMACD = sc.Subgraph[2];
        SCSubgraphRef Subgraph_FastDMACD = sc.Subgraph[3];
        SCSubgraphRef Subgraph_FastKFastDMACD = sc.Subgraph[4];
        SCSubgraphRef Subgraph_Overbought = sc.Subgraph[5];
        SCSubgraphRef Subgraph_Oversold = sc.Subgraph[6];

        SCInputRef Input_InputData = sc.Input[0];
        SCInputRef Input_FastLength = sc.Input[2];
        SCInputRef Input_SlowLength = sc.Input[3];
        SCInputRef Input_MovingAverageType = sc.Input[4];
        SCInputRef Input_Length = sc.Input[5];
        SCInputRef Input_Multiplier = sc.Input[6];
        SCInputRef Input_Overbought = sc.Input[7];
        SCInputRef Input_Oversold = sc.Input[8];

        if (sc.SetDefaults)
        {
            sc.GraphName = "Schaff Trend Cycle";
            sc.AutoLoop = 1;
            sc.GraphRegion = 1;

            Subgraph_SchaffTrendCycle.Name = "Schaff Trend Cycle";
            Subgraph_SchaffTrendCycle.DrawStyle = DRAWSTYLE_LINE;
            Subgraph_SchaffTrendCycle.DrawZeros = true;
            Subgraph_SchaffTrendCycle.PrimaryColor = RGB(0, 0, 255);

            Subgraph_MACD.Name = "MACD";
            Subgraph_MACD.DrawStyle = DRAWSTYLE_IGNORE;

            Subgraph_FastKMACD.Name = "Fast %K of MACD";
            Subgraph_FastKMACD.DrawStyle = DRAWSTYLE_IGNORE;

            Subgraph_FastDMACD.Name = "Fast %D of MACD";
            Subgraph_FastDMACD.DrawStyle = DRAWSTYLE_IGNORE;

            Subgraph_FastKFastDMACD.Name = "Fast %K of Fast %D of MACD";
            Subgraph_FastKFastDMACD.DrawStyle = DRAWSTYLE_IGNORE;

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

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

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

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

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

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

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

            Input_Multiplier.Name = "Multiplier";
            Input_Multiplier.SetFloat(0.5f);

            Input_Overbought.Name = "Overbought Level";
            Input_Overbought.SetFloat(75.0f);

            Input_Oversold.Name = "Oversold Level";
            Input_Oversold.SetFloat(25.0f);

            return;
        }

        // MACD of Price Data
        sc.MACD(sc.BaseDataIn[Input_InputData.GetInputDataIndex()], Subgraph_MACD, sc.Index, Input_FastLength.GetInt(), Input_SlowLength.GetInt(), Input_Length.GetInt(), Input_MovingAverageType.GetInt());

        // Fast %K of MACD
        float MaxMACD = sc.GetHighest(Subgraph_MACD, sc.Index, Input_Length.GetInt());
        float MinMACD = sc.GetLowest(Subgraph_MACD, sc.Index, Input_Length.GetInt());
        float RangeMACD = MaxMACD - MinMACD;

        if (RangeMACD > 0.0f)
            Subgraph_FastKMACD[sc.Index] = 100.0f * (Subgraph_MACD[sc.Index] - MinMACD) / RangeMACD;
        else
            Subgraph_FastKMACD[sc.Index] = Subgraph_FastKMACD[sc.Index - 1];

        // Fast %D of MACD
        if (sc.Index == 0)
            Subgraph_FastDMACD[sc.Index] = Subgraph_FastKMACD[sc.Index];
        else
            Subgraph_FastDMACD[sc.Index] = Subgraph_FastDMACD[sc.Index - 1] + Input_Multiplier.GetFloat() * (Subgraph_FastKMACD[sc.Index] - Subgraph_FastDMACD[sc.Index - 1]);

        // Fast %K of Fast %D of MACD
        float MaxFastDMACD = sc.GetHighest(Subgraph_FastDMACD, sc.Index, Input_Length.GetInt());
        float MinFastDMACD = sc.GetLowest(Subgraph_FastDMACD, sc.Index, Input_Length.GetInt());
        float RangeFastDMACD = MaxFastDMACD - MinFastDMACD;

        if (RangeFastDMACD > 0.0f)
            Subgraph_FastKFastDMACD[sc.Index] = 100.0f * (Subgraph_FastDMACD[sc.Index] - MinFastDMACD) / RangeFastDMACD;
        else
            Subgraph_FastKFastDMACD[sc.Index] = Subgraph_FastKFastDMACD[sc.Index - 1];

        // Schaff Trend Cycle
        if (sc.Index == 0)
            Subgraph_SchaffTrendCycle[sc.Index] = Subgraph_FastKFastDMACD[sc.Index];
        else
            Subgraph_SchaffTrendCycle[sc.Index] = Subgraph_SchaffTrendCycle[sc.Index - 1] + Input_Multiplier.GetFloat() * (Subgraph_FastKFastDMACD[sc.Index] - Subgraph_SchaffTrendCycle[sc.Index - 1]);

        // Overbought and Oversold Lines
        Subgraph_Overbought[sc.Index] = Input_Overbought.GetFloat();
        Subgraph_Oversold[sc.Index] = Input_Oversold.GetFloat();
    }

    /*==========================================================================*/
    SCSFExport scsf_PremierStochasticOscillator(SCStudyInterfaceRef sc)
    {
        SCSubgraphRef Subgraph_FastK = sc.Subgraph[0];
        SCSubgraphRef Subgraph_FastD = sc.Subgraph[1];
        SCSubgraphRef Subgraph_SlowD = sc.Subgraph[2];
        SCSubgraphRef Subgraph_PSO = sc.Subgraph[3];
        SCSubgraphRef Subgraph_Line1 = sc.Subgraph[4];
        SCSubgraphRef Subgraph_Line2 = sc.Subgraph[5];
        SCSubgraphRef Subgraph_Line3 = sc.Subgraph[6];
        SCSubgraphRef Subgraph_Line4 = sc.Subgraph[7];
        SCSubgraphRef Subgraph_CenterLine = sc.Subgraph[8];

        SCFloatArrayRef Array_Stochastic = sc.Subgraph[3].Arrays[0];
        SCFloatArrayRef Array_EMAStochastic = sc.Subgraph[3].Arrays[1];
        SCFloatArrayRef Array_EMAEMAStochastic = sc.Subgraph[3].Arrays[2];
        SCFloatArrayRef Array_ExponentialValue = sc.Subgraph[3].Arrays[3];

        SCInputRef Input_InputDataHigh = sc.Input[0];
        SCInputRef Input_InputDataLow = sc.Input[1];
        SCInputRef Input_InputDataLast = sc.Input[2];
        SCInputRef Input_StochasticType = sc.Input[3];
        SCInputRef Input_FastKLength = sc.Input[4];
        SCInputRef Input_FastDLength = sc.Input[5];
        SCInputRef Input_SlowDLength = sc.Input[6];
        SCInputRef Input_PercentDMovAvgType = sc.Input[7];
        SCInputRef Input_PSOLength = sc.Input[8];
        SCInputRef Input_PSOMovAvgType = sc.Input[9];
        SCInputRef Input_Line1Value = sc.Input[10];
        SCInputRef Input_Line2Value = sc.Input[11];
        SCInputRef Input_Line3Value = sc.Input[12];
        SCInputRef Input_Line4Value = sc.Input[13];

        if (sc.SetDefaults)
        {
            sc.GraphName = "Premier Stochastic Oscillator";

            sc.ValueFormat = 2;

            Subgraph_FastK.Name = "Fast %K";
            Subgraph_FastK.DrawStyle = DRAWSTYLE_IGNORE;

            Subgraph_FastD.Name = "Fast %D (Slow %K)";
            Subgraph_FastD.DrawStyle = DRAWSTYLE_IGNORE;

            Subgraph_SlowD.Name = "Slow %D";
            Subgraph_SlowD.DrawStyle = DRAWSTYLE_IGNORE;

            Subgraph_PSO.Name = "Premier Stochastic Oscillator";
            Subgraph_PSO.DrawStyle = DRAWSTYLE_LINE;
            Subgraph_PSO.PrimaryColor = RGB(0, 255, 0);
            Subgraph_PSO.DrawZeros = true;

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

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

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

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

            Subgraph_CenterLine.Name = "Center Line";
            Subgraph_CenterLine.DrawStyle = DRAWSTYLE_LINE;
            Subgraph_CenterLine.PrimaryColor = RGB(128, 0, 128);
            Subgraph_CenterLine.DrawZeros = true;

            Input_InputDataHigh.Name = "Input Data for High";
            Input_InputDataHigh.SetInputDataIndex(SC_HIGH);

            Input_InputDataLow.Name = "Input Data for Low";
            Input_InputDataLow.SetInputDataIndex(SC_LOW);

            Input_InputDataLast.Name = "Input Data for Last";
            Input_InputDataLast.SetInputDataIndex(SC_LAST);

            Input_StochasticType.Name = "Stochastic Type";
            Input_StochasticType.SetCustomInputStrings
            ("Fast %K"
                ";Fast %D (Slow %K)"
                ";Slow %D"
            );
            Input_StochasticType.SetCustomInputIndex(0);

            Input_FastKLength.Name = "Fast %K Length";
            Input_FastKLength.SetInt(8);
            Input_FastKLength.SetIntLimits(1, MAX_STUDY_LENGTH);

            Input_FastDLength.Name = "Fast %D (Slow %K) Length";
            Input_FastDLength.SetInt(8);
            Input_FastDLength.SetIntLimits(1, MAX_STUDY_LENGTH);

            Input_SlowDLength.Name = "Slow %D Length";
            Input_SlowDLength.SetInt(8);
            Input_SlowDLength.SetIntLimits(1, MAX_STUDY_LENGTH);

            Input_PercentDMovAvgType.Name = "Fast/Slow %D Moving Average Type";
            Input_PercentDMovAvgType.SetMovAvgType(MOVAVGTYPE_SIMPLE);

            Input_PSOLength.Name = "PSO Length";
            Input_PSOLength.SetInt(5);
            Input_PSOLength.SetIntLimits(1, MAX_STUDY_LENGTH);

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

            Input_Line1Value.Name = "Line 1 Value";
            Input_Line1Value.SetFloat(0.5f);
            Input_Line1Value.SetFloatLimits(-1.0f, 1.0f);

            Input_Line2Value.Name = "Line 2 Value";
            Input_Line2Value.SetFloat(0.25f);
            Input_Line2Value.SetFloatLimits(-1.0f, 1.0f);

            Input_Line3Value.Name = "Line 3 Value";
            Input_Line3Value.SetFloat(-0.25f);
            Input_Line3Value.SetFloatLimits(-1.0f, 1.0f);

            Input_Line4Value.Name = "Line 4 Value";
            Input_Line4Value.SetFloat(-0.5f);
            Input_Line4Value.SetFloatLimits(-1.0f, 1.0f);

            sc.AutoLoop = true;
            return;
        }

        sc.Stochastic(
            sc.BaseData[Input_InputDataHigh.GetInputDataIndex()],
            sc.BaseData[Input_InputDataLow.GetInputDataIndex()],
            sc.BaseData[Input_InputDataLast.GetInputDataIndex()],
            Subgraph_FastK,  // Data member is Fast %K
            Input_FastKLength.GetInt(),
            Input_FastDLength.GetInt(),
            Input_SlowDLength.GetInt(),
            Input_PercentDMovAvgType.GetMovAvgType());

        Subgraph_FastD[sc.Index] = Subgraph_FastK.Arrays[0][sc.Index];
        Subgraph_SlowD[sc.Index] = Subgraph_FastK.Arrays[1][sc.Index];

        const int SelectedIndex = Input_StochasticType.GetIndex();

        switch (SelectedIndex)
        {
        case 0:
        {
            sc.DataStartIndex = Input_FastKLength.GetInt() + 2 * Input_PSOMovAvgType.GetInt() - 1;

            Array_Stochastic[sc.Index] = 0.1f * (Subgraph_FastK[sc.Index] - 50.0f);
        }
        break;

        case 1:
        {
            sc.DataStartIndex = Input_FastKLength.GetInt() + Input_FastDLength.GetInt() + 2 * Input_PSOMovAvgType.GetInt() - 1;

            Array_Stochastic[sc.Index] = 0.1f * (Subgraph_FastD[sc.Index] - 50.0f);
        }
        break;

        case 2:
        {
            sc.DataStartIndex = Input_FastKLength.GetInt() + Input_FastDLength.GetInt() + Input_SlowDLength.GetInt() + 2 * Input_PSOMovAvgType.GetInt() - 1;

            Array_Stochastic[sc.Index] = 0.1f * (Subgraph_SlowD[sc.Index] - 50.0f);

        }
        break;
        }

        sc.MovingAverage(Array_Stochastic, Array_EMAStochastic, Input_PSOMovAvgType.GetMovAvgType(), Input_PSOLength.GetInt());
        sc.MovingAverage(Array_EMAStochastic, Array_EMAEMAStochastic, Input_PSOMovAvgType.GetMovAvgType(), Input_PSOLength.GetInt());

        Array_ExponentialValue[sc.Index] = exp(Array_EMAEMAStochastic[sc.Index]);

        Subgraph_PSO[sc.Index] = (Array_ExponentialValue[sc.Index] - 1) / (Array_ExponentialValue[sc.Index] + 1);

        Subgraph_Line1[sc.Index] = Input_Line1Value.GetFloat();
        Subgraph_Line2[sc.Index] = Input_Line2Value.GetFloat();
        Subgraph_Line3[sc.Index] = Input_Line3Value.GetFloat();
        Subgraph_Line4[sc.Index] = Input_Line4Value.GetFloat();

        Subgraph_CenterLine[sc.Index] = 0.0f;
    }

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

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

        if (sc.SetDefaults)
        {
            sc.GraphName = "Super Smoother Filter";

            sc.AutoLoop = 1;
            sc.GraphRegion = 1;

            Subgraph_SuperSmootherFilter.Name = "Super Smoother Filter";
            Subgraph_SuperSmootherFilter.DrawStyle = DRAWSTYLE_LINE;
            Subgraph_SuperSmootherFilter.PrimaryColor = RGB(0, 255, 0);

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

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

            Input_Poles.Name = "Number of Poles";
            Input_Poles.SetCustomInputStrings("2;3");
            Input_Poles.SetCustomInputIndex(0);

            return;
        }

        const int SelectedIndex = Input_Poles.GetIndex();
        switch (SelectedIndex)
        {
        case 0:
        {
            sc.SuperSmoother2Pole(sc.BaseDataIn[Input_InputData.GetInputDataIndex()], Subgraph_SuperSmootherFilter, sc.Index, Input_Length.GetInt());
        }
        break;

        case 1:
        {
            sc.SuperSmoother3Pole(sc.BaseDataIn[Input_InputData.GetInputDataIndex()], Subgraph_SuperSmootherFilter, sc.Index, Input_Length.GetInt());
        }
        break;
        }
    }

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

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

        if (sc.SetDefaults)
        {
            sc.GraphName = "Butterworth Filter";

            sc.AutoLoop = 1;
            sc.GraphRegion = 1;

            Subgraph_ButterworthFilter.Name = "Butterworth Filter";
            Subgraph_ButterworthFilter.DrawStyle = DRAWSTYLE_LINE;
            Subgraph_ButterworthFilter.PrimaryColor = RGB(0, 255, 0);

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

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

            Input_Poles.Name = "Number of Poles";
            Input_Poles.SetCustomInputStrings("2;3");
            Input_Poles.SetCustomInputIndex(0);

            return;
        }

        const int SelectedIndex = Input_Poles.GetIndex();
        switch (SelectedIndex)
        {
        case 0:
        {
            sc.Butterworth2Pole(sc.BaseDataIn[Input_InputData.GetInputDataIndex()], Subgraph_ButterworthFilter, sc.Index, Input_Length.GetInt());
        }
        break;

        case 1:
        {
            sc.Butterworth3Pole(sc.BaseDataIn[Input_InputData.GetInputDataIndex()], Subgraph_ButterworthFilter, sc.Index, Input_Length.GetInt());
        }
        break;
        }
    }

    /*==========================================================================*/
    SCSFExport scsf_ConnorsRSI(SCStudyInterfaceRef sc)
    {
        SCSubgraphRef Subgraph_RSI = sc.Subgraph[0];
        SCSubgraphRef Subgraph_UpDownLength = sc.Subgraph[1];
        SCSubgraphRef Subgraph_RSIUpDownLength = sc.Subgraph[2];
        SCSubgraphRef Subgraph_RateOfChange = sc.Subgraph[3];
        SCSubgraphRef Subgraph_ConnorsRSI = sc.Subgraph[4];
        SCSubgraphRef Subgraph_Line1 = sc.Subgraph[5];
        SCSubgraphRef Subgraph_Line2 = sc.Subgraph[6];

        SCFloatArrayRef Array_PriceChange = sc.Subgraph[3].Arrays[0];

        SCInputRef Input_InputData = sc.Input[0];
        SCInputRef Input_RSILength = sc.Input[1];
        SCInputRef Input_RSIAvgType = sc.Input[2];
        SCInputRef Input_RateOfChangeLength = sc.Input[3];
        SCInputRef Input_Line1Value = sc.Input[4];
        SCInputRef Input_Line2Value = sc.Input[5];

        if (sc.SetDefaults)
        {
            sc.GraphName = "RSI - Connors ";

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

            Subgraph_RSI.Name = "RSI";
            Subgraph_RSI.DrawStyle = DRAWSTYLE_IGNORE;

            Subgraph_UpDownLength.Name = "Up-Down Streak Length";
            Subgraph_UpDownLength.DrawStyle = DRAWSTYLE_IGNORE;

            Subgraph_RSIUpDownLength.Name = "RSI of Up-Down Streak Length";
            Subgraph_RSIUpDownLength.DrawStyle = DRAWSTYLE_IGNORE;

            Subgraph_RateOfChange.Name = "Rate of Change";
            Subgraph_RateOfChange.DrawStyle = DRAWSTYLE_IGNORE;

            Subgraph_ConnorsRSI.Name = "Connors RSI";
            Subgraph_ConnorsRSI.DrawStyle = DRAWSTYLE_LINE;
            Subgraph_ConnorsRSI.PrimaryColor = RGB(0, 0, 255);
            Subgraph_ConnorsRSI.DrawZeros = true;

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

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

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

            Input_RSILength.Name = "RSI Length";
            Input_RSILength.SetInt(3);
            Input_RSILength.SetIntLimits(1, MAX_STUDY_LENGTH);

            Input_RSIAvgType.Name = "RSI Average Type";
            Input_RSIAvgType.SetMovAvgType(MOVAVGTYPE_WILDERS);

            Input_RateOfChangeLength.Name = "Rate of Change Length";
            Input_RateOfChangeLength.SetInt(100);
            Input_RateOfChangeLength.SetIntLimits(1, MAX_STUDY_LENGTH);

            Input_Line1Value.Name = "Line 1 Value";
            Input_Line1Value.SetFloat(70.0f);

            Input_Line2Value.Name = "Line 2 Value";
            Input_Line2Value.SetFloat(30.0f);

            return;
        }

        //Compute RSI
        sc.RSI(sc.BaseDataIn[Input_InputData.GetInputDataIndex()], Subgraph_RSI, Input_RSIAvgType.GetMovAvgType(), Input_RSILength.GetInt());

        //Compute RSI of Up-Down Length
        if (sc.Index == 0)
        {
            Subgraph_UpDownLength[sc.Index] = 0;
            Subgraph_RateOfChange[sc.Index] = 0;
        }
        else
        {
            int i = 0;
            int j = 0;
            float UpDownStreak = 0.0f;

            while (sc.BaseDataIn[Input_InputData.GetInputDataIndex()][sc.Index - i - 1] < sc.BaseDataIn[Input_InputData.GetInputDataIndex()][sc.Index - i])
            {
                UpDownStreak += 1.0f;

                i++;
            }

            while (sc.BaseDataIn[Input_InputData.GetInputDataIndex()][sc.Index - j - 1] > sc.BaseDataIn[Input_InputData.GetInputDataIndex()][sc.Index - j])
            {
                UpDownStreak -= 1.0f;

                j++;
            }

            Subgraph_UpDownLength[sc.Index] = UpDownStreak;
        }

        sc.RSI(Subgraph_UpDownLength, Subgraph_RSIUpDownLength, Input_RSIAvgType.GetMovAvgType(), 2);

        //Compute Rate of Change
        Array_PriceChange[sc.Index] = sc.BaseDataIn[Input_InputData.GetInputDataIndex()][sc.Index] - sc.BaseDataIn[Input_InputData.GetInputDataIndex()][sc.Index - 1];

        float ROCStreak = 0.0f;

        for (int i = 1; i <= Input_RateOfChangeLength.GetInt(); i++)
        {
            if (Array_PriceChange[sc.Index - i] < Array_PriceChange[sc.Index])
                ROCStreak += 1;
        }

        float ROCLength = static_cast<float>(Input_RateOfChangeLength.GetInt());

        Subgraph_RateOfChange[sc.Index] = 100.0f * ROCStreak / ROCLength;

        //Compute Connors RSI
        Subgraph_ConnorsRSI[sc.Index] = (Subgraph_RSI[sc.Index] + Subgraph_RSIUpDownLength[sc.Index] + Subgraph_RateOfChange[sc.Index]) / 3.0f;

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

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

        SCFloatArrayRef Array_AvgVol = sc.Subgraph[0].Arrays[0];
        SCFloatArrayRef Array_StdDevVol = sc.Subgraph[0].Arrays[1];

        SCInputRef Input_Length = sc.Input[0];
        SCInputRef Input_NumStDevs = sc.Input[1];
        SCInputRef Input_MovAvgType = sc.Input[2];

        if (sc.SetDefaults)
        {
            sc.GraphName = "Relative Volume Standard Deviation";

            sc.GraphRegion = 1;
            sc.AutoLoop = 1;

            Subgraph_RelVol.Name = "Relative Volume Standard Deviation";
            Subgraph_RelVol.DrawStyle = DRAWSTYLE_BAR;
            Subgraph_RelVol.PrimaryColor = RGB(0, 255, 0);
            Subgraph_RelVol.SecondaryColor = RGB(255, 0, 0);

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

            Input_NumStDevs.Name = "Number of Standard Deviations";
            Input_NumStDevs.SetInt(2);
            Input_NumStDevs.SetIntLimits(1, MAX_STUDY_LENGTH);

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

            return;
        }

        sc.MovingAverage(sc.Volume, Array_AvgVol, Input_MovAvgType.GetMovAvgType(), Input_Length.GetInt());

        sc.StdDeviation(sc.Volume, Array_StdDevVol, Input_Length.GetInt());

        if (Array_StdDevVol[sc.Index] != 0.0f)
            Subgraph_RelVol[sc.Index] = (sc.Volume[sc.Index] - Array_AvgVol[sc.Index]) / Array_StdDevVol[sc.Index];
        else
            Subgraph_RelVol[sc.Index] = 0.0f;

        if (Subgraph_RelVol[sc.Index] > Input_NumStDevs.GetInt())
            Subgraph_RelVol.DataColor[sc.Index] = Subgraph_RelVol.PrimaryColor;
        else
            Subgraph_RelVol.DataColor[sc.Index] = Subgraph_RelVol.SecondaryColor;
    }

    /*==========================================================================*/
    SCSFExport scsf_FreedomOfMovement(SCStudyInterfaceRef sc)
    {
        SCSubgraphRef Subgraph_NormMove = sc.Subgraph[0];
        SCSubgraphRef Subgraph_NormRelVol = sc.Subgraph[1];
        SCSubgraphRef Subgraph_FOM = sc.Subgraph[2];

        SCFloatArrayRef Array_Move = sc.Subgraph[0].Arrays[0];
        SCFloatArrayRef Array_HighMove = sc.Subgraph[0].Arrays[1];
        SCFloatArrayRef Array_LowMove = sc.Subgraph[0].Arrays[2];
        SCFloatArrayRef Array_RelVol = sc.Subgraph[1].Arrays[0];
        SCFloatArrayRef Array_AvgVol = sc.Subgraph[1].Arrays[1];
        SCFloatArrayRef Array_StdDevVol = sc.Subgraph[1].Arrays[2];
        SCFloatArrayRef Array_HighRelVol = sc.Subgraph[1].Arrays[3];
        SCFloatArrayRef Array_LowRelVol = sc.Subgraph[1].Arrays[4];
        SCFloatArrayRef Array_RelVolByMove = sc.Subgraph[2].Arrays[0];
        SCFloatArrayRef Array_AvgRelVolByMove = sc.Subgraph[2].Arrays[1];
        SCFloatArrayRef Array_SDRelVolByMove = sc.Subgraph[2].Arrays[2];

        SCInputRef Input_InputData = sc.Input[0];
        SCInputRef Input_Length = sc.Input[1];
        SCInputRef Input_NumStDevs = sc.Input[2];
        SCInputRef Input_MovAvgType = sc.Input[3];

        if (sc.SetDefaults)
        {
            sc.GraphName = "Freedom of Movement";

            sc.GraphRegion = 1;
            sc.AutoLoop = 1;

            Subgraph_NormMove.Name = "Normalized Move";
            Subgraph_NormMove.DrawStyle = DRAWSTYLE_IGNORE;

            Subgraph_NormRelVol.Name = "Normalized Relative Volume Standard Deviation";
            Subgraph_NormRelVol.DrawStyle = DRAWSTYLE_IGNORE;

            Subgraph_FOM.Name = "Freedom of Movement";
            Subgraph_FOM.DrawStyle = DRAWSTYLE_BAR;
            Subgraph_FOM.PrimaryColor = RGB(0, 255, 0);
            Subgraph_FOM.SecondaryColor = RGB(255, 0, 0);

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

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

            Input_NumStDevs.Name = "Number of Standard Deviations";
            Input_NumStDevs.SetInt(2);
            Input_NumStDevs.SetIntLimits(1, MAX_STUDY_LENGTH);

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

            return;
        }

        // Compute Normalized Move
        if (sc.BaseDataIn[Input_InputData.GetInputDataIndex()][sc.Index - 1] != 0.0f)
            Array_Move[sc.Index] = (sc.BaseDataIn[Input_InputData.GetInputDataIndex()][sc.Index] - sc.BaseDataIn[Input_InputData.GetInputDataIndex()][sc.Index - 1]) / sc.BaseDataIn[Input_InputData.GetInputDataIndex()][sc.Index - 1];
        else
            Array_Move[sc.Index] = 0.0f;

        sc.Highest(Array_Move, Array_HighMove, Input_Length.GetInt());
        float HighMove = Array_HighMove[sc.Index];

        sc.Lowest(Array_Move, Array_LowMove, Input_Length.GetInt());
        float LowMove = Array_LowMove[sc.Index];

        if (HighMove - LowMove != 0.0f)
            Subgraph_NormMove[sc.Index] = 1.0f + 9.0f * (Array_Move[sc.Index] - LowMove) / (HighMove - LowMove);
        else
            Subgraph_NormMove[sc.Index] = 0.0f;

        // Compute Normalized Relative Volume
        sc.MovingAverage(sc.Volume, Array_AvgVol, Input_MovAvgType.GetMovAvgType(), Input_Length.GetInt());

        sc.StdDeviation(sc.Volume, Array_StdDevVol, Input_Length.GetInt());

        if (Array_StdDevVol[sc.Index] != 0.0f)
            Array_RelVol[sc.Index] = (sc.Volume[sc.Index] - Array_AvgVol[sc.Index]) / Array_StdDevVol[sc.Index];
        else
            Array_RelVol[sc.Index] = 0.0f;

        sc.MovingAverage(sc.Volume, Array_AvgVol, Input_MovAvgType.GetMovAvgType(), Input_Length.GetInt());

        sc.StdDeviation(sc.Volume, Array_StdDevVol, Input_Length.GetInt());

        if (Array_StdDevVol[sc.Index] != 0.0f)
            Array_RelVol[sc.Index] = (sc.Volume[sc.Index] - Array_AvgVol[sc.Index]) / Array_StdDevVol[sc.Index];
        else
            Array_RelVol[sc.Index] = 0.0f;

        sc.Highest(Array_RelVol, Array_HighRelVol, Input_Length.GetInt());
        float HighRelVol = Array_HighRelVol[sc.Index];

        sc.Lowest(Array_RelVol, Array_LowRelVol, Input_Length.GetInt());
        float LowRelVol = Array_LowRelVol[sc.Index];

        if (HighRelVol - LowRelVol != 0.0f)
            Subgraph_NormRelVol[sc.Index] = 1.0f + 9.0f * (Array_RelVol[sc.Index] - LowRelVol) / (HighRelVol - LowRelVol);
        else
            Subgraph_NormRelVol[sc.Index] = 0.0f;

        // Compute Freedom of Movement
        if (Subgraph_NormMove[sc.Index] != 0.0f)
            Array_RelVolByMove[sc.Index] = Subgraph_NormRelVol[sc.Index] / Subgraph_NormMove[sc.Index];
        else
            Array_RelVolByMove[sc.Index] = 0.0f;

        sc.MovingAverage(Array_RelVolByMove, Array_AvgRelVolByMove, Input_MovAvgType.GetMovAvgType(), Input_Length.GetInt());

        sc.StdDeviation(Array_RelVolByMove, Array_SDRelVolByMove, Input_Length.GetInt());

        if (Array_SDRelVolByMove[sc.Index] != 0.0f)
            Subgraph_FOM[sc.Index] = (Array_RelVolByMove[sc.Index] - Array_AvgRelVolByMove[sc.Index]) / Array_SDRelVolByMove[sc.Index];
        else
            Subgraph_FOM[sc.Index] = 0.0f;

        if (Subgraph_FOM[sc.Index] > Input_NumStDevs.GetInt())
            Subgraph_FOM.DataColor[sc.Index] = Subgraph_FOM.PrimaryColor;
        else
            Subgraph_FOM.DataColor[sc.Index] = Subgraph_FOM.SecondaryColor;
    }