    #include "sierrachart.h"
    #include "scstudyfunctions.h"

    /*==========================================================================*/
    SCSFExport scsf_MarketStructure(SCStudyInterfaceRef sc)
    {
        SCFloatArrayRef Array_High = sc.High;
        SCFloatArrayRef ArrayLow = sc.Low;
        SCFloatArrayRef Array_Open = sc.Open;
        SCFloatArrayRef Array_Close = sc.Close;

        SCSubgraphRef Subgraph_MSH = sc.Subgraph[0];
        SCSubgraphRef Subgraph_MSL = sc.Subgraph[1];
        SCSubgraphRef Subgraph_Labels = sc.Subgraph[2];
        SCSubgraphRef Subgraph_BarTypes = sc.Subgraph[3];

        SCInputRef Input_DrawLabels = sc.Input[0];
        SCInputRef Input_LabelsOffset = sc.Input[1];
        SCInputRef Input_DisplayPriceValues = sc.Input[2];

        // Set configuration variables
        if (sc.SetDefaults)
        {

            sc.GraphName="Market Structure MSL/MSH";

            sc.GraphRegion = 0; // Use the main price graph region

            Subgraph_MSH.Name = "MSH";
            Subgraph_MSH.PrimaryColor = RGB(255,0 ,255);
            Subgraph_MSH.DrawStyle = DRAWSTYLE_COLOR_BAR;
            Subgraph_MSH.LineWidth = 2;
            Subgraph_MSH.DrawZeros = false;

            Subgraph_MSL.Name = "MSL";
            Subgraph_MSL.PrimaryColor = RGB(255, 128, 0);
            Subgraph_MSL.DrawStyle = DRAWSTYLE_COLOR_BAR;
            Subgraph_MSL.LineWidth = 2;
            Subgraph_MSL.DrawZeros = false;

            Subgraph_Labels.Name = "Labels";
            Subgraph_Labels.DrawStyle = DRAWSTYLE_CUSTOM_TEXT;
            Subgraph_Labels.PrimaryColor = RGB(255, 0 ,255);
            Subgraph_Labels.SecondaryColor = RGB(255, 128, 0);
            Subgraph_Labels.LineWidth = 10;
            Subgraph_Labels.SecondaryColorUsed = true;
            Subgraph_Labels.DrawZeros = false;

            Input_DrawLabels.Name = "Draw Labels";
            Input_DrawLabels.SetYesNo(true);

            Input_LabelsOffset.Name = "Text Labels Percentage Offset";
            Input_LabelsOffset.SetFloat(5.0f);

            Input_DisplayPriceValues.Name = "Display Price Values";
            Input_DisplayPriceValues.SetYesNo(0);

            sc.AutoLoop             = 1;

            return;
        }

        // define constants
        enum MarketStructureValues
        {
            NONE    = 0,
            HH      = 1,
            LH      = 2,
            LL      = 3,
            HL      = 4
        };

        enum BarTypeValues
        {
            BT_DOWN,
            BT_UP,
            BT_NEUTRAL
        };

        const int UniqueID  = 1546846579;

        if(Array_Close[sc.Index] < Array_Open[sc.Index])
            Subgraph_BarTypes[sc.Index] = BT_DOWN;
        else
            if(Array_Close[sc.Index] > Array_Open[sc.Index])
                Subgraph_BarTypes[sc.Index] = BT_UP;
            else
                Subgraph_BarTypes[sc.Index] = BT_NEUTRAL;

        // we need at least 3 bars
        if(sc.Index < 2)
            return;

        sc.DataStartIndex = 2;

        // Start calculations here
        int CurrentIndex = sc.Index - 1;

        if(Subgraph_BarTypes[CurrentIndex-2] == BT_DOWN &&
            Subgraph_BarTypes[CurrentIndex-1] == BT_DOWN &&
            Subgraph_BarTypes[CurrentIndex] == BT_UP)
        {
            // these three bars can make MSL
            if(ArrayLow[CurrentIndex-2] > ArrayLow[CurrentIndex-1] &&
                ArrayLow[CurrentIndex] > ArrayLow[CurrentIndex-1])
            {
                // this is MSL
                Subgraph_MSL[CurrentIndex-1] = 1;
            }
        }

        if(Subgraph_BarTypes[CurrentIndex-2] == BT_UP &&
            Subgraph_BarTypes[CurrentIndex-1] == BT_UP &&
            Subgraph_BarTypes[CurrentIndex] == BT_DOWN)
        {
            // these three bars can make MSH
            if(Array_High[CurrentIndex-2] < Array_High[CurrentIndex-1] &&
                Array_High[CurrentIndex] < Array_High[CurrentIndex-1])
            {
                // this is MSH
                Subgraph_MSH[CurrentIndex-1] = 1;
            }
        }

        // Fill Labels array
        if(Subgraph_MSH[CurrentIndex-1] == 1)
        {
            // look back through Labels array to find previous label HH or LH
            int Index=CurrentIndex-1;
            for(; Index >= 0; Index--)
            {
                if(Subgraph_Labels[Index] == HH || Subgraph_Labels[Index] == LH)
                    break;
            }

            // now Index store index of the element
            if(Index < 0)   // this is a first label, assume HH
                Subgraph_Labels[CurrentIndex-1] = HH;
            else
            {
                // compare High values
                if(Array_High[Index] == Array_High[CurrentIndex-1])
                    Subgraph_Labels[CurrentIndex-1] = Subgraph_Labels[Index];
                else
                    if(Array_High[Index] < Array_High[CurrentIndex-1])
                        Subgraph_Labels[CurrentIndex-1] = HH;
                    else
                        Subgraph_Labels[CurrentIndex-1] = LH;
            }
        }

        if(Subgraph_MSL[CurrentIndex-1] == 1)
        {
            // look back through Labels array to find previous label LL or HL
            int Index=CurrentIndex-1;
            for(; Index >= 0; Index--)
            {
                if(Subgraph_Labels[Index] == LL || Subgraph_Labels[Index] == HL)
                    break;
            }

            // now Index store index of the element
            if(Index < 0)   // this is a first label, assume LL
                Subgraph_Labels[CurrentIndex-1] = LL;
            else
            {
                // compare Low values
                if(ArrayLow[Index] == ArrayLow[CurrentIndex-1])
                    Subgraph_Labels[CurrentIndex-1] = Subgraph_Labels[Index];
                else
                    if(ArrayLow[Index] > ArrayLow[CurrentIndex-1])
                        Subgraph_Labels[CurrentIndex-1] = LL;
                    else
                        Subgraph_Labels[CurrentIndex-1] = HL;
            }
        }

        // check if we need draw labels
        if(!Input_DrawLabels.GetYesNo())
            return;

        // if pattern is not set do not add the empty label
        if(Subgraph_Labels[sc.Index-2] == 0)
            return;

        // Since we are using UTAM_ADD_ALWAYS, we must not attempt to draw labels when we are on the last bar, even if the labels do not appear on the last bar. Otherwise, we get the same label added again and again as the bar is updated.
        if(sc.GetBarHasClosedStatus(sc.Index) == BHCS_BAR_HAS_NOT_CLOSED)
            return;

        s_UseTool Tool;
        Tool.Clear(); // reset tool structure for our next use
        Tool.ChartNumber    = sc.ChartNumber;
        Tool.DrawingType    = DRAWING_TEXT;
        Tool.Region         = sc.GraphRegion;
        Tool.FontFace = sc.ChartTextFont();
        Tool.FontBold = true;

        Tool.ReverseTextColor = 0;
        Tool.FontSize = Subgraph_Labels.LineWidth;

        Tool.LineNumber = UniqueID;
        Tool.BeginIndex =sc.Index-2;

        SCString    Label;
        SCString    Value;

        float Offset = Input_LabelsOffset.GetFloat()*0.01f*(sc.High[sc.Index - 2]-sc.Low[sc.Index - 2]);

        switch(static_cast<int>(Subgraph_Labels[sc.Index-2]))
        {
        case HH:
            {
                if(!Input_DisplayPriceValues.GetYesNo())
                {
                    Label = "HH";
                }
                else
                {
                    Value = sc.FormatGraphValue(sc.High[sc.Index-2], sc.BaseGraphValueFormat);
                    Label.Format("HH %s", Value.GetChars());
                }
                Tool.Text           = Label;
                Tool.Color          = Subgraph_Labels.PrimaryColor;

                Tool.BeginValue     = sc.High[sc.Index-2] + Offset;
                Tool.TextAlignment  = DT_CENTER | DT_BOTTOM;
                break;
            }

        case LH:
            {
                if(!Input_DisplayPriceValues.GetYesNo())
                {
                    Label = "LH";
                }
                else
                {
                    Value = sc.FormatGraphValue(sc.High[sc.Index-2], sc.BaseGraphValueFormat);
                    Label.Format("LH %s", Value.GetChars());
                }
                Tool.Text           = Label;
                Tool.Color          = Subgraph_Labels.PrimaryColor;

                Tool.BeginValue     = sc.High[sc.Index-2] + Offset;
                Tool.TextAlignment  = DT_CENTER | DT_BOTTOM;
                break;
            }

        case LL:
            {
                if(!Input_DisplayPriceValues.GetYesNo())
                {
                    Label = "LL";
                }
                else
                {
                    Value = sc.FormatGraphValue(sc.Low[sc.Index-2], sc.BaseGraphValueFormat);
                    Label.Format("LL %s", Value.GetChars());
                }
                Tool.Text           = Label;
                Tool.Color          = Subgraph_Labels.SecondaryColor;

                Tool.BeginValue     = sc.Low[sc.Index-2] - Offset;
                Tool.TextAlignment  = DT_CENTER | DT_TOP;
                break;
            }

        case HL:
            {
                if(!Input_DisplayPriceValues.GetYesNo())
                {
                    Label = "HL";
                }
                else
                {
                    Value = sc.FormatGraphValue(sc.Low[sc.Index-2], sc.BaseGraphValueFormat);
                    Label.Format("HL %s", Value.GetChars());
                }
                Tool.Text           = Label;
                Tool.Color          = Subgraph_Labels.SecondaryColor;

                Tool.BeginValue     = sc.Low[sc.Index-2] - Offset;
                Tool.TextAlignment  = DT_CENTER | DT_TOP;
                break;
            }

        default:
            return;
        }

        Tool.AddMethod = UTAM_ADD_ALWAYS;

        sc.UseTool(Tool);
    }

    /*==========================================================================*/
    SCSFExport scsf_WoodiesPanel(SCStudyInterfaceRef sc)
    {
        SCSubgraphRef Subgraph_CCIDiff = sc.Subgraph[0];
        SCSubgraphRef Subgraph_ProjectedBuy = sc.Subgraph[1];
        SCSubgraphRef Subgraph_ProjectedSell = sc.Subgraph[2];
        SCSubgraphRef Subgraph_CCIPred = sc.Subgraph[3];
        SCSubgraphRef Subgraph_BackColors = sc.Subgraph[4];
        SCSubgraphRef Subgraph_CCIDifferenceHigh = sc.Subgraph[5];
        SCSubgraphRef Subgraph_CCIDifferenceLow = sc.Subgraph[6];
        SCSubgraphRef Subgraph_HighPC = sc.Subgraph[7];
        SCSubgraphRef Subgraph_LastPC = sc.Subgraph[8];
        SCSubgraphRef Subgraph_LowPC = sc.Subgraph[9];
        SCSubgraphRef Subgraph_EmaAngle = sc.Subgraph[10];

        SCInputRef Input_PanelRangeTopVal = sc.Input[0];
        SCInputRef Input_PanelRangeBottomVal = sc.Input[1];
        SCInputRef Input_ShowLabels = sc.Input[2];
        SCInputRef Input_ColumnsNumber = sc.Input[3];
        SCInputRef Input_CCIStudyRef = sc.Input[4];
        SCInputRef Input_EntryOffset = sc.Input[5];
        SCInputRef Input_TradingStopTime = sc.Input[7];
        SCInputRef Input_CCIPredictorStudyRef = sc.Input[8];
        SCInputRef Input_ShowPreviousClose = sc.Input[9];
        SCInputRef Input_SideWinderStudyRef = sc.Input[11];
        SCInputRef Input_LeftEdgeTextOffset = sc.Input[12];

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

            sc.GraphName = "Woodies Panel";

            sc.AutoLoop = 0;
            sc.GraphRegion = 1;
            sc.CalculationPrecedence = LOW_PREC_LEVEL;

            Subgraph_CCIDiff.Name = "CCIDiff";
            Subgraph_CCIDiff.DrawStyle = DRAWSTYLE_CUSTOM_TEXT;
            Subgraph_CCIDiff.PrimaryColor = RGB(255,255,255);
            Subgraph_CCIDiff.LineWidth = 10; //font size
            Subgraph_CCIDiff.DrawZeros = false;

            Subgraph_ProjectedBuy.Name = "Projected Buy";
            Subgraph_ProjectedBuy.DrawStyle = DRAWSTYLE_CUSTOM_TEXT;
            Subgraph_ProjectedBuy.PrimaryColor = RGB(184,251,197);
            Subgraph_ProjectedBuy.LineWidth = 10; //font size
            Subgraph_ProjectedBuy.DrawZeros = false;

            Subgraph_ProjectedSell.Name = "Projected Sell";
            Subgraph_ProjectedSell.DrawStyle = DRAWSTYLE_CUSTOM_TEXT;
            Subgraph_ProjectedSell.PrimaryColor = RGB(239,204,246);
            Subgraph_ProjectedSell.LineWidth = 10; //font size
            Subgraph_ProjectedSell.DrawZeros = false;

            Subgraph_CCIPred.Name = "CCI Pred. H/L";
            Subgraph_CCIPred.DrawStyle = DRAWSTYLE_CUSTOM_TEXT;
            Subgraph_CCIPred.PrimaryColor = RGB(0,0,0);
            Subgraph_CCIPred.LineWidth = 10; //font size
            Subgraph_CCIPred.DrawZeros = false;

            Subgraph_BackColors.Name = "Background Colors";
            Subgraph_BackColors.DrawStyle = DRAWSTYLE_IGNORE;
            Subgraph_BackColors.PrimaryColor = RGB(64,128,128);
            Subgraph_BackColors.SecondaryColor = RGB(45,89,89);
            Subgraph_BackColors.SecondaryColorUsed = 1;
            Subgraph_BackColors.DrawZeros = false;

            Subgraph_CCIDifferenceHigh.Name = "CCIDiff H";
            Subgraph_CCIDifferenceHigh.DrawStyle = DRAWSTYLE_CUSTOM_TEXT;
            Subgraph_CCIDifferenceHigh.PrimaryColor = RGB(0,255,0);
            Subgraph_CCIDifferenceHigh.LineWidth = 10; //font size
            Subgraph_CCIDifferenceHigh.DrawZeros = false;

            Subgraph_CCIDifferenceLow.Name = "CCIDiff L";
            Subgraph_CCIDifferenceLow.DrawStyle = DRAWSTYLE_CUSTOM_TEXT;
            Subgraph_CCIDifferenceLow.PrimaryColor = RGB(237,80,255);
            Subgraph_CCIDifferenceLow.LineWidth = 10; //font size
            Subgraph_CCIDifferenceLow.DrawZeros = false;

            Subgraph_HighPC.Name = "High Prev/Cur";
            Subgraph_HighPC.DrawStyle = DRAWSTYLE_CUSTOM_TEXT;
            Subgraph_HighPC.PrimaryColor = RGB(0,0,0);
            Subgraph_HighPC.SecondaryColor = RGB(0,255,0);
            Subgraph_HighPC.SecondaryColorUsed = 1;
            Subgraph_HighPC.LineWidth = 10; //font size
            Subgraph_HighPC.DrawZeros = false;

            Subgraph_LastPC.Name = "Last Prev/Cur";
            Subgraph_LastPC.DrawStyle = DRAWSTYLE_CUSTOM_TEXT;
            Subgraph_LastPC.PrimaryColor = RGB(0,0,0);
            Subgraph_LastPC.LineWidth = 14; //font size
            Subgraph_LastPC.DrawZeros = false;

            Subgraph_LowPC.Name = "Low Prev/Cur";
            Subgraph_LowPC.DrawStyle = DRAWSTYLE_CUSTOM_TEXT;
            Subgraph_LowPC.PrimaryColor = RGB(0,0,0);
            Subgraph_LowPC.SecondaryColor = RGB(255,0,0);
            Subgraph_LowPC.SecondaryColorUsed = 1;
            Subgraph_LowPC.LineWidth = 10; //font size
            Subgraph_LowPC.DrawZeros = false;

            Subgraph_EmaAngle.Name = "EMA Angle";
            Subgraph_EmaAngle.DrawStyle = DRAWSTYLE_CUSTOM_TEXT;
            Subgraph_EmaAngle.PrimaryColor = RGB(0,0,0);
            Subgraph_EmaAngle.LineWidth = 10; //font size
            Subgraph_EmaAngle.DrawZeros = false;

            Input_PanelRangeTopVal.Name = "Panel Range Top Value";
            Input_PanelRangeTopVal.SetInt(250);

            Input_PanelRangeBottomVal.Name = "Panel Range Bottom Value";
            Input_PanelRangeBottomVal.SetInt(-250);

            Input_ShowLabels.Name = "Show Descriptive Labels";
            Input_ShowLabels.SetYesNo(true);

            Input_ColumnsNumber.Name = "Number of Fill Space Columns";
            Input_ColumnsNumber.SetInt(10);

            Input_CCIStudyRef.Name = "CCI Study Reference";
            Input_CCIStudyRef.SetStudyID(1);

            Input_EntryOffset.Name = "Projected Entry Offset in Ticks";
            Input_EntryOffset.SetInt(1);

            Input_TradingStopTime.Name = "Trading Stop Time";
            Input_TradingStopTime.SetTime(HMS_TIME(15, 30, 0));

            Input_CCIPredictorStudyRef.Name = "CCI Predictor Study Reference";
            Input_CCIPredictorStudyRef.SetStudyID(1);

            Input_ShowPreviousClose.Name = "Show Previous Close";
            Input_ShowPreviousClose.SetYesNo(false);

            Input_SideWinderStudyRef.Name = "SideWinder Study Reference";
            Input_SideWinderStudyRef.SetStudyID(1);

            Input_LeftEdgeTextOffset.Name = "Left Edge Text Offset";
            Input_LeftEdgeTextOffset.SetInt(1);
            Input_LeftEdgeTextOffset.SetIntLimits(0,4);

            sc.UpdateAlways = 1;

            return;
        }

        if (sc.LastCallToFunction)
        {

            sc.PreserveFillSpace = 0;
            sc.NumFillSpaceBars = 0;
            sc.UseGlobalChartColors = true;
            sc.ScaleBorderColor = RGB(128,128,128);

            return;
        }

        {
            sc.PreserveFillSpace = 1;
            sc.NumFillSpaceBars = Input_ColumnsNumber.GetInt();
        }

        int CurrentVisibleIndex = sc.IndexOfLastVisibleBar;

        if (Subgraph_BackColors.PrimaryColor == RGB(255,0,0))
        {
            Subgraph_BackColors.PrimaryColor = RGB(64,128,128);
            Subgraph_BackColors.SecondaryColor = RGB(45,89,89);
        }

        if (sc.GraphRegion >= 2)
            sc.GraphRegion = 1;

        float RangeIncrement = 0.0f;

        //Determine our value increment for the panel data lines based on what lines are visible.
        int NumberOfLines = 0;
        for(int c= 0; c<16; c++)
        {
            if(sc.Subgraph[c].DrawStyle != DRAWSTYLE_IGNORE && sc.Subgraph[c].DrawStyle != DRAWSTYLE_HIDDEN)
                NumberOfLines++;
        }

        RangeIncrement = (Input_PanelRangeTopVal.GetInt() - Input_PanelRangeBottomVal.GetInt())/(NumberOfLines+1.0f);

        float YValue = Input_PanelRangeTopVal.GetInt()-RangeIncrement;

        int TextOffset = -(2+Input_LeftEdgeTextOffset.GetInt());

        s_UseTool Tool;

        if(Subgraph_CCIDifferenceHigh.DrawStyle != DRAWSTYLE_IGNORE && Subgraph_CCIDifferenceHigh.DrawStyle != DRAWSTYLE_HIDDEN)
        {

            SCFloatArray CCIProjHigh;
            sc.GetStudyArrayUsingID(Input_CCIPredictorStudyRef.GetStudyID(),0,CCIProjHigh);

            float CCIDifferenceHighValue = 0;
            SCFloatArray CCI;
            sc.GetStudyArrayUsingID(Input_CCIStudyRef.GetStudyID(),0,CCI);
            CCIDifferenceHighValue = CCIProjHigh[CurrentVisibleIndex] - CCI[CurrentVisibleIndex-1];

            if (CurrentVisibleIndex != sc.ArraySize-1)
                CCIDifferenceHighValue = CCI[CurrentVisibleIndex] - CCI[CurrentVisibleIndex-1];

            //Worksheet Output
            Subgraph_CCIDifferenceHigh[sc.UpdateStartIndex] = 0;
            Subgraph_CCIDifferenceHigh[sc.ArraySize - 1] = CCIDifferenceHighValue;

            Tool.Clear(); // reset tool structure for our next use
            Tool.ChartNumber = sc.ChartNumber;
            Tool.DrawingType = DRAWING_TEXT;
            Tool.LineNumber = 5035;
            Tool.BeginDateTime = TextOffset;
            Tool.BeginValue = YValue;
            Tool.Color = Subgraph_CCIDifferenceHigh.PrimaryColor;
            Tool.Region = sc.GraphRegion;

            SCString Label;

            if (Input_ShowLabels.GetYesNo())
            {
                Label = Subgraph_CCIDifferenceHigh.Name;
            }

            Tool.Text.Format(" %.2f %s", CCIDifferenceHighValue, Label.GetChars());
            Tool.FontSize = Subgraph_CCIDifferenceHigh.LineWidth;
            Tool.FontBold = true;
            //Tool.FontFace= "Courier";
            Tool.AddMethod = UTAM_ADD_OR_ADJUST;
            Tool.ReverseTextColor = 0;

            sc.UseTool(Tool);
            YValue -= RangeIncrement;
        }

        if(Subgraph_CCIDiff.DrawStyle != DRAWSTYLE_IGNORE && Subgraph_CCIDiff.DrawStyle != DRAWSTYLE_HIDDEN)
        {
            float CCIDiffVal = 0;
            SCFloatArray CCI;
            sc.GetStudyArrayUsingID(Input_CCIStudyRef.GetStudyID(),0,CCI);
            CCIDiffVal = CCI[CurrentVisibleIndex] - CCI[CurrentVisibleIndex-1];

            Subgraph_CCIDiff[sc.UpdateStartIndex] = 0;
            Subgraph_CCIDiff[sc.ArraySize - 1] = CCIDiffVal;

            Tool.Clear(); // reset tool structure for our next use
            Tool.ChartNumber = sc.ChartNumber;
            Tool.DrawingType = DRAWING_TEXT;
            Tool.LineNumber = 5030;
            Tool.BeginDateTime = TextOffset;
            Tool.BeginValue = YValue;
            Tool.Color = Subgraph_CCIDiff.PrimaryColor;
            Tool.Region = sc.GraphRegion;

            SCString Label;

            if (Input_ShowLabels.GetYesNo())
            {
                Label = "CCIDiff";
            }

            Tool.Text.Format(" %.2f %s", CCIDiffVal , Label.GetChars());
            Tool.FontSize = Subgraph_CCIDiff.LineWidth;
            Tool.FontBold = true;
            Tool.AddMethod = UTAM_ADD_OR_ADJUST;
            Tool.ReverseTextColor = 0;

            sc.UseTool(Tool);
            YValue -= RangeIncrement;
        }

        if(Subgraph_CCIDifferenceLow.DrawStyle != DRAWSTYLE_IGNORE && Subgraph_CCIDifferenceLow.DrawStyle != DRAWSTYLE_HIDDEN)
        {
            SCFloatArray CCIProjLow;
            sc.GetStudyArrayUsingID(Input_CCIPredictorStudyRef.GetStudyID(),1,CCIProjLow);

            float CCIDifferenceLowValue = 0;
            SCFloatArray CCI;
            sc.GetStudyArrayUsingID(Input_CCIStudyRef.GetStudyID(),0,CCI);
            CCIDifferenceLowValue = CCIProjLow[CurrentVisibleIndex] - CCI[CurrentVisibleIndex-1];

            if (CurrentVisibleIndex != sc.ArraySize-1)
                CCIDifferenceLowValue = CCI[CurrentVisibleIndex] - CCI[CurrentVisibleIndex-1];

            Subgraph_CCIDifferenceLow[sc.UpdateStartIndex] = 0;
            Subgraph_CCIDifferenceLow[sc.ArraySize - 1] = CCIDifferenceLowValue;

            Tool.Clear(); // reset tool structure for our next use
            Tool.ChartNumber = sc.ChartNumber;
            Tool.DrawingType = DRAWING_TEXT;
            Tool.LineNumber = 5036;
            Tool.BeginDateTime = TextOffset;
            Tool.BeginValue = YValue;
            Tool.Color = Subgraph_CCIDifferenceLow.PrimaryColor;
            Tool.Region = sc.GraphRegion;

            SCString Label;

            if (Input_ShowLabels.GetYesNo())
            {
                Label = Subgraph_CCIDifferenceLow.Name;
            }

            Tool.Text.Format(" %.2f %s", CCIDifferenceLowValue, Label.GetChars());
            Tool.FontSize = Subgraph_CCIDifferenceLow.LineWidth;
            Tool.FontBold = true;
            Tool.AddMethod = UTAM_ADD_OR_ADJUST;
            Tool.ReverseTextColor = 0;

            sc.UseTool(Tool);
            YValue -= RangeIncrement;
        }

        if(Subgraph_HighPC.DrawStyle != DRAWSTYLE_IGNORE && Subgraph_HighPC.DrawStyle != DRAWSTYLE_HIDDEN)
        {
            Tool.Clear(); // reset tool structure for our next use
            Tool.ChartNumber = sc.ChartNumber;
            Tool.DrawingType = DRAWING_TEXT;
            Tool.LineNumber = 5037;
            Tool.BeginDateTime = TextOffset;
            Tool.BeginValue = YValue;
            if (sc.High[CurrentVisibleIndex] > sc.High[CurrentVisibleIndex-1])
            {
                Tool.Color = Subgraph_HighPC.SecondaryColor;
                Tool.ReverseTextColor = 0;
            }
            else
            {
                Tool.Color = Subgraph_HighPC.PrimaryColor;
                Tool.ReverseTextColor = 0;
            }

            Tool.Region = sc.GraphRegion;

            SCString Label;

            if (Input_ShowLabels.GetYesNo())
            {
                Label = Subgraph_HighPC.Name;
            }

            SCString CurrentHigh = sc.FormatGraphValue(sc.High[CurrentVisibleIndex], sc.BaseGraphValueFormat);
            SCString PrevHigh = sc.FormatGraphValue(sc.High[CurrentVisibleIndex-1], sc.BaseGraphValueFormat);
            Tool.Text.Format(" %s %s %s", PrevHigh.GetChars(), CurrentHigh.GetChars(), Label.GetChars());
            Tool.FontSize = Subgraph_HighPC.LineWidth;
            Tool.FontBold = true;
            Tool.AddMethod = UTAM_ADD_OR_ADJUST;

            sc.UseTool(Tool);
            YValue -= RangeIncrement;
            //Worksheet Output
            Subgraph_HighPC[sc.UpdateStartIndex] = 0;
            Subgraph_HighPC[sc.UpdateStartIndex-1] = 0;
            Subgraph_HighPC[sc.ArraySize - 1] = sc.High[CurrentVisibleIndex];
            Subgraph_HighPC[sc.ArraySize - 2] = sc.High[CurrentVisibleIndex-1];
        }

        if(Subgraph_LastPC.DrawStyle != DRAWSTYLE_IGNORE && Subgraph_LastPC.DrawStyle != DRAWSTYLE_HIDDEN)
        {
            Tool.Clear(); // reset tool structure for our next use
            Tool.ChartNumber = sc.ChartNumber;
            Tool.DrawingType = DRAWING_TEXT;
            Tool.LineNumber = 5038;
            Tool.BeginDateTime = TextOffset;
            Tool.BeginValue = YValue;

            {
                Tool.Color = Subgraph_LastPC.PrimaryColor;
                Tool.ReverseTextColor = 0;
            }

            Tool.Region = sc.GraphRegion;

            SCString Label;

            if (Input_ShowLabels.GetYesNo())
            {
                if(Input_ShowPreviousClose.GetYesNo())
                    Label = Subgraph_LastPC.Name;
                else
                    Label = "Last Price";
            }

            SCString CurLast = sc.FormatGraphValue(sc.Close[CurrentVisibleIndex], sc.BaseGraphValueFormat);
            SCString PrevLast = sc.FormatGraphValue(sc.Close[CurrentVisibleIndex-1], sc.BaseGraphValueFormat);

            //Worksheet Output
            Subgraph_LastPC[sc.UpdateStartIndex] = 0;
            Subgraph_LastPC[sc.UpdateStartIndex-1] = 0;
            Subgraph_LastPC[sc.ArraySize - 1] = sc.Close[CurrentVisibleIndex];
            Subgraph_LastPC[sc.ArraySize - 2] = sc.Close[CurrentVisibleIndex-1];

            if (Input_ShowPreviousClose.GetYesNo())
            {
                Tool.Text.Format(" %s %s %s", PrevLast.GetChars(), CurLast.GetChars(), Label.GetChars());
            }
            else
            {
                Tool.Text.Format(" %s %s", CurLast.GetChars(), Label.GetChars());
            }

            Tool.FontSize = Subgraph_LastPC.LineWidth;
            Tool.FontBold = true;
            Tool.AddMethod = UTAM_ADD_OR_ADJUST;

            sc.UseTool(Tool);
            YValue -= RangeIncrement;
        }

        if(Subgraph_LowPC.DrawStyle != DRAWSTYLE_IGNORE && Subgraph_LowPC.DrawStyle != DRAWSTYLE_HIDDEN)
        {
            Tool.Clear(); // reset tool structure for our next use
            Tool.ChartNumber = sc.ChartNumber;
            Tool.DrawingType = DRAWING_TEXT;
            Tool.LineNumber = 5039;
            Tool.BeginDateTime = TextOffset;
            Tool.BeginValue = YValue;
            if (sc.Low[CurrentVisibleIndex] < sc.Low[CurrentVisibleIndex-1])
            {
                Tool.Color = Subgraph_LowPC.SecondaryColor;
                Tool.ReverseTextColor = 0;
            }
            else
            {
                Tool.Color = Subgraph_LowPC.PrimaryColor;
                Tool.ReverseTextColor = 0;
            }

            Tool.Region = sc.GraphRegion;

            SCString Label;

            if (Input_ShowLabels.GetYesNo())
            {
                Label = Subgraph_LowPC.Name;
            }

            SCString CurLow = sc.FormatGraphValue(sc.Low[CurrentVisibleIndex], sc.BaseGraphValueFormat);
            SCString PrevLow = sc.FormatGraphValue(sc.Low[CurrentVisibleIndex-1], sc.BaseGraphValueFormat);

            //Worksheet Output
            Subgraph_LowPC[sc.UpdateStartIndex] = 0;
            Subgraph_LowPC[sc.UpdateStartIndex-1] = 0;
            Subgraph_LowPC[sc.ArraySize - 1] = sc.Low[CurrentVisibleIndex];
            Subgraph_LowPC[sc.ArraySize - 2] = sc.Low[CurrentVisibleIndex-1];

            Tool.Text.Format(" %s %s %s",PrevLow.GetChars(),CurLow.GetChars(),Label.GetChars());
            Tool.FontSize = Subgraph_LowPC.LineWidth;
            Tool.FontBold = true;
            Tool.AddMethod = UTAM_ADD_OR_ADJUST;

            sc.UseTool(Tool);
            YValue -= RangeIncrement;
        }

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

        if(Subgraph_ProjectedBuy.DrawStyle != DRAWSTYLE_IGNORE && Subgraph_ProjectedBuy.DrawStyle != DRAWSTYLE_HIDDEN)
        {
            float ProjHigh = 0;

            ProjHigh = sc.Low[CurrentVisibleIndex] + BarPeriod.IntradayChartBarPeriodParameter1 + (Input_EntryOffset.GetInt() * sc.TickSize);

            //Worksheet Output
            Subgraph_ProjectedBuy[sc.UpdateStartIndex] = 0;
            Subgraph_ProjectedBuy[sc.ArraySize - 1] = ProjHigh;

            Tool.Clear(); // reset tool structure for our next use
            Tool.ChartNumber = sc.ChartNumber;
            Tool.DrawingType = DRAWING_TEXT;
            Tool.LineNumber = 5031;
            Tool.BeginDateTime = TextOffset;
            Tool.BeginValue = YValue;
            Tool.Color = Subgraph_ProjectedBuy.PrimaryColor;
            Tool.Region = sc.GraphRegion;

            SCString Label;

            if (Input_ShowLabels.GetYesNo())
            {
                Label = "ProjHigh";
            }

            SCString StrValue = sc.FormatGraphValue(ProjHigh, sc.BaseGraphValueFormat);
            Tool.Text.Format(" %s %s", StrValue.GetChars(), Label.GetChars());
            Tool.FontSize = Subgraph_ProjectedBuy.LineWidth;
            Tool.FontBold = true;
            Tool.AddMethod = UTAM_ADD_OR_ADJUST;
            Tool.ReverseTextColor = 0;

            sc.UseTool(Tool);
            YValue -= RangeIncrement;

        }

        if(Subgraph_ProjectedSell.DrawStyle != DRAWSTYLE_IGNORE && Subgraph_ProjectedSell.DrawStyle != DRAWSTYLE_HIDDEN)
        {
            float ProjLow = 0;

            ProjLow = sc.High[CurrentVisibleIndex] - (BarPeriod.IntradayChartBarPeriodParameter1 + (Input_EntryOffset.GetInt() * sc.TickSize));

            //Spreadsheet Output
            Subgraph_ProjectedSell[sc.UpdateStartIndex] = 0;
            Subgraph_ProjectedSell[sc.ArraySize - 1] = ProjLow;

            Tool.Clear(); // reset tool structure for our next use
            Tool.ChartNumber = sc.ChartNumber;
            Tool.DrawingType = DRAWING_TEXT;
            Tool.LineNumber = 5032;
            Tool.BeginDateTime = TextOffset;
            Tool.BeginValue = YValue;
            Tool.Color = Subgraph_ProjectedSell.PrimaryColor;
            Tool.Region = sc.GraphRegion;

            SCString Label;

            if (Input_ShowLabels.GetYesNo())
            {
                Label = "ProjLow";
            }

            SCString StrValue = sc.FormatGraphValue(ProjLow, sc.BaseGraphValueFormat);
            Tool.Text.Format(" %s %s", StrValue.GetChars(), Label.GetChars());
            Tool.FontSize = Subgraph_ProjectedSell.LineWidth;
            Tool.FontBold = true;
            Tool.AddMethod = UTAM_ADD_OR_ADJUST;
            Tool.ReverseTextColor = 0;

            sc.UseTool(Tool);
            YValue -= RangeIncrement;
        }

        if(Subgraph_CCIPred.DrawStyle != DRAWSTYLE_IGNORE && Subgraph_CCIPred.DrawStyle != DRAWSTYLE_HIDDEN)
        {

            SCFloatArray CCIProjHigh;
            SCFloatArray CCIProjLow;

            sc.GetStudyArrayUsingID(Input_CCIPredictorStudyRef.GetStudyID(),0,CCIProjHigh);
            sc.GetStudyArrayUsingID(Input_CCIPredictorStudyRef.GetStudyID(),1,CCIProjLow);

            Tool.Clear(); // reset tool structure for our next use
            Tool.ChartNumber = sc.ChartNumber;
            Tool.DrawingType = DRAWING_TEXT;
            Tool.LineNumber = 5033;
            Tool.BeginDateTime = TextOffset;
            Tool.BeginValue = YValue;
            Tool.Color = Subgraph_CCIPred.PrimaryColor;
            Tool.Region = sc.GraphRegion;

            SCString Label;

            if (Input_ShowLabels.GetYesNo())
            {
                Label = Subgraph_CCIPred.Name;
            }

            float ProjHigh = CCIProjHigh[sc.ArraySize-1];
            float ProjLow = CCIProjLow[sc.ArraySize-1];

            if (CurrentVisibleIndex != sc.ArraySize-1)
            {
                SCFloatArray CCI;
                sc.GetStudyArrayUsingID(Input_CCIStudyRef.GetStudyID(),0,CCI);
                ProjLow = ProjHigh = CCI[CurrentVisibleIndex];
            }

            Tool.Text.Format(" %.1f  %.1f %s",ProjHigh,ProjLow,Label.GetChars());
            Tool.FontSize = Subgraph_CCIPred.LineWidth;
            Tool.FontBold = true;
            Tool.AddMethod = UTAM_ADD_OR_ADJUST;
            Tool.ReverseTextColor = 0;

            sc.UseTool(Tool);
            YValue -= RangeIncrement;

            //Worksheet Output
            Subgraph_CCIPred[sc.UpdateStartIndex] = 0;
            Subgraph_CCIPred[sc.UpdateStartIndex-1] = 0;
            Subgraph_CCIPred[sc.ArraySize - 1] = ProjHigh;
            Subgraph_CCIPred[sc.ArraySize - 2] = ProjLow;
        }

        if(Subgraph_LowPC.DrawStyle != DRAWSTYLE_IGNORE && Subgraph_LowPC.DrawStyle != DRAWSTYLE_HIDDEN)
        {
            SCFloatArray EMAAngle;
            sc.GetStudyArrayUsingID(Input_SideWinderStudyRef.GetStudyID(),7,EMAAngle);

            Tool.Clear(); // reset tool structure for our next use
            Tool.ChartNumber = sc.ChartNumber;
            Tool.DrawingType = DRAWING_TEXT;
            Tool.LineNumber = 5040;
            Tool.BeginDateTime = TextOffset;
            Tool.BeginValue = YValue;
            Tool.Color = Subgraph_LowPC.PrimaryColor;
            Tool.Region = sc.GraphRegion;

            SCString Label;

            if (Input_ShowLabels.GetYesNo())
            {
                Label = Subgraph_LowPC.Name;
            }

            Tool.Text.Format(" %.1f\u00B0 %s", EMAAngle[CurrentVisibleIndex], Label.GetChars());
            Tool.FontSize = Subgraph_LowPC.LineWidth;
            Tool.FontBold = true;
            Tool.AddMethod = UTAM_ADD_OR_ADJUST;
            Tool.ReverseTextColor = 0;

            sc.UseTool(Tool);
            YValue -= RangeIncrement;

            //Worksheet Output
            Subgraph_LowPC[sc.UpdateStartIndex] = 0;
            Subgraph_LowPC[sc.ArraySize - 1] = EMAAngle[CurrentVisibleIndex];

        }

    }

    /*==========================================================================*/
    void AccumulateZigZagVolume(SCStudyInterfaceRef sc, SCSubgraphRef AccumulatedVolume, SCFloatArrayRef ZigZagPeakType, int VolumeTypeToAccumulate, SCFloatArrayRef ZigZagReset)
    {
        if (VolumeTypeToAccumulate == 0)
            return;

        //Accumulate the volume across the last two zigzags

        //Determine starting point
        int Count = 0;//To count the number of zigzag lines
        int StartingIndex = sc.UpdateStartIndex+1;
        while (StartingIndex > 0 && Count < 2)
        {
            StartingIndex--;
            if (ZigZagPeakType[StartingIndex] != 0.0f)
                Count ++;
        }

        double Volume = 0;
        int Direction = 0;

        for (int Index = StartingIndex+1; Index < sc.ArraySize; ++Index)
        {
            if(ZigZagPeakType[Index-1] != 0)
            {
                Volume = 0;
                Direction = static_cast<int>(ZigZagPeakType[Index-1]);
            }

            if (ZigZagReset[Index-1] != 0) // First index, pick up initial volume
            {
                if (VolumeTypeToAccumulate == 1)
                    Volume = sc.Volume[Index-1];
                else if (VolumeTypeToAccumulate == 2)
                    Volume = sc.BidVolume[Index-1];
                else if (VolumeTypeToAccumulate == 3)
                    Volume = sc.AskVolume[Index-1];
                else if (VolumeTypeToAccumulate == 4)
                    Volume = sc.AskVolume[Index-1] - sc.BidVolume[Index-1];

                AccumulatedVolume[Index-1] = static_cast<float>(Volume);
                Direction = static_cast<int>(ZigZagPeakType[Index-1]);
            }

            if (Direction == 1)
                AccumulatedVolume.DataColor[Index]= AccumulatedVolume.PrimaryColor;
            else if (Direction == -1)
                AccumulatedVolume.DataColor[Index]= AccumulatedVolume.SecondaryColor;

            if (VolumeTypeToAccumulate == 1)
                Volume += sc.Volume[Index];
            else if (VolumeTypeToAccumulate == 2)
                Volume += sc.BidVolume[Index];
            else if (VolumeTypeToAccumulate == 3)
                Volume += sc.AskVolume[Index];
            else if (VolumeTypeToAccumulate == 4)
                Volume += sc.AskVolume[Index] - sc.BidVolume[Index];

            AccumulatedVolume[Index] = static_cast<float>(Volume);
        }
    }
    /*==========================================================================*/
    void CreateZigZagLineLabel(SCString &BarLabelText, SCFloatArrayRef ZigZagPeakType, const int ZigZagIndex, SCFloatArrayRef ZigZagPeakIndex, SCInputRef ShowRevPrice, SCInputRef UseMultiLineLabels, SCStudyInterfaceRef sc, SCSubgraphRef ZigZagLine, SCInputRef ShowLength, bool ShowLabelPrefixes, SCInputRef ShowTime, SCInputRef IncludeSecondsInTimeDisplay, SCInputRef ShowZigZagVolume, SCSubgraphRef AccumulatedVolume, SCInputRef FormatVolumeWithLargeNumberSuffix, SCInputRef ShowZigZagDuration, SCInputRef ShowZigZagNumBars, SCInputRef DisplayZigZagVolumeDividedByLengthInTicks, SCFloatArrayRef ZigZagReset, SCInputRef DisplayHHHLLLLHLabels, SCSubgraphRef TextLabels, double& ZigzagLineLength, int& CurrentZigZagNumBars)
    {

        int BackRefIndex = static_cast<int>(ZigZagPeakIndex[ZigZagIndex - 1]);

        if (ZigZagPeakType[BackRefIndex] == -1 * ZigZagPeakType[ZigZagIndex])
        {
            if (ShowRevPrice.GetYesNo())
            {
                if (BarLabelText.GetLength() != 0)
                {
                    if (UseMultiLineLabels.GetYesNo())
                        BarLabelText += "\n";
                    else
                        BarLabelText += " ";
                }

                SCString ReversalPrice;
                ReversalPrice = sc.FormatGraphValue(ZigZagLine[ZigZagIndex], sc.GetValueFormat());
                BarLabelText += ReversalPrice;
            }

            ZigzagLineLength = ZigZagLine[ZigZagIndex] - static_cast<double>(ZigZagLine[BackRefIndex]);
            if (ShowLength.GetIndex() != 0)
            {
                if (BarLabelText.GetLength() != 0)
                {
                    if (UseMultiLineLabels.GetYesNo())
                        BarLabelText += "\n";
                    else
                        BarLabelText += " ";
                }

                SCString LengthStr;
                if (ShowLabelPrefixes)
                    LengthStr = "L:";

                if (ShowLength.GetIndex() == 1)//Points
                    LengthStr += sc.FormatGraphValue(ZigzagLineLength, sc.GetValueFormat());
                else if (ShowLength.GetIndex() == 2)// Ticks
                {
                    double Ticks = sc.TickSize == 0 ? 0 : ZigzagLineLength / sc.TickSize;
                    LengthStr += sc.FormatGraphValue(Ticks, 0);
                    LengthStr += "T";
                }
                else if (ShowLength.GetIndex() == 3)//Percent
                {
                    float CurrentBarValue = sc.Close[ZigZagIndex];
                    float Percent = static_cast<float>((ZigzagLineLength / CurrentBarValue) * 100);
                    LengthStr += sc.FormatGraphValue(Percent, 2);
                }

                BarLabelText += LengthStr;
            }

            if (ShowTime.GetYesNo())
            {
                if (BarLabelText.GetLength() != 0)
                {
                    if (UseMultiLineLabels.GetYesNo())
                        BarLabelText += "\n";
                    else
                        BarLabelText += " ";
                }

                SCDateTime DT = sc.BaseDateTimeIn[ZigZagIndex];
                SCString TimeStr;
                if (IncludeSecondsInTimeDisplay.GetYesNo())
                    TimeStr.Format("%i:%02i:%02i", DT.GetHour(), DT.GetMinute(), DT.GetSecond());
                else
                    TimeStr.Format("%i:%02i", DT.GetHour(), DT.GetMinute());

                BarLabelText += TimeStr;
            }

            if (ShowZigZagVolume.GetYesNo())
            {
                if (BarLabelText.GetLength() != 0)
                {
                    if (UseMultiLineLabels.GetYesNo())
                        BarLabelText += "\n";
                    else
                        BarLabelText += " ";
                }

                SCString LengthStr;
                if (ShowLabelPrefixes)
                    LengthStr = "V:";

                LengthStr += sc.FormatVolumeValue(static_cast<int64_t>(AccumulatedVolume[ZigZagIndex]), 0, FormatVolumeWithLargeNumberSuffix.GetYesNo());

                BarLabelText += LengthStr;
            }

            if (ShowZigZagDuration.GetYesNo())
            {
                if (BarLabelText.GetLength() != 0)
                {
                    if (UseMultiLineLabels.GetYesNo())
                        BarLabelText += "\n";
                    else
                        BarLabelText += " ";
                }

                double ZigZagTimeSpan = 0;
                if (sc.ChartDataType == INTRADAY_DATA)
                {
                    if (ZigZagIndex < sc.ArraySize - 1)
                        ZigZagTimeSpan = (sc.BaseDateTimeIn[ZigZagIndex + 1] - sc.BaseDateTimeIn[BackRefIndex + 1]).GetAsDouble();
                    else
                        ZigZagTimeSpan = (sc.LatestDateTimeForLastBar - sc.BaseDateTimeIn[BackRefIndex + 1]).GetAsDouble();
                }
                else
                {
                    ZigZagTimeSpan = (sc.BaseDateTimeIn[ZigZagIndex] - sc.BaseDateTimeIn[BackRefIndex + 1]).GetAsDouble();
                }

                SCString TimeDurationStr;
                if (sc.ChartDataType == INTRADAY_DATA)
                {
                    TimeDurationStr = sc.FormatGraphValue(ZigZagTimeSpan, 20);

                    if (TimeDurationStr.GetLength() >= 3 && TimeDurationStr[0] == '0' && TimeDurationStr[1] == '0' && TimeDurationStr[2] == ':')
                        TimeDurationStr = TimeDurationStr.GetSubString(TimeDurationStr.GetLength() - 3, 3);
                }

                SCString LengthStr;
                if (ShowLabelPrefixes)
                    LengthStr = "D:";
                if (ZigZagTimeSpan >= 1.0)
                {
                    SCString DaysStr;
                    if (sc.ChartDataType == INTRADAY_DATA)
                        DaysStr.Format("%iD ", static_cast<int>(ZigZagTimeSpan));
                    else
                        DaysStr.Format("%i ", static_cast<int>(ZigZagTimeSpan));

                    LengthStr += DaysStr;
                }
                LengthStr += TimeDurationStr;

                BarLabelText += LengthStr;
            }

            CurrentZigZagNumBars = ZigZagIndex - BackRefIndex;

            if (ShowZigZagNumBars.GetYesNo())
            {
                if (BarLabelText.GetLength() != 0)
                {
                    if (UseMultiLineLabels.GetYesNo())
                        BarLabelText += "\n";
                    else
                        BarLabelText += " ";
                }

                SCString LengthStr;
                if (ShowLabelPrefixes)
                    LengthStr = "B:";

                SCString NumStr;
                NumStr.Format("%i ", CurrentZigZagNumBars);
                LengthStr += NumStr;

                BarLabelText += LengthStr;
            }

            if (DisplayZigZagVolumeDividedByLengthInTicks.GetYesNo())
            {
                if (BarLabelText.GetLength() != 0)
                {
                    if (UseMultiLineLabels.GetYesNo())
                        BarLabelText += "\n";
                    else
                        BarLabelText += " ";
                }

                if (ShowLabelPrefixes)
                    BarLabelText += "V/L:";

                int64_t VolumeDividedByLengthInTicks = static_cast <int64_t>(AccumulatedVolume[ZigZagIndex] / (ZigzagLineLength / sc.TickSize));

                BarLabelText += sc.FormatVolumeValue(VolumeDividedByLengthInTicks, 0, FormatVolumeWithLargeNumberSuffix.GetYesNo());

            }
        }

        // now go back one more swing
        if (ZigZagReset[BackRefIndex] == 0)
        {
            BackRefIndex = static_cast<int>(ZigZagPeakIndex[BackRefIndex - 1]);

            if (ZigZagPeakType[BackRefIndex] == ZigZagPeakType[ZigZagIndex])
            {
                if (DisplayHHHLLLLHLabels.GetYesNo())
                {
                    if (BarLabelText.GetLength() != 0)
                    {
                        if (UseMultiLineLabels.GetYesNo())
                            BarLabelText += "\n";
                        else
                            BarLabelText += " ";
                    }

                    if (ZigZagPeakType[BackRefIndex] == 1.0f)//High
                    {
                        if (ZigZagLine[BackRefIndex] > ZigZagLine[ZigZagIndex]) //LowerHigh
                        {
                            BarLabelText += "LH";
                            TextLabels.Data[ZigZagIndex] = 1;
                        }
                        else //HigherHigh
                        {
                            BarLabelText += "HH";
                            TextLabels.Data[ZigZagIndex] = 2;
                        }
                    }
                    else //Low
                    {
                        if (ZigZagLine[BackRefIndex] < ZigZagLine[ZigZagIndex]) //HigherLow
                        {
                            BarLabelText += "HL";
                            TextLabels.Data[ZigZagIndex] = 3;
                        }
                        else //LowerLow
                        {
                            BarLabelText += "LL";
                            TextLabels.Data[ZigZagIndex] = 4;
                        }
                    }
                }
            }
        }
        else
        {
            if (ZigZagLine[BackRefIndex] > ZigZagLine[ZigZagIndex])
                TextLabels.Data[ZigZagIndex] = 11;  // first pivot low
            else
                TextLabels.Data[ZigZagIndex] = 12;  // first pivot high
        }
    }

    /*==========================================================================*/
    SCSFExport scsf_ZigZagStudy(SCStudyInterfaceRef sc)
    {
        SCSubgraphRef Subgraph_ZigZagLine        = sc.Subgraph[0];
        SCSubgraphRef Subgraph_TextLabels        = sc.Subgraph[1];
        SCSubgraphRef Subgraph_ReversalPrice     = sc.Subgraph[2];
        SCSubgraphRef Subgraph_ZigzagLength      = sc.Subgraph[3];
        SCSubgraphRef Subgraph_AccumulatedVolume = sc.Subgraph[4];
        SCSubgraphRef Subgraph_ZigzagNumBars     = sc.Subgraph[5];
        SCSubgraphRef Subgraph_ZigzagMidPoint    = sc.Subgraph[6];
        SCSubgraphRef Subgraph_ExtensionLinesSubgraph = sc.Subgraph[7];
        SCSubgraphRef Subgraph_ZigZagOscillator = sc.Subgraph[8];
        SCSubgraphRef Subgraph_ZigZagLineDuration = sc.Subgraph[9];

        SCInputRef Input_VolumeToAccumulate = sc.Input[0];
        SCInputRef Input_LabelOffsetType = sc.Input[1];
        SCInputRef Input_FormatVolumeWithLargeNumberSuffix = sc.Input[2];
        SCInputRef Input_ColorZigZagLine = sc.Input[3];
        SCInputRef Input_VersionUpdate = sc.Input[14];
        SCInputRef Input_DataHigh = sc.Input[15];
        SCInputRef Input_DataLow = sc.Input[16];
        SCInputRef Input_CalculationMode = sc.Input[17];
        SCInputRef Input_ReversalPercent = sc.Input[18];
        SCInputRef Input_ReversalAmount = sc.Input[19];
        SCInputRef Input_NumberBarsForReversal = sc.Input[20];
        SCInputRef Input_ShowRevPrice = sc.Input[21];
        SCInputRef Input_DisplayHHHLLLLHLabels = sc.Input[22];
        SCInputRef Input_LabelsOffset = sc.Input[23];
        SCInputRef Input_AdditionalOutputForSpreadsheets = sc.Input[24];
        SCInputRef Input_ShowTime = sc.Input[25];
        SCInputRef Input_ShowLength = sc.Input[26];
        SCInputRef Input_CalcOnBarClose = sc.Input[27];
        SCInputRef Input_CalculateZigZagVolume_UpgradeOnly = sc.Input[28];
        SCInputRef Input_ShowZigZagVolume = sc.Input[29];
        SCInputRef Input_ShowZigZagDuration = sc.Input[30];
        SCInputRef Input_UseMultiLineLabels = sc.Input[31];
        SCInputRef Input_OmitLabelPrefixes = sc.Input[32];
        SCInputRef Input_ShowZigZagNumBars = sc.Input[33];
        SCInputRef Input_ResetAtStartOfSession = sc.Input[34];
        SCInputRef Input_DisplayZigZagVolumeDividedByLengthInTicks = sc.Input[35];
        SCInputRef Input_ExtendEndPointsUntilFutureIntersection = sc.Input[36];
        SCInputRef Input_IncludeSecondsInTimeDisplay = sc.Input[37];
        SCInputRef Input_DisplayValueLabel = sc.Input[38];
        SCInputRef Input_SingleLineTextHorizontalAlignment = sc.Input[39];
        SCInputRef Input_MultiLineTextHorizontalAlignment = sc.Input[40];

        if(sc.SetDefaults)
        {
            sc.GraphName="Zig Zag";

            //Manual looping
            sc.AutoLoop = 0;

            sc.GraphRegion = 0;

            sc.ValueFormat = VALUEFORMAT_INHERITED;

            Subgraph_ZigZagLine.Name = "Zig Zag";
            Subgraph_ZigZagLine.DrawStyle = DRAWSTYLE_LINE;
            Subgraph_ZigZagLine.LineStyle = LINESTYLE_DOT;
            Subgraph_ZigZagLine.PrimaryColor = RGB(255,0,255);
            Subgraph_ZigZagLine.SecondaryColorUsed = 1;
            Subgraph_ZigZagLine.SecondaryColor = RGB(255,0,0);
            Subgraph_ZigZagLine.LineWidth = 3;
            Subgraph_ZigZagLine.DrawZeros = false;

            Subgraph_TextLabels.Name = "Text Labels";
            Subgraph_TextLabels.SecondaryColorUsed = 1;
            Subgraph_TextLabels.PrimaryColor = RGB(0,255,0);
            Subgraph_TextLabels.SecondaryColor = RGB(255,0,0);
            Subgraph_TextLabels.LineWidth = 10;
            Subgraph_TextLabels.DrawStyle = DRAWSTYLE_CUSTOM_TEXT;

            Subgraph_ReversalPrice.DrawStyle = DRAWSTYLE_IGNORE;
            Subgraph_ZigzagLength.DrawStyle = DRAWSTYLE_IGNORE;
            Subgraph_ZigzagNumBars.DrawStyle = DRAWSTYLE_IGNORE;
            Subgraph_AccumulatedVolume.DrawStyle = DRAWSTYLE_IGNORE;
            Subgraph_AccumulatedVolume.SecondaryColorUsed = 1;

            Subgraph_ZigzagMidPoint.Name = "Zig Zag Mid-Point";
            Subgraph_ZigzagMidPoint.DrawStyle = DRAWSTYLE_IGNORE;
            Subgraph_ZigzagMidPoint.PrimaryColor = RGB(128,128,255);
            Subgraph_ZigzagMidPoint.LineWidth = 1;
            Subgraph_ZigzagMidPoint.DrawZeros = false;

            Subgraph_ExtensionLinesSubgraph.Name = "Extension Lines";
            Subgraph_ExtensionLinesSubgraph.DrawStyle = DRAWSTYLE_LINE;
            Subgraph_ExtensionLinesSubgraph.PrimaryColor = RGB(128, 128, 255);
            Subgraph_ExtensionLinesSubgraph.SecondaryColorUsed = true;
            Subgraph_ExtensionLinesSubgraph.SecondaryColor = RGB(128, 0, 255);
            Subgraph_ExtensionLinesSubgraph.LineWidth = 1;
            Subgraph_ExtensionLinesSubgraph.DrawZeros = false;

            Subgraph_ZigZagOscillator.Name = "Zig Zag Oscillator";
            Subgraph_ZigZagOscillator.DrawStyle = DRAWSTYLE_IGNORE;
            Subgraph_ZigZagOscillator.PrimaryColor = RGB(0, 200, 0);
            Subgraph_ZigZagOscillator.SecondaryColor = RGB(200, 0, 0);
            Subgraph_ZigZagOscillator.AutoColoring = AUTOCOLOR_POSNEG;
            Subgraph_ZigZagOscillator.LineWidth = 3;
            Subgraph_ZigZagOscillator.DrawZeros = false;

            Input_VersionUpdate.SetInt(4);

            unsigned short DisplayOrder = 1;

            Input_DataHigh.Name = "Input Data for High";
            Input_DataHigh.SetInputDataIndex(SC_HIGH);
            Input_DataHigh.DisplayOrder = DisplayOrder++;

            Input_DataLow.Name = "Input Data for Low";
            Input_DataLow.SetInputDataIndex(SC_LOW);
            Input_DataLow.DisplayOrder = DisplayOrder++;

            Input_CalculationMode.Name = "Calculation Mode (1,2,3)";
            Input_CalculationMode.SetInt(1);
            Input_CalculationMode.SetIntLimits(1, 3);
            Input_CalculationMode.DisplayOrder = DisplayOrder++;

            Input_ReversalPercent.Name = "Reversal % for Calculation Mode 1";
            Input_ReversalPercent.SetFloat(.5f);
            Input_ReversalPercent.DisplayOrder = DisplayOrder++;

            Input_ReversalAmount.Name = "Reversal Amount for Calculation Mode 2,3";
            Input_ReversalAmount.SetFloat(0.01f);
            Input_ReversalAmount.DisplayOrder = DisplayOrder++;

            Input_NumberBarsForReversal.Name = "Number of Bars Required for Reversal (Calculation Mode 2)";
            Input_NumberBarsForReversal.SetInt(5);
            Input_NumberBarsForReversal.DisplayOrder = DisplayOrder++;

            Input_VolumeToAccumulate.Name = "Volume To Accumulate";
            Input_VolumeToAccumulate.SetCustomInputStrings("None;Total Volume;Bid Volume;Ask Volume;Ask Bid Volume Difference");
            Input_VolumeToAccumulate.SetCustomInputIndex(0);
            Input_VolumeToAccumulate.DisplayOrder = DisplayOrder++;

            Input_ResetAtStartOfSession.Name = "Reset ZigZag At Start Of Trading Day";
            Input_ResetAtStartOfSession.SetYesNo(0);
            Input_ResetAtStartOfSession.DisplayOrder = DisplayOrder++;

            Input_CalcOnBarClose.Name = "Calculate New Values On Bar Close";
            Input_CalcOnBarClose.SetYesNo(0);
            Input_CalcOnBarClose.DisplayOrder = DisplayOrder++;

            Input_AdditionalOutputForSpreadsheets.Name = "Additional Output for Spreadsheets";
            Input_AdditionalOutputForSpreadsheets.SetYesNo(false);
            Input_AdditionalOutputForSpreadsheets.DisplayOrder = DisplayOrder++;

            Input_DisplayHHHLLLLHLabels.Name = "Display HH,HL,LL,LH Labels";
            Input_DisplayHHHLLLLHLabels.SetYesNo(0);
            Input_DisplayHHHLLLLHLabels.DisplayOrder = DisplayOrder++;

            Input_ShowRevPrice.Name = "Display Reversal Price";
            Input_ShowRevPrice.SetYesNo(0);
            Input_ShowRevPrice.DisplayOrder = DisplayOrder++;

            Input_ShowLength.Name = "Display Length of Zig Zag Line";
            Input_ShowLength.SetCustomInputStrings("None;Points;Ticks;Percent");
            Input_ShowLength.SetCustomInputIndex(0);
            Input_ShowLength.DisplayOrder = DisplayOrder++;

            Input_ShowZigZagVolume.Name = "Display ZigZag Volume";
            Input_ShowZigZagVolume.SetYesNo(0);
            Input_ShowZigZagVolume.DisplayOrder = DisplayOrder++;

            Input_FormatVolumeWithLargeNumberSuffix.Name = "Format Volume Using Large Number Suffix (K/M)";
            Input_FormatVolumeWithLargeNumberSuffix.SetYesNo(0);
            Input_FormatVolumeWithLargeNumberSuffix.DisplayOrder = DisplayOrder++;

            Input_ShowTime.Name = "Display Time Labels";
            Input_ShowTime.SetYesNo(0);
            Input_ShowTime.DisplayOrder = DisplayOrder++;

            Input_IncludeSecondsInTimeDisplay.Name = "Include Seconds in Time Display";
            Input_IncludeSecondsInTimeDisplay.SetYesNo(1);
            Input_IncludeSecondsInTimeDisplay.DisplayOrder = DisplayOrder++;

            Input_ShowZigZagDuration.Name = "Display ZigZag Time Duration";
            Input_ShowZigZagDuration.SetYesNo(0);
            Input_ShowZigZagDuration.DisplayOrder = DisplayOrder++;

            Input_ShowZigZagNumBars.Name = "Display ZigZag Number Of Bars";
            Input_ShowZigZagNumBars.SetYesNo(0);
            Input_ShowZigZagNumBars.DisplayOrder = DisplayOrder++;

            Input_DisplayZigZagVolumeDividedByLengthInTicks.Name = "Display ZigZag Volume / Length in Ticks";
            Input_DisplayZigZagVolumeDividedByLengthInTicks.SetYesNo(0);
            Input_DisplayZigZagVolumeDividedByLengthInTicks.DisplayOrder = DisplayOrder++;

            Input_UseMultiLineLabels.Name = "Use Multi-Line Labels";
            Input_UseMultiLineLabels.SetYesNo(0);
            Input_UseMultiLineLabels.DisplayOrder = DisplayOrder++;

            Input_OmitLabelPrefixes.Name = "Omit Label Prefixes";
            Input_OmitLabelPrefixes.SetYesNo(0);
            Input_OmitLabelPrefixes.DisplayOrder = DisplayOrder++;

            Input_LabelOffsetType.Name = "Text Label Offset Specified As";
            Input_LabelOffsetType.SetCustomInputStrings("Percentage Of Bar;Tick Offset");
            Input_LabelOffsetType.SetCustomInputIndex(1);
            Input_LabelOffsetType.DisplayOrder = DisplayOrder++;

            Input_LabelsOffset.Name = "Text Label Offset";
            Input_LabelsOffset.SetFloat(1.0f);
            Input_LabelsOffset.DisplayOrder = DisplayOrder++;

            Input_ColorZigZagLine.Name = "Color ZigZag Line Using";
            Input_ColorZigZagLine.SetCustomInputStrings("None;Slope;Trend Confirmed Volume;Confirmed Volume");
            Input_ColorZigZagLine.SetCustomInputIndex(0);
            Input_ColorZigZagLine.DisplayOrder = DisplayOrder++;

            Input_ExtendEndPointsUntilFutureIntersection.Name = "Extend End Points Until Future Intersection";
            Input_ExtendEndPointsUntilFutureIntersection.SetYesNo(false);
            Input_ExtendEndPointsUntilFutureIntersection.DisplayOrder = DisplayOrder++;

            Input_DisplayValueLabel.Name = "Display Value Label for Extension Lines";
            Input_DisplayValueLabel.SetYesNo(false);
            Input_DisplayValueLabel.DisplayOrder = DisplayOrder++;

            Input_SingleLineTextHorizontalAlignment.Name = "Single Line Text Horizontal Alignment";
            Input_SingleLineTextHorizontalAlignment.SetCustomInputStrings("Left;Center;Right");
            Input_SingleLineTextHorizontalAlignment.SetCustomInputIndex(1);
            Input_SingleLineTextHorizontalAlignment.DisplayOrder = DisplayOrder++;

            Input_MultiLineTextHorizontalAlignment.Name = "Multi-Line Text Horizontal Alignment";
            Input_MultiLineTextHorizontalAlignment.SetCustomInputStrings("Left;Center;Right");
            Input_MultiLineTextHorizontalAlignment.SetCustomInputIndex(0);
            Input_MultiLineTextHorizontalAlignment.DisplayOrder = DisplayOrder++;

            return;
        }

        SCFloatArrayRef ZigZagPeakType  = Subgraph_ZigZagLine.Arrays[0];  // ZigZagPeakType : +1=high peak, -1=low peak, 0=not peak
        SCFloatArrayRef ZigZagPeakIndex = Subgraph_ZigZagLine.Arrays[1];  // ZigZagPeakIndex: index of current peak, -1=no peak yet
        SCFloatArrayRef ZigZagReset     = Subgraph_ZigZagLine.Arrays[2];  // ZigZagReset: 0=no reset, 1=reset
        SCFloatArrayRef ZigZagTrend     = Subgraph_ZigZagLine.Arrays[3];  // ZigZagTrend: 0=none, 1=confirmed up, -1=confirmed down

        int& LastCalcIndex            = sc.GetPersistentInt(1);
        int& PriorLastZZEndpointIndex = sc.GetPersistentInt(2);
        int& ZigZagStartIndex         = sc.GetPersistentInt(3);
        int& LastUsedLabelDrawingNumber       = sc.GetPersistentInt(4);
        int& LastUsedBarIndexForExtensionLine = sc.GetPersistentInt(5);

        if(sc.UpdateStartIndex == 0)
        {
            LastCalcIndex = -1;
            LastUsedLabelDrawingNumber = -1;
            LastUsedBarIndexForExtensionLine = -1;
            PriorLastZZEndpointIndex = -1;
            ZigZagStartIndex = 0;
            ZigZagReset[0] = 1.0f;
            Subgraph_TextLabels[0] = 10;  // first point

            if (Input_VersionUpdate.GetInt() < 2)
            {
                Input_ResetAtStartOfSession.SetYesNo(0);
                Input_VersionUpdate.SetInt(2);
            }

            if (Input_VersionUpdate.GetInt() < 3)
            {
                Input_LabelOffsetType.SetCustomInputIndex(0);
                Input_FormatVolumeWithLargeNumberSuffix.SetYesNo(0);
                Subgraph_ZigZagLine.SecondaryColorUsed = 1;
                Subgraph_ZigZagLine.SecondaryColor = RGB(255,0,0);
                Input_ColorZigZagLine.SetCustomInputIndex(0);
                Input_VolumeToAccumulate.SetCustomInputIndex(Input_VolumeToAccumulate.GetIndex()+1);
                if (Input_CalculateZigZagVolume_UpgradeOnly.GetYesNo() == 0)
                    Input_VolumeToAccumulate.SetCustomInputIndex(0);

                Input_VersionUpdate.SetInt(3);
            }

            if (Input_VersionUpdate.GetInt() < 4)
            {
                Input_SingleLineTextHorizontalAlignment.SetCustomInputIndex(1);
                Input_MultiLineTextHorizontalAlignment.SetCustomInputIndex(0);
                Input_VersionUpdate.SetInt(4);
            }

            if (Input_AdditionalOutputForSpreadsheets.GetYesNo())
            {
                Subgraph_ReversalPrice.Name = "Reversal Price";
                Subgraph_ZigzagLength.Name = "Zig Zag Line Length";
                Subgraph_ZigzagNumBars.Name = "Zig Zag Num Bars";
            }
            else
            {
                Subgraph_ReversalPrice.Name = "";
                Subgraph_ZigzagLength.Name = "";
                Subgraph_ZigzagNumBars.Name = "";
            }

            if (Input_ShowZigZagVolume.GetYesNo() && Input_VolumeToAccumulate.GetIndex() == 0)
                Input_VolumeToAccumulate.SetCustomInputIndex(1);

            if(Input_VolumeToAccumulate.GetIndex() != 0)
                Subgraph_AccumulatedVolume.Name= "AccumulatedVolume";
            else
                Subgraph_AccumulatedVolume.Name= "";
        }
        else
        {
            if (LastUsedLabelDrawingNumber != -1)
            {
                sc.DeleteACSChartDrawing(sc.ChartNumber, TOOL_DELETE_CHARTDRAWING, LastUsedLabelDrawingNumber);

                LastUsedLabelDrawingNumber = -1;
            }

            if (LastUsedBarIndexForExtensionLine != -1)
            {
                sc.DeleteLineUntilFutureIntersection(LastUsedBarIndexForExtensionLine, 0);

                LastUsedBarIndexForExtensionLine = -1;
            }

        }

        bool ShowLabelPrefixes = Input_OmitLabelPrefixes.GetYesNo() == 0;

        SCDateTime NextSessionStart = 0;
        if (sc.UpdateStartIndex > 0)
            NextSessionStart = SCDateTime(sc.GetTradingDayStartDateTimeOfBar(sc.BaseDateTimeIn[sc.UpdateStartIndex - 1])) + SCDateTime::DAYS(1);

        sc.EarliestUpdateSubgraphDataArrayIndex = sc.UpdateStartIndex;

        // Standard Manual Looping loop
        for (int Index = sc.UpdateStartIndex; Index < sc.ArraySize; ++Index)
        {
            if (Input_ResetAtStartOfSession.GetYesNo() != 0)
            {
                SCDateTime IndexDateTime = sc.BaseDateTimeIn[Index];

                if (IndexDateTime >= NextSessionStart)
                {
                    ZigZagStartIndex = Index;
                    ZigZagReset[Index] = 1.0f;
                    Subgraph_TextLabels[Index] = 10;  // first point

                    NextSessionStart = SCDateTime(sc.GetTradingDayStartDateTimeOfBar(IndexDateTime)) + SCDateTime::DAYS(1);
                }
            }

            int CalcIndex = Index;

            if (Input_CalcOnBarClose.GetYesNo())
            {
                CalcIndex--;
                if (CalcIndex <= LastCalcIndex)
                    continue;
                LastCalcIndex = CalcIndex;
            }

            //Calculate and set the zigzag lines
            switch (Input_CalculationMode.GetInt())
            {
            case 1:
                sc.ZigZag(
                    sc.BaseData[Input_DataHigh.GetInputDataIndex()],
                    sc.BaseData[Input_DataLow.GetInputDataIndex()],
                    Subgraph_ZigZagLine,
                    CalcIndex,
                    Input_ReversalPercent.GetFloat() * 0.01f,
                    ZigZagStartIndex);
                break;
            case 2:
                sc.ZigZag2(
                    sc.BaseData[Input_DataHigh.GetInputDataIndex()],
                    sc.BaseData[Input_DataLow.GetInputDataIndex()],
                    Subgraph_ZigZagLine,
                    CalcIndex,
                    Input_NumberBarsForReversal.GetInt(),
                    Input_ReversalAmount.GetFloat(),
                    ZigZagStartIndex);
                break;
            case 3:
                sc.ZigZag(
                    sc.BaseData[Input_DataHigh.GetInputDataIndex()],
                    sc.BaseData[Input_DataLow.GetInputDataIndex()],
                    Subgraph_ZigZagLine,
                    CalcIndex,
                    0.0f,
                    Input_ReversalAmount.GetFloat(),
                    ZigZagStartIndex);
                break;
            }
        }

        AccumulateZigZagVolume(sc, Subgraph_AccumulatedVolume, ZigZagPeakType, Input_VolumeToAccumulate.GetIndex(), ZigZagReset);

        if (PriorLastZZEndpointIndex != -1)
        {
            for (int ZeroIndex = PriorLastZZEndpointIndex; ZeroIndex < sc.ArraySize; ZeroIndex++)
            {
                Subgraph_TextLabels[ZeroIndex] = 0;
                Subgraph_ReversalPrice[ZeroIndex] = 0;
                Subgraph_ZigzagLength[ZeroIndex] = 0;
                Subgraph_ZigzagNumBars[ZeroIndex] = 0;
            }
        }

        if (PriorLastZZEndpointIndex == -1)
            PriorLastZZEndpointIndex = 0;

        // Get the index of the last endpoint
        int IndexOfLastEndPoint = 0;
        if (Input_CalcOnBarClose.GetYesNo() && sc.ArraySize > 1)
            IndexOfLastEndPoint = static_cast<int>(ZigZagPeakIndex[sc.ArraySize-2]);
        else
            IndexOfLastEndPoint = static_cast<int>(ZigZagPeakIndex[sc.ArraySize-1]);

        for (int ZigZagIndex = PriorLastZZEndpointIndex; ZigZagIndex < sc.ArraySize; ZigZagIndex++)
        {
            if (Subgraph_ZigZagLine[ZigZagIndex] != 0)
            {
                if (Input_ColorZigZagLine.GetIndex() == 0)
                {
                    Subgraph_ZigZagLine.DataColor[ZigZagIndex] = Subgraph_ZigZagLine.PrimaryColor;
                }
                else if (Input_ColorZigZagLine.GetIndex() == 1 && ZigZagIndex > 0)
                {
                    if (Subgraph_ZigZagLine[ZigZagIndex] > Subgraph_ZigZagLine[ZigZagIndex-1])
                        Subgraph_ZigZagLine.DataColor[ZigZagIndex] = Subgraph_ZigZagLine.PrimaryColor;
                    else
                        Subgraph_ZigZagLine.DataColor[ZigZagIndex] = Subgraph_ZigZagLine.SecondaryColor;
                }
                else if (Input_ColorZigZagLine.GetIndex() == 2 || Input_ColorZigZagLine.GetIndex() == 3)
                {
                    if (ZigZagTrend[ZigZagIndex] > 0)
                        Subgraph_ZigZagLine.DataColor[ZigZagIndex] = Subgraph_ZigZagLine.PrimaryColor;
                    else if (ZigZagTrend[ZigZagIndex] < 0)
                        Subgraph_ZigZagLine.DataColor[ZigZagIndex] = Subgraph_ZigZagLine.SecondaryColor;
                }
            }

            int CurrentPeakIndex = static_cast<int>(ZigZagPeakIndex[ZigZagIndex]);

            Subgraph_ZigZagOscillator[ZigZagIndex] = sc.Close[ZigZagIndex] - Subgraph_ZigZagLine[CurrentPeakIndex];

            if (ZigZagPeakType[ZigZagIndex] == 0.0f) //not a peak, nothing to be drawn
                continue;

            if (ZigZagReset[ZigZagIndex] != 0)//Continue processing if this is a reset index
            {
                continue;
            }

            int PrevEndPointIndex = -1;
            if (ZigZagIndex > 0)
                PrevEndPointIndex = static_cast<int>(ZigZagPeakIndex[ZigZagIndex-1]);

            if (PrevEndPointIndex >= 0)
            {
                float MidPoint = (Subgraph_ZigZagLine[ZigZagIndex] + Subgraph_ZigZagLine[PrevEndPointIndex]) / 2.0f;
                if (Subgraph_ZigzagMidPoint[ZigZagIndex] != MidPoint)
                {
                    for (int UpdateIndex=PrevEndPointIndex+1; UpdateIndex<=ZigZagIndex; UpdateIndex++)
                        Subgraph_ZigzagMidPoint[UpdateIndex] = MidPoint;
                }
            }

            if (Input_ColorZigZagLine.GetIndex() == 2 || Input_ColorZigZagLine.GetIndex() == 3) // determine zig zag trend color with confirmed volume
            {
                if (PrevEndPointIndex >= 0)
                {
                    float Trend = ZigZagPeakType[ZigZagIndex];  // default trend is current direction

                    if (PrevEndPointIndex > 0 && ZigZagReset[PrevEndPointIndex] == 0)   // have more than one swing
                    {
                        if (((Input_ColorZigZagLine.GetIndex() == 2 && Trend != ZigZagTrend[PrevEndPointIndex]) || // use current trend and volume
                            Input_ColorZigZagLine.GetIndex() == 3)  // only use volume
                            && Subgraph_AccumulatedVolume[ZigZagIndex] < Subgraph_AccumulatedVolume[PrevEndPointIndex])
                        {
                            Trend = -Trend;
                        }
                    }

                    if (ZigZagTrend[ZigZagIndex] != Trend)
                    {
                        for (int UpdateIndex=PrevEndPointIndex+1; UpdateIndex<=ZigZagIndex; UpdateIndex++)
                        {
                            ZigZagTrend[UpdateIndex] = Trend;

                            if (Trend > 0)
                                Subgraph_ZigZagLine.DataColor[UpdateIndex] = Subgraph_ZigZagLine.PrimaryColor;
                            else
                                Subgraph_ZigZagLine.DataColor[UpdateIndex] = Subgraph_ZigZagLine.SecondaryColor;
                        }
                    }
                }
            }

            //At this point we have a label to draw

            PriorLastZZEndpointIndex = ZigZagIndex;

            SCString BarLabelText;

            int VerticalTextAlignment = ZigZagPeakType[ZigZagIndex] == 1.0 ? DT_BOTTOM : DT_TOP;

            double ZigzagLineLength = 0;
            int CurrentZigZagNumBars = 0;

            CreateZigZagLineLabel(BarLabelText, ZigZagPeakType, ZigZagIndex, ZigZagPeakIndex, Input_ShowRevPrice, Input_UseMultiLineLabels, sc, Subgraph_ZigZagLine, Input_ShowLength, ShowLabelPrefixes, Input_ShowTime, Input_IncludeSecondsInTimeDisplay, Input_ShowZigZagVolume, Subgraph_AccumulatedVolume, Input_FormatVolumeWithLargeNumberSuffix, Input_ShowZigZagDuration, Input_ShowZigZagNumBars, Input_DisplayZigZagVolumeDividedByLengthInTicks, ZigZagReset, Input_DisplayHHHLLLLHLabels, Subgraph_TextLabels, ZigzagLineLength, CurrentZigZagNumBars);

            if (BarLabelText.GetLength() > 0 && !sc.HideStudy)
            {
                s_UseTool Tool;
                Tool.Clear();
                Tool.ChartNumber = sc.ChartNumber;
                Tool.Region = sc.GraphRegion;
                Tool.DrawingType = DRAWING_TEXT;
                Tool.ReverseTextColor = 0;
                Tool.BeginIndex = ZigZagIndex;

                float Offset;
                if (Input_LabelOffsetType.GetIndex() == 0)
                    Offset = Input_LabelsOffset.GetFloat()*0.01f*(sc.High[ZigZagIndex]-sc.Low[ZigZagIndex]);
                else
                    Offset = Input_LabelsOffset.GetFloat()*sc.TickSize;

                if(ZigZagPeakType[ZigZagIndex] == 1.0f)
                    Tool.BeginValue = Subgraph_ZigZagLine[ZigZagIndex] + Offset;
                else
                    Tool.BeginValue = Subgraph_ZigZagLine[ZigZagIndex] - Offset;

                if (ZigZagPeakType[ZigZagIndex] == 1.0f)
                    Tool.Color =  Subgraph_TextLabels.PrimaryColor;
                else
                    Tool.Color = Subgraph_TextLabels.SecondaryColor;

                //Tool.FontFace = sc.GetChartTextFontFaceName();
                Tool.FontSize = Subgraph_TextLabels.LineWidth;
                Tool.FontBold = true;
                Tool.Text = BarLabelText;
                Tool.AddMethod = UTAM_ADD_ALWAYS;
                Tool.LineNumber = -1;

                if (Input_UseMultiLineLabels.GetYesNo())
                {
                    if (Input_MultiLineTextHorizontalAlignment.GetIndex() == 0)
                    {
                        Tool.TextAlignment = DT_LEFT | VerticalTextAlignment;
                    }
                    else if (Input_MultiLineTextHorizontalAlignment.GetIndex() == 1)
                    {
                        Tool.TextAlignment = DT_CENTER | VerticalTextAlignment;
                    }
                    else
                    {
                        Tool.TextAlignment = DT_RIGHT | VerticalTextAlignment;
                    }
                }
                else
                {
                    if (Input_SingleLineTextHorizontalAlignment.GetIndex() == 0)
                    {
                        Tool.TextAlignment = DT_LEFT | VerticalTextAlignment;
                    }
                    else if (Input_SingleLineTextHorizontalAlignment.GetIndex() == 1)
                    {
                        Tool.TextAlignment = DT_CENTER | VerticalTextAlignment;
                    }
                    else
                    {
                        Tool.TextAlignment = DT_RIGHT | VerticalTextAlignment;
                    }
                }

                sc.UseTool(Tool);
                LastUsedLabelDrawingNumber = Tool.LineNumber;
            }

            if (Input_ExtendEndPointsUntilFutureIntersection.GetYesNo())
            {
                sc.AddLineUntilFutureIntersection
                (ZigZagIndex
                    , 0  // LineIDForBar
                    , Subgraph_ZigZagLine[ZigZagIndex]
                    , ZigZagPeakType[ZigZagIndex] == 1.0f ? Subgraph_ExtensionLinesSubgraph.PrimaryColor : Subgraph_ExtensionLinesSubgraph.SecondaryColor
                    , Subgraph_ExtensionLinesSubgraph.LineWidth
                    , Subgraph_ExtensionLinesSubgraph.LineStyle
                    , Input_DisplayValueLabel.GetBoolean()
                    , false
                    , ""
                );

                LastUsedBarIndexForExtensionLine = ZigZagIndex;
            }

            Subgraph_ReversalPrice[ZigZagIndex] = Subgraph_ZigZagLine[ZigZagIndex];
            Subgraph_ZigzagLength[ZigZagIndex] = static_cast<float>(ZigzagLineLength);
            Subgraph_ZigzagNumBars[ZigZagIndex] = static_cast<float>(CurrentZigZagNumBars);
        }

        //Determine the beginning of the last line
        int Count = 0; //To count the number of zigzag pivots
        int StartingIndex = sc.ArraySize;
        while (StartingIndex > 0 && Count < 2)
        {
            StartingIndex--;
            if (ZigZagPeakType[StartingIndex] != 0.0f)
                Count ++;
        }

        sc.EarliestUpdateSubgraphDataArrayIndex = StartingIndex;
    }

    /*==========================================================================*/
    SCSFExport scsf_ZigZagCumulativeVolumeStudy(SCStudyInterfaceRef sc)
    {
        SCSubgraphRef Subgraph_ZigZagLine = sc.Subgraph[0];
        SCSubgraphRef Subgraph_AccumulatedVolume = sc.Subgraph[4];

        SCFloatArrayRef Array_ZigZagPeakType  = Subgraph_ZigZagLine.Arrays[0];
        SCFloatArrayRef Array_ZigZagReset     = Subgraph_ZigZagLine.Arrays[2];  // ZigZagReset: 0=no reset, 1=reset

        SCInputRef Input_VolumeToAccumulate = sc.Input [0];
        SCInputRef Input_VersionUpdate = sc.Input[14];
        SCInputRef Input_DataHigh = sc.Input[15];
        SCInputRef Input_DataLow = sc.Input[16];
        SCInputRef Input_CalculationMode = sc.Input[17];
        SCInputRef Input_ReversalPercent = sc.Input[18];
        SCInputRef Input_ReversalAmount = sc.Input[19];
        SCInputRef Input_NumberBarsForReversal = sc.Input[20];
        SCInputRef Input_ResetAtStartOfSession = sc.Input[26];
        SCInputRef Input_CalcOnBarClose = sc.Input[27];

        if(sc.SetDefaults)
        {
            sc.GraphName="Zig Zag Cumulative Volume";

            //Manual looping
            sc.AutoLoop = 0;
            sc.ValueFormat= 0;
            sc.GraphRegion = 1;

            Subgraph_ZigZagLine.Name = "Zig Zag";
            Subgraph_ZigZagLine.DrawStyle = DRAWSTYLE_IGNORE;

            Subgraph_AccumulatedVolume.Name= "AccumulatedVolume";
            Subgraph_AccumulatedVolume.DrawStyle = DRAWSTYLE_BAR;
            Subgraph_AccumulatedVolume.SecondaryColorUsed = 1;

            Input_VolumeToAccumulate.Name= "Volume To Accumulate";
            Input_VolumeToAccumulate.SetCustomInputStrings("Total Volume;Bid Volume;Ask Volume;Ask Bid Volume Difference");
            Input_VolumeToAccumulate.SetCustomInputIndex(0);

            Input_VersionUpdate.SetInt(2);

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

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

            Input_CalculationMode.Name = "Calculation Mode (1,2,3)";
            Input_CalculationMode.SetInt(1);
            Input_CalculationMode.SetIntLimits(1, 3);

            Input_ReversalPercent.Name = "Reversal % for Calculation Mode 1";
            Input_ReversalPercent.SetFloat(.5f);

            Input_ReversalAmount.Name = "Reversal Amount for Calculation Mode 2,3";
            Input_ReversalAmount.SetFloat(0.01f);

            Input_NumberBarsForReversal.Name = "Number of Bars Required for Reversal (Calculation Mode 2)";
            Input_NumberBarsForReversal.SetInt(5);

            Input_ResetAtStartOfSession.Name = "Reset ZigZag At Start Of Trading Day";
            Input_ResetAtStartOfSession.SetYesNo(0);

            Input_CalcOnBarClose.Name = "Calculate New Values On Bar Close";
            Input_CalcOnBarClose.SetYesNo(0);

            return;
        }

        int &LastCalcIndex    = sc.GetPersistentInt(1);
        int &ZigZagStartIndex = sc.GetPersistentInt(2);

        if (sc.UpdateStartIndex == 0)
        {
            LastCalcIndex = -1;
            ZigZagStartIndex = 0;
            Array_ZigZagReset[0] = 1.0f;

            if (Input_VersionUpdate.GetInt() < 2)
            {
                Input_ResetAtStartOfSession.SetYesNo(0);
                Input_VersionUpdate.SetInt(2);
            }
        }

        int VolumeTypeToAccumulate = Input_VolumeToAccumulate.GetIndex() + 1;  // adjust for no "none" option

        SCDateTime NextSessionStart = 0;
        if (sc.UpdateStartIndex > 0)
            NextSessionStart = SCDateTime(sc.GetTradingDayStartDateTimeOfBar(sc.BaseDateTimeIn[sc.UpdateStartIndex - 1])) + SCDateTime::DAYS(1);

        sc.EarliestUpdateSubgraphDataArrayIndex = sc.UpdateStartIndex;

        // Standard Manual Looping loop
        for (int Index = sc.UpdateStartIndex; Index < sc.ArraySize; Index++)
        {
            if (Input_ResetAtStartOfSession.GetYesNo() != 0)
            {
                SCDateTime IndexDateTime = sc.BaseDateTimeIn[Index];

                if (IndexDateTime >= NextSessionStart)
                {
                    ZigZagStartIndex = Index;
                    Array_ZigZagReset[Index] = 1.0f;

                    NextSessionStart = SCDateTime(sc.GetTradingDayStartDateTimeOfBar(IndexDateTime)) + SCDateTime::DAYS(1);
                }
            }

            int CalcIndex = Index;

            if (Input_CalcOnBarClose.GetYesNo())
            {
                CalcIndex--;
                if (CalcIndex <= LastCalcIndex)
                    continue;
                LastCalcIndex = CalcIndex;
            }

            switch (Input_CalculationMode.GetInt())
            {
            case 1:
                sc.ZigZag(
                    sc.BaseData[Input_DataHigh.GetInputDataIndex()],
                    sc.BaseData[Input_DataLow.GetInputDataIndex()],
                    Subgraph_ZigZagLine,
                    CalcIndex,
                    Input_ReversalPercent.GetFloat() * 0.01f,
                    ZigZagStartIndex);
                break;
            case 2:
                sc.ZigZag2(
                    sc.BaseData[Input_DataHigh.GetInputDataIndex()],
                    sc.BaseData[Input_DataLow.GetInputDataIndex()],
                    Subgraph_ZigZagLine,
                    CalcIndex,
                    Input_NumberBarsForReversal.GetInt(),
                    Input_ReversalAmount.GetFloat(),
                    ZigZagStartIndex);
                break;
            case 3:
                sc.ZigZag(
                    sc.BaseData[Input_DataHigh.GetInputDataIndex()],
                    sc.BaseData[Input_DataLow.GetInputDataIndex()],
                    Subgraph_ZigZagLine,
                    CalcIndex,
                    0.0f,
                    Input_ReversalAmount.GetFloat(),
                    ZigZagStartIndex);
                break;
            }

        }

        AccumulateZigZagVolume(sc, Subgraph_AccumulatedVolume, Array_ZigZagPeakType, VolumeTypeToAccumulate, Array_ZigZagReset);

        //Determine the beginning of the last line
        int Count = 0; //To count the number of zigzag pivots
        int StartingIndex = sc.ArraySize;
        while (StartingIndex > 0 && Count < 2)
        {
            StartingIndex--;
            if (Array_ZigZagPeakType[StartingIndex] != 0.0f)
                Count ++;
        }

        sc.EarliestUpdateSubgraphDataArrayIndex = StartingIndex;
    }

    /*==========================================================================*/
    SCSFExport scsf_VolumeColoredBasedOnVolume2(SCStudyInterfaceRef sc)
    {

        SCSubgraphRef Subgraph_Volume = sc.Subgraph[0];
        SCSubgraphRef Subgraph_Volume3rdColor = sc.Subgraph[1];
        SCSubgraphRef Subgraph_Volume4thColor = sc.Subgraph[2];

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

            sc.GraphName = "Volume - Colored Based on Volume 2";

            sc.StudyDescription = "This study displays the Volume per bar. Each volume bar is colored based upon whether the volume is up or down compared to the previous bar volume. It uses a 3rd color when the Volume is lower than the 2 previous bars.";

            sc.AutoLoop = 1;  // true

            Subgraph_Volume.Name = "Volume";
            Subgraph_Volume.DrawStyle = DRAWSTYLE_BAR;
            Subgraph_Volume.SecondaryColorUsed = 1;
            Subgraph_Volume.PrimaryColor = RGB(0,255,0);
            Subgraph_Volume.SecondaryColor = RGB(255,0,0);

            Subgraph_Volume3rdColor.Name = "Volume 3rd Color";
            Subgraph_Volume3rdColor.PrimaryColor = RGB(255,128,64);

            Subgraph_Volume4thColor.Name = "Default Color";
            Subgraph_Volume4thColor.PrimaryColor = RGB(0,128,255);

            return;
        }

        // Section 2 - Do data processing here

        Subgraph_Volume[sc.Index] = sc.Volume[sc.Index];

        if(sc.Volume[sc.Index] < sc.Volume[sc.Index-1]
        && sc.Volume[sc.Index] < sc.Volume[sc.Index-2])
            Subgraph_Volume.DataColor[sc.Index] = Subgraph_Volume3rdColor.PrimaryColor;
        else if(sc.Volume[sc.Index-1] > sc.Volume[sc.Index])
            Subgraph_Volume.DataColor[sc.Index] = Subgraph_Volume.SecondaryColor;
        else if(sc.Volume[sc.Index-1] < sc.Volume[sc.Index])
            Subgraph_Volume.DataColor[sc.Index] = Subgraph_Volume.PrimaryColor;
        else //If volume is equal
            Subgraph_Volume.DataColor[sc.Index] = Subgraph_Volume4thColor.PrimaryColor;

    }

    /*==========================================================================*/
    SCSFExport scsf_BackgroundColoring(SCStudyInterfaceRef sc)
    {
        SCSubgraphRef Subgraph_Top = sc.Subgraph[0];
        SCSubgraphRef Subgraph_Bottom = sc.Subgraph[1];

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

            sc.GraphName = "Background Coloring";

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

            Subgraph_Top.Name ="Top";
            Subgraph_Top.DrawStyle = DRAWSTYLE_FILL_RECTANGLE_TOP;
            Subgraph_Top.PrimaryColor = RGB(0,255,0);
            Subgraph_Top.DrawZeros = false;

            Subgraph_Bottom.Name ="Bottom";
            Subgraph_Bottom.DrawStyle = DRAWSTYLE_FILL_RECTANGLE_BOTTOM;
            Subgraph_Bottom.DrawZeros = RGB(255,0,255);
            Subgraph_Bottom.DrawZeros = false;

            sc.ScaleRangeType = SCALE_INDEPENDENT;

            return;
        }

        // Do data processing

        Subgraph_Top[sc.ArraySize - 1] = 2;
        Subgraph_Bottom[sc.ArraySize - 1] = 1;
    }

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

        SCInputRef Input_Data = sc.Input[0];
        SCInputRef Input_Length = sc.Input[3];

        if (sc.SetDefaults)
        {
            sc.GraphName = "Moving Average - Simple";

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

            Subgraph_Avg.Name = "Avg";
            Subgraph_Avg.DrawStyle = DRAWSTYLE_LINE;
            Subgraph_Avg.PrimaryColor = RGB(0, 255, 0);
            Subgraph_Avg.LineWidth = 1;
            Subgraph_Avg.DrawZeros = true;

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

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

            return;
        }

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

        sc.SimpleMovAvg(sc.BaseDataIn[Input_Data.GetInputDataIndex()], Subgraph_Avg,  Input_Length.GetInt());
    }

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

        SCInputRef Input_Data = sc.Input[0];
        SCInputRef Input_Length = sc.Input[3];

        if (sc.SetDefaults)
        {
            sc.GraphName = "Moving Average - Simple Skip Zeros";

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

            Subgraph_Avg.Name = "Avg";
            Subgraph_Avg.DrawStyle = DRAWSTYLE_LINE;
            Subgraph_Avg.PrimaryColor = RGB(0, 255, 0);
            Subgraph_Avg.LineWidth = 1;
            Subgraph_Avg.DrawZeros = false;

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

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

            return;
        }

        int LengthInput = Input_Length.GetInt();

        sc.DataStartIndex = LengthInput - 1;

        SCFloatArrayRef InputArray = sc.BaseDataIn[Input_Data.GetInputDataIndex()];

        if (LengthInput <= 0)
            return;

        float Sum = 0;
        int Count = 0;
        if (sc.Index < LengthInput - 1)
            LengthInput = sc.Index + 1;

        for(int BarIndex = sc.Index - LengthInput + 1; BarIndex <= sc.Index; BarIndex++)
        {
            if (InputArray[BarIndex] == 0.0f)
                continue;

            Sum  += InputArray[BarIndex];
            Count ++;
        }

        if (Count > 0)
            Subgraph_Avg[sc.Index] = Sum / Count;
        else
            Subgraph_Avg[sc.Index] = 0;

        return;
    }

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

        SCInputRef Input_Data = sc.Input[0];
        SCInputRef Input_TimePeriodType = sc.Input[1];
        SCInputRef Input_TimePeriodLength = sc.Input[2];

        if (sc.SetDefaults)
        {
            sc.GraphName = "Moving Average - Time Period";

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

            Subgraph_Average.Name = "Avg";
            Subgraph_Average.DrawStyle = DRAWSTYLE_LINE;
            Subgraph_Average.PrimaryColor = RGB(0, 255, 0);
            Subgraph_Average.LineWidth = 1;
            Subgraph_Average.DrawZeros = false;

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

            Input_TimePeriodType.Name = "Time Period Type";
            Input_TimePeriodType.SetTimePeriodType(TIME_PERIOD_LENGTH_UNIT_DAYS);

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

            return;
        }

        SCDateTime TimePeriodLengthAsDateTime = sc.TimePeriodSpan(Input_TimePeriodType.GetIndex(), Input_TimePeriodLength.GetInt());
        int LengthInput = 0;

        int LookbackStartIndex = sc.GetContainingIndexForSCDateTime(sc.ChartNumber, (sc.BaseDateTimeIn[sc.UpdateStartIndex + 1] - TimePeriodLengthAsDateTime).GetAsDouble());

        SCFloatArrayRef Array_InputData = sc.BaseDataIn[Input_Data.GetInputDataIndex()];

        for(int BarIndex = sc.UpdateStartIndex; BarIndex < sc.ArraySize; BarIndex++)
        {
            float Sum = 0;
            int Count = 0;

            for (int LookbackIndex = LookbackStartIndex; LookbackIndex <= BarIndex; LookbackIndex++)
            {
                if (Array_InputData[LookbackIndex] == 0.0f)
                    continue;

                Sum += Array_InputData[LookbackIndex];
                Count++;
            }

            if (Count > 0)
                Subgraph_Average[BarIndex] = Sum / Count;
            else
                Subgraph_Average[BarIndex] = 0;

            if (BarIndex < sc.ArraySize - 1)
            {
                SCDateTime NewLookbackStartDateTime = sc.BaseDateTimeIn[BarIndex + 1] - TimePeriodLengthAsDateTime;

                while (true)
                {
                    SCDateTime CurrentAbsoluteTimeDifference = SCDateTime(sc.BaseDateTimeIn[LookbackStartIndex] - NewLookbackStartDateTime).GetAbsoluteValue();
                    SCDateTime NextAbsoluteTimeDifference = SCDateTime(sc.BaseDateTimeIn[LookbackStartIndex + 1] - NewLookbackStartDateTime).GetAbsoluteValue();

                    if (NextAbsoluteTimeDifference > CurrentAbsoluteTimeDifference)
                        break;

                    LookbackStartIndex++;

                }
            }
        }

        return;
    }

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

    SCSFExport scsf_AverageDailyRange(SCStudyInterfaceRef sc)
    {
        SCSubgraphRef Subgraph_ADR = sc.Subgraph[0];

        SCInputRef Input_Length = sc.Input[0];

        if (sc.SetDefaults)
        {
            sc.GraphName = "Average Daily Range";

            sc.GraphRegion = 1;
            sc.ValueFormat = VALUEFORMAT_INHERITED;

            sc.AutoLoop = 1;

            Subgraph_ADR.Name = "ADR";
            Subgraph_ADR.DrawStyle = DRAWSTYLE_LINE;
            Subgraph_ADR.PrimaryColor = RGB(0, 255, 0);
            Subgraph_ADR.LineWidth = 2;
            Subgraph_ADR.DrawZeros = true;

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

            return;
        }

        sc.DataStartIndex = Input_Length.GetInt() - 1;
        Subgraph_ADR.Arrays[0][sc.Index] = sc.High[sc.Index] - sc.Low[sc.Index];

        sc.SimpleMovAvg(Subgraph_ADR.Arrays[0], Subgraph_ADR,  Input_Length.GetInt());
    }
    /*==========================================================================*/
    SCSFExport scsf_OBVWithMovAvg(SCStudyInterfaceRef sc)
    {
        SCSubgraphRef Subgraph_OBV = sc.Subgraph[0];
        SCSubgraphRef Subgraph_Avg = sc.Subgraph[1];
        SCInputRef Input_OBVLength = sc.Input[3];
        SCInputRef Input_MovAvgLength = sc.Input[4];

        if (sc.SetDefaults)
        {
            sc.GraphName = "On Balance Volume with Mov Avg";

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

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

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

            //OBVLength.Name = "OBV Length";
            Input_OBVLength.SetInt(10);
            Input_OBVLength.SetIntLimits(1, MAX_STUDY_LENGTH);

            Input_MovAvgLength.Name = "Mov Avg Length";
            Input_MovAvgLength.SetInt(10);
            Input_MovAvgLength.SetIntLimits(1, MAX_STUDY_LENGTH);

            return;
        }

        sc.DataStartIndex = Input_MovAvgLength.GetInt();

        int i = (sc.Index >=1 ? sc.Index : 1);

        if(sc.Close[i] > sc.Close[i - 1])
        {
            Subgraph_OBV[i] = Subgraph_OBV[i - 1] + sc.Volume[i];
        }
        else if(sc.Close[i] < sc.Close[i - 1])
        {
            Subgraph_OBV[i] = Subgraph_OBV[i - 1] - sc.Volume[i];
        }
        else
            Subgraph_OBV[i] = Subgraph_OBV[i - 1];

        sc.SimpleMovAvg(Subgraph_OBV, Subgraph_Avg, Input_MovAvgLength.GetInt());
    }

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

        if (sc.SetDefaults)
        {
            sc.GraphName = "Open Interest";

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

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

            return;
        }

        Subgraph_OI[sc.Index]= sc.OpenInterest[sc.Index];
    }

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

        if (sc.SetDefaults)
        {
            sc.GraphName = "Number of Trades";

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

            NumTrades.Name = "NumTrades";
            NumTrades.PrimaryColor = RGB(0,255,0);
            NumTrades.DrawStyle = DRAWSTYLE_BAR;
            NumTrades.LineWidth= 2;
            NumTrades.DrawZeros = false;

            return;
        }

        NumTrades[sc.Index]= sc.NumberOfTrades[sc.Index];
    }

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

        if (sc.SetDefaults)
        {
            sc.GraphName = "Volume / NumberTrades";

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

            Subgraph_NumTrades.Name = "NumTrades";
            Subgraph_NumTrades.PrimaryColor = RGB(0,255,0);
            Subgraph_NumTrades.DrawStyle = DRAWSTYLE_BAR;
            Subgraph_NumTrades.LineWidth= 2;
            Subgraph_NumTrades.DrawZeros = false;

            return;
        }

        if (sc.NumberOfTrades[sc.Index] != 0)
            Subgraph_NumTrades[sc.Index] = sc.Volume[sc.Index] / sc.NumberOfTrades[sc.Index];
        else
            Subgraph_NumTrades[sc.Index] = 0.0f;
    }
    /*==========================================================================*/
    SCSFExport scsf_SumBar(SCStudyInterfaceRef sc)
    {
        SCSubgraphRef Open = sc.Subgraph[0];
        SCSubgraphRef High = sc.Subgraph[1];
        SCSubgraphRef Low = sc.Subgraph[2];
        SCSubgraphRef Last = sc.Subgraph[3];
        SCSubgraphRef Volume = sc.Subgraph[4];
        SCSubgraphRef OpenInterest = sc.Subgraph[5];
        SCSubgraphRef OHLCAvg = sc.Subgraph[6];
        SCSubgraphRef HLCAvg = sc.Subgraph[7];
        SCSubgraphRef HLAvg = sc.Subgraph[8];
        SCSubgraphRef BidVol = sc.Subgraph[9];
        SCSubgraphRef AskVol = sc.Subgraph[10];

        SCInputRef InChart2Number = sc.Input[3];
        SCInputRef InChart1Multiplier = sc.Input[4];
        SCInputRef InChart2Multiplier = sc.Input[5];

        if (sc.SetDefaults)
        {
            sc.GraphName = "Sum (Bar)";

            sc.ValueFormat = 2;
            sc.GraphRegion = 1;
            sc.UseGlobalChartColors = 0;
            sc.GraphDrawType        = GDT_OHLCBAR;
            sc.StandardChartHeader  = 1;

            // We are using Manual looping.
            sc.AutoLoop = false;

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

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

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

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

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

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

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

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

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

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

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

            InChart2Number.Name = "Chart 2 Number";
            InChart2Number.SetChartNumber(1);

            InChart1Multiplier.Name = "Chart 1 Multiplier";
            InChart1Multiplier.SetFloat(1.0f);

            InChart2Multiplier.Name = "Chart 2 Multiplier";
            InChart2Multiplier.SetFloat(1.0f);

            return;
        }

        // Obtain a reference to the Base Data in the specified chart.  This call
        // is relatively efficient, but it should be called as minimally as
        // possible.  To reduce the number of calls we have it outside of the
        // primary "for" loop in this study function.  And we also use Manual
        // Looping by not defining sc.AutoLoop = 1.  In this way,
        // sc.GetChartBaseData is called only once per call to this study
        // function.  sc.GetChartBaseData is a new function to get all of the Base
        // Data arrays with one efficient call.
        SCGraphData Chart2BaseData;
        sc.GetChartBaseData(-InChart2Number.GetChartNumber(), Chart2BaseData);

        for (int Index = sc.UpdateStartIndex; Index < sc.ArraySize; Index++)
        {
            int Chart2Index = sc.GetNearestMatchForDateTimeIndex(InChart2Number.GetChartNumber(), Index);

            for (int SubgraphIndex = SC_OPEN; SubgraphIndex <= SC_NUM_TRADES; SubgraphIndex++)
            {
                sc.Subgraph[SubgraphIndex][Index]
                    = (sc.BaseDataIn[SubgraphIndex][Index] * InChart1Multiplier.GetFloat())
                    + (Chart2BaseData[SubgraphIndex][Chart2Index] * InChart2Multiplier.GetFloat());
            }

            sc.Subgraph[SC_HIGH][Index]
                = max(sc.Subgraph[SC_OPEN][Index],
                    max(sc.Subgraph[SC_HIGH][Index],
                        max(sc.Subgraph[SC_LOW][Index], sc.Subgraph[SC_LAST][Index])
                    )
                );

            sc.Subgraph[SC_LOW][Index]
                = min(sc.Subgraph[SC_OPEN][Index],
                    min(sc.Subgraph[SC_HIGH][Index],
                        min(sc.Subgraph[SC_LOW][Index], sc.Subgraph[SC_LAST][Index])
                    )
                );

            sc.CalculateOHLCAverages(Index);
        }

        SCString Chart1Name = sc.GetStudyNameFromChart(sc.ChartNumber, 0);
        SCString Chart2Name = sc.GetStudyNameFromChart(InChart2Number.GetChartNumber(), 0);
        sc.GraphName.Format("Sum %s + %s", Chart1Name.GetChars(), Chart2Name.GetChars());
    }

    /*==========================================================================*/
    SCSFExport scsf_RatioBar(SCStudyInterfaceRef sc)
    {
        SCSubgraphRef Subgraph_Open = sc.Subgraph[0];
        SCSubgraphRef Subgraph_High = sc.Subgraph[1];
        SCSubgraphRef Subgraph_Low = sc.Subgraph[2];
        SCSubgraphRef Subgraph_Last = sc.Subgraph[3];
        SCSubgraphRef Subgraph_Volume = sc.Subgraph[4];
        SCSubgraphRef Subgraph_OpenInterest = 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];
        SCSubgraphRef Subgraph_Unused11 = sc.Subgraph[11];
        SCSubgraphRef Subgraph_Unused12 = sc.Subgraph[12];

        SCInputRef Input_Chart2Number = sc.Input[3];
        SCInputRef Input_Chart1Multiplier = sc.Input[4];
        SCInputRef Input_Chart2Multiplier = sc.Input[5];
        SCInputRef Input_ZeroOutputWhenNonExactDateMatch = sc.Input[6];
        SCInputRef Input_UseLatestSourceDataForLastBar = sc.Input[7];

        if (sc.SetDefaults)
        {
            sc.GraphName = "Ratio (Bar)";

            sc.UseGlobalChartColors = 0;

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

            sc.GraphDrawType = GDT_OHLCBAR;
            sc.StandardChartHeader = 1;

            sc.GraphUsesChartColors = 1;

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

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

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

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

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

            Subgraph_OpenInterest.Name = "# of Trades / OI";
            Subgraph_OpenInterest.DrawStyle = DRAWSTYLE_IGNORE;
            Subgraph_OpenInterest.PrimaryColor = RGB(0,0,255);
            Subgraph_OpenInterest.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;

            Subgraph_Unused11.DrawStyle = DRAWSTYLE_IGNORE;
            Subgraph_Unused11.DrawZeros = false;

            Subgraph_Unused12.DrawStyle = DRAWSTYLE_IGNORE;
            Subgraph_Unused12.DrawZeros = false;

            Input_Chart2Number.Name = "Chart 2 Number";
            Input_Chart2Number.SetChartNumber(1);

            Input_Chart1Multiplier.Name = "Chart 1 Multiplier";
            Input_Chart1Multiplier.SetFloat(1.0f);

            Input_Chart2Multiplier.Name = "Chart 2 Multiplier";
            Input_Chart2Multiplier.SetFloat(1.0f);

            Input_ZeroOutputWhenNonExactDateMatch.Name = "Zero Output When Non Exact Date Match";
            Input_ZeroOutputWhenNonExactDateMatch.SetYesNo(false);

            Input_UseLatestSourceDataForLastBar.Name = "Use Latest Source Data For Last Bar";
            Input_UseLatestSourceDataForLastBar.SetYesNo(0);

            return;
        }

        SCGraphData Chart2Arrays;
        sc.GetChartBaseData(-Input_Chart2Number.GetChartNumber(), Chart2Arrays);

        if (Chart2Arrays[0].GetArraySize() == 0)
            return;

        for (int Index = sc.UpdateStartIndex; Index < sc.ArraySize; Index++)
        {
            int Chart2Index = 0;
            if(Input_ZeroOutputWhenNonExactDateMatch.GetYesNo() == false)
            {
                Chart2Index = sc.GetNearestMatchForDateTimeIndex(Input_Chart2Number.GetChartNumber(), Index);

                //When 'use latest source data for last bar' is set to Yes, replay is not running and at last bar in the destination chart, then use the data from the very latest bar in the source chart.
                if(Input_UseLatestSourceDataForLastBar.GetYesNo() && !sc.IsReplayRunning() && Index == sc.ArraySize - 1)
                    Chart2Index = Chart2Arrays[0].GetArraySize() - 1;

            }
            else
            {

                Chart2Index = sc.GetExactMatchForSCDateTime(Input_Chart2Number.GetChartNumber(), sc.BaseDateTimeIn[Index]);
                if(Chart2Index == -1)
                {
                    for (int SubgraphIndex = SC_OPEN; SubgraphIndex <= SC_HL_AVG; SubgraphIndex++)
                    {
                        sc.Subgraph[SubgraphIndex][Index] = 0.0;
                    }

                    continue;
                }
            }

            for (int SubgraphIndex = SC_OPEN; SubgraphIndex <= SC_NUM_TRADES; SubgraphIndex++)
            {
                if (sc.BaseDataIn[SubgraphIndex][Index] == 0 || Chart2Arrays[SubgraphIndex][Chart2Index] == 0)
                {
                    sc.Subgraph[SubgraphIndex][Index] = 0;
                    continue;
                }

                sc.Subgraph[SubgraphIndex][Index] = (sc.BaseDataIn[SubgraphIndex][Index] * Input_Chart1Multiplier.GetFloat())
                    / (Chart2Arrays[SubgraphIndex][Chart2Index] * Input_Chart2Multiplier.GetFloat());
            }

            sc.Subgraph[SC_HIGH][Index]
            = max(sc.Subgraph[0][Index],
                max(sc.Subgraph[1][Index],
                max(sc.Subgraph[2][Index],sc.Subgraph[3][Index])
                )
                );

            sc.Subgraph[SC_LOW][Index]
            = min(sc.Subgraph[0][Index],
                min(sc.Subgraph[1][Index],
                min(sc.Subgraph[2][Index],sc.Subgraph[3][Index])
                )
                );

            sc.CalculateOHLCAverages(Index);
        }

        SCString Chart1Name = sc.GetStudyNameFromChart(sc.ChartNumber, 0);
        SCString Chart2Name = sc.GetStudyNameFromChart(Input_Chart2Number.GetChartNumber(), 0);
        sc.GraphName.Format("Ratio %s / %s", Chart1Name.GetChars(), Chart2Name.GetChars());
    }

    /*==========================================================================*/
    SCSFExport scsf_MultiplyBar(SCStudyInterfaceRef sc)
    {
        SCSubgraphRef Subgraph_Open = sc.Subgraph[0];
        SCSubgraphRef Subgraph_High = sc.Subgraph[1];
        SCSubgraphRef Subgraph_Low = sc.Subgraph[2];
        SCSubgraphRef Subgraph_Last = sc.Subgraph[3];
        SCSubgraphRef Subgraph_Volume = sc.Subgraph[4];
        SCSubgraphRef Subgraph_OpenInterest = 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];
        SCSubgraphRef Subgraph_Unused11 = sc.Subgraph[11];
        SCSubgraphRef Subgraph_Unused12 = sc.Subgraph[12];

        SCInputRef Input_Chart2Number = sc.Input[3];
        SCInputRef Input_Chart1Multiplier = sc.Input[4];
        SCInputRef Input_Chart2Multiplier = sc.Input[5];

        if (sc.SetDefaults)
        {
            sc.GraphName = "Multiply Charts - Bar";

            sc.GraphUsesChartColors = true;

            sc.ValueFormat = VALUEFORMAT_INHERITED;
            sc.GraphRegion = 1;
            sc.GraphDrawType = GDT_OHLCBAR;
            sc.StandardChartHeader = 1;

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

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

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

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

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

            Subgraph_OpenInterest.Name = "# of Trades / OI";
            Subgraph_OpenInterest.DrawStyle = DRAWSTYLE_IGNORE;
            Subgraph_OpenInterest.PrimaryColor = RGB(0,0,255);
            Subgraph_OpenInterest.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;

            Subgraph_Unused11.DrawStyle = DRAWSTYLE_IGNORE;
            Subgraph_Unused11.DrawZeros = false;

            Subgraph_Unused12.DrawStyle = DRAWSTYLE_IGNORE;
            Subgraph_Unused12.DrawZeros = false;

            Input_Chart2Number.Name = "Chart 2 Number";
            Input_Chart2Number.SetChartNumber(1);

            Input_Chart1Multiplier.Name = "Chart 1 Multiplier";
            Input_Chart1Multiplier.SetFloat(1.0f);

            Input_Chart2Multiplier.Name = "Chart 2 Multiplier";
            Input_Chart2Multiplier.SetFloat(1.0f);

            return;
        }

        SCGraphData Chart2Arrays;
        sc.GetChartBaseData(-Input_Chart2Number.GetChartNumber(), Chart2Arrays);

        if (Chart2Arrays[0].GetArraySize() == 0)
            return;

        for (int Index = sc.UpdateStartIndex; Index < sc.ArraySize; Index++)
        {
            int i1 = sc.GetNearestMatchForDateTimeIndex(Input_Chart2Number.GetChartNumber(), Index);

            for (int i2 = SC_OPEN; i2 <= SC_NUM_TRADES; i2++)
            {

                sc.Subgraph[i2][Index] = (sc.BaseDataIn[i2][Index] * Input_Chart1Multiplier.GetFloat())
                    * (Chart2Arrays[i2][i1] * Input_Chart2Multiplier.GetFloat());
            }

            sc.Subgraph[1][Index]
            = max(sc.Subgraph[0][Index],
                max(sc.Subgraph[1][Index],
                max(sc.Subgraph[2][Index],sc.Subgraph[3][Index])
                )
                );

            sc.Subgraph[2][Index]
            = min(sc.Subgraph[0][Index],
                min(sc.Subgraph[1][Index],
                min(sc.Subgraph[2][Index],sc.Subgraph[3][Index])
                )
                );

            sc.CalculateOHLCAverages(Index);
        }

        SCString Chart1Name = sc.GetStudyNameFromChart(sc.ChartNumber, 0);
        SCString Chart2Name = sc.GetStudyNameFromChart(Input_Chart2Number.GetChartNumber(), 0);
        sc.GraphName.Format("Multiply %s * %s", Chart1Name.GetChars(), Chart2Name.GetChars());
    }

    /*==========================================================================*/
    SCSFExport scsf_OnBalanceVolume(SCStudyInterfaceRef sc)
    {
        SCSubgraphRef Subgraph_OBV = sc.Subgraph[0];
        SCInputRef Input_ResetAtStartOfTradingDay = sc.Input[0];

        if (sc.SetDefaults)
        {
            sc.GraphName = "On Balance Volume";
            sc.ValueFormat = 0;
            sc.AutoLoop = 0;

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

            Input_ResetAtStartOfTradingDay.Name = "Reset at Start of Trading Day";
            Input_ResetAtStartOfTradingDay.SetYesNo(false);

            return;
        }

        sc.DataStartIndex = 1;

        for (int Index = max(1, sc.UpdateStartIndex); Index < sc.ArraySize; Index++)
        {
            bool NeedReset = false;

            if (Input_ResetAtStartOfTradingDay.GetYesNo())
            {
                SCDateTime PriorTradingDayDate = sc.GetTradingDayDate(sc.BaseDateTimeIn[Index - 1]);
                SCDateTime TradingDayDate = sc.GetTradingDayDate(sc.BaseDateTimeIn[Index]);
                NeedReset = PriorTradingDayDate != TradingDayDate;
            }

            if (NeedReset)
            {
                if (sc.BaseDataIn[SC_LAST][Index] > sc.BaseDataIn[SC_LAST][Index - 1])
                    Subgraph_OBV[Index] = sc.BaseDataIn[SC_VOLUME][Index];
                else if (sc.BaseDataIn[SC_LAST][Index] < sc.BaseDataIn[SC_LAST][Index - 1])
                    Subgraph_OBV[Index] = sc.BaseDataIn[SC_VOLUME][Index] * -1;
                else  // Equal
                    Subgraph_OBV[Index] = 0;
            }
            else
            {
                if (sc.BaseDataIn[SC_LAST][Index] > sc.BaseDataIn[SC_LAST][Index - 1])
                    Subgraph_OBV[Index] = Subgraph_OBV[Index - 1] + sc.BaseDataIn[SC_VOLUME][Index];
                else if (sc.BaseDataIn[SC_LAST][Index] < sc.BaseDataIn[SC_LAST][Index - 1])
                    Subgraph_OBV[Index] = Subgraph_OBV[Index - 1] - sc.BaseDataIn[SC_VOLUME][Index];
                else  // Equal
                    Subgraph_OBV[Index] = Subgraph_OBV[Index - 1];
            }
        }
    }

    /*==========================================================================*/
    SCSFExport scsf_PriceOpenInterestVolume(SCStudyInterfaceRef sc)
    {
        SCSubgraphRef Subgraph_POIV = sc.Subgraph[0];
        SCFloatArrayRef Array_TrueHigh = sc.Subgraph[0].Arrays[0];
        SCFloatArrayRef Array_TrueLow = sc.Subgraph[0].Arrays[1];
        SCFloatArrayRef Array_IntermediateCalculation = sc.Subgraph[0].Arrays[2];
        SCFloatArrayRef Array_OBV = sc.Subgraph[0].Arrays[3];

        if (sc.SetDefaults)
        {
            sc.GraphName = "Price, Open Interest, Volume";
            sc.ValueFormat = 0;
            sc.AutoLoop = 1;

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

            return;
        }

        sc.DataStartIndex = 1;

        if (sc.Index < 1)
            return;

        //CumulativeSum (Open Interest * (Close - Close.1) / (True High - True Low)) + OBV

        sc.OnBalanceVolume(sc.BaseDataIn, Array_OBV);

        float TrueHighLowDifference = sc.GetTrueHigh(sc.BaseDataIn) - sc.GetTrueLow(sc.BaseDataIn);

        if (TrueHighLowDifference != 0)
        {
            Array_IntermediateCalculation[sc.Index]
                =  (
                (sc.BaseDataIn[SC_OPEN_INTEREST][sc.Index]
                    * (sc.BaseDataIn[SC_LAST][sc.Index] - sc.BaseDataIn[SC_LAST][sc.Index - 1])
                    )
                    / TrueHighLowDifference
                    )
                    + Array_OBV[sc.Index];

            sc.CumulativeSummation(Array_IntermediateCalculation, Subgraph_POIV);
        }
        else
        {
            Subgraph_POIV[sc.Index] = Subgraph_POIV[sc.Index - 1];
        }
    }

    /*==========================================================================*/
    SCSFExport scsf_Line(SCStudyInterfaceRef sc)
    {
        SCSubgraphRef Subgraph_Line = sc.Subgraph[0];
        SCInputRef Input_Value = sc.Input[3];
        SCInputRef Input_NumberOfDaysToCalculate = sc.Input[0];

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

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

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

            Input_Value.Name = "Value";
            Input_Value.SetFloat(1.0f);

            Input_NumberOfDaysToCalculate.Name = "Number of Days to Calculate";
            Input_NumberOfDaysToCalculate.SetInt(0);

            sc.DataStartIndex = 0;

            return;
        }

        if(Input_NumberOfDaysToCalculate.GetInt() > 0)
        {
            Subgraph_Line.DrawZeros = 0;

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

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

            if ((TradingDayDateForLastBar.GetDate() - TradingDayDateForBar.GetDate() + 1)
        > Input_NumberOfDaysToCalculate.GetInt())
            {
                return;
            }
        }

        Subgraph_Line[sc.Index] = Input_Value.GetFloat();
    }

    /*==========================================================================*/
    SCSFExport scsf_AverageTrueRange(SCStudyInterfaceRef sc)
    {
        SCSubgraphRef Subgraph_ATR = sc.Subgraph[0];
        SCInputRef Subgraph_MAType = sc.Input[0];
        SCInputRef Subgraph_Length = sc.Input[3];

        if (sc.SetDefaults)
        {
            sc.GraphName = "Average True Range";

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

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

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

            Subgraph_Length.Name = "Moving Average Length";
            Subgraph_Length.SetInt(14);
            Subgraph_Length.SetIntLimits(1, MAX_STUDY_LENGTH);

            return;
        }

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

        sc.ATR(sc.BaseDataIn, Subgraph_ATR, Subgraph_Length.GetInt(), Subgraph_MAType.GetMovAvgType());
    }

    /*==========================================================================*/
    SCSFExport scsf_AverageTrueRangeExample(SCStudyInterfaceRef sc)
    {
        SCSubgraphRef Subgraph_ATR = sc.Subgraph[0];
        SCInputRef Subgraph_Length = sc.Input[1];

        if (sc.SetDefaults)
        {
            sc.GraphName = "Average True Range Example";

            sc.GraphRegion = 1;
            sc.ValueFormat = VALUEFORMAT_INHERITED;
            sc.AutoLoop = 1; //Automatic looping

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

            Subgraph_Length.Name = "Moving Average Length";
            Subgraph_Length.SetInt(14);
            Subgraph_Length.SetIntLimits(1, MAX_STUDY_LENGTH);

            return;
        }

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

        sc.ATR(sc.BaseDataIn, Subgraph_ATR.Arrays[0], Subgraph_ATR, Subgraph_Length.GetInt(), MOVAVGTYPE_SIMPLE);

        float TrueRange = Subgraph_ATR.Arrays[0][sc.Index];
    }

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

        if (sc.SetDefaults)
        {
            sc.GraphName = "True Range";

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

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

            return;
        }

        sc.TrueRange(sc.BaseDataIn, Subgraph_TR);
    }

    /*==========================================================================*/
    SCSFExport scsf_NormalizedAverageTrueRange(SCStudyInterfaceRef sc)
    {

        SCSubgraphRef Subgraph_ATR = sc.Subgraph[0];
        SCSubgraphRef Subgraph_NATR = sc.Subgraph[1];

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

        if (sc.SetDefaults)
        {
            sc.GraphName = "Average True Range - Normalized";

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

            Subgraph_ATR.Name = "ATR";
            Subgraph_ATR.DrawStyle = DRAWSTYLE_IGNORE;

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

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

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

            return;
        }

        sc.DataStartIndex = Input_Length.GetInt() - 1;
        sc.ATR(sc.BaseDataIn, Subgraph_ATR, Input_Length.GetInt(), Input_MAType.GetMovAvgType());

        if (sc.BaseData[SC_LAST][sc.Index] == 0)
            Subgraph_NATR[sc.Index] = 0;
        else
            Subgraph_NATR[sc.Index] = 100 * Subgraph_ATR[sc.Index] / sc.BaseData[SC_LAST][sc.Index];
    }
    /*==========================================================================*/
    SCSFExport scsf_Vortex(SCStudyInterfaceRef sc)
    {
        SCSubgraphRef Subgraph_VIPlus = sc.Subgraph[0];
        SCSubgraphRef Subgraph_VIMinus = sc.Subgraph[1];

        SCInputRef Input_VortexLength = sc.Input[1];

        if (sc.SetDefaults)
        {
            sc.GraphName = "Vortex";

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

            Subgraph_VIPlus.Name = "VI+";
            Subgraph_VIPlus.DrawZeros = false;
            Subgraph_VIPlus.PrimaryColor = RGB(0, 128, 255);
            Subgraph_VIPlus.DrawStyle = DRAWSTYLE_LINE;

            Subgraph_VIMinus.Name = "VI-";
            Subgraph_VIMinus.DrawZeros = false;
            Subgraph_VIMinus.PrimaryColor = COLOR_CRIMSON;
            Subgraph_VIMinus.DrawStyle = DRAWSTYLE_LINE;

            Input_VortexLength.Name = "Vortex Length";
            Input_VortexLength.SetInt(21);
            Input_VortexLength.SetIntLimits(1, MAX_STUDY_LENGTH);

            return;
        }

        sc.Vortex(sc.BaseDataIn, Subgraph_VIPlus, Subgraph_VIMinus, Input_VortexLength.GetInt());
    }

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

        SCInputRef Input_DailyRangeStudy        = sc.Input[0];
        SCInputRef Input_GapAdjustWithYesterdaysClose = sc.Input[1];
        SCInputRef Input_NumDaysToDisplay       = sc.Input[2];
        SCInputRef Input_BandMultiplier       = sc.Input[3];
        SCInputRef Input_UseDailyHighLow          = sc.Input[4];
        SCInputRef Input_DailyRangeDisplacement = sc.Input[5];
        SCInputRef Input_StopUpdatingOnRangeMet = sc.Input[6];

        if (sc.SetDefaults)
        {
            sc.GraphName = "Daily Range Bands";

            sc.GraphRegion = 0;
            sc.AutoLoop = 0; // Manual Looping
            sc.DrawZeros = 0;

            // Subgraphs
            Subgraph_UpperBand.Name = "Upper Range Band";
            Subgraph_UpperBand.DrawZeros = false;
            Subgraph_UpperBand.PrimaryColor = RGB(0,128,192);
            Subgraph_UpperBand.DrawStyle = DRAWSTYLE_STAIR_STEP;

            Subgraph_LowerBand.Name = "Lower Range Band";
            Subgraph_LowerBand.DrawZeros = false;
            Subgraph_LowerBand.PrimaryColor = RGB(192,0,0);
            Subgraph_LowerBand.DrawStyle = DRAWSTYLE_STAIR_STEP;

            // Inputs
            Input_DailyRangeStudy.Name = "Range Study Reference Subgraph";
            Input_DailyRangeStudy.SetChartStudySubgraphValues(1, 1, 0);

            Input_GapAdjustWithYesterdaysClose.Name = "Gap Adjust With Yesterdays Close";
            Input_GapAdjustWithYesterdaysClose.SetYesNo(1);

            Input_NumDaysToDisplay.Name = "Number of Days To Display (0=All)";
            Input_NumDaysToDisplay.SetInt(0);
            Input_NumDaysToDisplay.SetIntLimits(0,MAX_STUDY_LENGTH);

            Input_BandMultiplier.Name = "Band Multiplier";
            Input_BandMultiplier.SetFloat(1.0f);
            Input_BandMultiplier.SetFloatLimits(0, FLT_MAX);

            Input_UseDailyHighLow.Name = "Use High/Low From Historical Daily Chart";
            Input_UseDailyHighLow.SetYesNo(0);

            Input_DailyRangeDisplacement.Name = "Daily Range Displacement";
            Input_DailyRangeDisplacement.SetInt(0);
            Input_DailyRangeDisplacement.SetIntLimits(0, 1000);

            Input_StopUpdatingOnRangeMet.Name = "Stop Updating High/Low When Projected Range Met";
            Input_StopUpdatingOnRangeMet.SetYesNo(0);

            return;
        }

        float& TodaysHigh = sc.GetPersistentFloat(1);
        float& TodaysLow  = sc.GetPersistentFloat(2);
        SCDateTime& CurrentSessionStartDateTime = sc.GetPersistentSCDateTime(1);

        int DailyChartNumber = Input_DailyRangeStudy.GetChartNumber();

        SCGraphData BaseData;
        sc.GetChartBaseData(DailyChartNumber, BaseData);

        SCFloatArrayRef DailyClose = BaseData[SC_LAST];
        SCFloatArrayRef DailyHigh = BaseData[SC_HIGH];
        SCFloatArrayRef DailyLow = BaseData[SC_LOW];

        SCFloatArray DailyBandRange;
        sc.GetStudyArrayFromChartUsingID(Input_DailyRangeStudy.GetChartStudySubgraphValues(), DailyBandRange);

        for (int BarIndex = sc.UpdateStartIndex; BarIndex < sc.ArraySize; BarIndex++ )
        {
            int TradeDate = sc.GetTradingDayDate(sc.BaseDateTimeIn[BarIndex]);

            bool NewDay = BarIndex == 0 || sc.BaseDateTimeIn[BarIndex] >= CurrentSessionStartDateTime + SCDateTime::DAYS(1);

            if (NewDay)
            {
                TodaysHigh = sc.High[BarIndex];
                TodaysLow = sc.Low[BarIndex];
                CurrentSessionStartDateTime = sc.GetStartDateTimeForTradingDate(TradeDate);

                if (BarIndex != 0 && Input_NumDaysToDisplay.GetInt() != 0)
                {
                    SCDateTime FirstCalcDateTime = CurrentSessionStartDateTime - SCDateTime::DAYS(Input_NumDaysToDisplay.GetInt() - 1);
                    int FirstCalcIndex = sc.GetContainingIndexForSCDateTime(sc.ChartNumber, FirstCalcDateTime.GetAsDouble());
                    for (int Index=0; Index<FirstCalcIndex; ++Index)
                    {
                        Subgraph_UpperBand[Index] = 0;
                        Subgraph_LowerBand[Index] = 0;
                    }
                }
            }

            int DailyIndex = sc.GetFirstIndexForDate(DailyChartNumber, TradeDate);

            if (Input_UseDailyHighLow.GetYesNo())
            {
                TodaysHigh = DailyHigh[DailyIndex];
                TodaysLow = DailyLow[DailyIndex];
            }
            else
            {
                if (sc.High[BarIndex] > TodaysHigh)
                    TodaysHigh = sc.High[BarIndex];
                if (sc.Low[BarIndex] < TodaysLow)
                    TodaysLow = sc.Low[BarIndex];
            }

            float RangeStudyValue = 0;
            if (DailyIndex >= Input_DailyRangeDisplacement.GetInt())
                RangeStudyValue = DailyBandRange[DailyIndex-Input_DailyRangeDisplacement.GetInt()];

            if (Input_BandMultiplier.GetFloat() != 0)
                RangeStudyValue *= Input_BandMultiplier.GetFloat();

            float GapAdjustedHigh = TodaysHigh;
            float GapAdjustedLow  = TodaysLow;

            if (Input_GapAdjustWithYesterdaysClose.GetYesNo())
            {
                if (DailyIndex > 0)
                {
                    float PriorClose = DailyClose[DailyIndex-1];
                    if (PriorClose != 0)
                    {
                        GapAdjustedLow  = min(TodaysLow, PriorClose);
                        GapAdjustedHigh = max(TodaysHigh, PriorClose);
                    }
                }
            }

            if (Input_StopUpdatingOnRangeMet.GetYesNo() && !NewDay)
            {
                if ((Subgraph_UpperBand[BarIndex-1] - Subgraph_LowerBand[BarIndex-1]) <= RangeStudyValue)
                {
                    Subgraph_UpperBand[BarIndex] = Subgraph_UpperBand[BarIndex-1];
                    Subgraph_LowerBand[BarIndex] = Subgraph_LowerBand[BarIndex-1];
                }
                else
                {
                    if (TodaysHigh >= Subgraph_UpperBand[BarIndex-1])
                        Subgraph_LowerBand[BarIndex] = Subgraph_UpperBand[BarIndex-1] - RangeStudyValue;
                    else
                        Subgraph_LowerBand[BarIndex] = GapAdjustedHigh - RangeStudyValue;

                    if (TodaysLow <= Subgraph_LowerBand[BarIndex-1])
                        Subgraph_UpperBand[BarIndex] = Subgraph_LowerBand[BarIndex-1] + RangeStudyValue;
                    else
                        Subgraph_UpperBand[BarIndex] = GapAdjustedLow + RangeStudyValue;
                }
            }
            else
            {
                Subgraph_UpperBand[BarIndex] = GapAdjustedLow  + RangeStudyValue;
                Subgraph_LowerBand[BarIndex] = GapAdjustedHigh - RangeStudyValue;
            }
        }
    }

    /*==========================================================================*/
    SCSFExport scsf_MovingAverageExponential(SCStudyInterfaceRef sc)
    {
        SCSubgraphRef Subgraph_Avg = sc.Subgraph[0];
        SCInputRef Input_Data = sc.Input[0];
        SCInputRef Input_Length = sc.Input[3];

        if (sc.SetDefaults)
        {
            sc.GraphName = "Moving Average - Exponential";

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

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

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

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

            return;
        }

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

        sc.ExponentialMovAvg(sc.BaseDataIn[Input_Data.GetInputDataIndex()], Subgraph_Avg, Input_Length.GetInt());
    }

    /*==========================================================================*/
    SCSFExport scsf_MovingAverageWeighted(SCStudyInterfaceRef sc)
    {
        SCSubgraphRef Subgraph_Avg = sc.Subgraph[0];
        SCInputRef Input_Data = sc.Input[0];
        SCInputRef Input_Length = sc.Input[3];

        if (sc.SetDefaults)
        {
            sc.GraphName = "Moving Average - Weighted";

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

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

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

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

            return;
        }

        //sc.DataStartIndex = Length.GetInt() - 1;

        sc.WeightedMovingAverage(sc.BaseDataIn[Input_Data.GetInputDataIndex()], Subgraph_Avg, Input_Length.GetInt());
    }

    /*==========================================================================*/
    SCSFExport scsf_MovingAverageLeastSquares(SCStudyInterfaceRef sc)
    {
        SCSubgraphRef Subgraph_Avg = sc.Subgraph[0];
        SCInputRef Input_Data = sc.Input[0];
        SCInputRef Input_Length = sc.Input[3];

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

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

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

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

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

            return;
        }

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

        sc.LinearRegressionIndicator(sc.BaseDataIn[Input_Data.GetInputDataIndex()], Subgraph_Avg, Input_Length.GetInt());
    }

    /*==========================================================================*/
    SCSFExport scsf_MovingAverageEnvelope(SCStudyInterfaceRef sc)
    {
        SCSubgraphRef Subgraph_TopBand = sc.Subgraph[0];
        SCSubgraphRef Subgraph_BottomBand = sc.Subgraph[1];
        SCSubgraphRef Subgraph_Average = sc.Subgraph[2];

        SCInputRef Input_Data = sc.Input[0];
        SCInputRef Input_PercentageOrFixed = sc.Input[1];
        SCInputRef Input_Percentage = sc.Input[3];
        SCInputRef Input_MAType = sc.Input[4];
        SCInputRef Input_MALength = sc.Input[5];
        SCInputRef Input_FixedValue = sc.Input[7];

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

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

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

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

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

            Input_Data.Name = "Input Data";
            Input_Data.SetInputDataIndex(SC_LAST);
            Input_Data.DisplayOrder = 1;

            Input_PercentageOrFixed.Name = "Percentage or Fixed Value";
            Input_PercentageOrFixed.SetCustomInputStrings( "Percentage;Fixed Value");
            Input_PercentageOrFixed.SetCustomInputIndex( 0);
            Input_PercentageOrFixed.DisplayOrder = 2;

            Input_Percentage.Name = "Percentage (.01 = 1%)";
            Input_Percentage.SetFloat(0.005f);
            Input_Percentage.DisplayOrder = 3;

            Input_FixedValue.Name = "Fixed Value";
            Input_FixedValue.SetFloat(10.0f);
            Input_FixedValue.DisplayOrder = 4;

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

            Input_MALength.Name = "Moving Average Length";
            Input_MALength.SetInt(10);
            Input_MALength.SetIntLimits(1, MAX_STUDY_LENGTH);
            Input_MALength.DisplayOrder = 6;

            return;
        }

        sc.MovingAverage(sc.BaseDataIn[Input_Data.GetInputDataIndex()], Subgraph_Average, Input_MAType.GetMovAvgType(), Input_MALength.GetInt());

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

        if (sc.Index < sc.DataStartIndex)
            return;

        if (Input_PercentageOrFixed.GetIndex()  ==  1)//fixed value
        {
            Subgraph_TopBand[sc.Index] = Subgraph_Average[sc.Index] + Input_FixedValue.GetFloat();
            Subgraph_BottomBand[sc.Index] = Subgraph_Average[sc.Index] - Input_FixedValue.GetFloat();
        }
        else//percentage
        {
            Subgraph_TopBand[sc.Index] = Subgraph_Average[sc.Index] * (1 + Input_Percentage.GetFloat());
            Subgraph_BottomBand[sc.Index] = Subgraph_Average[sc.Index] * (1 - Input_Percentage.GetFloat());
        }
    }

    /*==========================================================================*/
    SCSFExport scsf_MarketFacilitationIndex(SCStudyInterfaceRef sc)
    {
        SCSubgraphRef Subgraph_MFI = sc.Subgraph[0];
        SCInputRef Input_Multiplier = sc.Input[0];

        if (sc.SetDefaults)
        {
            sc.GraphName = "Market Facilitation Index";

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

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

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

            return;
        }

        Subgraph_MFI[sc.Index] = Input_Multiplier.GetFloat() * (sc.High[sc.Index] - sc.Low[sc.Index]) /
                        sc.Volume[sc.Index];
    }

    /*==========================================================================*/
    SCSFExport scsf_Momentum(SCStudyInterfaceRef sc)
    {
        SCSubgraphRef Subgraph_Momentum = sc.Subgraph[0];
        SCSubgraphRef Subgraph_CenterLine = sc.Subgraph[1];
        SCInputRef Input_Data = sc.Input[0];
        SCInputRef Input_Length = sc.Input[3];
        SCInputRef Input_MomentumType = sc.Input[4];

        if (sc.SetDefaults)
        {
            sc.GraphName = "Momentum";

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

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

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

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

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

            Input_MomentumType.Name = "Momentum Type";
            Input_MomentumType.SetCustomInputStrings("Difference;Quotient");
            Input_MomentumType.SetCustomInputIndex(0);

            return;
        }

        sc.DataStartIndex = Input_Length.GetInt();

        if (sc.Index < sc.DataStartIndex)
            return;

        const int SelectedIndex = Input_MomentumType.GetIndex();
        switch (SelectedIndex)
        {
        case 0:
        {
            Subgraph_Momentum[sc.Index] = sc.BaseDataIn[Input_Data.GetInputDataIndex()][sc.Index] - sc.BaseDataIn[Input_Data.GetInputDataIndex()][sc.Index - Input_Length.GetInt()];

            Subgraph_CenterLine[sc.Index] = 0.0;
        }
        break;

        case 1:
        {
            if (sc.BaseDataIn[Input_Data.GetInputDataIndex()][sc.Index - Input_Length.GetInt()] != 0.0f)
                Subgraph_Momentum[sc.Index] = (sc.BaseDataIn[Input_Data.GetInputDataIndex()][sc.Index] / sc.BaseDataIn[Input_Data.GetInputDataIndex()][sc.Index - Input_Length.GetInt()]) * 100;
            else
                Subgraph_Momentum[sc.Index] = 0.0f;

            Subgraph_CenterLine[sc.Index] = 100.0;
        }
        break;
        }
    }

    /*==========================================================================*/
    SCSFExport scsf_OnBalanceOpenInterest(SCStudyInterfaceRef sc)
    {
        SCSubgraphRef Subgraph_OBOI = sc.Subgraph[0];
        SCInputRef Input_Length = sc.Input[3];

        if (sc.SetDefaults)
        {
            sc.GraphName = "On Balance Open Interest";

            sc.AutoLoop = 1;

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

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

            return;
        }

        sc.DataStartIndex = 1;

        if (sc.Index == 0)
            return;

        if (sc.Close[sc.Index] > sc.Close[sc.Index - 1])
            Subgraph_OBOI[sc.Index] = Subgraph_OBOI[sc.Index - 1] + sc.OpenInterest[sc.Index];
        else if (sc.Close[sc.Index] < sc.Close[sc.Index - 1])
            Subgraph_OBOI[sc.Index] = Subgraph_OBOI[sc.Index - 1] - sc.OpenInterest[sc.Index];
        else
            Subgraph_OBOI[sc.Index] = Subgraph_OBOI[sc.Index - 1];
    }

    /*==========================================================================*/
    SCSFExport scsf_RateOfChangePercentage(SCStudyInterfaceRef sc)
    {
        SCSubgraphRef Subgraph_ROC = sc.Subgraph[0];
        SCInputRef Input_Data = sc.Input[0];
        SCInputRef Input_Length = sc.Input[3];
        SCInputRef Input_MultFactor = sc.Input[4];

        if (sc.SetDefaults)
        {
            sc.GraphName = "Rate Of Change - Percentage";

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

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

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

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

            Input_MultFactor.Name = "Multiplication Factor";
            Input_MultFactor.SetFloat(100.0f);
            Input_MultFactor.SetFloatLimits(1.0f, static_cast<float>(MAX_STUDY_LENGTH));

            return;
        }

        sc.DataStartIndex = Input_Length.GetInt();

        if (sc.Index < sc.DataStartIndex)
            return;

        Subgraph_ROC[sc.Index] = (sc.BaseDataIn[Input_Data.GetInputDataIndex()][sc.Index] -
                        sc.BaseDataIn[Input_Data.GetInputDataIndex()][sc.Index - Input_Length.GetInt()]) /
                        sc.BaseDataIn[Input_Data.GetInputDataIndex()][sc.Index - Input_Length.GetInt()] * Input_MultFactor.GetFloat();
    }

    /*==========================================================================*/
    SCSFExport scsf_KeltnerChannel(SCStudyInterfaceRef sc)
    {
        SCSubgraphRef Subgraph_KeltnerAverage = sc.Subgraph[0];
        SCSubgraphRef Subgraph_TopBand = sc.Subgraph[1];
        SCSubgraphRef Subgraph_BottomBand = sc.Subgraph[2];
        SCSubgraphRef Subgraph_AtrTemp3 = sc.Subgraph[3];
        SCSubgraphRef Subgraph_AtrTemp4 = sc.Subgraph[4];

        SCInputRef Input_Data = sc.Input[0];
        SCInputRef Input_KeltnerMALength = sc.Input[3];
        SCInputRef Input_TrueRangeAvgLength = sc.Input[4];
        SCInputRef Input_TopBandMult = sc.Input[5];
        SCInputRef Input_BottomBandMult = sc.Input[6];
        SCInputRef Input_KeltnerMAType = sc.Input[7];
        SCInputRef Input_ATR_MAType = sc.Input[8];

        if (sc.SetDefaults)
        {
            sc.GraphName = "Keltner Channel";

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

            Subgraph_KeltnerAverage.Name = "Keltner Average";
            Subgraph_KeltnerAverage.DrawStyle = DRAWSTYLE_LINE;
            Subgraph_KeltnerAverage.PrimaryColor = RGB(0,255,0);
            Subgraph_KeltnerAverage.DrawZeros = true;

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

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

            Input_Data.Name = "Input Data";
            Input_Data.SetInputDataIndex(SC_OHLC_AVG);

            Input_KeltnerMALength.Name = "Keltner Mov Avg Length";
            Input_KeltnerMALength.SetInt(10);
            Input_KeltnerMALength.SetIntLimits(1, MAX_STUDY_LENGTH);

            Input_TrueRangeAvgLength.Name = "True Range Avg Length";
            Input_TrueRangeAvgLength.SetInt(10);
            Input_TrueRangeAvgLength.SetIntLimits(1, MAX_STUDY_LENGTH);

            Input_TopBandMult.Name = "Top Band Multiplier";
            Input_TopBandMult.SetFloat(1.6f);

            Input_BottomBandMult.Name="Bottom Band Multiplier";
            Input_BottomBandMult.SetFloat(1.6f);

            Input_KeltnerMAType.Name = "Keltner Mov Avg Type (Center line)";
            Input_KeltnerMAType.SetMovAvgType(MOVAVGTYPE_SIMPLE);

            Input_ATR_MAType.Name = "ATR Mov Avg Type";
            Input_ATR_MAType.SetMovAvgType(MOVAVGTYPE_WILDERS);

            return;
        }

        sc.DataStartIndex = max(Input_KeltnerMALength.GetInt(), Input_TrueRangeAvgLength.GetInt());

        sc.MovingAverage(sc.BaseDataIn[static_cast<int>(Input_Data.GetInputDataIndex())], Subgraph_KeltnerAverage, Input_KeltnerMAType.GetMovAvgType(), Input_KeltnerMALength.GetInt());

        sc.ATR(sc.BaseDataIn, Subgraph_AtrTemp3, Input_TrueRangeAvgLength.GetInt(), Input_ATR_MAType.GetMovAvgType());
        sc.ATR(sc.BaseDataIn, Subgraph_AtrTemp4, Input_TrueRangeAvgLength.GetInt(), Input_ATR_MAType.GetMovAvgType());

        Subgraph_TopBand[sc.Index] = Subgraph_AtrTemp3[sc.Index] * Input_TopBandMult.GetFloat() + Subgraph_KeltnerAverage[sc.Index];
        Subgraph_BottomBand[sc.Index] = Subgraph_KeltnerAverage[sc.Index] - (Subgraph_AtrTemp4[sc.Index] * Input_BottomBandMult.GetFloat());
    }

    /*==========================================================================*/
    SCSFExport scsf_OnBalanceVolumeShortTerm(SCStudyInterfaceRef sc)
    {
        SCSubgraphRef Subgraph_OBV = sc.Subgraph[0];
        SCInputRef Input_Length = sc.Input[3];

        if (sc.SetDefaults)
        {
            sc.GraphName = "On Balance Volume - Short Term";

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

            Subgraph_OBV.Name = "OBV Length";
            Subgraph_OBV.DrawStyle = DRAWSTYLE_LINE;
            Subgraph_OBV.PrimaryColor = RGB(0,255,0);
            Subgraph_OBV.DrawZeros = true;

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

            return;
        }

        sc.OnBalanceVolumeShortTerm(sc.BaseDataIn, Subgraph_OBV, Input_Length.GetInt());
    }

    /*==========================================================================*/
    SCSFExport scsf_RSI(SCStudyInterfaceRef sc)
    {
        SCSubgraphRef Subgraph_RSI = sc.Subgraph[0];
        SCSubgraphRef Subgraph_Line1 = sc.Subgraph[1];
        SCSubgraphRef Subgraph_Line2 = sc.Subgraph[2];
        SCSubgraphRef Subgraph_RSIAvg = sc.Subgraph[3];

        SCInputRef Input_Data = sc.Input[0];
        SCInputRef Input_RSILength = sc.Input[3];
        SCInputRef Input_RSI_MALength = sc.Input[4];
        SCInputRef Input_Line1Value = sc.Input[5];
        SCInputRef Input_Line2Value = sc.Input[6];
        SCInputRef Input_AvgType = sc.Input[7];
        SCInputRef Input_UseRSIMinus50 = sc.Input[8];

        if (sc.SetDefaults)
        {
            sc.GraphName = "RSI";
            sc.GraphRegion = 1;
            sc.ValueFormat = 2;
            sc.AutoLoop = 1;

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

            Subgraph_RSIAvg.Name = "RSI Avg";
            Subgraph_RSIAvg.DrawStyle = DRAWSTYLE_LINE;
            Subgraph_RSIAvg.PrimaryColor = RGB(255, 127, 0);
            Subgraph_RSIAvg.DrawZeros = true;

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

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

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

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

            Input_RSI_MALength.Name = "RSI Mov Avg Length";
            Input_RSI_MALength.SetInt(3);
            Input_RSI_MALength.SetIntLimits(1, MAX_STUDY_LENGTH);

            Input_UseRSIMinus50.Name = "Use RSI - 50";
            Input_UseRSIMinus50.SetYesNo(0);

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

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

            Input_AvgType.Name = "Average Type";
            Input_AvgType.SetMovAvgType(MOVAVGTYPE_SIMPLE);

            return;
        }

        sc.DataStartIndex = (Input_RSILength.GetInt() + Input_RSI_MALength.GetInt());

        sc.RSI(sc.BaseDataIn[Input_Data.GetInputDataIndex()], Subgraph_RSI, Input_AvgType.GetMovAvgType(), Input_RSILength.GetInt());

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

        if (Input_UseRSIMinus50.GetYesNo() == 1)
        {
            Subgraph_RSI[sc.Index] = Subgraph_RSI[sc.Index] - 50.0f;
            Subgraph_Line1[sc.Index] = Input_Line1Value.GetFloat() - 50.0f;
            Subgraph_Line2[sc.Index] = Input_Line2Value.GetFloat() - 50.0f;
        }

        sc.MovingAverage(Subgraph_RSI, Subgraph_RSIAvg, Input_AvgType.GetMovAvgType(), Input_RSI_MALength.GetInt());
    }

    /*==========================================================================*/
    SCSFExport scsf_AdaptiveRSIMovingAverage(SCStudyInterfaceRef sc)
    {
        SCSubgraphRef Subgraph_ARSI = sc.Subgraph[0];
        SCSubgraphRef Subgraph_RSI  = sc.Subgraph[1];  // subgraph and arrays used for base RSI calc

        SCFloatArrayRef Array_Price       = Subgraph_ARSI.Arrays[0];
        SCFloatArrayRef Array_RSISmoothed = Subgraph_ARSI.Arrays[1];

        SCInputRef Input_ARSIPeriod           = sc.Input[0];
        SCInputRef Input_ARSIMAType           = sc.Input[1];
        SCInputRef Input_Data                 = sc.Input[2];
        SCInputRef Input_PriceSetSmoothing    = sc.Input[3];
        SCInputRef Input_PriceSmoothingPeriod = sc.Input[4];
        SCInputRef Input_PriceSmoothingMAType = sc.Input[5];
        SCInputRef Input_RSISetSmoothing      = sc.Input[6];
        SCInputRef Input_RSISmoothingPeriod   = sc.Input[7];
        SCInputRef Input_RSISmoothingMAType   = sc.Input[8];
        SCInputRef Input_ARSIScaleFactor      = sc.Input[9];

        if (sc.SetDefaults)
        {
            sc.GraphName = "Adaptive RSI Moving Average With Smoothing";

            // Data for the "Display Study Documentation" button
            sc.StudyDescription = "Adaptive RSI Moving Average With Smoothing. Traditional Adaptive RSI (ARSI) uses straight price and then RSI as the scaling factor without smoothing. The \"Set Price Smoothing?\" option enables cleaning up the price before calculations. If price is really noisy, recommended settings are EMA 3-10. Otherwise leave price smoothing off. The \"Set RSI Smoothing?\" option enables cleaning up some of the RSI noise before ARSI is calculated. It is recommended to smooth RSI out with an EMA 3-7. This allows for less volatility and more consistent movements.<p>To use traditional ARSI without any enhancements, turn off both smoothing options.<p>Observations: When there's a strong reversal, ARSI will go flat and then bend to follow the price. On weaker events, ARSI will go flat while price bounces around above or below and then returns to the ARSI line. Check indicators and wave counts to verify final motion.<p>To visualize what the scaling factor is doing, a separate RSI graph can be added with the selected smoothing values. When RSI is close to 50, the ARSI line will go flat and move less. Further away from 50 will increase the line movement.";

            sc.StudyVersion = 1;
            sc.GraphRegion = 0; // main price graph

            sc.AutoLoop = 1;    // auto looping is enabled

            // subgraphs
            Subgraph_ARSI.Name = "ARSI";
            Subgraph_ARSI.PrimaryColor = RGB(0, 0, 255);
            Subgraph_ARSI.DrawStyle = DRAWSTYLE_LINE;
            Subgraph_ARSI.LineStyle = LINESTYLE_SOLID;
            Subgraph_ARSI.LineWidth = 2;
            Subgraph_ARSI.DrawZeros = 0;

            // inputs
            Input_ARSIPeriod.Name = "ARSI Period";
            Input_ARSIPeriod.SetInt(35);
            Input_ARSIPeriod.SetIntLimits(3, 300);
            Input_ARSIPeriod.SetDescription("Number of bars for the period. Useful values are 25 and higher.");

            Input_ARSIMAType.Name = "ARSI Moving Average Type";
            Input_ARSIMAType.SetMovAvgType(MOVAVGTYPE_EXPONENTIAL);
            Input_ARSIMAType.SetDescription("Moving average for the base RSI calculation.");

            Input_ARSIScaleFactor.Name = "ARSI Scale Factor";
            Input_ARSIScaleFactor.SetFloat(1.0f);
            Input_ARSIScaleFactor.SetFloatLimits(0.1f, 200.0f);
            Input_ARSIScaleFactor.SetDescription("Additional Scale Factor for Adaptive calculation.");

            Input_Data.Name = "Input Data";
            Input_Data.SetInputDataIndex(SC_LAST); //default to bar close.
            Input_Data.SetDescription("Usually \"Last\" for bar close when viewing stock prices. One of the averages can be used for forex and other less time synchronized data.");

            Input_PriceSetSmoothing.Name = "Set Price Smoothing";
            Input_PriceSetSmoothing.SetYesNo(0);
            Input_PriceSetSmoothing.SetDescription("Enables extended price smoothing options.");

            Input_PriceSmoothingPeriod.Name = "Price Smoothing Period";
            Input_PriceSmoothingPeriod.SetInt(3);
            Input_PriceSmoothingPeriod.SetIntLimits(2, 50);
            Input_PriceSmoothingPeriod.SetDescription("Number of bars for the period. Usually 3-10.");

            Input_PriceSmoothingMAType.Name = "Price Smoothing Moving Average Type";
            Input_PriceSmoothingMAType.SetMovAvgType(MOVAVGTYPE_EXPONENTIAL);
            Input_PriceSmoothingMAType.SetDescription("Usually EMA, but others can be experimented with.");

            Input_RSISetSmoothing.Name = "Set RSI Smoothing";
            Input_RSISetSmoothing.SetYesNo(1);
            Input_RSISetSmoothing.SetDescription("Enables extended RSI smoothing options.");

            Input_RSISmoothingPeriod.Name = "RSI Smoothing Period";
            Input_RSISmoothingPeriod.SetInt(5);
            Input_RSISmoothingPeriod.SetIntLimits(2, 50);
            Input_RSISmoothingPeriod.SetDescription("Number of bars for the period. Usually 3-7.");

            Input_RSISmoothingMAType.Name = "RSI Smoothing Moving Average Type";
            Input_RSISmoothingMAType.SetMovAvgType(MOVAVGTYPE_EXPONENTIAL);
            Input_RSISmoothingMAType.SetDescription("Usually EMA, but others can be experimented with.");

            //Set printed output value format. Number is the index of the selected format.
            sc.ValueFormat = sc.BaseGraphValueFormat;

            return;
        }

        if (sc.Index == 0)
        {
            // Set the index of the first array element to begin drawing at
            sc.DataStartIndex = Input_ARSIPeriod.GetInt() - 1;
        }

        // Handle price smoothing.
        if (Input_PriceSetSmoothing.GetYesNo())
        {
            sc.MovingAverage(sc.BaseDataIn[Input_Data.GetInputDataIndex()], Array_Price, Input_PriceSmoothingMAType.GetMovAvgType(), Input_PriceSmoothingPeriod.GetInt() );
        }
        else
        {
            Array_Price[sc.Index] = sc.BaseDataIn[Input_Data.GetInputDataIndex()][sc.Index];
        }

        // Not enough data yet. Pre-load existing data into array for later calculations.
        if (sc.Index < Input_ARSIPeriod.GetInt())
        {
            Subgraph_ARSI[sc.Index] = Array_Price[sc.Index];
            return;
        }

        // Do the ARSI calculations.

        sc.RSI(Array_Price, Subgraph_RSI, Input_ARSIMAType.GetMovAvgType(), Input_ARSIPeriod.GetInt());

        float ScalingFactor=0;

        if (Input_RSISetSmoothing.GetYesNo())
        {
            sc.MovingAverage(Subgraph_RSI, Array_RSISmoothed, Input_RSISmoothingMAType.GetMovAvgType(), Input_RSISmoothingPeriod.GetInt());
            ScalingFactor = ((Array_RSISmoothed[sc.Index] / 100.0f) - 0.5f) * 2.0f; //range -1.0 to 1.0
            //Note that a MA may overshoot the range a little. For this it doesn't matter.
        }
        else
        {
            ScalingFactor = ((Subgraph_RSI[sc.Index] / 100.0f) - 0.5f) * 2.0f; //range -1.0 to 1.0
        }

        ScalingFactor *= Input_ARSIScaleFactor.GetFloat();

        if (ScalingFactor < 0.0f)
        {
            ScalingFactor *= -1.0f; //range must be positive for the next calculation
        }

        Subgraph_ARSI[sc.Index] = ((Array_Price[sc.Index] - Subgraph_ARSI[sc.Index-1]) * ScalingFactor) + Subgraph_ARSI[sc.Index-1];
    }

    /*==========================================================================*/
    SCSFExport scsf_RSI_W(SCStudyInterfaceRef sc)
    {
        SCSubgraphRef Subgraph_RSIW = sc.Subgraph[0];
        SCSubgraphRef Subgraph_Line1 = sc.Subgraph[1];
        SCSubgraphRef Subgraph_Line2 = sc.Subgraph[2];
        SCSubgraphRef Subgraph_RSIWAvg = sc.Subgraph[3];

        SCInputRef Input_Data = sc.Input[0];
        SCInputRef Input_RSILength = sc.Input[3];
        SCInputRef Input_RSI_MALength = sc.Input[4];
        SCInputRef Input_Line1Value = sc.Input[5];
        SCInputRef Input_Line2Value = sc.Input[6];
        SCInputRef Input_AvgType = sc.Input[7];
        SCInputRef Input_UseRSIMinus50 = sc.Input[8];

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

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

            Subgraph_RSIW.Name = "RSI-W";
            Subgraph_RSIW.DrawStyle = DRAWSTYLE_LINE;
            Subgraph_RSIW.PrimaryColor = RGB(0,255,0);
            Subgraph_RSIW.DrawZeros = true;

            Subgraph_RSIWAvg.Name = "RSI-W Avg";
            Subgraph_RSIWAvg.DrawStyle = DRAWSTYLE_LINE;
            Subgraph_RSIWAvg.PrimaryColor = RGB(255, 127, 0);
            Subgraph_RSIWAvg.DrawZeros = true;

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

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

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

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

            Input_RSI_MALength.Name = "RSI Mov Avg Length";
            Input_RSI_MALength.SetInt(3);
            Input_RSI_MALength.SetIntLimits(1, MAX_STUDY_LENGTH);

            Input_UseRSIMinus50.Name = "Use RSI - 50";
            Input_UseRSIMinus50.SetYesNo(0);

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

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

            Input_AvgType.Name = "Average Type";
            Input_AvgType.SetMovAvgType(MOVAVGTYPE_WILDERS);

            return;
        }

        sc.DataStartIndex = (Input_RSILength.GetInt() + Input_RSI_MALength.GetInt());

        sc.RSI(sc.BaseDataIn[Input_Data.GetInputDataIndex()], Subgraph_RSIW, Input_AvgType.GetMovAvgType(), Input_RSILength.GetInt());

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

        if (Input_UseRSIMinus50.GetYesNo() == 1)
        {
            Subgraph_RSIW[sc.Index] = Subgraph_RSIW[sc.Index] - 50.0f;
            Subgraph_Line1[sc.Index] = Input_Line1Value.GetFloat() - 50.0f;
            Subgraph_Line2[sc.Index] = Input_Line2Value.GetFloat() - 50.0f;
        }

        sc.MovingAverage(Subgraph_RSIW, Subgraph_RSIWAvg, Input_AvgType.GetMovAvgType(), Input_RSI_MALength.GetInt());
    }

    /*==========================================================================*/
    SCSFExport scsf_AccumulationDistributionFlow(SCStudyInterfaceRef sc)
    {
        SCSubgraphRef Subgraph_AccumulationDistribution = sc.Subgraph[0];
        SCSubgraphRef Subgraph_ADFlowAvg = sc.Subgraph[1];
        SCInputRef Input_MALength = sc.Input[3];
        SCInputRef Input_UsePrevClose = sc.Input[4];

        if (sc.SetDefaults)
        {
            sc.GraphName = "Accumulation/Distribution Flow";

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

            Subgraph_AccumulationDistribution.Name = "A/D Flow";
            Subgraph_AccumulationDistribution.DrawStyle = DRAWSTYLE_LINE;
            Subgraph_AccumulationDistribution.PrimaryColor = RGB(0,255,0);
            Subgraph_AccumulationDistribution.DrawZeros = true;

            Subgraph_ADFlowAvg.Name = "A/D Flow Avg";
            Subgraph_ADFlowAvg.DrawStyle = DRAWSTYLE_LINE;
            Subgraph_ADFlowAvg.PrimaryColor = RGB(255,0,255);
            Subgraph_ADFlowAvg.DrawZeros = true;

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

            Input_UsePrevClose.Name = "Use Previous Close";
            Input_UsePrevClose.SetYesNo(true);

            return;
        }

        sc.DataStartIndex = Input_MALength.GetInt();

        if (sc.Index == 0)
        {
            Subgraph_AccumulationDistribution[sc.Index] = 5000.0f;
            return;
        }

        float OpenOrClose = 0.0f;
        if (Input_UsePrevClose.GetYesNo())
        {
            OpenOrClose = sc.Close[sc.Index - 1];
        }
        else
        {
            OpenOrClose = sc.Open[sc.Index];
        }

        if (sc.High[sc.Index] - sc.Low[sc.Index] == 0.0f)
        {
            Subgraph_AccumulationDistribution[sc.Index] = Subgraph_AccumulationDistribution[sc.Index - 1];
        }
        else
        {
            Subgraph_AccumulationDistribution[sc.Index] = ((sc.Close[sc.Index] - OpenOrClose) / (sc.High[sc.Index] - sc.Low[sc.Index]) *
                sc.Volume[sc.Index]) + Subgraph_AccumulationDistribution[sc.Index - 1];
        }

        sc.SimpleMovAvg(Subgraph_AccumulationDistribution, Subgraph_ADFlowAvg, Input_MALength.GetInt());
    }

    /*==========================================================================*/
    SCSFExport scsf_AccumulationDistribution(SCStudyInterfaceRef sc)
    {

        //Subgraph references
        SCSubgraphRef Subgraph_AccumulationDistribution = sc.Subgraph[0];

        if (sc.SetDefaults)
        {
            sc.GraphName = "Accumulation/Distribution";

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

            Subgraph_AccumulationDistribution.Name = "A/D";
            Subgraph_AccumulationDistribution.DrawStyle = DRAWSTYLE_LINE;
            Subgraph_AccumulationDistribution.PrimaryColor = RGB(0,255,0);
            Subgraph_AccumulationDistribution.DrawZeros = true;

            return;
        }

        sc.DataStartIndex = 0;

        float RangeVolume = (sc.High[sc.Index] - sc.Low[sc.Index]) * sc.Volume[sc.Index];

        //In the case where RangeVolume equals 0 at sc.Index = 0, then AccumulationDistribution[sc.Index-1] is going to equal 0. Otherwise, it is the prior AccumulationDistribution value.
        if(RangeVolume == 0)
            Subgraph_AccumulationDistribution[sc.Index] = Subgraph_AccumulationDistribution[sc.Index - 1];
        else
            // Accumulation/Distribution = ((Close - Low) - (High - Close)) / (High - Low) * Bar Volume
            Subgraph_AccumulationDistribution[sc.Index] = ((sc.Close[sc.Index] - sc.Low[sc.Index]) - (sc.High[sc.Index] - sc.Close[sc.Index])) /  RangeVolume;

    }

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

        SCFloatArrayRef Array_High = sc.High;
        SCFloatArrayRef Array_Low = sc.Low;
        SCFloatArrayRef Array_Volume = sc.Volume;

        if (sc.SetDefaults)
        {
            sc.GraphName = "Volume Bar Range Ratio";

            sc.StudyDescription = "Formula: Volume / (High - Low)";
            sc.AutoLoop = 1;

            Subgraph_Ratio.Name = "Ratio";
            Subgraph_Ratio.DrawStyle = DRAWSTYLE_BAR;
            Subgraph_Ratio.PrimaryColor = RGB(0,255,0);

            return;
        }

        float Range = Array_High[sc.Index] - Array_Low[sc.Index];

        if (Range>0.0)
            Subgraph_Ratio[sc.Index] = Array_Volume[sc.Index] / Range;
        else//If we have no range, then use the prior calculated value.
            Subgraph_Ratio[sc.Index] = Subgraph_Ratio[sc.Index-1];

    }

    /*==========================================================================*/
    SCSFExport scsf_MovingAverages(SCStudyInterfaceRef sc)
    {
        SCSubgraphRef Subgraph_Avg1 = sc.Subgraph[0];
        SCSubgraphRef Subgraph_Avg2 = sc.Subgraph[1];
        SCSubgraphRef Subgraph_Avg3 = sc.Subgraph[2];

        SCInputRef Input_MAType1 = sc.Input[0];
        SCInputRef Input_Data1 = sc.Input[1];
        SCInputRef Input_Length1 = sc.Input[2];

        SCInputRef Input_MAType2 = sc.Input[3];
        SCInputRef Input_Data2 = sc.Input[4];
        SCInputRef Input_Length2 = sc.Input[5];

        SCInputRef Input_MAType3 = sc.Input[6];
        SCInputRef Input_Data3 = sc.Input[7];
        SCInputRef Input_Length3 = sc.Input[8];

        SCInputRef Input_Version = sc.Input[12];

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

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

            Subgraph_Avg1.Name = "Avg1";
            Subgraph_Avg1.DrawStyle = DRAWSTYLE_LINE;
            Subgraph_Avg1.PrimaryColor = RGB(0,255,0);

            Subgraph_Avg2.Name = "Avg2";
            Subgraph_Avg2.DrawStyle = DRAWSTYLE_LINE;
            Subgraph_Avg2.PrimaryColor = RGB(255,0,255);

            Subgraph_Avg3.Name = "Avg3";
            Subgraph_Avg3.DrawStyle = DRAWSTYLE_LINE;
            Subgraph_Avg3.PrimaryColor = RGB(255,255,0);

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

            Input_Data1.Name = "Input Data 1";
            Input_Data1.SetInputDataIndex(SC_LAST);

            Input_Length1.Name = "Length 1";
            Input_Length1.SetInt(5);
            Input_Length1.SetIntLimits(1, INT_MAX);

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

            Input_Data2.Name = "Input Data 2";
            Input_Data2.SetInputDataIndex(SC_LAST);

            Input_Length2.Name = "Length 2";
            Input_Length2.SetInt(10);
            Input_Length2.SetIntLimits(1, INT_MAX);

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

            Input_Data3.Name = "Input Data 3";
            Input_Data3.SetInputDataIndex(SC_LAST);

            Input_Length3.Name = "Length 3";
            Input_Length3.SetInt(15);
            Input_Length3.SetIntLimits(1, INT_MAX);

            Input_Version.SetInt(2);

            return;
        }

        if (Input_Version.GetInt() < 2)
        {
            uint32_t OldInputData = sc.Input[0].GetInputDataIndex();
            int OldLength1 = sc.Input[3].GetInt();
            int OldLength2 = sc.Input[4].GetInt();
            int OldLength3 = sc.Input[5].GetInt();
            uint32_t OldMAtype = sc.Input[7].GetMovAvgType();

            Input_MAType1.SetMovAvgType(OldMAtype);
            Input_Data1.SetInputDataIndex(OldInputData);
            Input_Length1.SetInt(OldLength1);

            Input_MAType2.SetMovAvgType(OldMAtype);
            Input_Data2.SetInputDataIndex(OldInputData);
            Input_Length2.SetInt(OldLength2);

            Input_MAType3.SetMovAvgType(OldMAtype);
            Input_Data3.SetInputDataIndex(OldInputData);
            Input_Length3.SetInt(OldLength3);

            Input_Version.SetInt(2);
        }

        //
        if(Input_Length1.GetInt()  <= 0)
        {
            Input_Length1.SetInt(10);
            Input_MAType1.SetMovAvgType(MOVAVGTYPE_SIMPLE);
            Input_Data1.SetInputDataIndex(SC_LAST);
        }

        if(Input_Length2.GetInt() <= 0)
        {
            Input_Length2.SetInt(20);
            Input_MAType2.SetMovAvgType(MOVAVGTYPE_SIMPLE);
            Input_Data2.SetInputDataIndex(SC_LAST);
        }

        if(Input_Length3.GetInt()  <= 0)
        {
            Input_Length3.SetInt(50);
            Input_MAType3.SetMovAvgType(MOVAVGTYPE_SIMPLE);
            Input_Data3.SetInputDataIndex(SC_LAST);
        }

        sc.DataStartIndex = max(Input_Length3.GetInt(), max(Input_Length1.GetInt(), Input_Length2.GetInt()));

        sc.MovingAverage(sc.BaseDataIn[Input_Data1.GetInputDataIndex()], Subgraph_Avg1, Input_MAType1.GetMovAvgType(), Input_Length1.GetInt());
        sc.MovingAverage(sc.BaseDataIn[Input_Data2.GetInputDataIndex()], Subgraph_Avg2, Input_MAType2.GetMovAvgType(), Input_Length2.GetInt());
        sc.MovingAverage(sc.BaseDataIn[Input_Data3.GetInputDataIndex()], Subgraph_Avg3, Input_MAType3.GetMovAvgType(), Input_Length3.GetInt());
    }

    /*==========================================================================*/
    SCSFExport scsf_MovingAverageCrossover(SCStudyInterfaceRef sc)
    {
        SCSubgraphRef Subgraph_Avg1 = sc.Subgraph[0];
        SCSubgraphRef Subgraph_Avg2 = sc.Subgraph[1];
        SCSubgraphRef Subgraph_CrossFromBottom = sc.Subgraph[2];
        SCSubgraphRef Subgraph_CrossFromTop = sc.Subgraph[3];

        SCInputRef Input_MAType1 = sc.Input[0];
        SCInputRef Input_Data1 = sc.Input[1];
        SCInputRef Input_Length1 = sc.Input[2];

        SCInputRef Input_MAType2 = sc.Input[3];
        SCInputRef Input_Data2 = sc.Input[4];
        SCInputRef Input_Length2 = sc.Input[5];

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

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

            Subgraph_Avg1.Name = "Avg1";
            Subgraph_Avg1.DrawStyle = DRAWSTYLE_LINE;
            Subgraph_Avg1.PrimaryColor = RGB(0,255,0);

            Subgraph_Avg2.Name = "Avg2";
            Subgraph_Avg2.DrawStyle = DRAWSTYLE_LINE;
            Subgraph_Avg2.PrimaryColor = RGB(255,0,255);

            Subgraph_CrossFromBottom.Name = "Cross From Bottom";
            Subgraph_CrossFromBottom.DrawStyle = DRAWSTYLE_ARROW_UP;
            Subgraph_CrossFromBottom.PrimaryColor = RGB(0,255,0);
            Subgraph_CrossFromBottom.LineWidth = 2;

            Subgraph_CrossFromTop.Name = "Cross From Top";
            Subgraph_CrossFromTop.DrawStyle = DRAWSTYLE_ARROW_DOWN;
            Subgraph_CrossFromTop.PrimaryColor = RGB(255,0,255);
            Subgraph_CrossFromTop.LineWidth = 2;

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

            Input_Data1.Name = "Input Data 1";
            Input_Data1.SetInputDataIndex(SC_LAST);

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

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

            Input_Data2.Name = "Input Data 2";
            Input_Data2.SetInputDataIndex(SC_LAST);

            Input_Length2.Name = "Length 2";
            Input_Length2.SetInt(20);
            Input_Length2.SetIntLimits(1, MAX_STUDY_LENGTH);
            return;
        }

        sc.DataStartIndex = max(Input_Length1.GetInt(), Input_Length2.GetInt());

        sc.MovingAverage(sc.BaseDataIn[Input_Data1.GetInputDataIndex()], Subgraph_Avg1, Input_MAType1.GetMovAvgType(), Input_Length1.GetInt());
        sc.MovingAverage(sc.BaseDataIn[Input_Data2.GetInputDataIndex()], Subgraph_Avg2, Input_MAType2.GetMovAvgType(), Input_Length2.GetInt());

        if(Input_Length1.GetInt() <= Input_Length2.GetInt() && sc.CrossOver(Subgraph_Avg1, Subgraph_Avg2) == CROSS_FROM_TOP)//Sell
        {
            Subgraph_CrossFromBottom[sc.Index] = 0;
            Subgraph_CrossFromTop[sc.Index] = sc.High[sc.Index];
        }
        else if(Input_Length1.GetInt() <= Input_Length2.GetInt() && sc.CrossOver(Subgraph_Avg1, Subgraph_Avg2) == CROSS_FROM_BOTTOM)//Buy
        {
            Subgraph_CrossFromBottom[sc.Index] = sc.Low[sc.Index];
            Subgraph_CrossFromTop[sc.Index] = 0;
        }
        else if(Input_Length1.GetInt() > Input_Length2.GetInt() && sc.CrossOver(Subgraph_Avg1, Subgraph_Avg2) == CROSS_FROM_TOP)//Buy
        {
            Subgraph_CrossFromBottom[sc.Index] = sc.Low[sc.Index];
            Subgraph_CrossFromTop[sc.Index] = 0;
        }
        else if(Input_Length1.GetInt() > Input_Length2.GetInt() && sc.CrossOver(Subgraph_Avg1, Subgraph_Avg2) == CROSS_FROM_BOTTOM)//Sell
        {
            Subgraph_CrossFromBottom[sc.Index] = 0;
            Subgraph_CrossFromTop[sc.Index] = sc.High[sc.Index];
        }
        else
        {
            Subgraph_CrossFromBottom[sc.Index] = 0;
            Subgraph_CrossFromTop[sc.Index] = 0;
        }
    }
    /*==========================================================================*/
    SCSFExport scsf_STIX(SCStudyInterfaceRef sc)
    {
        SCSubgraphRef Subgraph_STIX = sc.Subgraph[0];
        SCInputRef Input_DecliningIssuesSymbolStudy = sc.Input[0];

        if (sc.SetDefaults)
        {
            sc.GraphName = "STIX";
            sc.GraphRegion = 1;
            sc.ValueFormat = 0;

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

            Input_DecliningIssuesSymbolStudy.Name = "Declining Issues Add Additional Symbol Study";
            Input_DecliningIssuesSymbolStudy.SetStudyID(1);

            return;
        }

        SCFloatArray Chart2Array;
        sc.GetStudyArrayUsingID(Input_DecliningIssuesSymbolStudy.GetStudyID(), SC_LAST, Chart2Array);

        if (Chart2Array.GetArraySize() == 0)
            return;

        for (int BarIndex = sc.UpdateStartIndex; BarIndex < sc.ArraySize; BarIndex++)
        {
            if (sc.Close[BarIndex] == 0 || Chart2Array[BarIndex] == 0)
            {
                Subgraph_STIX[BarIndex] = Subgraph_STIX[BarIndex - 1];
            }
            else
            {
                Subgraph_STIX[BarIndex] = sc.Close[BarIndex] / (sc.Close[BarIndex] + Chart2Array[BarIndex]) * 9.0f +
                    (Subgraph_STIX[BarIndex - 1] * 0.91f);
            }
        }
    }

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

        SCInputRef Input_Data = 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 = "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_Data.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()) - 1;

        sc.MovingAverage(sc.BaseDataIn[Input_Data.GetInputDataIndex()], Subgraph_AO.Arrays[0], Input_MAType.GetMovAvgType(), Input_MA1Length.GetInt());
        sc.MovingAverage(sc.BaseDataIn[Input_Data.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_MovingAverageDifference(SCStudyInterfaceRef sc)
    {
        SCSubgraphRef Subgraph_MovAvgDiff = sc.Subgraph[0];
        SCInputRef Input_Data = sc.Input[0];
        SCInputRef Input_MA1Length = sc.Input[2];
        SCInputRef Input_MA2Length = sc.Input[3];
        SCInputRef Input_MovAvgType = sc.Input[4];
        SCInputRef Input_Version = sc.Input[5];

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

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

            Subgraph_MovAvgDiff.Name = "MovAvg Diff";
            Subgraph_MovAvgDiff.DrawStyle = DRAWSTYLE_BAR;
            Subgraph_MovAvgDiff.SecondaryColor = RGB(255,0,0);
            Subgraph_MovAvgDiff.AutoColoring = AUTOCOLOR_SLOPE;
            Subgraph_MovAvgDiff.DrawZeros = true;

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

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

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

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

            Input_Version.SetInt(1);

            return;
        }

        if(Input_Version.GetInt() < 1)
        {
            Input_MovAvgType.SetMovAvgType(MOVAVGTYPE_SIMPLE);
            Input_Version.SetInt(1);
        }

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

        sc.MovingAverage(sc.BaseDataIn[Input_Data.GetInputDataIndex()], Subgraph_MovAvgDiff.Arrays[0], Input_MovAvgType.GetMovAvgType(), Input_MA1Length.GetInt());
        sc.MovingAverage(sc.BaseDataIn[Input_Data.GetInputDataIndex()], Subgraph_MovAvgDiff.Arrays[1], Input_MovAvgType.GetMovAvgType(), Input_MA2Length.GetInt());
        Subgraph_MovAvgDiff[sc.Index] = Subgraph_MovAvgDiff.Arrays[0][sc.Index] - Subgraph_MovAvgDiff.Arrays[1][sc.Index];
    }

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

    SCSFExport scsf_Volume(SCStudyInterfaceRef sc)
    {
        SCSubgraphRef Subgraph_Volume = sc.Subgraph[0];

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

            sc.ValueFormat = 0;
            sc.AutoLoop = false;
            sc.ScaleRangeType = SCALE_ZEROBASED;

            Subgraph_Volume.Name = "Volume";
            Subgraph_Volume.DrawStyle = DRAWSTYLE_BAR;
            Subgraph_Volume.AutoColoring = AUTOCOLOR_BASEGRAPH;
            Subgraph_Volume.PrimaryColor = RGB(0, 255, 0);
            Subgraph_Volume.SecondaryColor = RGB(255, 0, 0);
            Subgraph_Volume.DrawZeros = false;
            Subgraph_Volume.LineWidth = 2;

            sc.DisplayStudyInputValues = false;

            return;
        }

        int CalculationStartIndex = sc.GetCalculationStartIndexForStudy();
        if (CalculationStartIndex > sc.UpdateStartIndex)
            CalculationStartIndex = sc.UpdateStartIndex;

        for (int BarIndex = CalculationStartIndex; BarIndex < sc.ArraySize; BarIndex++)
        {
            Subgraph_Volume[BarIndex] = sc.Volume[BarIndex];
        }

    }

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

    SCSFExport scsf_VolumeWithZeroColor(SCStudyInterfaceRef sc)
    {
        SCSubgraphRef Subgraph_Volume = sc.Subgraph[0];
        SCSubgraphRef Subgraph_NoPriceChangeColor = sc.Subgraph[1];

        if (sc.SetDefaults)
        {
            sc.GraphName = "Volume with 0 Color";

            sc.ValueFormat = 0;
            sc.AutoLoop = true;
            sc.ScaleRangeType = SCALE_ZEROBASED;

            Subgraph_Volume.Name = "Volume";
            Subgraph_Volume.DrawStyle = DRAWSTYLE_BAR;
            Subgraph_Volume.PrimaryColor = RGB(0, 255, 0);
            Subgraph_Volume.SecondaryColor = RGB(255, 0, 0);
            Subgraph_Volume.SecondaryColorUsed = true;
            Subgraph_Volume.DrawZeros = false;
            Subgraph_Volume.LineWidth = 2;

            Subgraph_NoPriceChangeColor.Name = "No Price Change Color";
            Subgraph_NoPriceChangeColor.DrawStyle = DRAWSTYLE_CUSTOM_TEXT;
            Subgraph_NoPriceChangeColor.PrimaryColor = RGB(0, 255, 0);
            Subgraph_NoPriceChangeColor.DrawZeros = false;
            Subgraph_NoPriceChangeColor.DisplayNameValueInWindowsFlags = 0;
            sc.DisplayStudyInputValues = false;

            return;
        }

        Subgraph_Volume[sc.Index] = sc.Volume[sc.Index];

        if(sc.FormattedEvaluate(sc.BaseData[SC_OPEN][sc.Index], sc.BaseGraphValueFormat, LESS_OPERATOR, sc.BaseData[SC_LAST][sc.Index], sc.BaseGraphValueFormat) )
            Subgraph_Volume.DataColor[sc.Index] =   Subgraph_Volume.PrimaryColor;
        else if(sc.FormattedEvaluate(sc.BaseData[SC_OPEN][sc.Index], sc.BaseGraphValueFormat, GREATER_OPERATOR, sc.BaseData[SC_LAST][sc.Index], sc.BaseGraphValueFormat) )
            Subgraph_Volume.DataColor[sc.Index] =   Subgraph_Volume.SecondaryColor;
        else
            Subgraph_Volume.DataColor[sc.Index] =   Subgraph_NoPriceChangeColor.PrimaryColor;
    }

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

    SCSFExport scsf_VolumeColoredBasedOnBarCloses(SCStudyInterfaceRef sc)
    {
        SCSubgraphRef Subgraph_Volume = sc.Subgraph[0];

        if (sc.SetDefaults)
        {
            sc.GraphName = "Volume-Colored Based on Bar Closes";

            sc.ValueFormat = 0;

            sc.AutoLoop = true;
            sc.ScaleRangeType = SCALE_ZEROBASED;

            Subgraph_Volume.Name = "Volume";
            Subgraph_Volume.DrawStyle = DRAWSTYLE_BAR;
            Subgraph_Volume.PrimaryColor = RGB(0, 255, 0);
            Subgraph_Volume.SecondaryColor = RGB(255, 0, 0);
            Subgraph_Volume.SecondaryColorUsed = 1;
            Subgraph_Volume.LineWidth = 2;
            Subgraph_Volume.DrawZeros = false;

            sc.DisplayStudyInputValues = false;

            return;
        }

        Subgraph_Volume[sc.Index] = sc.Volume[sc.Index];

        if (sc.FormattedEvaluate(sc.Close[sc.Index], sc.BaseGraphValueFormat, GREATER_EQUAL_OPERATOR, sc.Close[sc.Index - 1], sc.BaseGraphValueFormat))
        {
            Subgraph_Volume.DataColor[sc.Index] = Subgraph_Volume.PrimaryColor;
        }
        else
            Subgraph_Volume.DataColor[sc.Index] = Subgraph_Volume.SecondaryColor;

    }

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

    SCSFExport scsf_VolumeWithNegativeDownVolume(SCStudyInterfaceRef sc)
    {
        SCSubgraphRef Subgraph_Volume = sc.Subgraph[0];

        if (sc.SetDefaults)
        {
            sc.GraphName = "Volume - With Negative Down Volume";

            sc.ValueFormat = 0;

            sc.AutoLoop = true;
            sc.ScaleRangeType = SCALE_AUTO;

            Subgraph_Volume.Name = "Volume";
            Subgraph_Volume.DrawStyle = DRAWSTYLE_BAR;
            Subgraph_Volume.PrimaryColor = RGB(0, 255, 0);
            Subgraph_Volume.SecondaryColor = RGB(255, 0, 0);
            Subgraph_Volume.SecondaryColorUsed = 1;
            Subgraph_Volume.LineWidth = 2;
            Subgraph_Volume.DrawZeros = false;

            sc.DisplayStudyInputValues = false;

            return;
        }

        if(sc.Close[sc.Index] >=  sc.Open[sc.Index])
        {
            Subgraph_Volume[sc.Index] = sc.Volume[sc.Index];
            Subgraph_Volume.DataColor[sc.Index] = Subgraph_Volume.PrimaryColor;
        }
        else
        {
            Subgraph_Volume[sc.Index] = sc.Volume[sc.Index] * -1;
            Subgraph_Volume.DataColor[sc.Index] = Subgraph_Volume.SecondaryColor;
        }

    }

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

    SCSFExport scsf_Spread3Chart(SCStudyInterfaceRef sc)
    {
        SCSubgraphRef Subgraph_Open = sc.Subgraph[0];
        SCSubgraphRef Subgraph_High = sc.Subgraph[1];
        SCSubgraphRef Subgraph_Low = sc.Subgraph[2];
        SCSubgraphRef Subgraph_Last = sc.Subgraph[3];
        SCSubgraphRef Subgraph_Volume = sc.Subgraph[4];
        SCSubgraphRef Subgraph_OpenInterest = 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];

        SCInputRef Input_InChart2Number = sc.Input[3];
        SCInputRef Input_InChart3Number = sc.Input[4];
        SCInputRef Input_InChart1Multiplier = sc.Input[5];
        SCInputRef Input_InChart2Multiplier = sc.Input[6];
        SCInputRef Input_InChart3Multiplier = sc.Input[7];

        if (sc.SetDefaults)
        {
            sc.GraphName = "Spread - 3 Chart";

            sc.AutoLoop = 0;

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

            sc.UseGlobalChartColors = 0;
            sc.GraphDrawType        = GDT_OHLCBAR;
            sc.StandardChartHeader  = 1;

            Subgraph_Open.Name = "Open";
            Subgraph_Open.DrawStyle = DRAWSTYLE_LINE;
            Subgraph_Open.PrimaryColor = RGB(0,255,0);
            Subgraph_Open.SecondaryColor = RGB(0,255,0);

            Subgraph_High.Name = "High";
            Subgraph_High.DrawStyle = DRAWSTYLE_LINE;
            Subgraph_High.PrimaryColor = RGB(0,255,0);
            Subgraph_High.SecondaryColor = RGB(0,255,0);

            Subgraph_Low.Name = "Low";
            Subgraph_Low.DrawStyle = DRAWSTYLE_LINE;
            Subgraph_Low.PrimaryColor = RGB(0,255,0);
            Subgraph_Low.SecondaryColor = RGB(0,255,0);

            Subgraph_Last.Name = "Last";
            Subgraph_Last.DrawStyle = DRAWSTYLE_LINE;
            Subgraph_Last.PrimaryColor = RGB(0,255,0);
            Subgraph_Last.SecondaryColor = RGB(0,255,0);

            Subgraph_Volume.Name = "Volume";
            Subgraph_Volume.DrawStyle = DRAWSTYLE_IGNORE;
            Subgraph_Volume.PrimaryColor = RGB(255,0,0);

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

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

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

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

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

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

            Input_InChart2Number.Name = "Chart 2 Number";
            Input_InChart2Number.SetChartNumber(1);

            Input_InChart3Number.Name = "Chart 3 Number";
            Input_InChart3Number.SetChartNumber(1);

            Input_InChart1Multiplier.Name = "Chart 1 Multiplier";
            Input_InChart1Multiplier.SetFloat(1.0f);

            Input_InChart2Multiplier.Name = "Chart 2 Multiplier";
            Input_InChart2Multiplier.SetFloat(1.0f);

            Input_InChart3Multiplier.Name = "Chart 3 Multiplier";
            Input_InChart3Multiplier.SetFloat(1.0f);

            return;
        }

        if(sc.IsFullRecalculation && sc.UpdateStartIndex == 0)
        {
            SCString Chart1Name = sc.GetChartName(sc.ChartNumber);
            SCString Chart2Name = sc.GetChartName(Input_InChart2Number.GetChartNumber());
            SCString Chart3Name = sc.GetChartName(Input_InChart3Number.GetChartNumber());
            sc.GraphName.Format("Spread - 3 Chart: %s + %s - %s", Chart1Name.GetChars(), Chart2Name.GetChars(), Chart3Name.GetChars());
        }

        SCGraphData Chart2BaseData;
        sc.GetChartBaseData(-Input_InChart2Number.GetChartNumber(), Chart2BaseData);

        SCGraphData Chart3BaseData;
        sc.GetChartBaseData(-Input_InChart3Number.GetChartNumber(), Chart3BaseData);

        // Iterate through the bars
        for (int Index = sc.UpdateStartIndex; Index < sc.ArraySize; Index++)
        {
            int Chart2Index = sc.GetNearestMatchForDateTimeIndex(Input_InChart2Number.GetChartNumber(), Index);
            int Chart3Index = sc.GetNearestMatchForDateTimeIndex(Input_InChart3Number.GetChartNumber(), Index);

            // Iterate through the subgraphs
            for (int SubgraphIndex = SC_OPEN; SubgraphIndex <= SC_NUM_TRADES; SubgraphIndex++)
            {
                sc.Subgraph[SubgraphIndex][Index]
                    = (sc.BaseDataIn[SubgraphIndex][Index] * Input_InChart1Multiplier.GetFloat())
                    + (Chart2BaseData[SubgraphIndex][Chart2Index] * Input_InChart2Multiplier.GetFloat())
                    - (Chart3BaseData[SubgraphIndex][Chart3Index] * Input_InChart3Multiplier.GetFloat())
                    ;
            }

            sc.Subgraph[SC_HIGH][Index]
                = max(
                    sc.Subgraph[SC_OPEN][Index],
                    max(
                        sc.Subgraph[SC_HIGH][Index],
                        max(
                            sc.Subgraph[SC_LOW][Index],
                            sc.Subgraph[SC_LAST][Index]
                        )
                    )
                );

            sc.Subgraph[SC_LOW][Index]
                = min(
                    sc.Subgraph[SC_OPEN][Index],
                    min(
                        sc.Subgraph[SC_HIGH][Index],
                        min(
                            sc.Subgraph[SC_LOW][Index],
                            sc.Subgraph[SC_LAST][Index]
                        )
                    )
                );

            sc.CalculateOHLCAverages(Index);
        }

    }

    /*==========================================================================*/
    SCSFExport scsf_SpreadButterfly(SCStudyInterfaceRef sc)
    {
        SCSubgraphRef Subgraph_Open = sc.Subgraph[0];
        SCSubgraphRef Subgraph_High = sc.Subgraph[1];
        SCSubgraphRef Subgraph_Low = sc.Subgraph[2];
        SCSubgraphRef Subgraph_Last = sc.Subgraph[3];
        SCSubgraphRef Subgraph_Volume = sc.Subgraph[4];
        SCSubgraphRef Subgraph_OpenInterest = 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];

        SCInputRef Input_UseLatestSourceDataForLastBar = sc.Input[2];
        SCInputRef Input_InChart2Number = sc.Input[3];
        SCInputRef Input_InChart3Number = sc.Input[4];
        SCInputRef Input_InChart1Multiplier = sc.Input[5];
        SCInputRef Input_InChart2Multiplier = sc.Input[6];
        SCInputRef Input_InChart3Multiplier = sc.Input[7];

        if (sc.SetDefaults)
        {
            sc.GraphName = "Spread - Butterfly";

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

            sc.UseGlobalChartColors = 0;
            sc.GraphDrawType        = GDT_OHLCBAR;
            sc.StandardChartHeader  = 1;

            Subgraph_Open.Name = "Open";
            Subgraph_Open.DrawStyle = DRAWSTYLE_LINE;
            Subgraph_Open.PrimaryColor = RGB(0,255,0);
            Subgraph_Open.SecondaryColor = RGB(0,255,0);

            Subgraph_High.Name = "High";
            Subgraph_High.DrawStyle = DRAWSTYLE_LINE;
            Subgraph_High.PrimaryColor = RGB(0,255,0);
            Subgraph_High.SecondaryColor = RGB(0,255,0);

            Subgraph_Low.Name = "Low";
            Subgraph_Low.DrawStyle = DRAWSTYLE_LINE;
            Subgraph_Low.PrimaryColor = RGB(0,255,0);
            Subgraph_Low.SecondaryColor = RGB(0,255,0);

            Subgraph_Last.Name = "Last";
            Subgraph_Last.DrawStyle = DRAWSTYLE_LINE;
            Subgraph_Last.PrimaryColor = RGB(0,255,0);
            Subgraph_Last.SecondaryColor = RGB(0,255,0);

            Subgraph_Volume.Name = "Volume";
            Subgraph_Volume.DrawStyle = DRAWSTYLE_IGNORE;
            Subgraph_Volume.PrimaryColor = RGB(255,0,0);

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

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

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

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

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

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

            Input_UseLatestSourceDataForLastBar.Name = "Use Latest Source Data For Last Bar";
            Input_UseLatestSourceDataForLastBar.SetYesNo(0);

            Input_InChart2Number.Name = "Chart 2 Number";
            Input_InChart2Number.SetChartNumber(1);

            Input_InChart3Number.Name = "Chart 3 Number";
            Input_InChart3Number.SetChartNumber(1);

            Input_InChart1Multiplier.Name = "Chart 1 Multiplier";
            Input_InChart1Multiplier.SetFloat(1.0f);

            Input_InChart2Multiplier.Name = "Chart 2 Multiplier";
            Input_InChart2Multiplier.SetFloat(2.0f);

            Input_InChart3Multiplier.Name = "Chart 3 Multiplier";
            Input_InChart3Multiplier.SetFloat(1.0f);

            return;
        }

        //Formula: Buy1 Sell2 Buy1

        SCGraphData Chart2BaseData;
        sc.GetChartBaseData(-Input_InChart2Number.GetChartNumber(), Chart2BaseData);

        SCGraphData Chart3BaseData;
        sc.GetChartBaseData(-Input_InChart3Number.GetChartNumber(), Chart3BaseData);

        // Iterate through the bars
        for (int Index = sc.UpdateStartIndex; Index < sc.ArraySize; Index++)
        {
            int Chart2Index = sc.GetNearestMatchForDateTimeIndex(Input_InChart2Number.GetChartNumber(), Index);
            int Chart3Index = sc.GetNearestMatchForDateTimeIndex(Input_InChart3Number.GetChartNumber(), Index);

            //When use latest source data for last bar is set to Yes, replay is not running and at last bar in the destination chart, then use the data from the very latest bar in the source charts.
            if(Input_UseLatestSourceDataForLastBar.GetYesNo() && !sc.IsReplayRunning() &&  Index == sc.ArraySize - 1)
            {
                Chart2Index = Chart2BaseData[SC_OPEN].GetArraySize() - 1;
                Chart3Index = Chart3BaseData[SC_OPEN].GetArraySize() - 1;
            }

            // Iterate through the subgraphs
            for (int SubgraphIndex = SC_OPEN; SubgraphIndex <= SC_NUM_TRADES; SubgraphIndex++)
            {
                sc.Subgraph[SubgraphIndex][Index]
                    = (sc.BaseDataIn[SubgraphIndex][Index] * Input_InChart1Multiplier.GetFloat())
                    - (Chart2BaseData[SubgraphIndex][Chart2Index] * Input_InChart2Multiplier.GetFloat())
                    + (Chart3BaseData[SubgraphIndex][Chart3Index] * Input_InChart3Multiplier.GetFloat())
                    ;
            }

            sc.Subgraph[SC_HIGH][Index]
                = max(
                    sc.Subgraph[SC_OPEN][Index],
                    max(
                        sc.Subgraph[SC_HIGH][Index],
                        max(
                            sc.Subgraph[SC_LOW][Index],
                            sc.Subgraph[SC_LAST][Index]
                        )
                    )
                );

            sc.Subgraph[SC_LOW][Index]
                = min(
                    sc.Subgraph[SC_OPEN][Index],
                    min(
                        sc.Subgraph[SC_HIGH][Index],
                        min(
                            sc.Subgraph[SC_LOW][Index],
                            sc.Subgraph[SC_LAST][Index]
                        )
                    )
                );

            sc.CalculateOHLCAverages(Index);
        }

        sc.GraphName.Format("Butterfly Spread: +%s - %s + %s",
            sc.GetChartName(sc.ChartNumber).GetChars(),
            sc.GetChartName(Input_InChart2Number.GetChartNumber()).GetChars(),
            sc.GetChartName(Input_InChart3Number.GetChartNumber()).GetChars());
    }

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

    SCSFExport scsf_Sum3Chart(SCStudyInterfaceRef sc)
    {

        SCInputRef Input_InChart2Number = sc.Input[3];
        SCInputRef Input_InChart3Number = sc.Input[4];
        SCInputRef Input_InChart1Multiplier = sc.Input[5];
        SCInputRef Input_InChart2Multiplier = sc.Input[6];
        SCInputRef Input_InChart3Multiplier = sc.Input[7];

        if (sc.SetDefaults)
        {
            sc.GraphName = "Sum - 3 Chart";

            sc.ValueFormat = VALUEFORMAT_INHERITED;
            sc.GraphRegion = 1;
            sc.AutoLoop = 0;
            sc.GraphUsesChartColors = 1;
            sc.GraphDrawType = GDT_OHLCBAR;
            sc.StandardChartHeader = 1;

            Input_InChart2Number.Name = "Chart 2 Number";
            Input_InChart2Number.SetChartNumber(1);

            Input_InChart3Number.Name = "Chart 3 Number";
            Input_InChart3Number.SetChartNumber(1);

            Input_InChart1Multiplier.Name = "Chart 1 Multiplier";
            Input_InChart1Multiplier.SetFloat(1.0f);

            Input_InChart2Multiplier.Name = "Chart 2 Multiplier";
            Input_InChart2Multiplier.SetFloat(1.0f);

            Input_InChart3Multiplier.Name = "Chart 3 Multiplier";
            Input_InChart3Multiplier.SetFloat(1.0f);

            return;
        }

        if (sc.IsFullRecalculation && sc.UpdateStartIndex == 0)
        {
            for (int SubgraphIndex = 0; SubgraphIndex <= NUM_BASE_GRAPH_ARRAYS; ++SubgraphIndex)
            {
                sc.Subgraph[SubgraphIndex].Name = sc.GetStudySubgraphName(0, SubgraphIndex);
            }

            SCString Chart1Name = sc.GetChartName(sc.ChartNumber);
            SCString Chart2Name = sc.GetChartName(Input_InChart2Number.GetChartNumber());
            SCString Chart3Name = sc.GetChartName(Input_InChart3Number.GetChartNumber());
            sc.GraphName.Format("Sum - 3 Chart: %s + %s + %s", Chart1Name.GetChars(), Chart2Name.GetChars(), Chart3Name.GetChars());

        }

        SCGraphData Chart2BaseData;
        sc.GetChartBaseData(-Input_InChart2Number.GetChartNumber(), Chart2BaseData);

        SCGraphData Chart3BaseData;
        sc.GetChartBaseData(-Input_InChart3Number.GetChartNumber(), Chart3BaseData);

        // Iterate through the bars
        for (int Index = sc.UpdateStartIndex; Index < sc.ArraySize; Index++)
        {
            int Chart2Index = sc.GetNearestMatchForDateTimeIndex(Input_InChart2Number.GetChartNumber(), Index);
            int Chart3Index = sc.GetNearestMatchForDateTimeIndex(Input_InChart3Number.GetChartNumber(), Index);

            // Iterate through the subgraphs
            for (int SubgraphIndex = SC_OPEN; SubgraphIndex <= SC_NUM_TRADES; SubgraphIndex++)
            {
                sc.Subgraph[SubgraphIndex][Index]
                    = (sc.BaseDataIn[SubgraphIndex][Index] * Input_InChart1Multiplier.GetFloat())
                    + (Chart2BaseData[SubgraphIndex][Chart2Index] * Input_InChart2Multiplier.GetFloat())
                    + (Chart3BaseData[SubgraphIndex][Chart3Index] * Input_InChart3Multiplier.GetFloat())
                    ;
            }

            sc.Subgraph[SC_HIGH][Index]
                = max(
                    sc.Subgraph[SC_OPEN][Index],
                    max(
                        sc.Subgraph[SC_HIGH][Index],
                        max(
                            sc.Subgraph[SC_LOW][Index],
                            sc.Subgraph[SC_LAST][Index]
                        )
                    )
                );

            sc.Subgraph[SC_LOW][Index]
                = min(
                    sc.Subgraph[SC_OPEN][Index],
                    min(
                        sc.Subgraph[SC_HIGH][Index],
                        min(
                            sc.Subgraph[SC_LOW][Index],
                            sc.Subgraph[SC_LAST][Index]
                        )
                    )
                );

            sc.CalculateOHLCAverages(Index);
        }

    }
    /*==========================================================================*/
    SCSFExport scsf_HighestHighLowestLowOverNBars(SCStudyInterfaceRef sc)
    {
        SCSubgraphRef Subgraph_HighestHigh = sc.Subgraph[0];
        SCSubgraphRef Subgraph_LowestLow = sc.Subgraph[1];

        SCInputRef Input_Length = sc.Input[3];
        SCInputRef Input_DataHigh = sc.Input[5];
        SCInputRef Input_DataLow = sc.Input[6];

        if (sc.SetDefaults)
        {
            sc.GraphName = "Highest High / Lowest Low Over N Bars";

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

            Subgraph_HighestHigh.Name= "Highest High";
            Subgraph_HighestHigh.DrawStyle = DRAWSTYLE_LINE;
            Subgraph_HighestHigh.PrimaryColor = RGB(0,255,0);
            Subgraph_HighestHigh.DrawZeros = true;

            Subgraph_LowestLow.Name = "Lowest Low";
            Subgraph_LowestLow.DrawStyle = DRAWSTYLE_LINE;
            Subgraph_LowestLow.PrimaryColor = RGB(255,0,255);
            Subgraph_LowestLow.DrawZeros = true;

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

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

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

            return;
        }

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

        int & HighestIndex = sc.GetPersistentInt(1);
        int & LowestIndex = sc.GetPersistentInt(2);
        float & CurrentHighest = sc.GetPersistentFloat(1);
        float & CurrentLowest = sc.GetPersistentFloat(2);
        if (sc.UpdateStartIndex== 0)
        {
            HighestIndex = -1;
            LowestIndex = -1;
            CurrentHighest = -FLT_MAX;
            CurrentLowest = FLT_MAX;
        }

        int HighDataIndex =  Input_DataHigh.GetInputDataIndex();
        int LowDataIndex = Input_DataLow.GetInputDataIndex();
        for (int BarIndex = sc.UpdateStartIndex; BarIndex < sc.ArraySize; BarIndex++)
        {
            int EarliestIndex = BarIndex - (Input_Length.GetInt() - 1);
            bool NeedToDetermineHigh =
                (HighestIndex < EarliestIndex || sc.BaseDataIn[HighDataIndex][BarIndex] > CurrentHighest);

            bool NeedToDetermineLow =
                (LowestIndex < EarliestIndex || sc.BaseDataIn[LowDataIndex][BarIndex] < CurrentLowest);

            if (NeedToDetermineHigh || NeedToDetermineLow)
            {
                if (NeedToDetermineHigh)
                    CurrentHighest = -FLT_MAX;

                if (NeedToDetermineLow)
                    CurrentLowest = FLT_MAX;

                for (int PriorBarIndex = EarliestIndex; PriorBarIndex <= BarIndex; PriorBarIndex++)
                {
                    if (NeedToDetermineHigh)
                    {
                        if (CurrentHighest < sc.BaseDataIn[HighDataIndex][PriorBarIndex])
                        {
                            CurrentHighest = sc.BaseDataIn[HighDataIndex][PriorBarIndex];
                            HighestIndex = PriorBarIndex;
                        }
                    }

                    if (NeedToDetermineLow)
                    {
                        if (CurrentLowest > sc.BaseDataIn[LowDataIndex][PriorBarIndex])
                        {
                            CurrentLowest = sc.BaseDataIn[LowDataIndex][PriorBarIndex];
                            LowestIndex = PriorBarIndex;
                        }
                    }
                }

            }
            Subgraph_HighestHigh[BarIndex] = CurrentHighest;
            Subgraph_LowestLow[BarIndex] = CurrentLowest;
        }
    }

    /*==========================================================================*/
    SCSFExport scsf_DonchianChannel(SCStudyInterfaceRef sc)
    {
        SCSubgraphRef Subgraph_HighestHigh = sc.Subgraph[0];
        SCSubgraphRef Subgraph_LowestLow = sc.Subgraph[1];
        SCSubgraphRef Subgraph_Midline = sc.Subgraph[2];
        SCInputRef Input_Length = sc.Input[3];
        SCInputRef Input_UseClose = sc.Input[4];

        if (sc.SetDefaults)
        {
            sc.GraphName = "Donchian Channel";

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

            Subgraph_HighestHigh.Name= "Highest High";
            Subgraph_HighestHigh.DrawStyle=  DRAWSTYLE_LINE;
            Subgraph_HighestHigh.DrawZeros= true;
            Subgraph_HighestHigh.GraphicalDisplacement= 1;

            Subgraph_LowestLow.Name = "Lowest Low";
            Subgraph_LowestLow.DrawStyle=  DRAWSTYLE_LINE;
            Subgraph_LowestLow.DrawZeros= true;
            Subgraph_LowestLow.GraphicalDisplacement= 1;

            Subgraph_Midline.Name = "Mid Line";
            Subgraph_Midline.DrawStyle=  DRAWSTYLE_LINE;
            Subgraph_Midline.LineStyle= LINESTYLE_DOT;
            Subgraph_Midline.DrawZeros= true;
            Subgraph_Midline.GraphicalDisplacement= 1;

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

            Input_UseClose.Name = "Use Close instead of High and Low";
            Input_UseClose.SetYesNo(false);

            return;
        }

        float Lowest = FLT_MAX;
        float Highest = -FLT_MAX;

        if (Input_UseClose.GetYesNo())
        {
            for (int BarIndex = sc.Index - (Input_Length.GetInt() - 1); BarIndex <= sc.Index; BarIndex++)
            {
                Highest = (Highest < sc.Close[BarIndex]) ? sc.Close[BarIndex] : Highest;

                Lowest = (Lowest > sc.Close[BarIndex]) ? sc.Close[BarIndex] : Lowest;
            }
        }
        else
        {
            for (int BarIndex = sc.Index - (Input_Length.GetInt() - 1); BarIndex <= sc.Index; BarIndex++)
            {
                if (Highest < sc.High[BarIndex])
                    Highest = sc.High[BarIndex];

                if (Lowest > sc.Low[BarIndex])
                    Lowest = sc.Low[BarIndex];
            }

        }

        Subgraph_HighestHigh[sc.Index] = Highest;
        Subgraph_LowestLow[sc.Index] = Lowest;
        Subgraph_Midline[sc.Index] = (Highest + Lowest)/2.0f;
    }

    /*==========================================================================*/
    SCSFExport scsf_McClellanOscillator(SCStudyInterfaceRef sc)
    {
        SCSubgraphRef Subgraph_MO = sc.Subgraph[0];
        SCSubgraphRef Subgraph_Temp2 = sc.Subgraph[2];
        SCSubgraphRef Subgraph_Temp3 = sc.Subgraph[3];

        SCInputRef Input_DecliningIssuesChartNumber = sc.Input[3];
        SCInputRef Input_UseAbsValue = sc.Input[4];

        if (sc.SetDefaults)
        {
            sc.GraphName = "McClellan Oscillator" ;
            sc.GraphRegion = 1;
            sc.ValueFormat = 3;

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

            Input_DecliningIssuesChartNumber.Name = "Declining Issues Chart #";
            Input_DecliningIssuesChartNumber.SetChartNumber(1);

            Input_UseAbsValue.Name = "Use ABS Value";
            Input_UseAbsValue.SetYesNo(0);

            return;
        }

        SCGraphData ChartBaseData;
        sc.GetChartBaseData(-Input_DecliningIssuesChartNumber.GetChartNumber(), ChartBaseData);

        SCFloatArrayRef Chart2Array = ChartBaseData[SC_LAST];

        if (Chart2Array.GetArraySize() == 0)
            return;

        int i1 = 0;
        int i = 0;
        sc.DataStartIndex = 1;

        Subgraph_Temp3[i] = Subgraph_Temp2[i] = sc.Close[i] - Chart2Array[i1];

        for (i = max(1, sc.UpdateStartIndex); i < sc.ArraySize; i++)
        {
            int i1 = sc.GetNearestMatchForDateTimeIndex(Input_DecliningIssuesChartNumber.GetChartNumber(), i);

            Subgraph_Temp3[i] = Subgraph_Temp3[i - 1] * 0.9f +
                ((sc.Close[i] - Chart2Array[i1]) * 0.1f);

            if (Input_UseAbsValue.GetYesNo())
            {
                Subgraph_Temp2[i] = Subgraph_Temp2[i - 1] * 0.95f +
                    (fabs(
                    (sc.Close[i] - Chart2Array[i1]) *0.05f));
            }
            else
            {
                Subgraph_Temp2[i] = Subgraph_Temp2[i - 1] * 0.95f +
                    ((
                    (sc.Close[i] - Chart2Array[i1]) *0.05f));
            }

            Subgraph_MO[i] = Subgraph_Temp3[i] - Subgraph_Temp2[i];
        }
    }

    /*==========================================================================*/
    SCSFExport scsf_BarDifference(SCStudyInterfaceRef sc)
    {
        SCSubgraphRef Subgraph_Difference = sc.Subgraph[0];
        SCInputRef Input_Data1 = sc.Input[0];
        SCInputRef Input_Data2 = sc.Input[1];
        SCInputRef Input_Data1Offset = sc.Input[2];
        SCInputRef Input_Data2Offset = sc.Input[3];
        SCInputRef Input_CalculateDifferenceInPriceTicks = sc.Input[4];

        if (sc.SetDefaults)
        {
            sc.GraphName = "Bar Difference";

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

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

            Input_Data1.Name = "Input Data 1";
            Input_Data1.SetInputDataIndex(SC_HIGH);

            Input_Data2.Name = "Input Data 2";
            Input_Data2.SetInputDataIndex(SC_LOW);

            Input_Data1Offset.Name = "Input Data 1 Offset";
            Input_Data1Offset.SetInt(0);
            Input_Data1Offset.SetIntLimits(0, MAX_STUDY_LENGTH);

            Input_Data2Offset.Name = "Input Data 2 Offset";
            Input_Data2Offset.SetInt(0);
            Input_Data2Offset.SetIntLimits(0, MAX_STUDY_LENGTH);

            Input_CalculateDifferenceInPriceTicks.Name = "Calculate Difference in Price Ticks";
            Input_CalculateDifferenceInPriceTicks.SetYesNo(false);

            return;
        }

        if (sc.Index < Input_Data2Offset.GetInt()
            || sc.Index < Input_Data1Offset.GetInt())
        {
            return;
        }

        Subgraph_Difference[sc.Index] =
            sc.BaseDataIn[Input_Data1.GetInputDataIndex()][sc.Index - Input_Data1Offset.GetInt()] -
            sc.BaseDataIn[Input_Data2.GetInputDataIndex()][sc.Index - Input_Data2Offset.GetInt()];

        if (Input_CalculateDifferenceInPriceTicks.GetYesNo() && sc.TickSize != 0)
            Subgraph_Difference[sc.Index] /= sc.TickSize;
    }

    /*==========================================================================*/
    SCSFExport scsf_McClellanSummationIndex(SCStudyInterfaceRef sc)
    {
        SCSubgraphRef Subgraph_Sum = sc.Subgraph[0];
        SCSubgraphRef Subgraph_Temp2 = sc.Subgraph[2];
        SCSubgraphRef Subgraph_Temp3 = sc.Subgraph[3];

        SCInputRef DecliningIssuesChartNumber = sc.Input[3];

        if (sc.SetDefaults)
        {
            sc.GraphName = "McClellan Summation Index";

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

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

            DecliningIssuesChartNumber.Name = "Declining Issues Chart #";
            DecliningIssuesChartNumber.SetChartNumber(1);

            return;
        }

        SCGraphData ChartBaseData;
        sc.GetChartBaseData(-DecliningIssuesChartNumber.GetChartNumber(), ChartBaseData);

        SCFloatArrayRef Chart2Array = ChartBaseData[SC_LAST];
        if (Chart2Array.GetArraySize() == 0)
            return;

        sc.DataStartIndex = 1;

        Subgraph_Temp3[0] = Subgraph_Temp2[0] = sc.Close[0] - Chart2Array[0];

        for (int i = max(1, sc.UpdateStartIndex); i < sc.ArraySize; i++)
        {
            int i1 = sc.GetNearestMatchForDateTimeIndex(DecliningIssuesChartNumber.GetChartNumber(), i);

            if (sc.Close[i] == 0 || Chart2Array[i1] == 0)
            {
                Subgraph_Sum[i] = Subgraph_Sum[i - 1];
                continue;
            }

            Subgraph_Temp3[i] = Subgraph_Temp3[i - 1] * 0.9f +
                ((sc.Close[i] - Chart2Array[i1]) * 0.1f);

            Subgraph_Temp2[i] = Subgraph_Temp2[i - 1] * 0.95f +
                ((
                (sc.Close[i] - Chart2Array[i1]) * 0.05f));

            Subgraph_Sum[i] = Subgraph_Sum[i - 1] + (Subgraph_Temp3[i] - Subgraph_Temp2[i]);
        }
    }

    /*==========================================================================*/
    SCSFExport scsf_MomentumTrend(SCStudyInterfaceRef sc)
    {
        SCSubgraphRef Subgraph_MomentumUp = sc.Subgraph[0];
        SCSubgraphRef Subgraph_MomentumDown = sc.Subgraph[1];
        SCSubgraphRef Subgraph_Momentum = sc.Subgraph[2];

        SCInputRef Input_Data = sc.Input[0];
        SCInputRef Input_Length = sc.Input[3];
        SCInputRef Input_MomentumType = sc.Input[4];

        if (sc.SetDefaults)
        {
            sc.GraphName = "Momentum Trend";

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

            Subgraph_MomentumUp.Name = "Momentum Up";
            Subgraph_MomentumUp.DrawStyle = DRAWSTYLE_POINT;
            Subgraph_MomentumUp.PrimaryColor = RGB(0,255,0);
            Subgraph_MomentumUp.LineWidth = 5;
            Subgraph_MomentumUp.DrawZeros = false;

            Subgraph_MomentumDown.Name = "Momentum Down";
            Subgraph_MomentumDown.DrawStyle = DRAWSTYLE_POINT;
            Subgraph_MomentumDown.PrimaryColor = RGB(255,0,255);
            Subgraph_MomentumDown.LineWidth = 5;
            Subgraph_MomentumDown.DrawZeros = false;

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

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

            Input_MomentumType.Name = "Momentum Type";
            Input_MomentumType.SetCustomInputStrings("Difference;Quotient");
            Input_MomentumType.SetCustomInputIndex(0);

            return;
        }

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

        if (sc.Index < sc.DataStartIndex - 1)
            return;

        const int SelectedIndex = Input_MomentumType.GetIndex();
        switch (SelectedIndex)
        {
        case 0:
        {
            Subgraph_Momentum[sc.Index] = sc.BaseDataIn[Input_Data.GetInputDataIndex()][sc.Index] - sc.BaseDataIn[Input_Data.GetInputDataIndex()][sc.Index - Input_Length.GetInt()];
        }
        break;

        case 1:
        {
            if (sc.BaseDataIn[Input_Data.GetInputDataIndex()][sc.Index - Input_Length.GetInt()] != 0.0f)
                Subgraph_Momentum[sc.Index] = (sc.BaseDataIn[Input_Data.GetInputDataIndex()][sc.Index] / sc.BaseDataIn[Input_Data.GetInputDataIndex()][sc.Index - Input_Length.GetInt()]) * 100;
            else
                Subgraph_Momentum[sc.Index] = 0.0f;
        }
        break;
        }

        if (sc.Index < sc.DataStartIndex)
            return;

        if (Subgraph_Momentum[sc.Index] > Subgraph_Momentum[sc.Index - 1])
        {
            Subgraph_MomentumUp[sc.Index] = sc.High[sc.Index];
            Subgraph_MomentumDown[sc.Index] = 0;
        }
        else
        {
            Subgraph_MomentumDown[sc.Index] = sc.Low[sc.Index];
            Subgraph_MomentumUp[sc.Index] = 0;
        }
    }

    /*==========================================================================*/
    SCSFExport scsf_SumAllCharts(SCStudyInterfaceRef sc)
    {
        SCSubgraphRef Subgraph_Open = sc.Subgraph[0];
        SCSubgraphRef Subgraph_High = sc.Subgraph[1];
        SCSubgraphRef Subgraph_Low = sc.Subgraph[2];
        SCSubgraphRef Subgraph_Last = sc.Subgraph[3];
        SCSubgraphRef Subgraph_Volume = sc.Subgraph[4];
        SCSubgraphRef Subgraph_OpenInterest = 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)
        {
            sc.GraphName = "Sum All Charts";

            sc.ValueFormat          = 2;
            sc.GraphRegion          = 1;
            sc.UseGlobalChartColors = 0;
            sc.GraphDrawType        = GDT_OHLCBAR;
            sc.StandardChartHeader  = 1;

            // We are using Manual looping.
            sc.AutoLoop = false;

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

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

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

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

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

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

            Subgraph_OHLCAvg.Name = "OHLC Avg";
            Subgraph_OHLCAvg.DrawStyle = DRAWSTYLE_IGNORE;
            Subgraph_OHLCAvg.PrimaryColor = RGB(0,255,0);
            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;

            return;
        }

        // Initialize elements to 0
        for (int Index = sc.UpdateStartIndex; Index < sc.ArraySize; Index++)
        {
            for (int SubgraphIndex = SC_OPEN; SubgraphIndex <= SC_NUM_TRADES; SubgraphIndex++)
            {
                sc.Subgraph[SubgraphIndex][Index] = 0;
            }
        }

        // Sum charts
        const int MaxCharts = 200;
        for (int ChartIndex = 1; ChartIndex <= MaxCharts; ChartIndex++)
        {
            SCGraphData RefChartBaseData;
            sc.GetChartBaseData(-ChartIndex, RefChartBaseData);

            if (RefChartBaseData[SC_OPEN].GetArraySize() == 0)
                continue;

            for (int Index = sc.UpdateStartIndex; Index < sc.ArraySize; Index++)
            {
                int RefChartIndex = sc.GetNearestMatchForDateTimeIndex(ChartIndex, Index);

                for (int SubgraphIndex = SC_OPEN; SubgraphIndex <= SC_NUM_TRADES; SubgraphIndex++)
                {
                    sc.Subgraph[SubgraphIndex][Index] += RefChartBaseData[SubgraphIndex][RefChartIndex];
                }

                sc.Subgraph[SC_HIGH][Index]
                    = max(sc.Subgraph[SC_OPEN][Index],
                        max(sc.Subgraph[SC_HIGH][Index],
                            max(sc.Subgraph[SC_LOW][Index], sc.Subgraph[SC_LAST][Index])
                        )
                    );

                sc.Subgraph[SC_LOW][Index]
                    = min(sc.Subgraph[SC_OPEN][Index],
                        min(sc.Subgraph[SC_HIGH][Index],
                            min(sc.Subgraph[SC_LOW][Index], sc.Subgraph[SC_LAST][Index])
                        )
                    );
            }
        }

        // Calculate averages
        for (int Index = sc.UpdateStartIndex; Index < sc.ArraySize; Index++)
            sc.CalculateOHLCAverages(Index);
    }

    /*==========================================================================*/
    SCSFExport scsf_Kurtosis(SCStudyInterfaceRef sc)
    {
        SCSubgraphRef Subgraph_SecondCentralMoment = sc.Subgraph[0];
        SCSubgraphRef Subgraph_FourthCentralMoment = sc.Subgraph[1];
        SCSubgraphRef Subgraph_Kurtosis = sc.Subgraph[2];
        SCSubgraphRef Subgraph_Line = sc.Subgraph[3];

        SCFloatArrayRef Array_Avg = Subgraph_Kurtosis.Arrays[0];

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

        if (sc.SetDefaults)
        {
            sc.GraphName = "Kurtosis";

            sc.AutoLoop = 1;

            Subgraph_SecondCentralMoment.Name = "Second Central Moment";
            Subgraph_SecondCentralMoment.DrawStyle = DRAWSTYLE_IGNORE;

            Subgraph_FourthCentralMoment.Name = "Fourth Central Moment";
            Subgraph_FourthCentralMoment.DrawStyle = DRAWSTYLE_IGNORE;

            Subgraph_Kurtosis.Name = "Kurtosis";
            Subgraph_Kurtosis.DrawStyle = DRAWSTYLE_BAR;
            Subgraph_Kurtosis.PrimaryColor = RGB(0, 255, 0);
            Subgraph_Kurtosis.SecondaryColor = RGB(255, 0, 0);
            Subgraph_Kurtosis.SecondaryColorUsed = true;
            Subgraph_Kurtosis.DrawZeros = false;

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

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

            Input_Length.Name = "Length";
            Input_Length.SetInt(10);
            Input_Length.SetIntLimits(4, INT_MAX);

            Input_KurtosisType.Name = "Kurtosis Type";
            Input_KurtosisType.SetCustomInputStrings("Population;" "Sample");
            Input_KurtosisType.SetCustomInputIndex(0);

            return;
        }

        int Length = Input_Length.GetInt();

        sc.DataStartIndex = Length - 1;

        sc.SimpleMovAvg(sc.BaseDataIn[Input_InputData.GetInputDataIndex()], Array_Avg, Length);

        // Compute second and fourth central moments.
        float Deviation = 0.0f;
        float DeviationSquared = 0.0f;
        float SumDeviationSquared = 0.0f;
        float DeviationFourthPower = 0.0f;
        float SumDeviationFourthPower = 0.0f;

        for (int i = sc.Index - Length + 1; i <= sc.Index; i++)
        {
            Deviation = sc.BaseDataIn[Input_InputData.GetInputDataIndex()][i] - Array_Avg[i];
            DeviationSquared = Deviation * Deviation;
            SumDeviationSquared += DeviationSquared;
            DeviationFourthPower = DeviationSquared * DeviationSquared;
            SumDeviationFourthPower += DeviationFourthPower;
        }

        Subgraph_SecondCentralMoment[sc.Index] = SumDeviationSquared / Length;
        Subgraph_FourthCentralMoment[sc.Index] = SumDeviationFourthPower / Length;

        // Two cases for Kurtosis Type:
        const int SelectedIndex = Input_KurtosisType.GetIndex();

        switch (SelectedIndex)
        {
        case 0:
        {
            Subgraph_Kurtosis[sc.Index] = Subgraph_FourthCentralMoment[sc.Index] / (Subgraph_SecondCentralMoment[sc.Index] * Subgraph_SecondCentralMoment[sc.Index]) - 3.0f;

            if (Subgraph_Kurtosis[sc.Index] > 0)
                Subgraph_Kurtosis.DataColor[sc.Index] = Subgraph_Kurtosis.PrimaryColor;
            else
                Subgraph_Kurtosis.DataColor[sc.Index] = Subgraph_Kurtosis.SecondaryColor;
        }
        break;

        case 1:
        {
            Subgraph_Kurtosis[sc.Index] = ((Length - 1.0f)*(Length + 1.0f)) / ((Length - 2.0f)*(Length - 3.0f))*Subgraph_FourthCentralMoment[sc.Index] / (Subgraph_SecondCentralMoment[sc.Index] * Subgraph_SecondCentralMoment[sc.Index]) - 3.0f*(Length - 1)*(Length - 1) / ((Length - 2)*(Length - 3));

            if (Subgraph_Kurtosis[sc.Index] > 0)
                Subgraph_Kurtosis.DataColor[sc.Index] = Subgraph_Kurtosis.PrimaryColor;
            else
                Subgraph_Kurtosis.DataColor[sc.Index] = Subgraph_Kurtosis.SecondaryColor;
        }
        break;
        }

        Subgraph_Line[sc.Index] = 0.0f;

    }

    /*==========================================================================*/
    SCSFExport scsf_AC_DC_Histogram(SCStudyInterfaceRef sc)
    {
        SCSubgraphRef Subgraph_ACDC = sc.Subgraph[0];
        SCSubgraphRef Subgraph_Temp3 = sc.Subgraph[3];
        SCSubgraphRef Subgraph_Temp4 = sc.Subgraph[4];
        SCSubgraphRef Subgraph_Temp5 = sc.Subgraph[5];
        SCSubgraphRef Subgraph_Temp6 = sc.Subgraph[6];
        SCSubgraphRef Subgraph_Temp7 = sc.Subgraph[7];

        SCInputRef Input_Data = sc.Input[0];
        SCInputRef Input_MA1Length = sc.Input[2];
        SCInputRef Input_MA2Length = sc.Input[3];
        SCInputRef Input_MA3Length = sc.Input[4];
        SCInputRef Input_MA4Length = sc.Input[5];

        if (sc.SetDefaults)
        {
            sc.GraphName = "AC/DC Histogram";

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

            Subgraph_ACDC.Name = "AC/DC";
            Subgraph_ACDC.DrawStyle = DRAWSTYLE_BAR;
            Subgraph_ACDC.SecondaryColor = RGB(255,0,0);
            Subgraph_ACDC.AutoColoring = AUTOCOLOR_SLOPE;
            Subgraph_ACDC.DrawZeros = false;

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

            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_MA3Length.Name = "Moving Average 3 Length";
            Input_MA3Length.SetInt(34);
            Input_MA3Length.SetIntLimits(1, MAX_STUDY_LENGTH);

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

            return;
        }

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

        sc.SimpleMovAvg(sc.BaseDataIn[Input_Data.GetInputDataIndex()], Subgraph_Temp3, Input_MA1Length.GetInt());
        sc.SimpleMovAvg(sc.BaseDataIn[Input_Data.GetInputDataIndex()], Subgraph_Temp4, Input_MA2Length.GetInt());

        if (sc.Index > 0)
            Subgraph_Temp5[sc.Index] = Subgraph_Temp4[sc.Index] - Subgraph_Temp3[sc.Index];

        sc.SimpleMovAvg(Subgraph_Temp5, Subgraph_Temp6, Input_MA4Length.GetInt());
        Subgraph_Temp7[sc.Index]  = Subgraph_Temp5[sc.Index] - Subgraph_Temp6[sc.Index];
        sc.SimpleMovAvg(Subgraph_Temp7, Subgraph_ACDC, Input_MA3Length.GetInt());
    }

    /*==========================================================================*/
    SCSFExport scsf_MovingAverageTriangular(SCStudyInterfaceRef sc)
    {
        SCSubgraphRef Subgraph_MA = sc.Subgraph[0];
        SCSubgraphRef Subgraph_TempMA = sc.Subgraph[1];

        SCInputRef Input_Data = sc.Input[0];
        SCInputRef Input_Length = sc.Input[3];

        if (sc.SetDefaults)
        {
            sc.GraphName = "Moving Average - Triangular";

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

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

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

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

            return;
        }

        sc.DataStartIndex = Input_Length.GetInt() ;

        sc.TriangularMovingAverage(sc.BaseDataIn[Input_Data.GetInputDataIndex()], Subgraph_MA, Input_Length.GetInt());

    }

    /*==========================================================================*/
    SCSFExport scsf_1DividedByPrice(SCStudyInterfaceRef sc)
    {
        SCSubgraphRef Subgraph_Open = sc.Subgraph[0];
        SCSubgraphRef Subgraph_High = sc.Subgraph[1];
        SCSubgraphRef Subgraph_Low = sc.Subgraph[2];
        SCSubgraphRef Subgraph_Last = sc.Subgraph[3];
        SCSubgraphRef Subgraph_Volume = sc.Subgraph[4];
        SCSubgraphRef Subgraph_OpenInterest = 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)
        {
            sc.GraphName = "1 Divided by Price";

            sc.GraphUsesChartColors= true;

            sc.ValueFormat = VALUEFORMAT_INHERITED;
            sc.GraphRegion = 0;
            sc.DisplayAsMainPriceGraph= true;
            sc.AutoLoop = 1;

            sc.GraphDrawType = GDT_OHLCBAR;
            sc.StandardChartHeader = 1;

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

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

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

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

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

            Subgraph_OpenInterest.Name = "Num Trades / OpenInterest";
            Subgraph_OpenInterest.DrawStyle = DRAWSTYLE_IGNORE;
            Subgraph_OpenInterest.PrimaryColor = RGB(0,0,255);
            Subgraph_OpenInterest.DrawZeros = false;

            Subgraph_OHLCAvg.Name = "OHLC Avg";
            Subgraph_OHLCAvg.DrawStyle = DRAWSTYLE_IGNORE;
            Subgraph_OHLCAvg.PrimaryColor = RGB(0,255,0);
            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;

            return;
        }

            if (sc.BaseDataIn[SC_OPEN][sc.Index] == 0.0f)
                sc.Subgraph[SC_OPEN][sc.Index] = 0.0f;
            else
                sc.Subgraph[SC_OPEN][sc.Index] = 1.0f / sc.BaseDataIn[SC_OPEN][sc.Index];

            if (sc.BaseDataIn[SC_HIGH][sc.Index] == 0.0f)
                sc.Subgraph[SC_LOW][sc.Index] = 0.0f;
            else
                sc.Subgraph[SC_LOW][sc.Index] = 1.0f / sc.BaseDataIn[SC_HIGH][sc.Index];

            if (sc.BaseDataIn[SC_LOW][sc.Index] == 0.0f)
                sc.Subgraph[SC_HIGH][sc.Index] = 0.0f;
            else
                sc.Subgraph[SC_HIGH][sc.Index] = 1.0f / sc.BaseDataIn[SC_LOW][sc.Index];

            if (sc.BaseDataIn[SC_LAST][sc.Index] == 0.0f)
                sc.Subgraph[SC_LAST][sc.Index] = 0.0f;
            else
                sc.Subgraph[SC_LAST][sc.Index] = 1.0f / sc.BaseDataIn[SC_LAST][sc.Index];

            sc.Subgraph[SC_VOLUME][sc.Index] =sc.BaseDataIn[SC_VOLUME][sc.Index];
            sc.Subgraph[SC_NUM_TRADES][sc.Index] =sc.BaseDataIn[SC_NUM_TRADES][sc.Index];

            if (sc.BaseDataIn[SC_OHLC_AVG][sc.Index] == 0.0f)
                sc.Subgraph[SC_OHLC_AVG][sc.Index] = 0.0f;
            else
                sc.Subgraph[SC_OHLC_AVG][sc.Index] = 1.0f / sc.BaseDataIn[SC_OHLC_AVG][sc.Index];

            if (sc.BaseDataIn[SC_HLC_AVG][sc.Index] == 0.0f)
                sc.Subgraph[SC_HLC_AVG][sc.Index] = 0.0f;
            else
                sc.Subgraph[SC_HLC_AVG][sc.Index] = 1.0f / sc.BaseDataIn[SC_HLC_AVG][sc.Index];

            if (sc.BaseDataIn[SC_HL_AVG][sc.Index] == 0.0f)
                sc.Subgraph[SC_HL_AVG][sc.Index] = 0.0f;
            else
                sc.Subgraph[SC_HL_AVG][sc.Index] = 1.0f / sc.BaseDataIn[SC_HL_AVG][sc.Index];

            sc.Subgraph[SC_ASKVOL][sc.Index] = sc.BaseDataIn[SC_ASKVOL][sc.Index];
            sc.Subgraph[SC_BIDVOL][sc.Index] = sc.BaseDataIn[SC_BIDVOL][sc.Index];

        SCString ChartName = sc.GetStudyNameFromChart(sc.ChartNumber, 0);
        sc.GraphName.Format("1/P %s", ChartName.GetChars());
    }

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

    SCSFExport scsf_RoundPriceBarsToTickSize(SCStudyInterfaceRef sc)
    {
        SCSubgraphRef Subgraph_Open = sc.Subgraph[0];
        SCSubgraphRef Subgraph_High = sc.Subgraph[1];
        SCSubgraphRef Subgraph_Low = sc.Subgraph[2];
        SCSubgraphRef Subgraph_Last = sc.Subgraph[3];
        SCSubgraphRef Subgraph_Volume = sc.Subgraph[4];
        SCSubgraphRef Subgraph_OpenInterest = 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)
        {
            sc.GraphName = "Round Price Bars To Tick Size";

            sc.StudyDescription= "This study when applied to a chart will round the bar values to the Tick Size set in Chart >> Chart Settings.";

            sc.GraphUsesChartColors= true;

            sc.ValueFormat = VALUEFORMAT_INHERITED;
            sc.GraphRegion = 0;
            sc.DisplayAsMainPriceGraph= true;
            sc.AutoLoop = 1;

            sc.GraphDrawType = GDT_OHLCBAR;
            sc.StandardChartHeader = 1;

            Subgraph_Open.Name = "Open";
            Subgraph_Open.DrawStyle = DRAWSTYLE_LINE;
            Subgraph_Open.PrimaryColor = RGB(255, 255,255);

            Subgraph_High.Name = "High";
            Subgraph_High.DrawStyle = DRAWSTYLE_LINE;
            Subgraph_High.PrimaryColor = RGB(255, 255,255);

            Subgraph_Low.Name = "Low";
            Subgraph_Low.DrawStyle = DRAWSTYLE_LINE;
            Subgraph_Low.PrimaryColor = RGB(255, 255,255);

            Subgraph_Last.Name = "Last";
            Subgraph_Last.DrawStyle = DRAWSTYLE_LINE;
            Subgraph_Last.PrimaryColor = RGB(255, 255,255);

            Subgraph_Volume.Name = "Volume";
            Subgraph_Volume.DrawStyle = DRAWSTYLE_IGNORE;
            Subgraph_Volume.PrimaryColor = RGB(255,0,0);

            Subgraph_OpenInterest.Name = "Num Trades / OpenInterest";
            Subgraph_OpenInterest.DrawStyle = DRAWSTYLE_IGNORE;
            Subgraph_OpenInterest.PrimaryColor = RGB(0,0,255);

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

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

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

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

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

            return;
        }

            sc.Subgraph[SC_OPEN][sc.Index] = sc.RoundToTickSize(sc.BaseDataIn[SC_OPEN][sc.Index] , sc.TickSize);
            sc.Subgraph[SC_HIGH][sc.Index] = sc.RoundToTickSize(sc.BaseDataIn[SC_HIGH][sc.Index] , sc.TickSize);
            sc.Subgraph[SC_LOW][sc.Index] = sc.RoundToTickSize(sc.BaseDataIn[SC_LOW][sc.Index] , sc.TickSize);
            sc.Subgraph[SC_LAST][sc.Index] = sc.RoundToTickSize(sc.BaseDataIn[SC_LAST][sc.Index] , sc.TickSize);

            for(int SubgraphIndex =SC_VOLUME; SubgraphIndex <=SC_ASKVOL;SubgraphIndex++)
                sc.Subgraph[SubgraphIndex][sc.Index] =sc.BaseDataIn[SubgraphIndex][sc.Index];

        sc.GraphName= sc.GetStudyNameFromChart(sc.ChartNumber, 0);
    }

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

    SCSFExport scsf_DifferenceSingleLine(SCStudyInterfaceRef sc)
    {
        SCSubgraphRef Subgraph_Difference = sc.Subgraph[0];

        SCInputRef Input_Data = sc.Input[0];
        SCInputRef Input_UseLatestSourceDataForLastBar = sc.Input[1];
        SCInputRef Input_Chart2Number = sc.Input[3];
        SCInputRef Input_Chart1Multiplier = sc.Input[4];
        SCInputRef Input_Chart2Multiplier = sc.Input[5];
        SCInputRef Input_Chart1Addition = sc.Input[6];
        SCInputRef Input_ZeroOutputWhenOneSourceGraphHasZeroValues = sc.Input[7];

        if (sc.SetDefaults)
        {
            sc.GraphName = "Difference (Single Line)";

            sc.ValueFormat = VALUEFORMAT_INHERITED;
            sc.GraphRegion = 1;

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

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

            Input_UseLatestSourceDataForLastBar.Name = "Use Latest Source Data For Last Bar";
            Input_UseLatestSourceDataForLastBar.SetYesNo(0);

            Input_Chart2Number.Name = "Chart 2 Number";
            Input_Chart2Number.SetChartNumber(1);

            Input_Chart1Multiplier.Name = "Chart 1 Multiplier";
            Input_Chart1Multiplier.SetFloat(1.0f);

            Input_Chart2Multiplier.Name = "Chart 2 Multiplier";
            Input_Chart2Multiplier.SetFloat(1.0f);

            Input_Chart1Addition.Name = "Chart 1 Addition";
            Input_Chart1Addition.SetFloat(0.0f);

            Input_ZeroOutputWhenOneSourceGraphHasZeroValues.Name = "Zero Output When one Source Graph has Zero Values";
            Input_ZeroOutputWhenOneSourceGraphHasZeroValues.SetYesNo(0);

            return;
        }

        if (sc.IsFullRecalculation)
        {
            SCString Chart1Name = sc.GetStudyNameFromChart(sc.ChartNumber, 0);
            SCString Chart2Name = sc.GetStudyNameFromChart(Input_Chart2Number.GetChartNumber(), 0);
            sc.GraphName.Format("Diff %s - %s", Chart1Name.GetChars(), Chart2Name.GetChars());
        }

        SCFloatArray Chart2Array;
        sc.GetChartArray(Input_Chart2Number.GetChartNumber()*-1, Input_Data.GetInputDataIndex(), Chart2Array);

        if (Chart2Array.GetArraySize() == 0)
            return;

        sc.DataStartIndex = 0;

        int CalculationStartIndex = sc.GetCalculationStartIndexForStudy();

        for (int DestinationIndex = CalculationStartIndex; DestinationIndex < sc.ArraySize; DestinationIndex++)
        {
            int Chart2Index = sc.GetNearestMatchForDateTimeIndex(Input_Chart2Number.GetChartNumber(), DestinationIndex);

            //When use latest source data for last bar is set to Yes, replay is not running and at last bar in the destination chart, then use the data from the very latest bar in the source chart.
            if (Input_UseLatestSourceDataForLastBar.GetYesNo() && !sc.IsReplayRunning() && DestinationIndex == sc.ArraySize - 1)
            {
                Chart2Index = Chart2Array.GetArraySize() - 1;
            }

            if (Input_ZeroOutputWhenOneSourceGraphHasZeroValues.GetYesNo())
            {
                bool AllZeros = true;

                if (Chart2Array[Chart2Index] != 0)
                {
                    AllZeros = false;
                }

                if (AllZeros)
                    continue;

                AllZeros = true;

                if (sc.BaseDataIn[Input_Data.GetInputDataIndex()][DestinationIndex] != 0)
                {
                    AllZeros = false;
                }

                if (AllZeros)
                    continue;
            }

            Subgraph_Difference[DestinationIndex] = (sc.BaseDataIn[Input_Data.GetInputDataIndex()][DestinationIndex] * Input_Chart1Multiplier.GetFloat() + Input_Chart1Addition.GetFloat()) -
                (Chart2Array[Chart2Index] * Input_Chart2Multiplier.GetFloat());
        }

        sc.EarliestUpdateSubgraphDataArrayIndex = CalculationStartIndex;

    }
    /*==========================================================================*/

    SCSFExport scsf_DifferenceNetChange(SCStudyInterfaceRef sc)
    {
        SCSubgraphRef Subgraph_Difference = sc.Subgraph[0];
        SCInputRef Input_Chart2Number = sc.Input[3];

        if (sc.SetDefaults)
        {
            //Calculates the difference of the bar to bar price change between two charts
            sc.GraphName = "Bar Price Change Difference - 2 Chart";

            sc.ValueFormat = VALUEFORMAT_INHERITED;
            sc.GraphRegion = 1;

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

            Input_Chart2Number.Name = "Chart 2 Number";
            Input_Chart2Number.SetChartNumber(1);

            return;
        }

        SCFloatArray Chart2Array;
        sc.GetChartArray(Input_Chart2Number.GetChartNumber()*-1, SC_LAST, Chart2Array);

        if (Chart2Array.GetArraySize() == 0)
            return;

        sc.DataStartIndex = 1;

        for (int Chart1BarIndex = max(1, sc.UpdateStartIndex); Chart1BarIndex < sc.ArraySize; Chart1BarIndex++)
        {
            int Chart2Index = sc.GetNearestMatchForDateTimeIndex(Input_Chart2Number.GetChartNumber(), Chart1BarIndex);

            Subgraph_Difference[Chart1BarIndex] = (sc.BaseDataIn[SC_LAST][Chart1BarIndex] - sc.BaseDataIn[SC_LAST][Chart1BarIndex - 1] ) - ( Chart2Array[Chart2Index] - Chart2Array[Chart2Index - 1]);
        }

        SCString Chart1Name = sc.GetStudyNameFromChart(sc.ChartNumber, 0);
        SCString Chart2Name = sc.GetStudyNameFromChart(Input_Chart2Number.GetChartNumber(), 0);
        sc.GraphName.Format("Bar Change Difference %s - %s", Chart1Name.GetChars(), Chart2Name.GetChars());
    }

    /*==========================================================================*/
    SCSFExport scsf_RatioSingleLine(SCStudyInterfaceRef sc)
    {
        SCSubgraphRef Subgraph_Ratio = sc.Subgraph[0];
        SCInputRef Input_Data = sc.Input[0];
        SCInputRef Input_Chart2Number = sc.Input[3];
        SCInputRef Input_Chart1Multiplier = sc.Input[4];
        SCInputRef Input_Chart2Multiplier = sc.Input[5];
        SCInputRef Input_UseLatestSourceDataForLastBar = sc.Input[6];

        if (sc.SetDefaults)
        {
            sc.GraphName = "Ratio (Single Line)";

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

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

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

            Input_Chart2Number.Name = "Chart 2 Number";
            Input_Chart2Number.SetChartNumber(1);

            Input_Chart1Multiplier.Name = "Chart 1 Multiplier";
            Input_Chart1Multiplier.SetFloat(1.0f);

            Input_Chart2Multiplier.Name = "Chart 2 Multiplier";
            Input_Chart2Multiplier.SetFloat(1.0f);

            Input_UseLatestSourceDataForLastBar.Name = "Use Latest Source Data For Last Bar";
            Input_UseLatestSourceDataForLastBar.SetYesNo(0);

            return;
        }

        SCFloatArray Chart2Array;
        sc.GetChartArray(Input_Chart2Number.GetChartNumber()*-1, Input_Data.GetInputDataIndex(), Chart2Array);

        if (Chart2Array.GetArraySize() == 0)
            return;

        for (int BarIndex = sc.UpdateStartIndex; BarIndex < sc.ArraySize; BarIndex++)
        {
            int Chart2Index = sc.GetNearestMatchForDateTimeIndex(Input_Chart2Number.GetChartNumber(), BarIndex);

            //When 'use latest source data for last bar' is set to Yes, replay is not running and at last bar in the destination chart, then use the data from the very latest bar in the source chart.
            if(Input_UseLatestSourceDataForLastBar.GetYesNo() && !sc.IsReplayRunning() && BarIndex == sc.ArraySize - 1)
                Chart2Index = Chart2Array.GetArraySize() - 1;

            if (sc.BaseDataIn[Input_Data.GetInputDataIndex()][BarIndex] == 0
                || Chart2Array[Chart2Index] == 0)
            {
                Subgraph_Ratio[BarIndex] = 0;
                continue;
            }

            Subgraph_Ratio[BarIndex] = (sc.BaseDataIn[Input_Data.GetInputDataIndex()][BarIndex] * Input_Chart1Multiplier.GetFloat())
                        / (Chart2Array[Chart2Index] * Input_Chart2Multiplier.GetFloat());
        }

        SCString Chart1Name = sc.GetStudyNameFromChart(sc.ChartNumber, 0);
        SCString Chart2Name = sc.GetStudyNameFromChart(Input_Chart2Number.GetChartNumber(), 0);
        sc.GraphName.Format("Ratio %s / %s", Chart1Name.GetChars(), Chart2Name.GetChars());
    }

    /*==========================================================================*/
    SCSFExport scsf_OverlayBar(SCStudyInterfaceRef sc)
    {
        SCSubgraphRef Subgraph_Open = sc.Subgraph[0];
        SCSubgraphRef Subgraph_High = sc.Subgraph[1];
        SCSubgraphRef Subgraph_Low = sc.Subgraph[2];
        SCSubgraphRef Subgraph_Last = sc.Subgraph[3];
        SCSubgraphRef Subgraph_Volume = sc.Subgraph[4];
        SCSubgraphRef Subgraph_OpenInterest = 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];
        SCSubgraphRef Subgraph_Unused11 = sc.Subgraph[11];
        SCSubgraphRef Subgraph_Unused12 = sc.Subgraph[12];

        SCInputRef Input_OverlayFromSameChartAsStudy = sc.Input[0];
        SCInputRef Input_ChartOverlayNumber = sc.Input[3];
        SCInputRef Input_Multiplier = sc.Input[4];

        if (sc.SetDefaults)
        {
            sc.GraphName = "Overlay (Bar)";

            sc.UseGlobalChartColors = 0;

            //When the ability to access all the variables of another chart is supported,
            //this should be changed to get the value format from the source chart
            sc.ValueFormat = VALUEFORMAT_INHERITED;

            sc.GraphRegion =1;
            sc.ScaleRangeType = SCALE_INDEPENDENT;
            sc.GraphDrawType = GDT_OHLCBAR;
            sc.StandardChartHeader = 1;

            Subgraph_Open.Name = "Open";
            Subgraph_Open.DrawStyle = DRAWSTYLE_LINE;
            Subgraph_Open.PrimaryColor = RGB(0,255,0);
            Subgraph_Open.SecondaryColor = RGB(0,255,0);
            Subgraph_Open.SecondaryColorUsed = 1;
            Subgraph_Open.DrawZeros = false;

            Subgraph_High.Name = "High";
            Subgraph_High.DrawStyle = DRAWSTYLE_LINE;
            Subgraph_High.PrimaryColor = RGB(128,255,128);
            Subgraph_High.DrawZeros = false;

            Subgraph_Low.Name = "Low";
            Subgraph_Low.DrawStyle = DRAWSTYLE_LINE;
            Subgraph_Low.PrimaryColor = RGB(255,0,0);
            Subgraph_Low.SecondaryColor = RGB(255,0,0);
            Subgraph_Low.SecondaryColorUsed = 1;
            Subgraph_Low.DrawZeros = false;

            Subgraph_Last.Name = "Last";
            Subgraph_Last.DrawStyle = DRAWSTYLE_LINE;
            Subgraph_Last.PrimaryColor = RGB(255,128,128);
            Subgraph_Last.DrawZeros = false;
            Subgraph_Last.LineLabel = LL_DISPLAY_VALUE | LL_VALUE_ALIGN_VALUES_SCALE | LL_VALUE_ALIGN_CENTER;

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

            Subgraph_OpenInterest.Name = "# of Trades / OI";
            Subgraph_OpenInterest.DrawStyle = DRAWSTYLE_IGNORE;
            Subgraph_OpenInterest.PrimaryColor = RGB(0,0,255);
            Subgraph_OpenInterest.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;

            Subgraph_Unused11.DrawStyle = DRAWSTYLE_IGNORE;
            Subgraph_Unused12.DrawStyle = DRAWSTYLE_IGNORE;

            Input_OverlayFromSameChartAsStudy.Name = "Overlay from Same Chart as Study";
            Input_OverlayFromSameChartAsStudy.SetYesNo(false);

            Input_ChartOverlayNumber.Name = "Chart Number To Overlay";
            Input_ChartOverlayNumber.SetChartNumber(1);

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

            return;
        }

        if (Input_OverlayFromSameChartAsStudy.GetYesNo())
            Input_ChartOverlayNumber.SetChartNumber(sc.ChartNumber);

        SCGraphData ChartOverlayArrays;
        sc.GetChartBaseData(-Input_ChartOverlayNumber.GetChartNumber(), ChartOverlayArrays);

        if (ChartOverlayArrays[SC_OPEN].GetArraySize() == 0)
            return;

        for (int DataIndex = sc.UpdateStartIndex; DataIndex < sc.ArraySize; DataIndex++)
        {
            const int OverlayBarIndex = sc.GetNearestMatchForDateTimeIndex(Input_ChartOverlayNumber.GetChartNumber(), DataIndex);

            for (int SubgraphIndex = 0; SubgraphIndex < ChartOverlayArrays.GetArraySize(); SubgraphIndex++)
            {
                sc.Subgraph[SubgraphIndex][DataIndex] = ChartOverlayArrays[SubgraphIndex][OverlayBarIndex] * Input_Multiplier.GetFloat();
            }
        }

        SCString ChartOverlayName = sc.GetStudyNameFromChart(Input_ChartOverlayNumber.GetChartNumber(), 0);
        sc.GraphName.Format("%s Overlay", ChartOverlayName.GetChars());
    }

    /*==========================================================================*/
    SCSFExport scsf_HorizontalLines(SCStudyInterfaceRef sc)
    {
        const int NumberOfLines = SC_SUBGRAPHS_AVAILABLE - 1;
        SCInputRef Input_SetAllSubgraphsToBeSameAsFirst = sc.Input[SC_SUBGRAPHS_AVAILABLE - 1];

        if (sc.SetDefaults)
        {
            sc.GraphName = "Horizontal Lines";

            sc.ValueFormat = 3;
            sc.AutoLoop = 1;
            sc.DisplayStudyInputValues = false;

            for (int SubgraphIndex = 0; SubgraphIndex < NumberOfLines; SubgraphIndex++)
            {

                sc.Subgraph[SubgraphIndex].Name.Format("Line%d", SubgraphIndex + 1);
                sc.Subgraph[SubgraphIndex].DrawStyle = DRAWSTYLE_IGNORE;
                sc.Subgraph[SubgraphIndex].PrimaryColor = RGB(0,255,0);
                sc.Subgraph[SubgraphIndex].DrawZeros = true;
                sc.Subgraph[SubgraphIndex].DisplayNameValueInWindowsFlags = false;

                sc.Input[SubgraphIndex].Name.Format("Line%d Value", SubgraphIndex + 1);
                sc.Input[SubgraphIndex].SetFloat(1.0f);
                sc.Input[SubgraphIndex].SetFloatLimits(-FLT_MAX, FLT_MAX);
            }

            sc.Subgraph[0].DrawStyle = DRAWSTYLE_LINE;

            Input_SetAllSubgraphsToBeSameAsFirst.Name = "Set All Subgraph Display Settings to Be Same as First";
            Input_SetAllSubgraphsToBeSameAsFirst.SetYesNo(false);

            return;
        }

        for (int SubgraphIndex = 0; SubgraphIndex < NumberOfLines; SubgraphIndex++)
        {
            if (sc.Subgraph[SubgraphIndex].DrawStyle == DRAWSTYLE_IGNORE)
                continue;

            if (sc.IsFullRecalculation
                && sc.Index == 0
                && Input_SetAllSubgraphsToBeSameAsFirst.GetYesNo()
                && SubgraphIndex > 0)
            {
                sc.Subgraph[SubgraphIndex].DrawStyle = sc.Subgraph[0].DrawStyle;
                sc.Subgraph[SubgraphIndex].PrimaryColor = sc.Subgraph[0].PrimaryColor;
                sc.Subgraph[SubgraphIndex].LineStyle = sc.Subgraph[0].LineStyle;
                sc.Subgraph[SubgraphIndex].LineWidth = sc.Subgraph[0].LineWidth;
                sc.Subgraph[SubgraphIndex].LineLabel = sc.Subgraph[0].LineLabel;
            }

            //Only do this on the first iteration for efficiency
            if (sc.IsFullRecalculation && sc.Index == 0)
                sc.Input[SubgraphIndex].Name.Format("%s Value",sc.Subgraph[SubgraphIndex].Name.GetChars());

            sc.Subgraph[SubgraphIndex][sc.Index] = sc.Input[SubgraphIndex].GetFloat();
        }
    }

    /*==========================================================================*/
    SCSFExport scsf_HorizontalLinesAtIncrement(SCStudyInterfaceRef sc)
    {
        const int NumberOfLines = SC_SUBGRAPHS_AVAILABLE - 1;

        SCInputRef Input_StartValue = sc.Input[0];
        SCInputRef Input_LineIncrement = sc.Input[1];
        SCInputRef Input_SetAllSubgraphsToBeSameAsFirst = sc.Input[2];

        if (sc.SetDefaults)
        {
            sc.GraphName = "Horizontal Lines at Increment";

            sc.ValueFormat = VALUEFORMAT_INHERITED;
            sc.DisplayStudyInputValues = false;
            sc.ScaleRangeType = SCALE_SAMEASREGION;
            sc.GraphRegion = 0;

            for (int SubgraphIndex = 0; SubgraphIndex < NumberOfLines; SubgraphIndex++)
            {
                sc.Subgraph[SubgraphIndex].Name.Format("Line%d", SubgraphIndex + 1);
                sc.Subgraph[SubgraphIndex].DrawStyle = DRAWSTYLE_LINE;
                sc.Subgraph[SubgraphIndex].PrimaryColor = RGB(0,255,0);
                sc.Subgraph[SubgraphIndex].DrawZeros = false;
                sc.Subgraph[SubgraphIndex].DisplayNameValueInWindowsFlags = false;

            }

            Input_SetAllSubgraphsToBeSameAsFirst.Name = "Set All Subgraph Display Settings to Be Same as First";
            Input_SetAllSubgraphsToBeSameAsFirst.SetYesNo(false);

            Input_StartValue.Name = "Start Value";
            Input_StartValue.SetFloat(0);

            Input_LineIncrement.Name = "Line Increment";
            Input_LineIncrement.SetFloat(1);

            return;
        }

        for(int BarIndex = sc.UpdateStartIndex; BarIndex < sc.ArraySize; BarIndex++)
        {
            float CurrentLineValue = Input_StartValue.GetFloat();

            for (int SubgraphIndex = 0; SubgraphIndex < NumberOfLines; SubgraphIndex++)
            {
                if (sc.Subgraph[SubgraphIndex].DrawStyle == DRAWSTYLE_IGNORE)
                    continue;

                if (sc.IsFullRecalculation
                    && BarIndex == 0
                    && Input_SetAllSubgraphsToBeSameAsFirst.GetYesNo()
                    && SubgraphIndex > 0)
                {
                    sc.Subgraph[SubgraphIndex].DrawStyle = sc.Subgraph[0].DrawStyle;
                    sc.Subgraph[SubgraphIndex].PrimaryColor = sc.Subgraph[0].PrimaryColor;
                    sc.Subgraph[SubgraphIndex].LineStyle = sc.Subgraph[0].LineStyle;
                    sc.Subgraph[SubgraphIndex].LineWidth = sc.Subgraph[0].LineWidth;
                    sc.Subgraph[SubgraphIndex].LineLabel = sc.Subgraph[0].LineLabel;
                }

                sc.Subgraph[SubgraphIndex][BarIndex] = CurrentLineValue;

                CurrentLineValue += Input_LineIncrement.GetFloat();
            }

        }
    }

    /*==========================================================================*/
    SCSFExport scsf_RelativeMomentumIndex(SCStudyInterfaceRef sc)
    {
        SCSubgraphRef Subgraph_RMI = sc.Subgraph[0];
        SCSubgraphRef Subgraph_Line1 = sc.Subgraph[1];
        SCSubgraphRef Subgraph_Line2 = sc.Subgraph[2];
        SCSubgraphRef Subgraph_Midline = sc.Subgraph[3];

        SCInputRef Input_Data = sc.Input[0];
        SCInputRef Input_RMILength = sc.Input[3];
        SCInputRef Input_RMI_MALength = sc.Input[4];
        SCInputRef Input_RMI_MAType = sc.Input[5];
        SCInputRef Input_Line1Value = sc.Input[6];
        SCInputRef Input_Line2Value = sc.Input[7];
        SCInputRef Input_MidlineValue = sc.Input[8];

        SCFloatArrayRef Array_UpTemp = Subgraph_RMI.Arrays[0];
        SCFloatArrayRef Array_DownTemp = Subgraph_RMI.Arrays[1];
        SCFloatArrayRef Array_SmoothedUpTemp = Subgraph_RMI.Arrays[2];
        SCFloatArrayRef Array_SmoothedDownTemp = Subgraph_RMI.Arrays[3];

        if (sc.SetDefaults)
        {
            sc.GraphName = "Relative Momentum Index";

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

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

            Subgraph_Line1.Name = "Overbought";
            Subgraph_Line1.DrawStyle = DRAWSTYLE_LINE;
            Subgraph_Line1.PrimaryColor = RGB(128, 128, 128);
            Subgraph_Line1.DrawZeros = true;

            Subgraph_Line2.Name = "Oversold";
            Subgraph_Line2.DrawStyle = DRAWSTYLE_LINE;
            Subgraph_Line2.PrimaryColor = RGB(128, 128, 128);
            Subgraph_Line2.DrawZeros = true;

            Subgraph_Midline.Name = "Midline";
            Subgraph_Midline.DrawStyle = DRAWSTYLE_LINE;
            Subgraph_Midline.PrimaryColor = RGB(128, 128, 128);
            Subgraph_Midline.DrawZeros = true;

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

            Input_RMILength.Name = "RMI Length";
            Input_RMILength.SetInt(5);
            Input_RMILength.SetIntLimits(1, MAX_STUDY_LENGTH);

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

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

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

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

            Input_MidlineValue.Name = "Midline Value";
            Input_MidlineValue.SetFloat(50.0f);

            return;
        }

        sc.DataStartIndex = max(Input_RMILength.GetInt(), Input_RMI_MALength.GetInt());

        float previousValue = sc.BaseDataIn[Input_Data.GetInputDataIndex()][sc.Index - Input_RMILength.GetInt()];
        float currentValue = sc.BaseDataIn[Input_Data.GetInputDataIndex()][sc.Index];

        if (currentValue > previousValue)
        {
            Array_UpTemp[sc.Index] = currentValue - previousValue;
            Array_DownTemp[sc.Index] = 0.0f;
        }
        else
        {
            Array_UpTemp[sc.Index] = 0;
            Array_DownTemp[sc.Index] = previousValue - currentValue;
        }

        sc.MovingAverage(Array_UpTemp, Array_SmoothedUpTemp, Input_RMI_MAType.GetMovAvgType(), Input_RMI_MALength.GetInt());
        sc.MovingAverage(Array_DownTemp, Array_SmoothedDownTemp, Input_RMI_MAType.GetMovAvgType(), Input_RMI_MALength.GetInt());

        if (Array_SmoothedUpTemp[sc.Index] + Array_SmoothedDownTemp[sc.Index] != 0.0f)
        {
            Subgraph_RMI[sc.Index] = 100 * Array_SmoothedUpTemp[sc.Index] / (Array_SmoothedUpTemp[sc.Index] + Array_SmoothedDownTemp[sc.Index]);
        }
        else
        {
            Subgraph_RMI[sc.Index] = Subgraph_RMI[sc.Index - 1];
        }

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

    /*==========================================================================*/
    SCSFExport scsf_OverlayNonSync(SCStudyInterfaceRef sc)
    {
        SCSubgraphRef Subgraph_Open = sc.Subgraph[0];
        SCSubgraphRef Subgraph_High = sc.Subgraph[1];
        SCSubgraphRef Subgraph_Low = sc.Subgraph[2];
        SCSubgraphRef Subgraph_Last = sc.Subgraph[3];
        SCSubgraphRef Subgraph_Volume = sc.Subgraph[4];
        SCSubgraphRef Subgraph_OpenInterest = 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];
        SCSubgraphRef Subgraph_Unused11 = sc.Subgraph[11];
        SCSubgraphRef Subgraph_Unused12 = sc.Subgraph[12];

        SCInputRef Input_NumberOfBars = sc.Input[2];
        SCInputRef Input_ChartOverlayNumber = sc.Input[3];
        SCInputRef Input_Multiplier = sc.Input[4];

        if (sc.SetDefaults)
        {
            sc.GraphName = "Overlay (Non-Sync)";

            sc.UseGlobalChartColors = 0;

            sc.ValueFormat = 2;
            sc.GraphRegion = 0;
            sc.ScaleRangeType = SCALE_INDEPENDENT;
            sc.GraphDrawType = GDT_OHLCBAR;
            sc.StandardChartHeader = 1;

            Subgraph_Open.Name = "Open";
            Subgraph_Open.DrawStyle = DRAWSTYLE_LINE;
            Subgraph_Open.PrimaryColor = RGB(0,255,0);
            Subgraph_Open.SecondaryColor = RGB(0,255,0);
            Subgraph_Open.SecondaryColorUsed = 1;
            Subgraph_Open.DrawZeros = false;

            Subgraph_High.Name = "High";
            Subgraph_High.DrawStyle = DRAWSTYLE_LINE;
            Subgraph_High.PrimaryColor = RGB(128,255,128);
            Subgraph_High.DrawZeros = false;

            Subgraph_Low.Name = "Low";
            Subgraph_Low.DrawStyle = DRAWSTYLE_LINE;
            Subgraph_Low.PrimaryColor = RGB(255,0,0);
            Subgraph_Low.SecondaryColor = RGB(255,0,0);
            Subgraph_Low.SecondaryColorUsed = 1;
            Subgraph_Low.DrawZeros = false;

            Subgraph_Last.Name = "Last";
            Subgraph_Last.DrawStyle = DRAWSTYLE_LINE;
            Subgraph_Last.PrimaryColor = RGB(255,128,128);
            Subgraph_Last.DrawZeros = false;

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

            Subgraph_OpenInterest.Name = "# of Trades / OI";
            Subgraph_OpenInterest.DrawStyle = DRAWSTYLE_IGNORE;
            Subgraph_OpenInterest.PrimaryColor = RGB(0,0,255);
            Subgraph_OpenInterest.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;

            Subgraph_Unused11.DrawStyle = DRAWSTYLE_IGNORE;
            Subgraph_Unused12.DrawStyle = DRAWSTYLE_IGNORE;

            Input_NumberOfBars.Name = "Number of bars to Overlay";
            Input_NumberOfBars.SetInt(500);
            Input_NumberOfBars.SetIntLimits(1,MAX_STUDY_LENGTH);

            Input_ChartOverlayNumber.Name = "Chart Number To Overlay";
            Input_ChartOverlayNumber.SetChartNumber(1);

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

            return;
        }

        SCGraphData ChartOverlayArrays;
        sc.GetChartBaseData(Input_ChartOverlayNumber.GetChartNumber(), ChartOverlayArrays);

        int OverlayArraySize = ChartOverlayArrays[0].GetArraySize();
        if (OverlayArraySize == 0)
            return;

        for (int Index = sc.ArraySize - 1; (Index >= sc.ArraySize - Input_NumberOfBars.GetInt()) && (Index >= 0); Index--)
        {
            OverlayArraySize--;
            for (int i2 = 0; i2 < ChartOverlayArrays.GetArraySize(); i2++)
            {
                if (OverlayArraySize >= 0)
                {
                    sc.Subgraph[i2][Index] = ChartOverlayArrays[i2][OverlayArraySize] * Input_Multiplier.GetFloat();
                }
                else
                    sc.Subgraph[i2][Index] = 0.0f;
            }
        }

        for (int Index = sc.ArraySize - Input_NumberOfBars.GetInt() - 1; (Index >= sc.ArraySize - sc.UpdateStartIndex) && (Index >= 0); Index--)
        {
            for (int i2 = 0; i2 < ChartOverlayArrays.GetArraySize(); i2++)
                sc.Subgraph[i2][Index] = 0.0f;
        }

        SCString ChartOverlayName = sc.GetStudyNameFromChart(Input_ChartOverlayNumber.GetChartNumber(), 0);
        sc.GraphName.Format("%s Overlay", ChartOverlayName.GetChars());
    }

    /*==========================================================================*/
    SCSFExport scsf_OnBalanceOpenInterestShortTerm(SCStudyInterfaceRef sc)
    {
        SCSubgraphRef Subgraph_OBOI = sc.Subgraph[0];
        SCSubgraphRef Subgraph_Temp = sc.Subgraph[1];
        SCInputRef Input_Length = sc.Input[0];

        if (sc.SetDefaults)
        {
            sc.GraphName = "On Balance Open Interest - Short Term";

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

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

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

            return;
        }

        sc.DataStartIndex= Input_Length.GetInt();
        if (sc.Index < 1)
            return;

        if(sc.Close[sc.Index ] > sc.Close[sc.Index-1])
        {
            Subgraph_Temp[sc.Index] = sc.OpenInterest[sc.Index];
        }
        else if(sc.Close[sc.Index ] < sc.Close[sc.Index-1])
        {
            Subgraph_Temp[sc.Index] = -sc.OpenInterest[sc.Index];
        }
        else
        {
            Subgraph_Temp[sc.Index] = 0.0f;
        }

        if(sc.Index < Input_Length.GetInt())
        {
            Subgraph_OBOI[sc.Index] = Subgraph_OBOI[sc.Index - 1] + Subgraph_Temp[sc.Index];
        }
        else
        {
            Subgraph_OBOI[sc.Index] = Subgraph_OBOI[sc.Index - 1] + Subgraph_Temp[sc.Index] - Subgraph_Temp[sc.Index - Input_Length.GetInt()];
        }
    }

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

    Coppock Curve = 10-period WMA of 14-period RoC + 11-period RoC

    WMA = Weighted moving average
    RoC = Rate-of-Change

    ROC = [(Close - Close n periods ago) / (Close n periods ago)] * 100

    */
    SCSFExport scsf_CoppockCurve(SCStudyInterfaceRef sc)
    {
        SCSubgraphRef Subgraph_CoppockCurve = sc.Subgraph[0];
        SCFloatArrayRef Array_RateOfChangeSum = sc.Subgraph[0].Arrays[0];
        SCInputRef Input_Data = sc.Input[0];
        SCInputRef Input_MovingAverageLength = sc.Input[1];

        if (sc.SetDefaults)
        {
            sc.GraphName = "Coppock Curve";

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

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

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

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

            return;
        }

        //sc.DataStartIndex = MovingAverageLength.GetInt();

        if (sc.Index < sc.DataStartIndex)
            return;

        float ROC1 = 0.0;
        float ROC2 = 0.0;
        int InputDataIndex = Input_Data.GetInputDataIndex();

        ROC1 = ((sc.BaseData[InputDataIndex][sc.Index] - sc.BaseData[InputDataIndex][sc.Index - 14]) / sc.BaseData[InputDataIndex][sc.Index - 14]) * 100;

        ROC2 = ((sc.BaseData[InputDataIndex][sc.Index] - sc.BaseData[InputDataIndex][sc.Index - 11]) / sc.BaseData[InputDataIndex][sc.Index - 11]) * 100;

        Array_RateOfChangeSum[sc.Index] = ROC1 + ROC2;

        sc.WeightedMovingAverage(Array_RateOfChangeSum, Subgraph_CoppockCurve, Input_MovingAverageLength.GetInt());

    }

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

        SCInputRef Input_Data = sc.Input[0];
        SCInputRef Input_LengthIndex = sc.Input[1];
        SCInputRef Input_PerformCumulativeCalculation = sc.Input[2];

        if (sc.SetDefaults)
        {
            sc.GraphName = "Hurst Exponent";

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

            Subgraph_HurstExponent.Name = "HE";
            Subgraph_HurstExponent.DrawStyle = DRAWSTYLE_LINE;
            Subgraph_HurstExponent.PrimaryColor = RGB(0, 255, 0);
            Subgraph_HurstExponent.LineWidth = 1;
            Subgraph_HurstExponent.DrawZeros = true;

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

            Input_LengthIndex.Name = "Length";
            Input_LengthIndex.SetCustomInputStrings("32;64;128");
            Input_LengthIndex.SetCustomInputIndex(0);

            Input_PerformCumulativeCalculation.Name = "Perform Cumulative Calculation Across All Chart Bars";
            Input_PerformCumulativeCalculation.SetYesNo(false);

            return;
        }

        sc.DataStartIndex = atoi(Input_LengthIndex.GetSelectedCustomString().GetChars())-1;

        for (int BarIndex = max(1,sc.UpdateStartIndex); BarIndex < sc.ArraySize; BarIndex++)
        {
            if(Input_PerformCumulativeCalculation.GetYesNo())
            {

                CumulativeHurstExponent_S(sc.BaseData[Input_Data.GetInputDataIndex()],
                    Subgraph_HurstExponent,
                    Subgraph_HurstExponent.Arrays[0],
                    Subgraph_HurstExponent.Arrays[1],
                    Subgraph_HurstExponent.Arrays[2],
                    Subgraph_HurstExponent.Arrays[3],
                    Subgraph_HurstExponent.Arrays[4],
                    Subgraph_HurstExponent.Arrays[5],
                    Subgraph_HurstExponent.Arrays[6],
                    Subgraph_HurstExponent.Arrays[7],
                    Subgraph_HurstExponent.Arrays[8],
                    Subgraph_HurstExponent.Arrays[9],
                    Subgraph_HurstExponent.Arrays[10],
                    Subgraph_HurstExponent.Arrays[11],
                    sc.Subgraph[1].Arrays[0],
                    sc.Subgraph[1].Arrays[1],
                    BarIndex);

            }
            else
            {
                SCFloatArrayRef InputDataArray = sc.BaseData[Input_Data.GetInputDataIndex()];

                //Calculate Logarithmic Return
                sc.Subgraph[0].Arrays[0][BarIndex] = static_cast<float>(log(InputDataArray[BarIndex]/InputDataArray[BarIndex - 1]));

                sc.HurstExponent(sc.Subgraph[0].Arrays[0], Subgraph_HurstExponent, BarIndex, Input_LengthIndex.GetIndex());
            }

        }

    }

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

        SCInputRef Input_Data = sc.Input[0];

        if (sc.SetDefaults)
        {
            sc.GraphName = "Moving Average - Cumulative";

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

            Subgraph_Average.Name = "Avg";
            Subgraph_Average.DrawStyle = DRAWSTYLE_LINE;
            Subgraph_Average.PrimaryColor = RGB(0, 255, 0);
            Subgraph_Average.LineWidth = 1;
            Subgraph_Average.DrawZeros = true;

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

            return;
        }

        sc.DataStartIndex = 1;

        sc.MovingAverageCumulative(sc.BaseData[Input_Data.GetInputDataIndex()], Subgraph_Average);

    }

    /*==========================================================================*/
    SCSFExport scsf_CombinationSymbolChart(SCStudyInterfaceRef sc)
    {

        SCInputRef Input_UseLatestSourceDataForLastBar = sc.Input[0];

        SCInputRef Input_Chart1Multiplier = sc.Input[1];

        SCInputRef Input_UseChart2 = sc.Input[2];
        SCInputRef Input_Chart2Number = sc.Input[3];
        SCInputRef Input_Chart2Multiplier = sc.Input[4];

        SCInputRef Input_UseChart3 = sc.Input[5];
        SCInputRef Input_Chart3Number = sc.Input[6];
        SCInputRef Input_Chart3Multiplier = sc.Input[7];

        SCInputRef Input_UseChart4 = sc.Input[8];
        SCInputRef Input_Chart4Number = sc.Input[9];
        SCInputRef Input_Chart4Multiplier = sc.Input[10];

        SCInputRef Input_UseChart5 = sc.Input[11];
        SCInputRef Input_Chart5Number = sc.Input[12];
        SCInputRef Input_Chart5Multiplier = sc.Input[13];

        SCInputRef Input_UseChart6 = sc.Input[14];
        SCInputRef Input_Chart6Number = sc.Input[15];
        SCInputRef Input_Chart6Multiplier = sc.Input[16];

        if (sc.SetDefaults)
        {
            sc.GraphName = "Combination Symbol Chart";
            sc.AutoLoop = 0;
            sc.ValueFormat = VALUEFORMAT_INHERITED;
            sc.GraphRegion = 1;

            sc.GraphUsesChartColors = 1;//Use the global color settings
            sc.GraphDrawType = GDT_OHLCBAR;
            sc.StandardChartHeader = 1;

            Input_UseLatestSourceDataForLastBar.Name = "Use Latest Source Data For Last Bar";
            Input_UseLatestSourceDataForLastBar.SetYesNo(false);

            Input_Chart1Multiplier.Name = "Chart 1 Multiplier";
            Input_Chart1Multiplier.SetFloat(1.0f);

            Input_UseChart2.Name = "Use Chart 2";
            Input_UseChart2.SetYesNo(true);

            Input_Chart2Number.Name = "Chart 2 Number";
            Input_Chart2Number.SetChartNumber(1);

            Input_Chart2Multiplier.Name = "Chart 2 Multiplier";
            Input_Chart2Multiplier.SetFloat(1.0f);

            Input_UseChart3.Name = "Use Chart 3";
            Input_UseChart3.SetYesNo(true);

            Input_Chart3Number.Name = "Chart 3 Number";
            Input_Chart3Number.SetChartNumber(1);

            Input_Chart3Multiplier.Name = "Chart 3 Multiplier";
            Input_Chart3Multiplier.SetFloat(1.0f);

            Input_UseChart4.Name = "Use Chart 4";
            Input_UseChart4.SetYesNo(true);

            Input_Chart4Number.Name = "Chart 4 Number";
            Input_Chart4Number.SetChartNumber(1);

            Input_Chart4Multiplier.Name = "Chart 4 Multiplier";
            Input_Chart4Multiplier.SetFloat(1.0f);

            Input_UseChart5.Name = "Use Chart 5";
            Input_UseChart5.SetYesNo(true);

            Input_Chart5Number.Name = "Chart 5 Number";
            Input_Chart5Number.SetChartNumber(1);

            Input_Chart5Multiplier.Name = "Chart 5 Multiplier";
            Input_Chart5Multiplier.SetFloat(1.0f);

            Input_UseChart6.Name = "Use Chart 6";
            Input_UseChart6.SetYesNo(true);

            Input_Chart6Number.Name = "Chart 6 Number";
            Input_Chart6Number.SetChartNumber(1);

            Input_Chart6Multiplier.Name = "Chart 6 Multiplier";
            Input_Chart6Multiplier.SetFloat(1.0f);
            return;
        }

        if (sc.IsFullRecalculation && sc.UpdateStartIndex == 0)
        {
            for (int SubgraphIndex = 0; SubgraphIndex <= NUM_BASE_GRAPH_ARRAYS; ++SubgraphIndex)
            {
                sc.Subgraph[SubgraphIndex].Name = sc.GetStudySubgraphName(0, SubgraphIndex);
            }

            sc.GraphName = "Combination Chart: ";
            sc.GraphName += sc.GetChartName(sc.ChartNumber);

            if (Input_UseChart2.GetYesNo())
            {
                sc.GraphName += ", ";
                sc.GraphName += sc.GetChartName(Input_Chart2Number.GetChartNumber());
            }

            if (Input_UseChart3.GetYesNo())
            {
                sc.GraphName += ", ";
                sc.GraphName += sc.GetChartName(Input_Chart3Number.GetChartNumber());
            }

            if (Input_UseChart4.GetYesNo())
            {
                sc.GraphName += ", ";
                sc.GraphName += sc.GetChartName(Input_Chart4Number.GetChartNumber());
            }

            if (Input_UseChart5.GetYesNo())
            {
                sc.GraphName += ", ";
                sc.GraphName += sc.GetChartName(Input_Chart5Number.GetChartNumber());
            }

            if (Input_UseChart6.GetYesNo())
            {
                sc.GraphName += ", ";
                sc.GraphName += sc.GetChartName(Input_Chart6Number.GetChartNumber());
            }
        }

        SCGraphData Chart2BaseData;
        if(Input_UseChart2.GetYesNo())
            sc.GetChartBaseData(-Input_Chart2Number.GetChartNumber(), Chart2BaseData);

        SCGraphData Chart3BaseData;
        if (Input_UseChart3.GetYesNo())
            sc.GetChartBaseData(-Input_Chart3Number.GetChartNumber(), Chart3BaseData);

        SCGraphData Chart4BaseData;
        if (Input_UseChart4.GetYesNo())
            sc.GetChartBaseData(-Input_Chart4Number.GetChartNumber(), Chart4BaseData);

        SCGraphData Chart5BaseData;
        if (Input_UseChart5.GetYesNo())
            sc.GetChartBaseData(-Input_Chart5Number.GetChartNumber(), Chart5BaseData);

        SCGraphData Chart6BaseData;
        if (Input_UseChart6.GetYesNo())
            sc.GetChartBaseData(-Input_Chart6Number.GetChartNumber(), Chart6BaseData);

        int CalculationStartIndex = sc.GetCalculationStartIndexForStudy();

        // Iterate through the bars
        for (int Index = CalculationStartIndex; Index < sc.ArraySize; ++Index)
        {
            int Chart2Index = 0;
            if (Input_UseChart2.GetYesNo())
                Chart2Index = sc.GetNearestMatchForDateTimeIndex(Input_Chart2Number.GetChartNumber(), Index);

            int Chart3Index = 0;
            if (Input_UseChart3.GetYesNo())
                Chart3Index = sc.GetNearestMatchForDateTimeIndex(Input_Chart3Number.GetChartNumber(), Index);

            int Chart4Index = 0;
            if (Input_UseChart4.GetYesNo())
                Chart4Index = sc.GetNearestMatchForDateTimeIndex(Input_Chart4Number.GetChartNumber(), Index);

            int Chart5Index = 0;
            if (Input_UseChart5.GetYesNo())
                Chart5Index = sc.GetNearestMatchForDateTimeIndex(Input_Chart5Number.GetChartNumber(), Index);

            int Chart6Index = 0;
            if (Input_UseChart6.GetYesNo())
                Chart6Index = sc.GetNearestMatchForDateTimeIndex(Input_Chart6Number.GetChartNumber(), Index);

            //When use latest source data for last bar is set to Yes, replay is not running and at last bar in the destination chart, then use the data from the very latest bar in the source charts.
            if (Input_UseLatestSourceDataForLastBar.GetYesNo() && !sc.IsReplayRunning()
                && Index == sc.ArraySize - 1)
            {
                if(Input_UseChart2.GetYesNo())
                    Chart2Index = Chart2BaseData[SC_OPEN].GetArraySize() - 1;

                if (Input_UseChart3.GetYesNo())
                    Chart3Index = Chart3BaseData[SC_OPEN].GetArraySize() - 1;

                if (Input_UseChart4.GetYesNo())
                    Chart4Index = Chart4BaseData[SC_OPEN].GetArraySize() - 1;

                if (Input_UseChart5.GetYesNo())
                    Chart5Index = Chart5BaseData[SC_OPEN].GetArraySize() - 1;

                if (Input_UseChart6.GetYesNo())
                    Chart6Index = Chart6BaseData[SC_OPEN].GetArraySize() - 1;
            }

            // Iterate through the subgraphs
            for (int SubgraphIndex = SC_OPEN; SubgraphIndex <= SC_NUM_TRADES; SubgraphIndex++)
            {
                sc.Subgraph[SubgraphIndex][Index] = sc.BaseDataIn[SubgraphIndex][Index] * Input_Chart1Multiplier.GetFloat();

                if(Input_UseChart2.GetYesNo())
                    sc.Subgraph[SubgraphIndex][Index] += Chart2BaseData[SubgraphIndex][Chart2Index] * Input_Chart2Multiplier.GetFloat();

                if (Input_UseChart3.GetYesNo())
                    sc.Subgraph[SubgraphIndex][Index] += Chart3BaseData[SubgraphIndex][Chart3Index] * Input_Chart3Multiplier.GetFloat();

                if (Input_UseChart4.GetYesNo())
                    sc.Subgraph[SubgraphIndex][Index] += Chart4BaseData[SubgraphIndex][Chart4Index] * Input_Chart4Multiplier.GetFloat();

                if (Input_UseChart5.GetYesNo())
                    sc.Subgraph[SubgraphIndex][Index] += Chart5BaseData[SubgraphIndex][Chart5Index] * Input_Chart5Multiplier.GetFloat();

                if (Input_UseChart6.GetYesNo())
                    sc.Subgraph[SubgraphIndex][Index] += Chart6BaseData[SubgraphIndex][Chart6Index] * Input_Chart6Multiplier.GetFloat();

            }

            sc.Subgraph[SC_HIGH][Index]
                = max(
                    sc.Subgraph[SC_OPEN][Index],
                    max(
                        sc.Subgraph[SC_HIGH][Index],
                        max(
                            sc.Subgraph[SC_LOW][Index],
                            sc.Subgraph[SC_LAST][Index]
                        )
                    )
                );

            sc.Subgraph[SC_LOW][Index]
                = min(
                    sc.Subgraph[SC_OPEN][Index],
                    min(
                        sc.Subgraph[SC_HIGH][Index],
                        min(
                            sc.Subgraph[SC_LOW][Index],
                            sc.Subgraph[SC_LAST][Index]
                        )
                    )
                );

            sc.CalculateOHLCAverages(Index);
        }

        sc.EarliestUpdateSubgraphDataArrayIndex = CalculationStartIndex;
    }