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

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

        SCInputRef Input_Data = sc.Input[0];

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

            Subgraph_Summation.Name = "Sum";
            Subgraph_Summation.DrawStyle = DRAWSTYLE_LINE;
            Subgraph_Summation.PrimaryColor = RGB(0,255,0);

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

            sc.AutoLoop = 1;

            return;
        }

        sc.CumulativeSummation(sc.BaseData[Input_Data.GetInputDataIndex()], Subgraph_Summation, sc.Index);
    }

    /*==========================================================================*/
    SCSFExport scsf_ArmsEaseOfMovement(SCStudyInterfaceRef sc)
    {
        SCSubgraphRef Subgraph_EMV = sc.Subgraph[0];
        SCSubgraphRef Subgraph_EMVAvg = sc.Subgraph[1];

        SCInputRef Input_VolumeDivisor = sc.Input[0];
        SCInputRef Input_Length = sc.Input[1];
        SCInputRef Input_MovingAverageType = sc.Input[2];

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

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

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

            Subgraph_EMVAvg.Name = "MA of EMV";
            Subgraph_EMVAvg.DrawStyle = DRAWSTYLE_LINE;
            Subgraph_EMVAvg.PrimaryColor = RGB(0, 0, 255);
            Subgraph_EMVAvg.DrawZeros = false;

            Input_VolumeDivisor.Name = "Volume Divisor";
            Input_VolumeDivisor.SetInt(100000000);

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

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

            sc.AutoLoop = 1;

            return;
        }

        if (sc.Index < 1)
            return;

        sc.ArmsEMV(sc.BaseDataIn, Subgraph_EMV, Input_VolumeDivisor.GetInt(), sc.Index);

        sc.MovingAverage(Subgraph_EMV, Subgraph_EMVAvg, Input_MovingAverageType.GetMovAvgType(), Input_Length.GetInt());
    }

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

        SCInputRef Input_Length = sc.Input[3];

        if(sc.SetDefaults)
        {
            sc.GraphName = "Chaikin Money Flow";

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

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

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

            sc.AutoLoop = 1;

            return;
        }

        sc.ChaikinMoneyFlow(sc.BaseDataIn, Subgraph_CMF, Input_Length.GetInt());
    }

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

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

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

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

            Subgraph_Dispersion.Name = "Dispersion";
            Subgraph_Dispersion.DrawStyle = DRAWSTYLE_LINE;
            Subgraph_Dispersion.PrimaryColor = RGB(0,255,0);
            Subgraph_Dispersion.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);

            sc.AutoLoop = 1;

            return;
        }

        sc.Dispersion(sc.BaseDataIn[static_cast<int>(Input_Data.GetInputDataIndex())], Subgraph_Dispersion, sc.Index, Input_Length.GetInt());
    }

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

        SCInputRef Input_Data = sc.Input[0];
        SCInputRef Input_Value     = sc.Input[3];
        SCInputRef Input_BandsType = sc.Input[4];

        if(sc.SetDefaults)
        {
            sc.GraphName = "Bands/Envelope";

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

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

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

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

            Input_Value.Name = "Percentage/Fixed Value/Ticks";
            Input_Value.SetFloat(0.05f);
            Input_Value.SetFloatLimits(0.00001f, static_cast<float>(MAX_STUDY_LENGTH));

            Input_BandsType.Name = "Bands Type";
            Input_BandsType.SetCustomInputStrings("Percentage;Fixed Value;Number of Ticks");
            Input_BandsType.SetCustomInputIndex(0);

            sc.AutoLoop = 1;

            return;
        }

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

        if(Input_BandsType.GetIndex() == 0)
        {
            sc.EnvelopePct(In, Subgraph_TopBand, Input_Value.GetFloat());
            Subgraph_BottomBand[sc.Index] = Subgraph_TopBand.Arrays[0][sc.Index];
        }
        else if(Input_BandsType.GetIndex() == 1)
        {
            sc.EnvelopeFixed(In, Subgraph_TopBand, Input_Value.GetFloat());
            Subgraph_BottomBand[sc.Index] = Subgraph_TopBand.Arrays[0][sc.Index];
        }
        else
        {
            sc.EnvelopeFixed(In, Subgraph_TopBand, Input_Value.GetFloat() * sc.TickSize);
            Subgraph_BottomBand[sc.Index] = Subgraph_TopBand.Arrays[0][sc.Index];
        }
    }

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

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

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

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

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

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

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

            sc.AutoLoop = 1;

            return;
        }
        if(sc.Index < Input_Length.GetInt())
            return;

        SCFloatArrayRef In = sc.BaseDataIn[static_cast<int>(Input_Data.GetInputDataIndex())];
        sc.VHF(In, Subgraph_VHF, sc.Index, Input_Length.GetInt());
    }

    /*==========================================================================*/
    SCSFExport scsf_RWI(SCStudyInterfaceRef sc)
    {
        SCSubgraphRef Subgraph_RWIHigh = sc.Subgraph[0];
        SCSubgraphRef Subgraph_RWILow = sc.Subgraph[1];
        SCSubgraphRef Subgraph_Temp2 = sc.Subgraph[2];
        SCSubgraphRef Subgraph_Temp3 = sc.Subgraph[3];
        SCSubgraphRef Subgraph_Temp4 = sc.Subgraph[4];

        SCInputRef Input_Length = sc.Input[3];

        if(sc.SetDefaults)
        {
            sc.GraphName = "Random Walk Index";

            sc.GraphRegion = 1;

            Subgraph_RWIHigh.Name = "RWI High";
            Subgraph_RWIHigh.PrimaryColor = RGB(0,255,0);
            Subgraph_RWIHigh.DrawStyle = DRAWSTYLE_LINE;

            Subgraph_RWILow.Name = "RWI Low";
            Subgraph_RWILow.PrimaryColor = RGB(255,0,255);
            Subgraph_RWILow.DrawStyle = DRAWSTYLE_LINE;

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

            sc.AutoLoop = 1;

            return;
        }

        sc.DataStartIndex = Input_Length.GetInt() - 1;
        sc.InternalRWI(sc.BaseDataIn, Subgraph_RWIHigh, Subgraph_RWILow, Subgraph_Temp2, Subgraph_Temp3, Subgraph_Temp4, sc.Index, Input_Length.GetInt());
    }

    /*==========================================================================*/
    SCSFExport scsf_UltimateOscillator(SCStudyInterfaceRef sc)
    {
        SCSubgraphRef Subgraph_UltimateOscillatorOut1 = sc.Subgraph[0];
        SCSubgraphRef Subgraph_UltimateOscillatorOut2 = sc.Subgraph[1];

        SCInputRef Input_Length1 = sc.Input[3];
        SCInputRef Input_Length2 = sc.Input[4];
        SCInputRef Input_Length3 = sc.Input[5];

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

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

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

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

            Input_Length2.Name = "Length 2";
            Input_Length2.SetInt(14);
            Input_Length2.SetIntLimits(1,MAX_STUDY_LENGTH);

            Input_Length3.Name = " Length 3";
            Input_Length3.SetInt(28);
            Input_Length3.SetIntLimits(1,MAX_STUDY_LENGTH);

            sc.AutoLoop = 1;

            return;
        }

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

        sc.UltimateOscillator(sc.BaseData, Subgraph_UltimateOscillatorOut1,  Subgraph_UltimateOscillatorOut2, Input_Length1.GetInt(), Input_Length2.GetInt(), Input_Length3.GetInt());
    }

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

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

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

            Subgraph_AccumulationDistribution.Name = "AD";
            Subgraph_AccumulationDistribution.DrawStyle = DRAWSTYLE_LINE;
            Subgraph_AccumulationDistribution.PrimaryColor = RGB(0,255,0);

            sc.AutoLoop = 1;

            return;
        }

        sc.DataStartIndex = 1;

        sc.WilliamsAD(sc.BaseDataIn, Subgraph_AccumulationDistribution, sc.Index);

    }

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

        SCInputRef Input_Length = sc.Input[3];
        SCInputRef Input_Invert = sc.Input[4];
        SCInputRef Input_DataHigh = sc.Input[5];
        SCInputRef Input_DataLow = sc.Input[6];
        SCInputRef Input_DataLast = sc.Input[7];
        SCInputRef Input_UpdateFlag = sc.Input[8];

        if(sc.SetDefaults)
        {
            sc.GraphName = "Williams %R";

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

            Subgraph_PercentR.Name = "%R";
            Subgraph_PercentR.DrawZeros = true;
            Subgraph_PercentR.DrawStyle = DRAWSTYLE_LINE;
            Subgraph_PercentR.PrimaryColor = RGB(0,255,0);

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

            Input_Invert.Name = "Invert Output";
            Input_Invert.SetYesNo(1);

            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_DataLast.Name = "Input Data for Last";
            Input_DataLast.SetInputDataIndex(SC_LAST);

            Input_UpdateFlag.SetInt(1); //update flag

            sc.AutoLoop = 1;

            return;
        }

        if (Input_UpdateFlag.GetInt() == 0)
        {
            Input_DataHigh.SetInputDataIndex(SC_HIGH);
            Input_DataLow.SetInputDataIndex(SC_LOW);
            Input_DataLast.SetInputDataIndex(SC_LAST);
            Input_UpdateFlag.SetInt(1);
        }

        sc.DataStartIndex = Input_Length.GetInt();

        sc.WilliamsR(
            sc.BaseData[Input_DataHigh.GetInputDataIndex()],
            sc.BaseData[Input_DataLow.GetInputDataIndex()],
            sc.BaseData[Input_DataLast.GetInputDataIndex()],
            Subgraph_PercentR,
            sc.Index,
            Input_Length.GetInt()
            );

        if (Input_Invert.GetYesNo())
            Subgraph_PercentR[sc.Index] *= -1;
    }

    /*==========================================================================*/
    SCSFExport scsf_IslandReversal(SCStudyInterfaceRef sc)
    {
        SCSubgraphRef Subgraph_IslandReversal = sc.Subgraph[0];
        SCSubgraphRef Subgraph_GapUp = sc.Subgraph[1];
        SCSubgraphRef Subgraph_GapDown = sc.Subgraph[2];
        SCSubgraphRef Subgraph_GapUpIndex = sc.Subgraph[3];
        SCSubgraphRef Subgraph_GapDownIndex = sc.Subgraph[4];

        if (sc.SetDefaults)
        {
            sc.GraphName = "Island Reversal";

            sc.GraphRegion = 0;
            sc.ValueFormat = 0;

            Subgraph_IslandReversal.Name = "IR";
            Subgraph_IslandReversal.DrawStyle = DRAWSTYLE_POINT;
            Subgraph_IslandReversal.PrimaryColor = RGB(0, 255, 0);
            Subgraph_IslandReversal.LineWidth = 8;
            Subgraph_IslandReversal.DrawZeros = false;

            Subgraph_GapUp.Name = "Gap Up";
            Subgraph_GapUp.DrawStyle = DRAWSTYLE_IGNORE;

            Subgraph_GapDown.Name = "Gap Down";
            Subgraph_GapDown.DrawStyle = DRAWSTYLE_IGNORE;

            Subgraph_GapUpIndex.Name = "Gap Up Index";
            Subgraph_GapUpIndex.DrawStyle = DRAWSTYLE_IGNORE;

            Subgraph_GapDownIndex.Name = "Gap Down Index";
            Subgraph_GapDownIndex.DrawStyle = DRAWSTYLE_IGNORE;

            sc.AutoLoop = 1;

            return;
        }

        //Detect gaps in consecutive bars for sc.Index > 0
        if (sc.Index > 0)
        {
            //Gap Up
            if (sc.Low[sc.Index] > sc.High[sc.Index - 1])
            {
                Subgraph_GapUp[sc.Index] = 1;
                Subgraph_GapDown[sc.Index] = Subgraph_GapDown[sc.Index - 1];
                Subgraph_GapUpIndex[sc.Index] = static_cast<float>(sc.Index);
                Subgraph_GapDownIndex[sc.Index] = Subgraph_GapDownIndex[sc.Index - 1];
            }

            //Gap Down
            else if (sc.High[sc.Index] < sc.Low[sc.Index - 1])
            {
                Subgraph_GapUp[sc.Index] = Subgraph_GapUp[sc.Index - 1];
                Subgraph_GapDown[sc.Index] = 1;
                Subgraph_GapUpIndex[sc.Index] = Subgraph_GapUpIndex[sc.Index - 1];
                Subgraph_GapDownIndex[sc.Index] = static_cast<float>(sc.Index);
            }

            //No Gap (Overlapping Bars)
            else
            {
                Subgraph_GapUp[sc.Index] = Subgraph_GapUp[sc.Index - 1];
                Subgraph_GapDown[sc.Index] = Subgraph_GapDown[sc.Index - 1];
                Subgraph_GapUpIndex[sc.Index] = Subgraph_GapUpIndex[sc.Index - 1];
                Subgraph_GapDownIndex[sc.Index] = Subgraph_GapDownIndex[sc.Index - 1];
            }
        }

        //Detect Island Reversal
        if (Subgraph_GapUp[sc.Index] == 1 && Subgraph_GapDown[sc.Index] == 1)
        {
            //Gap Up occurs before Gap Down
            if (Subgraph_GapUpIndex[sc.Index] <= Subgraph_GapDownIndex[sc.Index] - 1)
            {
                float GapLevel = max(sc.High[static_cast<int>(Subgraph_GapUpIndex[sc.Index]) - 1], sc.High[static_cast<int>(Subgraph_GapDownIndex[sc.Index])]);
                int AreBarsAboveGapLevel = 1;

                //Check each bar between Up Gap and Down Gap to make sure it does not go below the Gap Up Level
                for (int BarIndex = static_cast<int>(Subgraph_GapUpIndex[sc.Index]); BarIndex < static_cast<int>(Subgraph_GapDownIndex[sc.Index]); BarIndex++)
                {
                    if (sc.Low[BarIndex] < GapLevel)
                        AreBarsAboveGapLevel = 0;
                }

                if (AreBarsAboveGapLevel == 1)
                {
                    Subgraph_IslandReversal[static_cast<int>(Subgraph_GapUpIndex[sc.Index])] = GapLevel;
                    Subgraph_IslandReversal[static_cast<int>(Subgraph_GapDownIndex[sc.Index]) - 1] = GapLevel;

                }

                //Disallow single-bar islands
                if (Subgraph_GapUpIndex[sc.Index] == Subgraph_GapDownIndex[sc.Index] - 1)
                    Subgraph_IslandReversal[static_cast<int>(Subgraph_GapUpIndex[sc.Index])] = 0;

                //Reset these variables to check for next pair of Gaps
                Subgraph_GapUp[sc.Index] = 0;
                Subgraph_GapUpIndex[sc.Index] = 0;
            }

            //Gap Down occurs before Gap Up
            else if (Subgraph_GapDownIndex[sc.Index] <= Subgraph_GapUpIndex[sc.Index] - 1)
            {
                float GapLevel = min(sc.Low[static_cast<int>(Subgraph_GapDownIndex[sc.Index]) - 1], sc.Low[static_cast<int>(Subgraph_GapUpIndex[sc.Index])]);
                int AreBarsBelowGapLevel = 1;

                //Check each bar between Down Gap and Up Gap to make sure it does not go above the Gap Down Level
                for (int BarIndex = static_cast<int>(Subgraph_GapDownIndex[sc.Index]); BarIndex < static_cast<int>(Subgraph_GapUpIndex[sc.Index]); BarIndex++)
                {
                    if (sc.High[BarIndex] > GapLevel)
                        AreBarsBelowGapLevel = 0;
                }

                if (AreBarsBelowGapLevel == 1)
                {
                    Subgraph_IslandReversal[static_cast<int>(Subgraph_GapUpIndex[sc.Index]) - 1] = GapLevel;
                    Subgraph_IslandReversal[static_cast<int>(Subgraph_GapDownIndex[sc.Index])] = GapLevel;
                }

                //Disallow single-bar islands
                if (Subgraph_GapDownIndex[sc.Index] == Subgraph_GapUpIndex[sc.Index] - 1)
                    Subgraph_IslandReversal[static_cast<int>(Subgraph_GapDownIndex[sc.Index])] = 0;

                //Reset these variables to check for next pair of Gaps
                Subgraph_GapDown[sc.Index] = 0;
                Subgraph_GapDownIndex[sc.Index] = 0;
            }
        }
    }
    /*==========================================================================*/
    SCSFExport scsf_WeightedAverageOscillator(SCStudyInterfaceRef sc)
    {
        SCSubgraphRef Subgraph_Oscillator = sc.Subgraph[0];
        SCSubgraphRef Subgraph_Temp1 = sc.Subgraph[1];
        SCSubgraphRef Subgraph_Temp2 = sc.Subgraph[2];

        SCInputRef Input_Data = sc.Input[0];
        SCInputRef Input_SlowAvgLength = sc.Input[3];
        SCInputRef Input_FastAvgLength = sc.Input[4];

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

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

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

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

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

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

            sc.AutoLoop = 1;

            return;
        }
        sc.DataStartIndex = max( Input_SlowAvgLength.GetInt(),Input_FastAvgLength.GetInt());

        sc.WeightedMovingAverage(sc.BaseDataIn[static_cast<int>(Input_Data.GetInputDataIndex())], Subgraph_Temp1, Input_SlowAvgLength.GetInt());
        sc.WeightedMovingAverage(sc.BaseDataIn[static_cast<int>(Input_Data.GetInputDataIndex())], Subgraph_Temp2, Input_FastAvgLength.GetInt());

        sc.Oscillator(Subgraph_Temp2, Subgraph_Temp1, Subgraph_Oscillator);
    }

    /*==========================================================================*/
    SCSFExport scsf_PreferredStochasticDiNapoli(SCStudyInterfaceRef sc)
    {
        SCSubgraphRef Subgraph_PercentK = sc.Subgraph[0];
        SCSubgraphRef Subgraph_PercentD = sc.Subgraph[1];
        SCSubgraphRef Subgraph_Line1 = sc.Subgraph[2];
        SCSubgraphRef Subgraph_Line2 = sc.Subgraph[3];

        SCInputRef Input_FastKLength = sc.Input[3];
        SCInputRef Input_FastDMovAvgLength = sc.Input[4];
        SCInputRef Input_ModifiedMovAvgLength = sc.Input[5];
        SCInputRef Input_Line1Value = sc.Input[6];
        SCInputRef Input_Line2Value = sc.Input[7];

        if(sc.SetDefaults)
        {
            sc.GraphName = "Preferred Stochastic - DiNapoli";

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

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

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

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

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

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

            Input_FastDMovAvgLength.Name = "Fast %D Mov Avg Length (Slow %K)";
            Input_FastDMovAvgLength.SetInt(3);
            Input_FastDMovAvgLength.SetIntLimits(1,MAX_STUDY_LENGTH);

            Input_ModifiedMovAvgLength.Name = "Modified Mov Avg Length (Slow %D)";
            Input_ModifiedMovAvgLength.SetInt(3);
            Input_ModifiedMovAvgLength.SetIntLimits(1,MAX_STUDY_LENGTH);

            Input_Line1Value.Name = "Line1 Value";
            Input_Line1Value.SetFloat(70);

            Input_Line2Value.Name = "Line2 Value";
            Input_Line2Value.SetFloat(30);

            sc.AutoLoop = 1;

            return;
        }

        int Index = sc.Index;
        sc.DataStartIndex = Input_FastKLength.GetInt() + Input_FastDMovAvgLength.GetInt() + 1;

        sc.Stochastic(sc.BaseDataIn, sc.Subgraph[4], Input_FastKLength.GetInt(), 3, 3, MOVAVGTYPE_SIMPLE);

        sc.ExponentialMovAvg(sc.Subgraph[4], Subgraph_PercentK, Index, Input_FastDMovAvgLength.GetInt());

        Subgraph_PercentD[Index] = Subgraph_PercentD[Index - 1] +
            ((Subgraph_PercentK[Index] - Subgraph_PercentD[Index - 1]) / Input_ModifiedMovAvgLength.GetInt());

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

    /*==========================================================================*/
    SCSFExport scsf_ElderRay(SCStudyInterfaceRef sc)
    {
        SCSubgraphRef Subgraph_BullPower = sc.Subgraph[0];
        SCSubgraphRef Subgraph_BearPower = sc.Subgraph[1];
        SCSubgraphRef Subgraph_Zero = sc.Subgraph[2];
        SCSubgraphRef Subgraph_MovAvgTemp = sc.Subgraph[3];

        SCInputRef Input_MovAvgLength = sc.Input[3];

        if(sc.SetDefaults)
        {
            sc.GraphName = "Elder Ray";

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

            Subgraph_BullPower.Name = "Bull Power";
            Subgraph_BullPower.DrawStyle = DRAWSTYLE_LINE;
            Subgraph_BullPower.PrimaryColor = RGB(0,255,0);
            Subgraph_BullPower.DrawZeros = true;

            Subgraph_BearPower.Name = "Bear Power";
            Subgraph_BearPower.DrawStyle = DRAWSTYLE_LINE;
            Subgraph_BearPower.PrimaryColor = RGB(255,0,255);
            Subgraph_BearPower.DrawZeros = true;

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

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

            sc.AutoLoop = 1;

            return;
        }

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

        int i = sc.Index;
        sc.ExponentialMovAvg(sc.Close, Subgraph_MovAvgTemp, i, Input_MovAvgLength.GetInt());

        Subgraph_BullPower[i] = sc.High[i] - Subgraph_MovAvgTemp[i];
        Subgraph_BearPower[i] = sc.Low[i]   - Subgraph_MovAvgTemp[i];
    }

    /*==========================================================================*/
    SCSFExport scsf_MomentumWithMovingAverage(SCStudyInterfaceRef sc)
    {
        SCSubgraphRef Subgraph_Momentum = sc.Subgraph[0];
        SCSubgraphRef Subgraph_MovingAverage = sc.Subgraph[1];
        SCSubgraphRef Subgraph_CenterLine = sc.Subgraph[2];

        SCInputRef Input_Data = sc.Input[0];
        SCInputRef Input_MomentumLength = sc.Input[3];
        SCInputRef Input_MovAvgLength = sc.Input[4];
        SCInputRef Input_MomentumType = sc.Input[5];

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

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

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

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

            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_MomentumLength.SetInt(10);
            Input_MomentumLength.SetIntLimits(1,MAX_STUDY_LENGTH);
            Input_MomentumLength.Name = "Momentum Length";

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

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

            sc.AutoLoop = 1;

            return;
        }

        sc.DataStartIndex = Input_MomentumLength.GetInt() + Input_MovAvgLength.GetInt();

        if(sc.Index < Input_MomentumLength.GetInt())
            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_MomentumLength.GetInt()];

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

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

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

        sc.SimpleMovAvg(Subgraph_Momentum, Subgraph_MovingAverage, sc.Index, Input_MovAvgLength.GetInt());
    }

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

        SCSubgraphRef Subgraph_Temp1 = sc.Subgraph[1];
        SCSubgraphRef Subgraph_Temp2 = sc.Subgraph[2];

        SCInputRef Input_Length = sc.Input[3];

        if(sc.SetDefaults)
        {
            sc.GraphName = "Volatility - Chaikin's";

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

            Subgraph_Volatility.Name = "Volatility";
            Subgraph_Volatility.DrawStyle = DRAWSTYLE_LINE;
            Subgraph_Volatility.PrimaryColor = RGB(0,255,0);

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

            sc.AutoLoop = 1;

            return;
        }

        sc.DataStartIndex = Input_Length.GetInt() + 4;
        int i = sc.Index;

        Subgraph_Temp2[i] = sc.High[i] - sc.Low[i];

        sc.ExponentialMovAvg(Subgraph_Temp2, Subgraph_Temp1, i, Input_Length.GetInt());

        Subgraph_Volatility[i] = ((Subgraph_Temp1[i] - Subgraph_Temp1[i - Input_Length.GetInt()])
            / Subgraph_Temp1[i-Input_Length.GetInt()]) * 100;
    }

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

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

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

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

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

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

            sc.AutoLoop=1;

            return;
        }
        sc.DataStartIndex = Input_Length.GetInt();

        Subgraph_ROC[sc.Index] = (sc.BaseDataIn[static_cast<int>(Input_Data.GetInputDataIndex())][sc.Index] - sc.BaseDataIn[static_cast<int>(Input_Data.GetInputDataIndex())][sc.Index - Input_Length.GetInt()]);
    }

    /*==========================================================================*/
    SCSFExport scsf_SquareOfNine(SCStudyInterfaceRef sc)
    {
        SCSubgraphRef Subgraph_Anchor = sc.Subgraph[0];
        SCSubgraphRef Subgraph_L1Plus = sc.Subgraph[1];
        SCSubgraphRef Subgraph_L1Minus = sc.Subgraph[2];
        SCSubgraphRef Subgraph_L1 = sc.Subgraph[3];

        SCFloatArrayRef Array_BaseUpper = sc.Subgraph[0].Arrays[0];
        SCFloatArrayRef Array_BaseLower = sc.Subgraph[0].Arrays[1];
        SCFloatArrayRef Array_Offset = sc.Subgraph[0].Arrays[2];

        SCInputRef Input_NumberOfDaysToCalculate = sc.Input[0];
        SCInputRef Input_AnchorValue = sc.Input[2];
        SCInputRef Input_Degree = sc.Input[3];
        SCInputRef Input_Level = sc.Input[4];
        SCInputRef Input_AutoAdjust = sc.Input[5];
        SCInputRef Input_InMultiplier = sc.Input[6];

        if(sc.SetDefaults)
        {
            sc.GraphName = "Square of 9";

            sc.GraphRegion = 0;

            const int LineLabelFlags = (LL_DISPLAY_VALUE
                | LL_DISPLAY_NAME
                | LL_NAME_ALIGN_FAR_RIGHT
                | LL_VALUE_ALIGN_FAR_RIGHT
                | LL_NAME_ALIGN_ABOVE
                | LL_VALUE_ALIGN_BELOW
                );

            Subgraph_Anchor.Name = "Anchor";
            Subgraph_Anchor.DrawStyle = DRAWSTYLE_DASH;// Set line style to Dash
            Subgraph_Anchor.PrimaryColor = RGB(0,255,255);
            Subgraph_Anchor.DrawZeros = false;
            Subgraph_Anchor.LineLabel = LineLabelFlags;

            Subgraph_L1Plus.Name = "L1+";
            Subgraph_L1Plus.DrawStyle = DRAWSTYLE_DASH;
            Subgraph_L1Plus.PrimaryColor = RGB(0,255,0);
            Subgraph_L1Plus.DrawZeros = false;
            Subgraph_L1Plus.LineLabel = LineLabelFlags;

            Subgraph_L1Minus.Name = "L1-";
            Subgraph_L1Minus.DrawStyle = DRAWSTYLE_DASH;
            Subgraph_L1Minus.PrimaryColor = RGB(255,0,0);
            Subgraph_L1Minus.DrawZeros = false;
            Subgraph_L1Minus.LineLabel = LineLabelFlags;

            Subgraph_L1.Name = "L1";
            Subgraph_L1.DrawStyle = DRAWSTYLE_DASH;
            Subgraph_L1.PrimaryColor = RGB(255,127,0);
            Subgraph_L1.DrawZeros = false;
            Subgraph_L1.LineLabel = LineLabelFlags;

            Input_NumberOfDaysToCalculate.Name = "Number of Days to Calculate";
            Input_NumberOfDaysToCalculate.SetInt(10);
            Input_NumberOfDaysToCalculate.SetIntLimits(1, MAX_STUDY_LENGTH);

            Input_AnchorValue.SetFloat(0);
            Input_AnchorValue.Name = "Anchor Value";
            Input_AnchorValue.SetFloatLimits(0, static_cast<float>(MAX_STUDY_LENGTH));

            Input_Degree.SetFloat(22.5);
            Input_Degree.Name = "Degrees";
            Input_Degree.SetFloatLimits(0,360);

            Input_Level.SetFloat(1);
            Input_Level.Name = "Level";
            Input_Level.SetFloatLimits(1,10);

            Input_AutoAdjust.SetYesNo(false);
            Input_AutoAdjust.Name = "Auto Adjust";

            Input_InMultiplier.SetFloat(1.0f);
            Input_InMultiplier.Name = "Price Multiplier";

            sc.ScaleRangeType = SCALE_SAMEASREGION;

            sc.AutoLoop=1;

            return;
        }

        float MultiplierValue = Input_InMultiplier.GetFloat();
        if (MultiplierValue == 0)
            MultiplierValue = 1;

        if (Input_AnchorValue.GetFloat() == 0)
        {
            Input_AnchorValue.SetFloat(sc.Close[sc.ArraySize - 1]*MultiplierValue);
        }

        int LevelInput = static_cast<int>(Input_Level.GetFloat() + 0.5f);

        if (sc.BaseDateTimeIn[sc.Index].GetDate() < sc.BaseDateTimeIn[sc.ArraySize - 1].GetDate() - Input_NumberOfDaysToCalculate.GetInt() + 1)
            return;

        if (Input_AutoAdjust.GetYesNo())
        {
            float SquareRoot = sqrt(Input_AnchorValue.GetFloat());

            float Offset = 0.0f;
            float Mid = 0.0f;
            float BaseUpper = 0.0f;
            float BaseLower = 0.0f;
            float Upper = 0.0f;
            float Lower = 0.0f;

            if(sc.Index == 0)
            {
                Offset = 0;
                BaseUpper = (SquareRoot + Input_Degree.GetFloat()/180) * (SquareRoot + Input_Degree.GetFloat()/180);
                BaseLower = (SquareRoot - Input_Degree.GetFloat()/180) * (SquareRoot - Input_Degree.GetFloat()/180);
                Mid = Input_AnchorValue.GetFloat();
                Upper = (SquareRoot + LevelInput * Input_Degree.GetFloat()/180) * (SquareRoot + LevelInput * Input_Degree.GetFloat()/180);
                Lower = (SquareRoot - LevelInput * Input_Degree.GetFloat()/180) * (SquareRoot - LevelInput * Input_Degree.GetFloat()/180);
            }
            else
            {
                Upper = Subgraph_L1Plus[sc.Index-1] * MultiplierValue;
                Lower = Subgraph_L1Minus[sc.Index-1] * MultiplierValue;
                Mid = Subgraph_L1[sc.Index-1] * MultiplierValue;

                BaseUpper = Array_BaseUpper[sc.Index-1];
                BaseLower = Array_BaseLower[sc.Index-1];
                Offset = Array_Offset[sc.Index-1];
            }

            SCString TempStr;
            TempStr.Format("+%g deg", LevelInput * Input_Degree.GetFloat());

            Subgraph_L1Plus.Name = TempStr;

            TempStr.Format("-%g deg", LevelInput * Input_Degree.GetFloat());
            Subgraph_L1Minus.Name = TempStr;

            Subgraph_L1.Name = "Mid";

            float PriceInput = sc.Close[sc.Index] * MultiplierValue;

            while (PriceInput > BaseUpper)
            {
                Offset += Input_Degree.GetFloat();
                BaseUpper = (SquareRoot + (Offset + Input_Degree.GetFloat())/180) * (SquareRoot + (Offset + Input_Degree.GetFloat())/180);
                BaseLower = (SquareRoot + (Offset - Input_Degree.GetFloat())/180) * (SquareRoot + (Offset - Input_Degree.GetFloat())/180);
                Upper = (SquareRoot + (Offset + LevelInput * Input_Degree.GetFloat())/180) * (SquareRoot + (Offset + LevelInput * Input_Degree.GetFloat())/180);
                Lower = (SquareRoot + (Offset - LevelInput * Input_Degree.GetFloat())/180) * (SquareRoot + (Offset - LevelInput * Input_Degree.GetFloat())/180);
                Mid = (SquareRoot + Offset/180) * (SquareRoot + Offset/180);
            }
            while (PriceInput < BaseLower)
            {
                Offset -= Input_Degree.GetFloat();
                BaseUpper = (SquareRoot + (Offset + Input_Degree.GetFloat())/180) * (SquareRoot + (Offset + Input_Degree.GetFloat())/180);
                BaseLower = (SquareRoot + (Offset - Input_Degree.GetFloat())/180) * (SquareRoot + (Offset - Input_Degree.GetFloat())/180);
                Upper = (SquareRoot + (Offset + LevelInput * Input_Degree.GetFloat())/180) * (SquareRoot + (Offset + LevelInput * Input_Degree.GetFloat())/180);
                Lower = (SquareRoot + (Offset - LevelInput * Input_Degree.GetFloat())/180) * (SquareRoot + (Offset - LevelInput * Input_Degree.GetFloat())/180);

                Mid = (SquareRoot + Offset/180) * (SquareRoot + Offset/180);
            }

            Subgraph_Anchor[sc.Index] = Input_AnchorValue.GetFloat() / MultiplierValue;
            Subgraph_L1Plus[sc.Index] = Upper / MultiplierValue;
            Subgraph_L1Minus[sc.Index] = Lower / MultiplierValue;
            Subgraph_L1[sc.Index] = Mid / MultiplierValue;
            Array_BaseUpper[sc.Index] = BaseUpper;
            Array_BaseLower[sc.Index] = BaseLower;
            Array_Offset[sc.Index] = Offset;

        }
        else
        {
            float L1 = 0.0f;
            float L2 = 0.0f;
            SCString PositiveDegrees;
            SCString NegativeDegrees;

            float squareRoot = sqrt(Input_AnchorValue.GetFloat());
            float localDegree = Input_Degree.GetFloat() * LevelInput;

            PositiveDegrees.Format("+%g deg", localDegree);
            NegativeDegrees.Format("-%g deg", localDegree);

            L1 = (squareRoot + localDegree/180) * (squareRoot + localDegree/180);
            L2 = (squareRoot - localDegree/180) * (squareRoot - localDegree/180);

            Subgraph_Anchor[sc.Index] = Input_AnchorValue.GetFloat() / MultiplierValue;
            Subgraph_L1Plus[sc.Index] = L1 / MultiplierValue;
            Subgraph_L1Minus[sc.Index] = L2 / MultiplierValue;
        }
    }

    /*==========================================================================*/
    SCSFExport scsf_LinearRegressionEndChannel(SCStudyInterfaceRef sc)
    {
        SCSubgraphRef Subgraph_LinearRegression = sc.Subgraph[0];
        SCSubgraphRef Subgraph_StdDevHigh = sc.Subgraph[1];
        SCSubgraphRef Subgraph_StdDevLow = sc.Subgraph[2];

        SCInputRef Input_Data = sc.Input[0];
        SCInputRef Input_PeriodType = sc.Input[1];
        SCInputRef Input_NumberOfBarsToCalculate = sc.Input[2];
        SCInputRef Input_NumberDeviations = sc.Input[3];
        SCInputRef Input_UseStartDateTime = sc.Input[4];
        SCInputRef Input_StartDateTime = sc.Input[5];
        SCInputRef Input_CalculateOnBarClose = sc.Input[6];
        SCInputRef Input_Version = sc.Input[7];

        enum PeriodTypeEnum
        { PERIOD_TYPE_NUMBER_OF_BARS = 0
        , PERIOD_TYPE_FROM_START_DATE_TIME = 1
        , PERIOD_TYPE_FROM_START_TIME = 2
        };

        static const int MAX_BARS_TO_CALCULATE = 10000;

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

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

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

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

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

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

            Input_PeriodType.Name = "Period Type";
            Input_PeriodType.SetCustomInputStrings("Number of Bars;From Start Date-Time;From Start Time");
            Input_PeriodType.SetCustomInputIndex(0);

            Input_NumberOfBarsToCalculate.Name = "Number of Bars";
            Input_NumberOfBarsToCalculate.SetInt(10);
            Input_NumberOfBarsToCalculate.SetIntLimits(1, MAX_BARS_TO_CALCULATE);

            Input_NumberDeviations.Name = "Number of Deviations";
            Input_NumberDeviations.SetFloat(2.0f);
            Input_NumberDeviations.SetFloatLimits(0.001f, 2000);

            //UseStartDateTime.Name = "Use Start Date-Time instead of Number of Bars";
            Input_UseStartDateTime.SetYesNo(false);

            Input_StartDateTime.Name = "Start Date and Time";
            Input_StartDateTime.SetDateTime(0);

            Input_CalculateOnBarClose.Name = "Calculate On Bar Close";
            Input_CalculateOnBarClose.SetYesNo(false);

            Input_Version.SetInt(1);

            return;
        }

        if (Input_Version.GetInt() < 1)
        {
            if (Input_UseStartDateTime.GetYesNo())
                Input_PeriodType.SetCustomInputIndex(1);

            Input_Version.SetInt(1);
        }

        int NumberOfBarsToCalculate = Input_NumberOfBarsToCalculate.GetInt();
        int InputDataOffset = 0;

        if(Input_CalculateOnBarClose.GetYesNo())
            InputDataOffset = 1;

        const int BaseDataArraySize = sc.ArraySize;
        // Formula is  y= a+bx
        // a= (sumY-(b)sumX)/n
        // b= ((n)sumXY-sumX*sumY)/((n)sumXX-(sumY)(sumY))
        float sumY = 0;
        float sumX = 0;
        float sumXY = 0;
        float sumXX = 0;
        float StandardDev = 0;
        float tempY = 0, a = 0, b = 0;
        int NumberOfBars = 0;

        int StartIndex = 0;

        switch (Input_PeriodType.GetIndex())
        {
            case PERIOD_TYPE_NUMBER_OF_BARS:
                StartIndex = max(0, BaseDataArraySize - NumberOfBarsToCalculate - InputDataOffset);
            break;

            case PERIOD_TYPE_FROM_START_DATE_TIME:
            {
                NumberOfBarsToCalculate = MAX_BARS_TO_CALCULATE;

                StartIndex = sc.GetContainingIndexForSCDateTime(sc.ChartNumber, Input_StartDateTime.GetDateTime().GetAsDouble());

                if (StartIndex < BaseDataArraySize - MAX_BARS_TO_CALCULATE)
                    StartIndex = BaseDataArraySize - MAX_BARS_TO_CALCULATE;
                else
                    NumberOfBarsToCalculate = BaseDataArraySize - StartIndex;
            }
            break;

            case PERIOD_TYPE_FROM_START_TIME:
            {
                const int LastBarDate = sc.BaseDateTimeIn[sc.ArraySize - 1].GetDate();
                const int StartTime = Input_StartDateTime.GetTime();

                const SCDateTime CurrentDayStartDateTime(LastBarDate, StartTime);

                StartIndex = sc.GetContainingIndexForSCDateTime(sc.ChartNumber, CurrentDayStartDateTime.GetAsDouble());

                NumberOfBarsToCalculate = BaseDataArraySize - StartIndex;
            }
            break;
        };

        for (int Index = StartIndex
            ; Index < StartIndex + NumberOfBarsToCalculate && Index < BaseDataArraySize
            ; Index++)
        {
            tempY = sc.BaseDataIn[Input_Data.GetInputDataIndex()][Index];
            NumberOfBars++;
            sumY += tempY;
            sumX += NumberOfBars;
            sumXY += (tempY*NumberOfBars);
            sumXX += NumberOfBars*NumberOfBars;
        }

        b = (NumberOfBars*sumXY - (sumX*sumY))/((NumberOfBars*sumXX) - (sumX*sumX));
        a = (sumY - (b*sumX))/NumberOfBars;

        // Solve StandardDev sqrt( sum((Xi-Xbar)^2)/n )
        float tempX = 0;
        for (int Index = StartIndex; Index < StartIndex + NumberOfBarsToCalculate && Index < BaseDataArraySize; Index++)
        {
            float diff = sc.BaseDataIn[Input_Data.GetInputDataIndex()][Index] - (a + b * (Index-StartIndex+1));
            tempX += (diff * diff);
        }

        StandardDev = sqrt(tempX/NumberOfBars);

        // Fill in the Linear Regression data

        sc.EarliestUpdateSubgraphDataArrayIndex = StartIndex;

        for(int BarIndex = 0; BarIndex < NumberOfBars; BarIndex++)
        {
            Subgraph_LinearRegression[StartIndex + BarIndex] = a + b * (BarIndex + 1);

            Subgraph_StdDevHigh[StartIndex + BarIndex] = Subgraph_LinearRegression[StartIndex + BarIndex] + (StandardDev * Input_NumberDeviations.GetFloat());

            Subgraph_StdDevLow[StartIndex + BarIndex] = Subgraph_LinearRegression[StartIndex + BarIndex] - (StandardDev * Input_NumberDeviations.GetFloat());
        }

        if (!Input_UseStartDateTime.GetYesNo())
        {
            // Zero out points that are not within the scope
            int NumNewElements = sc.Open.GetArraySize() - 1 - sc.UpdateStartIndex;

            int BarIndex = BaseDataArraySize - 1 - NumberOfBarsToCalculate - InputDataOffset;

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

            for (
                ; BarIndex >= 0 && NumNewElements > 0
                ; BarIndex--)
            {
                Subgraph_LinearRegression[BarIndex] = 0;
                Subgraph_StdDevHigh[BarIndex] = 0;
                Subgraph_StdDevLow[BarIndex] = 0;
                NumNewElements--;
            }
        }
    }

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

        if(sc.SetDefaults)
        {
            sc.GraphName = "Price Volume Trend";
            sc.GraphRegion = 1;

            Subgraph_PVT.Name = "PVT";
            Subgraph_PVT.DrawStyle = DRAWSTYLE_LINE;
            Subgraph_PVT.PrimaryColor = RGB(0,255,0);

            sc.AutoLoop = 1;

            return;
        }

        sc.DataStartIndex = 1;
        sc.PriceVolumeTrend(sc.BaseDataIn, Subgraph_PVT);
    }

    /*==========================================================================*/
    SCSFExport scsf_StandardDeviationBands(SCStudyInterfaceRef sc)
    {
        SCSubgraphRef Subgraph_TopBand = sc.Subgraph[0];
        SCSubgraphRef Subgraph_BottomBand = sc.Subgraph[1];
        SCSubgraphRef Subgraph_TopMovAvg = sc.Subgraph[2];
        SCSubgraphRef Subgraph_BottomMovAvg = sc.Subgraph[3];
        SCSubgraphRef Subgraph_Temp4 = sc.Subgraph[4];
        SCSubgraphRef Subgraph_Temp5 = sc.Subgraph[5];

        SCInputRef Input_TopBandInputData = sc.Input[0];
        SCInputRef Input_BottomBandInputData = sc.Input[1];
        SCInputRef Input_Length = sc.Input[3];
        SCInputRef Input_MultFactor = sc.Input[5];
        SCInputRef Input_MovAvgType = sc.Input[6];

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

            sc.GraphRegion = 0;

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

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

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

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

            Input_TopBandInputData.Name = "Top Band Input Data";
            Input_TopBandInputData.SetInputDataIndex(SC_HIGH);

            Input_BottomBandInputData.Name = "Bottom Band Input Data";
            Input_BottomBandInputData.SetInputDataIndex(SC_LOW);

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

            Input_MultFactor.Name = "Multiplication Factor";
            Input_MultFactor.SetFloat(1.8f);
            Input_MultFactor.SetFloatLimits(0.1f, 20.0f);

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

            sc.AutoLoop = false;

            return;
        }

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

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

        sc.EarliestUpdateSubgraphDataArrayIndex = CalculationStartIndex;

        for (int BarIndex = CalculationStartIndex; BarIndex < sc.ArraySize; BarIndex++)
        {
            SCFloatArrayRef HighArray = sc.BaseDataIn[Input_TopBandInputData.GetInputDataIndex()];
            SCFloatArrayRef LowArray = sc.BaseDataIn[Input_BottomBandInputData.GetInputDataIndex()];

            sc.MovingAverage(HighArray, Subgraph_TopMovAvg, Input_MovAvgType.GetMovAvgType(), BarIndex, Input_Length.GetInt());
            sc.MovingAverage(LowArray, Subgraph_BottomMovAvg, Input_MovAvgType.GetMovAvgType(), BarIndex, Input_Length.GetInt());

            sc.StdDeviation(HighArray, Subgraph_Temp4, BarIndex, Input_Length.GetInt());
            sc.StdDeviation(LowArray, Subgraph_Temp5, BarIndex, Input_Length.GetInt());

            Subgraph_TopBand[BarIndex] = (Subgraph_Temp4[BarIndex] * Input_MultFactor.GetFloat()) + Subgraph_TopMovAvg[BarIndex];
            Subgraph_BottomBand[BarIndex] = (Subgraph_Temp5[BarIndex] * -Input_MultFactor.GetFloat()) + Subgraph_BottomMovAvg[BarIndex];
        }
    }

    /*==========================================================================*/
    SCSFExport scsf_HighestLowestBars(SCStudyInterfaceRef sc)
    {
        SCSubgraphRef Subgraph_Highest = sc.Subgraph[0];
        SCSubgraphRef Subgraph_Lowest = sc.Subgraph[1];

        SCInputRef Input_HighestLength = sc.Input[0];
        SCInputRef Input_LowestLength = sc.Input[1];
        SCInputRef Input_Data = sc.Input[2];

        if(sc.SetDefaults)
        {
            sc.GraphName = "NumberOfBarsSinceHighestValue / NumberOfBarsSinceLowestValue";
            sc.GraphRegion = 2;

            Subgraph_Highest.Name = "Highest";
            Subgraph_Highest.DrawStyle = DRAWSTYLE_LINE;
            Subgraph_Highest.PrimaryColor = RGB(0,255,0);

            Subgraph_Lowest.Name = "Lowest";
            Subgraph_Lowest.DrawStyle = DRAWSTYLE_LINE;
            Subgraph_Lowest.PrimaryColor = RGB(255,0,255);

            Input_HighestLength.Name = "HighestLength";
            Input_HighestLength.SetInt(10);
            Input_HighestLength.SetIntLimits(2,MAX_STUDY_LENGTH);

            Input_LowestLength.Name = "LowestLength";
            Input_LowestLength.SetInt(10);
            Input_LowestLength.SetIntLimits(2,MAX_STUDY_LENGTH);

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

            sc.AutoLoop = 1;

            return;
        }

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

        sc.DataStartIndex = max(Input_HighestLength.GetInt(), Input_LowestLength.GetInt()) - 1;

        Subgraph_Highest[sc.Index] = static_cast<float>(sc.NumberOfBarsSinceHighestValue(In, sc.Index, Input_HighestLength.GetInt()));
        Subgraph_Lowest[sc.Index] = static_cast<float>(sc.NumberOfBarsSinceLowestValue(In, sc.Index, Input_LowestLength.GetInt()));
    }

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

        SCInputRef Input_CompareType = sc.Input[0];

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

            sc.GraphName = "Volume-Up";

            sc.StudyDescription = "The volume for up bars only.";

            sc.AutoLoop = 1;

            sc.ValueFormat = 0;

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

            Input_CompareType.Name = "Compare Close with: 0=PrevClose, 1=Open";
            Input_CompareType.SetInt(0);
            Input_CompareType.SetIntLimits(0,1);

            return;
        }

        // Do data processing

        bool IsUpBar = false;
        switch (Input_CompareType.GetInt())
        {
        case 0:
            if (sc.Index > 0)
                IsUpBar = sc.Close[sc.Index] > sc.Close[sc.Index - 1];
            break;

        case 1:
            IsUpBar = sc.Close[sc.Index] > sc.Open[sc.Index];
            break;
        }

        if (IsUpBar)
            Subgraph_Volume[sc.Index] = sc.Volume[sc.Index];
        else
            Subgraph_Volume[sc.Index] = 0;
    }

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

        SCInputRef Input_CompareType = sc.Input[0];

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

            sc.GraphName = "Volume-Down";

            sc.StudyDescription = "The volume for down bars only.";

            sc.AutoLoop = 1;

            sc.ValueFormat = 0;

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

            Input_CompareType.Name = "Compare Close with: 0=PrevClose, 1=Open";
            Input_CompareType.SetInt(0);
            Input_CompareType.SetIntLimits(0,1);

            return;
        }

        // Do data processing

        bool IsDownBar = false;
        switch (Input_CompareType.GetInt())
        {
        case 0:
            if (sc.Index > 0)
                IsDownBar = sc.Close[sc.Index] < sc.Close[sc.Index - 1];
            break;

        case 1:
            IsDownBar = sc.Close[sc.Index] < sc.Open[sc.Index];
            break;
        }

        if (IsDownBar)
            Subgraph_Volume[sc.Index] = sc.Volume[sc.Index];
        else
            Subgraph_Volume[sc.Index] = 0;
    }

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

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

            sc.GraphRegion = 1;
            sc.ValueFormat = VALUEFORMAT_TIME;

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

            sc.AutoLoop = 1;
            sc.MaintainAdditionalChartDataArrays = 1;

            return;
        }

        Subgraph_BET[sc.Index] =  static_cast<float>(sc.BaseDataEndDateTime[sc.Index].GetTimeAsSCDateTimeMS().GetAsDouble());
    }

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

        SCInputRef Input_Array1 = sc.Input[0];
        SCInputRef Input_Array2 = sc.Input[1];
        SCInputRef Input_Length = sc.Input[2];

        if(sc.SetDefaults)
        {
            sc.GraphName = "Correlation Coefficient";

            sc.GraphRegion = 1;

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

            Input_Array1.Name = "Input Array 1";
            Input_Array1.SetStudySubgraphValues(0,0);

            Input_Array2.Name = "Input Array 2";
            Input_Array2.SetStudySubgraphValues(0,0);

            Input_Length.Name = "Length";
            Input_Length.SetInt(200);

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

            return;
        }
        sc.DataStartIndex = Input_Length.GetInt();
        SCFloatArray Array1;
        SCFloatArray Array2;

        sc.GetStudyArrayUsingID(Input_Array1.GetStudyID(),Input_Array1.GetSubgraphIndex(),Array1);
        if(Array1.GetArraySize() < sc.ArraySize)
            return;

        sc.GetStudyArrayUsingID(Input_Array2.GetStudyID(),Input_Array2.GetSubgraphIndex(),Array2);
        if(Array2.GetArraySize() < sc.ArraySize)
            return;

        Subgraph_CorrelationCoefficient[sc.Index] = sc.GetCorrelationCoefficient(Array1, Array2, Input_Length.GetInt());

    }

    /*==========================================================================*/
    SCSFExport scsf_SierraSqueeze(SCStudyInterfaceRef sc)
    {
        SCSubgraphRef Subgraph_MomentumHist = sc.Subgraph[0];
        SCSubgraphRef Subgraph_SqueezeDots = sc.Subgraph[1];
        SCSubgraphRef Subgraph_MomentumHistUpColors = sc.Subgraph[2];
        SCSubgraphRef Subgraph_MomentumHistDownColors = sc.Subgraph[3];
        SCSubgraphRef Subgraph_Temp4 = sc.Subgraph[4];
        //SCSubgraphRef Temp5 = sc.Subgraph[5];
        SCSubgraphRef Subgraph_SignalValues = sc.Subgraph[6];
        SCSubgraphRef Subgraph_Temp8 = sc.Subgraph[8];

        SCInputRef Input_InputData = sc.Input[0];
        SCInputRef Input_HistogramLenFirstData = sc.Input[1];
        SCInputRef Input_SqueezeLength = sc.Input[2];
        SCInputRef Input_NK = sc.Input[3];
        SCInputRef Input_NB = sc.Input[4];
        SCInputRef Input_FirstMovAvgType = sc.Input[5];
        SCInputRef Input_HistogramLenSecondData = sc.Input[6];
        SCInputRef Input_SecondMovAvgType = sc.Input[7];
        SCInputRef Input_VersionUpdate = sc.Input[8];

        if (sc.SetDefaults)
        {
            sc.GraphName = "Squeeze Indicator 2";
            sc.StudyDescription = "Developed by the user Tony C.";

            Subgraph_MomentumHist.Name = "Momentum HISTOGRAM";
            Subgraph_MomentumHist.DrawStyle = DRAWSTYLE_BAR;
            Subgraph_MomentumHist.PrimaryColor = RGB(0,255,0);
            Subgraph_MomentumHist.LineWidth = 5;
            Subgraph_MomentumHist.DrawZeros = true;

            Subgraph_SqueezeDots.Name = "Squeeze Dots";
            Subgraph_SqueezeDots.DrawStyle = DRAWSTYLE_POINT;
            Subgraph_SqueezeDots.PrimaryColor = RGB(255,0,255);
            Subgraph_SqueezeDots.LineWidth = 4;
            Subgraph_SqueezeDots.DrawZeros = true;

            Subgraph_MomentumHistUpColors.Name = "Momentum HISTOGRAM Up Colors";
            Subgraph_MomentumHistUpColors.DrawStyle = DRAWSTYLE_IGNORE;
            Subgraph_MomentumHistUpColors.SecondaryColorUsed = 1;
            Subgraph_MomentumHistUpColors.PrimaryColor = RGB(0, 0, 255);
            Subgraph_MomentumHistUpColors.SecondaryColor = RGB(0, 0, 130);
            Subgraph_MomentumHistUpColors.DrawZeros = true;

            Subgraph_MomentumHistDownColors.Name    = "Momentum HISTOGRAM Down Colors";
            Subgraph_MomentumHistDownColors.DrawStyle = DRAWSTYLE_IGNORE;
            Subgraph_MomentumHistDownColors.SecondaryColorUsed = 1;
            Subgraph_MomentumHistDownColors.PrimaryColor = RGB(255, 0, 0);
            Subgraph_MomentumHistDownColors.SecondaryColor = RGB(130, 0, 0);
            Subgraph_MomentumHistDownColors.DrawZeros = true;

            Subgraph_SignalValues.Name = "Signal Values";
            Subgraph_SignalValues.DrawStyle = DRAWSTYLE_IGNORE;
            Subgraph_SignalValues.PrimaryColor = RGB(127,0,255);
            Subgraph_SignalValues.DrawZeros = true;

            Input_InputData.Name = "Input Data";
            Input_InputData.SetInputDataIndex(SC_LAST); // default data field

            Input_HistogramLenFirstData.Name = "Histogram Length First Data";
            Input_HistogramLenFirstData.SetInt(20);
            Input_HistogramLenFirstData.SetIntLimits(1,MAX_STUDY_LENGTH);

            Input_SqueezeLength.Name = "Squeeze Length";
            Input_SqueezeLength.SetFloat(20);

            Input_NK.Name = "NK.GetFloat()";
            Input_NK.SetFloat(1.5);

            Input_NB.Name = "NB.GetFloat()";
            Input_NB.SetFloat(2);

            Input_FirstMovAvgType.Name = "First MA Type";
            Input_FirstMovAvgType.SetMovAvgType(MOVAVGTYPE_EXPONENTIAL);

            Input_HistogramLenSecondData.Name = "Histogram Length Second Data";
            Input_HistogramLenSecondData.SetInt(20);
            Input_HistogramLenSecondData.SetIntLimits(1,MAX_STUDY_LENGTH);

            Input_SecondMovAvgType.Name = "Second MA Type";
            Input_SecondMovAvgType.SetMovAvgType(MOVAVGTYPE_LINEARREGRESSION);

            // hidden input for old versions support
            Input_VersionUpdate.SetInt(1);

            sc.AutoLoop = 1;

            return;
        }

        // upgrading the default settings
        if (Input_VersionUpdate.GetInt() != 1)
        {
            Subgraph_MomentumHistUpColors.Name = "Momentum Histogram Up Colors";
            Subgraph_MomentumHistUpColors.DrawStyle = DRAWSTYLE_IGNORE;
            Subgraph_MomentumHistUpColors.SecondaryColorUsed    = 1;
            Subgraph_MomentumHistUpColors.PrimaryColor = RGB(0, 0, 255);
            Subgraph_MomentumHistUpColors.SecondaryColor = RGB(0, 0, 130);

            Subgraph_MomentumHistDownColors.Name = "Momentum Histogram Down Colors";
            Subgraph_MomentumHistDownColors.DrawStyle = DRAWSTYLE_IGNORE;
            Subgraph_MomentumHistDownColors.SecondaryColorUsed = 1;
            Subgraph_MomentumHistDownColors.PrimaryColor = RGB(255, 0, 0);
            Subgraph_MomentumHistDownColors.SecondaryColor = RGB(130, 0, 0);

            Subgraph_SignalValues.Name = "Signal Values";
            Subgraph_SignalValues.DrawStyle = DRAWSTYLE_IGNORE;

            Input_VersionUpdate.SetInt(1);
        }

        // Inputs
        int i = sc.Index;
        const DWORD inside      = RGB(255, 0, 0);
        const DWORD outside     = RGB(0, 255, 0);

        Subgraph_MomentumHistUpColors[i] = 0;
        Subgraph_MomentumHistDownColors[i] = 0;

        // First output elements are not valid
        sc.DataStartIndex = Input_HistogramLenSecondData.GetInt();

        SCFloatArrayRef close =  sc.Close;
        sc.ExponentialMovAvg(close, Subgraph_MomentumHistUpColors, Input_HistogramLenSecondData.GetInt());  // Note: EMA returns close when index is < HistogramLenSecondData.GetInt()
        sc.MovingAverage(close,  Subgraph_MomentumHistUpColors, Input_FirstMovAvgType.GetMovAvgType(), Input_HistogramLenFirstData.GetInt());

        float hlh = sc.GetHighest(sc.High, Input_HistogramLenSecondData.GetInt());
        float lll = sc.GetLowest(sc.Low, Input_HistogramLenSecondData.GetInt());

        SCFloatArrayRef price = sc.Open;

        Subgraph_MomentumHistDownColors[sc.Index] = price[sc.Index] - ((hlh + lll)/2.0f + Subgraph_MomentumHistUpColors[sc.Index])/2.0f;
        sc.LinearRegressionIndicator(Subgraph_MomentumHistDownColors, Subgraph_MomentumHist, Input_HistogramLenSecondData.GetInt());
        sc.MovingAverage(close,  Subgraph_MomentumHistUpColors, Input_SecondMovAvgType.GetMovAvgType(), Input_HistogramLenSecondData.GetInt());

        if(
            (Subgraph_MomentumHist[i]<0)
            &&(Subgraph_MomentumHist[i] < Subgraph_MomentumHist[i-1])
            )

        {
            Subgraph_MomentumHist.DataColor[sc.Index] = Subgraph_MomentumHistDownColors.PrimaryColor;
        }
        else if(
            (Subgraph_MomentumHist[i]<=0)
            &&(Subgraph_MomentumHist[i] > Subgraph_MomentumHist[i-1])
            )
        {
            Subgraph_MomentumHist.DataColor[sc.Index] = Subgraph_MomentumHistDownColors.SecondaryColor;
        }
        else if(
            (Subgraph_MomentumHist[i]>0)
            &&(Subgraph_MomentumHist[i] > Subgraph_MomentumHist[i-1])
            )
        {
            Subgraph_MomentumHist.DataColor[sc.Index] = Subgraph_MomentumHistUpColors.PrimaryColor;
        }
        else if(
            (Subgraph_MomentumHist[i]>=0)
            &&(Subgraph_MomentumHist[i] < Subgraph_MomentumHist[i-1])
            )
        {
            Subgraph_MomentumHist.DataColor[sc.Index] = Subgraph_MomentumHistUpColors.SecondaryColor;
        }

        //Squeeze
        sc.Keltner(
            sc.BaseDataIn,
            sc.Close,
            Subgraph_Temp8,
            Input_SqueezeLength.GetInt(),
            MOVAVGTYPE_SMOOTHED,
            Input_SqueezeLength.GetInt(),
            MOVAVGTYPE_SMOOTHED,
            Input_NK.GetFloat(),
            Input_NK.GetFloat()
            );

        float TopBandOut = Subgraph_Temp8.Arrays[0][sc.Index];
        float BottomBandOut = Subgraph_Temp8.Arrays[1][sc.Index];

        sc.BollingerBands(sc.Close, Subgraph_Temp4, Input_SqueezeLength.GetInt(), Input_NB.GetFloat(), MOVAVGTYPE_SMOOTHED);

        float BU =Subgraph_Temp4.Arrays[0][sc.Index];
        float BL =Subgraph_Temp4.Arrays[1][sc.Index];

        if (
            (BU < TopBandOut)
            || (BL > BottomBandOut)
            )
        {
            Subgraph_SqueezeDots[sc.Index] = 0.0;
            Subgraph_SqueezeDots.DataColor[sc.Index] = inside;
            Subgraph_SignalValues[sc.Index] = 0.0;
            Subgraph_SignalValues.DataColor[sc.Index] = inside;
        }
        else
        {
            Subgraph_SqueezeDots[sc.Index] = 0.0;
            Subgraph_SqueezeDots.DataColor[sc.Index] = outside;
            Subgraph_SignalValues[sc.Index] = 1.0;
            Subgraph_SignalValues.DataColor[sc.Index] = outside;
        }
    }

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

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

        if(sc.SetDefaults)
        {
            sc.GraphName="R Squared";
            sc.StudyDescription="R Squared Indicator by ertrader.";

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

            Subgraph_RSquared.Name="R Squared";
            Subgraph_RSquared.DrawStyle = DRAWSTYLE_LINE;
            Subgraph_RSquared.LineWidth = 2;
            Subgraph_RSquared.PrimaryColor = COLOR_GREEN;
            Subgraph_RSquared.SecondaryColor = COLOR_RED;
            Subgraph_RSquared.DrawZeros = false;

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

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

        // Start plotting after good output elements are valid
        sc.DataStartIndex = Input_Length.GetInt();

        // R^2 indicator:  Pwr(Corr(Cum( 1 ),C,14,0),2)  or Correlation_Coefficient^2.  This method calculates R^ with minimal lag.
        SCFloatArrayRef PriceData = sc.BaseData[Input_Data.GetInputDataIndex()];

        //The following is a cumulative calculation.  It sums up a count of 1 for each bar.  It is then used to correlate data against
        Subgraph_RSquared.Arrays[0][sc.Index] = static_cast<float>(sc.Index + 1);

        //Get the correlation coefficient. Correlate Price Data against the cumulation
        float coef = sc.GetCorrelationCoefficient(Subgraph_RSquared.Arrays[0], PriceData, sc.Index, Input_Length.GetInt());

        // Calculate and Draw R squared
        //Pwr(Corr(Cum( 1 ),C,14,0),2) or Correlation_Coefficient^2
        Subgraph_RSquared[sc.Index]=coef*coef;
    }

    /*==========================================================================*/
    //http://en.wikipedia.org/wiki/Exponential_function
    SCSFExport scsf_RSIInverseFisherTransform(SCStudyInterfaceRef sc)
    {
        SCSubgraphRef Subgraph_RSI_IFT = sc.Subgraph[0];
        SCSubgraphRef Subgraph_Line1 = sc.Subgraph[1];
        SCSubgraphRef Subgraph_Line2 = sc.Subgraph[2];
        SCSubgraphRef Subgraph_RSI = sc.Subgraph[3];

        SCInputRef Input_RSILength = sc.Input[0];
        SCInputRef Input_RSIInternalMovAvgType = sc.Input[1];
        SCInputRef Input_RSIMovAvgType = sc.Input[2];
        SCInputRef Input_RSIMovAvgLength = sc.Input[3];
        SCInputRef Input_LineValue = sc.Input[4];

        if(sc.SetDefaults)
        {
            sc.GraphName="Inverse Fisher Transform RSI";
            sc.StudyDescription="Inverse Fisher Transform RSI by John Ehlers.";

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

            Subgraph_RSI_IFT.Name="RSI IFT";
            Subgraph_RSI_IFT.DrawStyle = DRAWSTYLE_LINE;
            Subgraph_RSI_IFT.LineWidth = 2;
            Subgraph_RSI_IFT.PrimaryColor = COLOR_GREEN;
            Subgraph_RSI_IFT.DrawZeros = true;

            Subgraph_Line1.Name="Line 1";
            Subgraph_Line1.DrawStyle = DRAWSTYLE_LINE;
            Subgraph_Line1.LineWidth = 1;
            Subgraph_Line1.PrimaryColor = COLOR_RED;
            Subgraph_Line1.DrawZeros = true;

            Subgraph_Line2.Name="Line 2";
            Subgraph_Line2.DrawStyle = DRAWSTYLE_LINE;
            Subgraph_Line2.LineWidth = 1;
            Subgraph_Line2.PrimaryColor = COLOR_BLUE;
            Subgraph_Line2.DrawZeros = true;

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

            Input_RSIInternalMovAvgType.Name="RSI Internal MovAvg Type";
            Input_RSIInternalMovAvgType.SetMovAvgType(MOVAVGTYPE_SIMPLE);

            Input_RSIMovAvgType.Name="RSI MovAvg Type";
            Input_RSIMovAvgType.SetMovAvgType(MOVAVGTYPE_WEIGHTED);

            Input_RSIMovAvgLength.Name="RSI MovAvg Length";
            Input_RSIMovAvgLength.SetInt(9);
            Input_RSIMovAvgLength.SetIntLimits(1,MAX_STUDY_LENGTH);

            Input_LineValue.Name="Line Value";
            Input_LineValue.SetFloat(0.5);

            return;
        }

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

        sc.InverseFisherTransformRSI(sc.Close, Subgraph_RSI_IFT, Input_RSILength.GetInt(), Input_RSIInternalMovAvgType.GetMovAvgType(), Input_RSIMovAvgLength.GetInt(), Input_RSIMovAvgType.GetMovAvgType());

        Subgraph_Line1[sc.Index] = Input_LineValue.GetFloat();
        Subgraph_Line2[sc.Index] = -Input_LineValue.GetFloat();
    }

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

    SCSFExport scsf_InverseFisherTransform(SCStudyInterfaceRef sc)
    {
        SCSubgraphRef Subgraph_InverseFisherTransform = sc.Subgraph[0];
        SCSubgraphRef Subgraph_Line1 = sc.Subgraph[1];
        SCSubgraphRef Subgraph_Line2 = sc.Subgraph[2];
        SCSubgraphRef Subgraph_IFTAvg = sc.Subgraph[3];

        SCInputRef Input_Data = sc.Input[0];
        SCInputRef Input_LineValue = sc.Input[1];
        SCInputRef Input_OutputMovAvgLength = sc.Input[2];
        SCInputRef Input_OutputMovAvgType = sc.Input[3];
        SCInputRef Input_MovAvgLength = sc.Input[4];
        SCInputRef Input_MovAvgType = sc.Input[5];
        SCInputRef Input_HighestLowestLength = sc.Input[6];

        if(sc.SetDefaults)
        {
            sc.GraphName="Inverse Fisher Transform";
            sc.StudyDescription="Inverse Fisher Transform.";

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

            Subgraph_InverseFisherTransform.Name="IFT";
            Subgraph_InverseFisherTransform.DrawStyle = DRAWSTYLE_LINE;
            Subgraph_InverseFisherTransform.LineWidth = 2;
            Subgraph_InverseFisherTransform.PrimaryColor = COLOR_GREEN;
            Subgraph_InverseFisherTransform.DrawZeros = true;

            Subgraph_Line1.Name="Line 1";
            Subgraph_Line1.DrawStyle = DRAWSTYLE_LINE;
            Subgraph_Line1.LineWidth = 1;
            Subgraph_Line1.PrimaryColor = COLOR_RED;
            Subgraph_Line1.DrawZeros = true;

            Subgraph_Line2.Name="Line 2";
            Subgraph_Line2.DrawStyle = DRAWSTYLE_LINE;
            Subgraph_Line2.LineWidth = 1;
            Subgraph_Line2.PrimaryColor = COLOR_BLUE;
            Subgraph_Line2.DrawZeros = true;

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

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

            Input_LineValue.Name="Line Value";
            Input_LineValue.SetFloat(0.5);

            Input_OutputMovAvgLength.Name="Output Mov Avg Length";
            Input_OutputMovAvgLength.SetInt(3);

            Input_OutputMovAvgType.Name="Output Mov Avg Type";
            Input_OutputMovAvgType.SetMovAvgType(MOVAVGTYPE_SIMPLE);

            Input_MovAvgLength.Name="Input Data Mov Avg Length";
            Input_MovAvgLength.SetInt(9);

            Input_MovAvgType.Name="Input Data Mov Avg Type";
            Input_MovAvgType.SetMovAvgType(MOVAVGTYPE_WEIGHTED);

            Input_HighestLowestLength.Name = "Highest Value/Lowest Value Length";
            Input_HighestLowestLength.SetInt(10);

            return;
        }

        sc.DataStartIndex = Input_MovAvgLength.GetInt()+Input_OutputMovAvgLength.GetInt();

        sc.InverseFisherTransform(sc.BaseData[Input_Data.GetInputDataIndex()], Subgraph_InverseFisherTransform, Input_HighestLowestLength.GetInt(), Input_MovAvgLength.GetInt(), Input_MovAvgType.GetMovAvgType());

        sc.MovingAverage(Subgraph_InverseFisherTransform, Subgraph_IFTAvg, Input_OutputMovAvgType.GetMovAvgType(),Input_OutputMovAvgLength.GetInt());

        Subgraph_Line1[sc.Index] = Input_LineValue.GetFloat();
        Subgraph_Line2[sc.Index] = -Input_LineValue.GetFloat();
    }

    /*============================================================================
    Sine-Wave Weighted Moving Average
    ----------------------------------------------------------------------------*/
    SCSFExport scsf_SineWaveWMA(SCStudyInterfaceRef sc)
    {
        SCSubgraphRef Subgraph_WMA = sc.Subgraph[0];

        SCInputRef Input_Data = sc.Input[0];

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

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

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

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

            return;
        }

        //PI:=3.1415926;
        //SD:=180/6;
        //S1:=Sin(1*180/6)*C;
        //S2:=Sin(2*180/6)*Ref(C,-1);
        //S3:=Sin(3*180/6)*Ref(C,-2);
        //S4:=Sin(4*180/6)*Ref(C,-3);
        //S5:=Sin(5*180/6)*Ref(C,-4);
        //Num:=S1+S2+S3+S4+S5;
        //Den:=Sin(SD)+Sin(2*SD)+Sin(3*SD)+Sin(4*SD)+Sin(5*SD);
        //Num/Den

        sc.DataStartIndex = 5;
        if (sc.Index < 4)
            return;

        int InputDataIndex = Input_Data.GetInputDataIndex();

        const float SD = static_cast<float>(M_PI/6);  // Note: the sin function takes radians, not degrees
        float S1 = sin(1*SD) * sc.BaseData[InputDataIndex][sc.Index - 0];
        float S2 = sin(2*SD) * sc.BaseData[InputDataIndex][sc.Index - 1];
        float S3 = sin(3*SD) * sc.BaseData[InputDataIndex][sc.Index - 2];
        float S4 = sin(4*SD) * sc.BaseData[InputDataIndex][sc.Index - 3];
        float S5 = sin(5*SD) * sc.BaseData[InputDataIndex][sc.Index - 4];

        float Num = S1 + S2 + S3 + S4 + S5;
        float Den = sin(1*SD) + sin(2*SD) + sin(3*SD) + sin(4*SD) + sin(5*SD);

        Subgraph_WMA[sc.Index] = Num / Den;
    }

    /*==========================================================================*/
    /*
    Bollinger bands squeeze.

    Proportion = (kUpper - kLower) / (bbUpper - bbLower);

    */
    SCSFExport scsf_BollingerSqueeze(SCStudyInterfaceRef sc)
    {
        SCSubgraphRef Subgraph_BandsRatio = sc.Subgraph[0];
        SCSubgraphRef Subgraph_SqueezeIndicator = sc.Subgraph[1];
        SCSubgraphRef Subgraph_Keltner = sc.Subgraph[2];
        SCSubgraphRef Subgraph_BollingerBands = sc.Subgraph[3];

        SCInputRef Input_Data = sc.Input[0];
        SCInputRef Input_InternalMovAvgType = sc.Input[1];
        SCInputRef Input_KeltnerBandsLength = sc.Input[2];
        SCInputRef Input_KeltnerTrueRangeMALength = sc.Input[3];
        SCInputRef Input_KeltnerBandsMultiplier = sc.Input[4];
        SCInputRef Input_BollingerBandsLength = sc.Input[5];
        SCInputRef Input_BollingerBandsMultiplier = sc.Input[6];

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

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

            Subgraph_BandsRatio.Name = "Bands Ratio";
            Subgraph_BandsRatio.DrawStyle = DRAWSTYLE_BAR;
            Subgraph_BandsRatio.PrimaryColor = RGB(0,255,0);
            Subgraph_BandsRatio.SecondaryColor = RGB(255,0,0);
            Subgraph_BandsRatio.SecondaryColorUsed = true;
            Subgraph_BandsRatio.DrawZeros = true;

            Subgraph_SqueezeIndicator.Name = "Squeeze Indicator";
            Subgraph_SqueezeIndicator.DrawStyle = DRAWSTYLE_POINT;
            Subgraph_SqueezeIndicator.LineWidth = 3;
            Subgraph_SqueezeIndicator.PrimaryColor = RGB(0,255,0);
            Subgraph_SqueezeIndicator.SecondaryColor = RGB(255,0,0);
            Subgraph_SqueezeIndicator.SecondaryColorUsed = true;
            Subgraph_SqueezeIndicator.DrawZeros = true;

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

            Input_InternalMovAvgType.Name="Moving Average Type for Internal Calculations";
            Input_InternalMovAvgType.SetMovAvgType(MOVAVGTYPE_SIMPLE);

            Input_KeltnerBandsLength.Name="Keltner Bands Length";
            Input_KeltnerBandsLength.SetInt(20);
            Input_KeltnerBandsLength.SetIntLimits(1,MAX_STUDY_LENGTH);

            Input_KeltnerTrueRangeMALength.Name = "Keltner True Range MovAvg Length";
            Input_KeltnerTrueRangeMALength.SetInt(20);
            Input_KeltnerTrueRangeMALength.SetIntLimits(1,MAX_STUDY_LENGTH);

            Input_KeltnerBandsMultiplier.Name="Keltner Bands Multiplier";
            Input_KeltnerBandsMultiplier.SetFloat(2.0f);

            Input_BollingerBandsLength.Name="Bollinger Bands Length";
            Input_BollingerBandsLength.SetInt(20);
            Input_BollingerBandsLength.SetIntLimits(1,MAX_STUDY_LENGTH);

            Input_BollingerBandsMultiplier.Name="Bollinger Bands Multiplier";
            Input_BollingerBandsMultiplier.SetFloat(2.0f);

            return;
        }

        sc.DataStartIndex = max(Input_BollingerBandsLength.GetInt(), max(Input_KeltnerBandsLength.GetInt(), Input_KeltnerTrueRangeMALength.GetInt())) - 1;

        // calculate Bollinger Bands
        sc.BollingerBands(sc.BaseData[Input_Data.GetInputDataIndex()],Subgraph_BollingerBands,Input_BollingerBandsLength.GetInt(),Input_BollingerBandsMultiplier.GetFloat(),Input_InternalMovAvgType.GetMovAvgType());

        // calculate Keltner
        sc.Keltner( sc.BaseData,sc.BaseData[Input_Data.GetInputDataIndex()],Subgraph_Keltner,Input_KeltnerBandsLength.GetInt(), Input_InternalMovAvgType.GetMovAvgType(),Input_BollingerBandsLength.GetInt(),Input_InternalMovAvgType.GetMovAvgType(), Input_KeltnerBandsMultiplier.GetFloat(),Input_KeltnerBandsMultiplier.GetFloat());

        float KUp = Subgraph_Keltner.Arrays[0][sc.CurrentIndex];
        float KDown = Subgraph_Keltner.Arrays[1][sc.CurrentIndex];

        float UBB = Subgraph_BollingerBands.Arrays[0][sc.CurrentIndex];
        float LBB = Subgraph_BollingerBands.Arrays[1][sc.CurrentIndex];

        if ((UBB > KUp) && (LBB < KDown))
            Subgraph_SqueezeIndicator.DataColor[sc.CurrentIndex] = Subgraph_SqueezeIndicator.PrimaryColor;
        else
            Subgraph_SqueezeIndicator.DataColor[sc.CurrentIndex] = Subgraph_SqueezeIndicator.SecondaryColor;

        Subgraph_BandsRatio[sc.CurrentIndex] = (KUp-KDown)/(UBB - LBB) - 1.0f;

        if (Subgraph_BandsRatio[sc.CurrentIndex] >= 0)
            Subgraph_BandsRatio.DataColor[sc.CurrentIndex] = Subgraph_BandsRatio.PrimaryColor;
        else
            Subgraph_BandsRatio.DataColor[sc.CurrentIndex] = Subgraph_BandsRatio.SecondaryColor;
    }

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

        SCInputRef Input_StudySubgraph1 = sc.Input[5];
        SCInputRef Input_StudySubgraph2 = sc.Input[6];
        SCInputRef Input_Study2SubgraphOffset = sc.Input[7];
        SCInputRef Input_VersionUpdate = sc.Input[8];

        SCInputRef Input_DrawZeros = sc.Input[9];
        SCInputRef Input_PerformSubtractWithZeroValue = sc.Input[10];

        if (sc.SetDefaults)
        {
            sc.GraphName = "Study Subgraphs Subtract/Difference";
            sc.StudyDescription = "Calculates the difference between the two selected study Subgraphs.";

            sc.AutoLoop = 0;//manual looping
            sc.CalculationPrecedence = LOW_PREC_LEVEL;

            Subgraph_Diff.Name = "Diff";
            Subgraph_Diff.DrawStyle = DRAWSTYLE_LINE;
            Subgraph_Diff.PrimaryColor = RGB(0,255,0);
            Subgraph_Diff.LineWidth = 1;

            Input_StudySubgraph1.Name = "Input Study 1";
            Input_StudySubgraph1.SetStudySubgraphValues(0, 0);

            Input_StudySubgraph2.Name = "Input Study 2";
            Input_StudySubgraph2.SetStudySubgraphValues(0, 0);

            Input_Study2SubgraphOffset.Name = "Study 2 Subgraph Offset";// This is always converted to a positive value and is the number of bars back
            Input_Study2SubgraphOffset.SetInt(0);

            Input_DrawZeros.Name = "Draw Zeros";
            Input_DrawZeros.SetYesNo(false);

            Input_VersionUpdate.SetInt(2);

            Input_PerformSubtractWithZeroValue.Name = "Perform Subtract With Zero Value";
            Input_PerformSubtractWithZeroValue.SetYesNo(true);

            return;
        }

        if (Input_VersionUpdate.GetInt() < 2)
        {
            Input_PerformSubtractWithZeroValue.SetYesNo(true);
            Input_VersionUpdate.SetInt(2);
        }

        if (sc.IsFullRecalculation && sc.UpdateStartIndex == 0)
            sc.GraphName = "Study Subgraphs Difference";

        Subgraph_Diff.DrawZeros = Input_DrawZeros.GetYesNo();

        SCFloatArray Study1Array;
        sc.GetStudyArrayUsingID(Input_StudySubgraph1.GetStudyID(), Input_StudySubgraph1.GetSubgraphIndex(), Study1Array);

        SCFloatArray Study2Array;
        sc.GetStudyArrayUsingID(Input_StudySubgraph2.GetStudyID(), Input_StudySubgraph2.GetSubgraphIndex(), Study2Array);

        int CalculationStartIndex = sc.GetCalculationStartIndexForStudy();

        for (int Index = CalculationStartIndex; Index < sc.ArraySize; Index++)
        {
            float Value1 = Study1Array[Index];
            float Value2 = Study2Array[Index - labs(Input_Study2SubgraphOffset.GetInt())];

            if (Input_PerformSubtractWithZeroValue.GetYesNo()
                || (Value1 != 0.0 && Value2 != 0.0))
            {
                Subgraph_Diff[Index] = Value1 - Value2;
            }
            else
            {
                Subgraph_Diff[Index] = 0.0;
            }
        }

        sc.EarliestUpdateSubgraphDataArrayIndex = CalculationStartIndex;

    }

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

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

        if (sc.SetDefaults)
        {
            sc.GraphName = "Linear Regressive Slope";

            sc.AutoLoop = 1;

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

            Subgraph_LRS.Name = "LRS";
            Subgraph_LRS.DrawStyle = DRAWSTYLE_LINE;
            Subgraph_LRS.PrimaryColor = RGB(0,255,0);
            Subgraph_LRS.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();

        int Len=Input_Length.GetInt();
        double SumBars = Len*(Len-1)/2.0;
        double SumSqrBars = (Len-1)*Len*(2*Len-1)/6.0;

        double Sum1       = 0;
        double SumY=0;
        for(int Index=sc.Index; Index > (sc.Index - Len); Index--)
        {
            int x =sc.Index-Index;
            Sum1= Sum1 + x*sc.BaseData[Input_Data.GetInputDataIndex()][Index];
            SumY += sc.BaseData[Input_Data.GetInputDataIndex()][Index];
        }

        double Sum2 = SumBars * SumY;
        double Num1 = Len*Sum1 - Sum2;
        double Num2 = SumBars*SumBars - Len*SumSqrBars;
        Subgraph_LRS[sc.Index] = static_cast<float>(Num1 / Num2);

        return;
    }

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

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

        if (sc.SetDefaults)
        {
            sc.GraphName = "Summation - Periodic";
            sc.StudyDescription = "The cumulative sum over the number of elements specified by the Length input.";

            sc.AutoLoop = 1;

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

            Subgraph_Sum.Name = "Sum";
            Subgraph_Sum.DrawStyle = DRAWSTYLE_LINE;
            Subgraph_Sum.PrimaryColor = RGB(0,255,0);
            Subgraph_Sum.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;
        }

        sc.Summation(sc.BaseData[Input_Data.GetInputDataIndex()], Subgraph_Sum, Input_Length.GetInt());
    }

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

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

        if (sc.SetDefaults)
        {
            sc.GraphName = "Summation of Study Subgraph - Periodic";

            sc.AutoLoop = 1;

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

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

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

            Input_StudySubgraphReference.Name = "Study and Subgraph To Reference";
            Input_StudySubgraphReference.SetStudySubgraphValues(1,0);

            return;
        }

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

        if(StudyArray.GetArraySize() == 0)
        {
            SCString Message;
            Message = sc.GraphName;
            Message += " Study being referenced does not exist.";
            sc.AddMessageToLog(Message, 1);
            return;
        }

        sc.DataStartIndex = sc.GetStudyDataStartIndexUsingID(Input_StudySubgraphReference.GetStudyID());

        sc.Summation(StudyArray, Subgraph_Sum, Input_Length.GetInt());
    }

    /*==========================================================================*/
    SCSFExport scsf_PeriodOHLCVariablePeriod(SCStudyInterfaceRef sc)
    {
        SCInputRef Input_TimePeriodType = sc.Input[0];
        SCInputRef Input_TimePeriodLength = sc.Input[1];
        SCInputRef Input_UseCurrentPeriod = sc.Input[2];
        SCInputRef Input_MinimumRequiredTimePeriodAsPercent = sc.Input[3];
        SCInputRef Input_NumberOfForwardBarsToProject = sc.Input[4];
        SCInputRef Input_DisplayDebuggingOutput = sc.Input[5];
        SCInputRef Input_ForwardProjectLines = sc.Input[6];
        SCInputRef Input_NumberOfDaysToCalculate = sc.Input[7];
        SCInputRef Input_AutoSkipPeriodOfNoTrading = sc.Input[8];
        SCInputRef Input_GraphHighLowLinesHistorically = sc.Input[9];

        if (sc.SetDefaults)
        {
            sc.GraphName = "Period OHLC-Variable Period";
            sc.AutoLoop = 0; // Manual Looping

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

            sc.Subgraph[SC_OPEN].Name = "Open";
            sc.Subgraph[SC_OPEN].DrawStyle = DRAWSTYLE_DASH;
            sc.Subgraph[SC_OPEN].PrimaryColor = RGB(0,255,0);
            sc.Subgraph[SC_OPEN].LineWidth = 2;
            sc.Subgraph[SC_OPEN].DrawZeros = false;

            sc.Subgraph[SC_HIGH].Name = "High";
            sc.Subgraph[SC_HIGH].DrawStyle = DRAWSTYLE_DASH;
            sc.Subgraph[SC_HIGH].PrimaryColor = RGB(255,0,255);
            sc.Subgraph[SC_HIGH].LineWidth = 2;
            sc.Subgraph[SC_HIGH].DrawZeros = false;

            sc.Subgraph[SC_LOW].Name = "Low";
            sc.Subgraph[SC_LOW].DrawStyle = DRAWSTYLE_DASH;
            sc.Subgraph[SC_LOW].PrimaryColor = RGB(255,255,0);
            sc.Subgraph[SC_LOW].LineWidth = 2;
            sc.Subgraph[SC_LOW].DrawZeros = false;

            sc.Subgraph[SC_LAST].Name = "Close";
            sc.Subgraph[SC_LAST].DrawStyle = DRAWSTYLE_DASH;
            sc.Subgraph[SC_LAST].PrimaryColor = RGB(255,127,0);
            sc.Subgraph[SC_LAST].LineWidth = 2;
            sc.Subgraph[SC_LAST].DrawZeros = false;

            sc.Subgraph[SC_OHLC_AVG].Name = "OHLC Avg";
            sc.Subgraph[SC_OHLC_AVG].DrawStyle = DRAWSTYLE_IGNORE;
            sc.Subgraph[SC_OHLC_AVG].PrimaryColor = RGB(128,128,128);
            sc.Subgraph[SC_OHLC_AVG].DrawZeros = false;

            sc.Subgraph[SC_HLC_AVG] .Name= "HLC Avg";
            sc.Subgraph[SC_HLC_AVG].DrawStyle = DRAWSTYLE_IGNORE;
            sc.Subgraph[SC_HLC_AVG].PrimaryColor = RGB(128,128,128);
            sc.Subgraph[SC_HLC_AVG].DrawZeros = false;

            sc.Subgraph[SC_HL_AVG] .Name= "HL Avg";
            sc.Subgraph[SC_HL_AVG].DrawStyle = DRAWSTYLE_IGNORE;
            sc.Subgraph[SC_HL_AVG].PrimaryColor = RGB(128,128,128);
            sc.Subgraph[SC_HL_AVG].DrawZeros = false;

            for (int SubgraphIndex = SC_OPEN; SubgraphIndex <= SC_HL_AVG; SubgraphIndex++)
            {
                sc.Subgraph[SubgraphIndex].LineLabel =
                    LL_DISPLAY_NAME  | LL_NAME_ALIGN_CENTER | LL_NAME_ALIGN_FAR_RIGHT |
                    LL_DISPLAY_VALUE | LL_VALUE_ALIGN_CENTER | LL_VALUE_ALIGN_VALUES_SCALE;
            }

            unsigned short DisplayOrder = 1;

            Input_TimePeriodType.Name = "Time Period Type";
            Input_TimePeriodType.SetTimePeriodType(TIME_PERIOD_LENGTH_UNIT_MINUTES);
            Input_TimePeriodType.DisplayOrder = DisplayOrder++;

            Input_TimePeriodLength.Name = "Time Period Length";
            Input_TimePeriodLength.SetInt(60);
            Input_TimePeriodLength.SetIntLimits(1, 7*MINUTES_PER_DAY);
            Input_TimePeriodLength.DisplayOrder = DisplayOrder++;

            Input_UseCurrentPeriod.Name = "Use Current Period";
            Input_UseCurrentPeriod.SetYesNo(false);
            Input_UseCurrentPeriod.DisplayOrder = DisplayOrder++;

            Input_AutoSkipPeriodOfNoTrading.Name = "Auto Skip Period of No Trading";
            Input_AutoSkipPeriodOfNoTrading.SetYesNo(false);
            Input_AutoSkipPeriodOfNoTrading.DisplayOrder = DisplayOrder++;

            Input_MinimumRequiredTimePeriodAsPercent.Name = "Minimum Required Time Period as %";
            Input_MinimumRequiredTimePeriodAsPercent.SetFloat(5.0f);
            Input_MinimumRequiredTimePeriodAsPercent.SetFloatLimits(1.0f, 100.0f);
            Input_MinimumRequiredTimePeriodAsPercent.DisplayOrder = DisplayOrder++;

            Input_ForwardProjectLines.Name = "Forward Project OHLC Lines";
            Input_ForwardProjectLines.SetYesNo(0);
            Input_ForwardProjectLines.DisplayOrder = DisplayOrder++;

            Input_NumberOfForwardBarsToProject.Name = "Number of Forward Bars to Project";
            Input_NumberOfForwardBarsToProject.SetInt(10);
            Input_NumberOfForwardBarsToProject.DisplayOrder = DisplayOrder++;

            Input_NumberOfDaysToCalculate.Name = "Number of Days to Calculate";
            Input_NumberOfDaysToCalculate.SetInt(250);
            Input_NumberOfDaysToCalculate.SetIntLimits(1, MAX_STUDY_LENGTH);
            Input_NumberOfDaysToCalculate.DisplayOrder = DisplayOrder++;

            Input_GraphHighLowLinesHistorically.Name = "Graph High/Low Lines Historically (Use Current Period = yes)";
            Input_GraphHighLowLinesHistorically.SetYesNo(0);
            Input_GraphHighLowLinesHistorically.DisplayOrder = DisplayOrder++;

            Input_DisplayDebuggingOutput.Name = "Display Debugging Output (slows study calculations)";
            Input_DisplayDebuggingOutput.SetYesNo(0);
            Input_DisplayDebuggingOutput.DisplayOrder = DisplayOrder++;

            return;
        }

        int PeriodLength = Input_TimePeriodLength.GetInt();

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

        int NumberOfForwardBars = 0;

        if (Input_ForwardProjectLines.GetYesNo())
        {
            NumberOfForwardBars = Input_NumberOfForwardBarsToProject.GetInt();

            for (int SubgraphIndex = SC_OPEN; SubgraphIndex <= SC_HL_AVG; SubgraphIndex++)
                sc.Subgraph[SubgraphIndex].ExtendedArrayElementsToGraph = NumberOfForwardBars;
        }
        else
        {
            for (int SubgraphIndex = SC_OPEN; SubgraphIndex <= SC_HL_AVG; SubgraphIndex++)
                sc.Subgraph[SubgraphIndex].ExtendedArrayElementsToGraph = 0;
        }

        if (Input_NumberOfDaysToCalculate.GetInt() < 1)
            Input_NumberOfDaysToCalculate.SetInt(250);

        if (Input_UseCurrentPeriod.GetYesNo() == 0)
            Input_GraphHighLowLinesHistorically.SetYesNo(false);

        SCDateTimeMS FirstDateToCalculate = sc.GetTradingDayDate(sc.BaseDateTimeIn[sc.ArraySize - 1]);
        FirstDateToCalculate.SubtractDays(Input_NumberOfDaysToCalculate.GetInt() - 1);

        float Open = 0, High = 0, Low = 0, Close = 0, NextOpen = 0;

        SCDateTimeMS BeginOfRefDateTime;
        SCDateTimeMS EndOfRefDateTime;
        SCDateTimeMS CurrentPeriodBeginDateTime;
        SCDateTimeMS CurrentPeriodEndDateTime;

        SCDateTimeMS PriorCurrentPeriodStartDateTime;

        for (int BarIndex = sc.UpdateStartIndex; BarIndex < sc.ArraySize + NumberOfForwardBars; BarIndex++)
        {
            const SCDateTimeMS CurrentBarDateTime = sc.BaseDateTimeIn[BarIndex];

            if (sc.GetTradingDayDate(CurrentBarDateTime) < FirstDateToCalculate)
                continue;

            bool GetReferenceData = true;

            CurrentPeriodBeginDateTime = sc.GetStartOfPeriodForDateTime(CurrentBarDateTime, Input_TimePeriodType.GetTimePeriodType(), PeriodLength, 0);

            if (CurrentPeriodBeginDateTime == PriorCurrentPeriodStartDateTime)
            {
                GetReferenceData = false;
            }

            PriorCurrentPeriodStartDateTime = CurrentPeriodBeginDateTime;

            bool IsStartOfNewPeriod = false;

            if (Input_GraphHighLowLinesHistorically.GetYesNo())
            {
                if (BarIndex == 0)
                    IsStartOfNewPeriod = true;
                else
                {
                    SCDateTimeMS PriorBarPeriodStartDateTime = sc.GetStartOfPeriodForDateTime(sc.BaseDateTimeIn[BarIndex - 1], Input_TimePeriodType.GetTimePeriodType(), PeriodLength, 0);
                    IsStartOfNewPeriod = PriorBarPeriodStartDateTime != CurrentPeriodBeginDateTime;
                }
            }

            SCDateTimeMS TimeIncrement = sc.TimePeriodSpan(Input_TimePeriodType.GetTimePeriodType(),  Input_TimePeriodLength.GetInt());

            //If there are insufficient bars for a reference period, then we will walk back 1 block/period at a time.

            if(GetReferenceData)
            {
                CurrentPeriodEndDateTime = sc.GetStartOfPeriodForDateTime(CurrentPeriodBeginDateTime, Input_TimePeriodType.GetTimePeriodType(), PeriodLength, 1);

                CurrentPeriodEndDateTime.SubtractMicroseconds(1);

                if (!Input_UseCurrentPeriod.GetYesNo())
                {
                    BeginOfRefDateTime = sc.GetStartOfPeriodForDateTime(CurrentPeriodBeginDateTime, Input_TimePeriodType.GetTimePeriodType(), PeriodLength, -1);

                    EndOfRefDateTime = CurrentPeriodBeginDateTime - SCDateTime::MICROSECONDS(1);
                }
                else
                {
                    BeginOfRefDateTime = CurrentPeriodBeginDateTime;

                    EndOfRefDateTime = CurrentPeriodEndDateTime;
                }

                if (Input_DisplayDebuggingOutput.GetYesNo() != 0)
                {
                    SCString Message;

                    Message.Format("Current Bar: %s, BeginOfRefDateTime: %s, EndOfRefDateTime: %s, CurrentPeriodBeginDateTime: %s, CurrentPeriodEndDateTime: %s",
                        sc.FormatDateTimeMS(CurrentBarDateTime).GetChars()
                        , sc.FormatDateTimeMS(BeginOfRefDateTime).GetChars()
                        , sc.FormatDateTimeMS(EndOfRefDateTime).GetChars()
                        , sc.FormatDateTimeMS(CurrentPeriodBeginDateTime).GetChars()
                        , sc.FormatDateTimeMS(CurrentPeriodEndDateTime).GetChars());

                    sc.AddMessageToLog(Message,0);

                }

                int MaxPeriodsToGoBack = 1;

                if(Input_AutoSkipPeriodOfNoTrading.GetYesNo())
                    MaxPeriodsToGoBack = 32;

                for (int WalkBack = 0; WalkBack < MaxPeriodsToGoBack; WalkBack++)
                {
                    if (!Input_UseCurrentPeriod.GetYesNo() && WalkBack >= 1) //Walk back 1 period.
                    {
                        SCDateTimeMS  PriorBeginOfRefDateTime = BeginOfRefDateTime;

                        BeginOfRefDateTime = sc.GetStartOfPeriodForDateTime(BeginOfRefDateTime, Input_TimePeriodType.GetTimePeriodType(),  PeriodLength, -1);
                        EndOfRefDateTime = PriorBeginOfRefDateTime - SCDateTime::MICROSECONDS(1);

                        if (Input_DisplayDebuggingOutput.GetYesNo() != 0)
                        {
                            SCString Message;

                            Message.Format("Moving back 1 period. BeginOfRefDateTime: %s, EndOfRefDateTime: %s.",
                                sc.FormatDateTimeMS(BeginOfRefDateTime).GetChars()
                                , sc.FormatDateTimeMS(EndOfRefDateTime).GetChars());

                            sc.AddMessageToLog(Message,0);
                        }
                    }

                    int NumberOfBars = 0;
                    SCDateTimeMS TotalTimeSpan;
                    int Result = 0;

                    if (Input_UseCurrentPeriod.GetYesNo())
                    {
                        Result = sc.GetOHLCOfTimePeriod(CurrentPeriodBeginDateTime, CurrentPeriodEndDateTime, Open, High, Low, Close, NextOpen, NumberOfBars, TotalTimeSpan);
                    }
                    else
                    {
                        Result = sc.GetOHLCOfTimePeriod(BeginOfRefDateTime, EndOfRefDateTime, Open, High, Low, Close, NextOpen, NumberOfBars, TotalTimeSpan);
                    }

                    if (Input_DisplayDebuggingOutput.GetYesNo() != 0)
                    {
                        SCString Message;
                        Message.Format("Number of Bars: %d, Total Time Span In Minutes: %d", NumberOfBars, static_cast<int>(TotalTimeSpan.GetSecondsSinceBaseDate() / SECONDS_PER_MINUTE));
                        sc.AddMessageToLog(Message,0);

                        Message.Format("RefOpen %f,RefHigh %f,RefLow %f,RefClose %f,RefNextOpen %f.",Open, High, Low, Close, NextOpen);
                        sc.AddMessageToLog(Message,0);
                    }

                    if (Input_UseCurrentPeriod.GetYesNo())
                        break;

                    if (!Result)
                        continue;

                    SCDateTimeMS MinimumTimeSpan = (TimeIncrement.GetAsDouble() * Input_MinimumRequiredTimePeriodAsPercent.GetFloat() / 100.0);

                    if (TotalTimeSpan >= MinimumTimeSpan)
                        break;
                }
            }

            if (!sc.IsFullRecalculation && Input_UseCurrentPeriod.GetYesNo())
            {
                int StartingBackIndex
                    = sc.GetContainingIndexForSCDateTime(sc.ChartNumber, CurrentPeriodBeginDateTime);

                //Adjust for incorrect date/time match from sc.GetContainingIndexForSCDateTime
                const SCDateTimeMS StartingBackIndexPeriodStartDateTime = sc.GetStartOfPeriodForDateTime(sc.BaseDateTimeIn[StartingBackIndex], Input_TimePeriodType.GetTimePeriodType(), PeriodLength, 0);

                if (StartingBackIndexPeriodStartDateTime < CurrentPeriodBeginDateTime
                    && StartingBackIndex < sc.ArraySize - 1)
                {
                    StartingBackIndex++;
                }

                for (int PriorBarIndex = StartingBackIndex; PriorBarIndex <= BarIndex; ++PriorBarIndex)
                {
                    sc.Subgraph[SC_OPEN][PriorBarIndex] = Open;

                    if (!Input_GraphHighLowLinesHistorically.GetYesNo())
                    {
                        sc.Subgraph[SC_HIGH][PriorBarIndex] = High;
                        sc.Subgraph[SC_LOW][PriorBarIndex] = Low;
                    }

                    sc.Subgraph[SC_LAST][PriorBarIndex] = Close;
                    sc.CalculateOHLCAverages(PriorBarIndex);
                }
            }
            else
            {
                sc.Subgraph[SC_OPEN][BarIndex] = Open;

                if (!Input_GraphHighLowLinesHistorically.GetYesNo())
                {
                    sc.Subgraph[SC_HIGH][BarIndex] = High;
                    sc.Subgraph[SC_LOW][BarIndex] = Low;
                }

                sc.Subgraph[SC_LAST][BarIndex] = Close;
                sc.CalculateOHLCAverages(BarIndex);
            }

            if (Input_GraphHighLowLinesHistorically.GetYesNo())
            {
                if (IsStartOfNewPeriod)
                {
                    sc.Subgraph[SC_HIGH][BarIndex] = sc.High[BarIndex];
                    sc.Subgraph[SC_LOW][BarIndex] = sc.Low[BarIndex];
                }
                else
                {
                    sc.Subgraph[SC_HIGH][BarIndex] = sc.Subgraph[SC_HIGH][BarIndex - 1];

                    if (sc.Subgraph[SC_HIGH][BarIndex] < sc.High[BarIndex])
                        sc.Subgraph[SC_HIGH][BarIndex] = sc.High[BarIndex];

                    sc.Subgraph[SC_LOW][BarIndex] = sc.Subgraph[SC_LOW][BarIndex - 1];

                    if (sc.Subgraph[SC_LOW][BarIndex] > sc.Low[BarIndex])
                        sc.Subgraph[SC_LOW][BarIndex] = sc.Low[BarIndex];
                }

            }
        } //for
    }

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

    SCSFExport scsf_RenkoChart(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_NumTrades = sc.Subgraph[5];
        SCSubgraphRef Subgraph_OHLCAvg = sc.Subgraph[6];
        SCSubgraphRef Subgraph_HLCAvg = sc.Subgraph[7];
        SCSubgraphRef Subgraph_HLAvg = sc.Subgraph[8];
        SCSubgraphRef Subgraph_BidVol = sc.Subgraph[9];
        SCSubgraphRef Subgraph_AskVol = sc.Subgraph[10];
        SCSubgraphRef Subgraph_RenkoUpDownTrend = sc.Subgraph[11];
        SCSubgraphRef Subgraph_RenkoLast = sc.Subgraph[12];

        SCInputRef Input_RenkoBoxSize = sc.Input[0];
        SCInputRef Input_UseHighLowInsteadOfLast = sc.Input[1];
        SCInputRef Input_IgnoreLatestBarUntilClose = sc.Input[2];

        if (sc.SetDefaults)
        {
            sc.GraphName = "Renko Chart (unsupported)";

            sc.GraphRegion = 0;
            sc.StandardChartHeader = 1;
            sc.IsCustomChart = 1;
            sc.GraphDrawType = GDT_RENKO_BRICK;

            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, 127, 0);
            Subgraph_High.DrawZeros = false;

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

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

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

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

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

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

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

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

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

            Input_RenkoBoxSize.Name = "Renko Box Size";
            Input_RenkoBoxSize.SetFloat(0.0f);
            Input_RenkoBoxSize.SetFloatLimits(0.0f, static_cast<float>(MAX_STUDY_LENGTH));

            Input_UseHighLowInsteadOfLast.Name = "Use High/Low Values instead of Last Value";
            Input_UseHighLowInsteadOfLast.SetYesNo(0);

            Input_IgnoreLatestBarUntilClose.Name = "Ignore Latest Underlying Bar until Close";
            Input_IgnoreLatestBarUntilClose.SetYesNo(0);

            return;
        }

        sc.ValueFormat = sc.BaseGraphValueFormat;
        int ValueFormat = sc.BaseGraphValueFormat;

        if (Input_RenkoBoxSize.GetFloat() == 0.0f)
        {
            Input_RenkoBoxSize.SetFloat(sc.TickSize*4);
        }

        sc.GraphName.Format("%s Renko - BoxSize: %s",
            sc.GetStudyName(0).GetChars(),
            sc.FormatGraphValue(Input_RenkoBoxSize.GetFloat(), ValueFormat).GetChars());

        int BaseGraphIndex = sc.UpdateStartIndex;

        if (Input_IgnoreLatestBarUntilClose.GetYesNo() != false && (sc.UpdateStartIndex == sc.ArraySize - 1))
            return; // No need to process last underlying bar.  However, during a full recalculation, the last bar will be processed. This is OK.

        float UpperBox = 0;
        float LowerBox = 0;
        float CumulativeVolume = 0;
        float CumulativeOIOrNT = 0;
        float CumulativeAskVolume = 0;
        float CumulativeBidVolume = 0;

        if (BaseGraphIndex == 0)
        {

            sc.ResizeArrays(0);

            if (!sc.AddElements(1))
                return;

            if (sc.ArraySize < 1)
                return; // nothing to display

            UpperBox = sc.Close[BaseGraphIndex];
            LowerBox = sc.Close[BaseGraphIndex];

            sc.DateTimeOut[0] = sc.BaseDateTimeIn[0];

            Subgraph_RenkoLast[0] = sc.Close[BaseGraphIndex];
            Subgraph_Open[0] = sc.Close[BaseGraphIndex];
            Subgraph_Last[0] = sc.Close[BaseGraphIndex];
            Subgraph_High[0] = sc.Close[BaseGraphIndex];
            Subgraph_Low[0] = sc.Close[BaseGraphIndex];
        }
        else
        {
            int RenkoIndex = sc.OutArraySize - 1;

            // When new data is updated within the same bar
            if (sc.DateTimeOut[RenkoIndex] == sc.BaseDateTimeIn[BaseGraphIndex])
            {
                // Decrement BaseGraphIndex to the first matching date time
                for (; BaseGraphIndex >= 0; BaseGraphIndex--)
                {
                    if (sc.DateTimeOut[RenkoIndex] != sc.BaseDateTimeIn[BaseGraphIndex])
                    {
                        BaseGraphIndex++;
                        break;
                    }
                }

                int LastIndex = RenkoIndex;
                // Delete the Renko Elements with that date time
                for (; RenkoIndex >= 0; RenkoIndex--)
                {
                    if (sc.DateTimeOut[LastIndex] != sc.DateTimeOut[RenkoIndex])
                    {
                        RenkoIndex++;
                        break;
                    }
                }
                sc.ResizeArrays(RenkoIndex);
                RenkoIndex = sc.OutArraySize - 1;
            }

            if (Subgraph_RenkoUpDownTrend[RenkoIndex] > 0) // Uptrend Box
            {
                UpperBox = Subgraph_RenkoLast[RenkoIndex];
                LowerBox = UpperBox - Input_RenkoBoxSize.GetFloat();
                LowerBox = static_cast<float>(sc.RoundToTickSize(LowerBox, Input_RenkoBoxSize.GetFloat()));
            }
            else
            {
                LowerBox = Subgraph_RenkoLast[RenkoIndex];
                UpperBox = LowerBox + Input_RenkoBoxSize.GetFloat();
                UpperBox = static_cast<float>(sc.RoundToTickSize(UpperBox, Input_RenkoBoxSize.GetFloat()));
            }

            // Calculate Cumulative Volume/OpenInterest/Number Of Trades for current index
            // Must calculate from Base Graph since current index could
            // potentially have grown in volume since last calculation.

            int i = BaseGraphIndex;
            for (; i >= 0; i--)
            {
                if (sc.BaseDateTimeIn[i] <= sc.DateTimeOut[RenkoIndex])
                    break;
            }

            for (int n = i; n < BaseGraphIndex; n++)
            {
                CumulativeVolume += sc.Volume[n];
                CumulativeOIOrNT += sc.OpenInterest[n];
                CumulativeAskVolume += sc.AskVolume[n];
                CumulativeBidVolume += sc.BidVolume[n];
            }

        }

        int OriginalRenkoIndex = sc.OutArraySize - 1;
        int BaseGraphEnd = sc.ArraySize;
        if (Input_IgnoreLatestBarUntilClose.GetYesNo() != 0)
            BaseGraphEnd--;

        for (;BaseGraphIndex < BaseGraphEnd; BaseGraphIndex++)
        {
            CumulativeVolume += sc.Volume[BaseGraphIndex];
            CumulativeOIOrNT += sc.OpenInterest[BaseGraphIndex];
            CumulativeAskVolume += sc.AskVolume[BaseGraphIndex];
            CumulativeBidVolume += sc.BidVolume[BaseGraphIndex];

            int NewEntry = 0;
            int UpperOrLowerTrend = 0;
            float HigherPrice = sc.Close[BaseGraphIndex];
            float LowerPrice = sc.Close[BaseGraphIndex];

            if (Input_UseHighLowInsteadOfLast.GetYesNo() != 0)
            {
                HigherPrice = sc.High[BaseGraphIndex];
                LowerPrice = sc.Low[BaseGraphIndex];
            }

            if (sc.FormattedEvaluateUsingDoubles(static_cast<double>(HigherPrice), ValueFormat, GREATER_EQUAL_OPERATOR, static_cast<double>(UpperBox + Input_RenkoBoxSize.GetFloat()), ValueFormat))
            {
                NewEntry = 1;
                UpperOrLowerTrend = 1;
            }
            else if (sc.FormattedEvaluateUsingDoubles(static_cast<double>(LowerPrice), ValueFormat, LESS_EQUAL_OPERATOR, static_cast<double>(LowerBox - Input_RenkoBoxSize.GetFloat()), ValueFormat))
            {
                NewEntry = 1;
                UpperOrLowerTrend = -1;
            }

            int NewEntryCounter = 0;

            while (NewEntry != 0)
            {
                NewEntryCounter++;
                if (NewEntryCounter >= 500)
                {
                    sc.AddMessageToLog("Renko Chart study: Renko error due to either data error or Box Size too small. Stopping processing and skipping until real time updates. Try increasing the Box Size input.", 1);
                    return;
                }

                sc.CalculateOHLCAverages(sc.OutArraySize - 1);

                NewEntry = 0;
                sc.AddElements(1);
                int NewBoxIndex = sc.OutArraySize - 1;
                sc.DateTimeOut[NewBoxIndex] = sc.BaseDateTimeIn[BaseGraphIndex];

                Subgraph_Volume[NewBoxIndex-1] = CumulativeVolume - sc.Volume[BaseGraphIndex];
                Subgraph_NumTrades[NewBoxIndex-1] = CumulativeOIOrNT - sc.OpenInterest[BaseGraphIndex];
                Subgraph_AskVol[NewBoxIndex-1] = CumulativeAskVolume - sc.AskVolume[BaseGraphIndex];
                Subgraph_BidVol[NewBoxIndex-1] = CumulativeBidVolume - sc.BidVolume[BaseGraphIndex];

                CumulativeVolume = sc.Volume[BaseGraphIndex];
                CumulativeOIOrNT = sc.OpenInterest[BaseGraphIndex];
                CumulativeAskVolume = sc.AskVolume[BaseGraphIndex];
                CumulativeBidVolume = sc.BidVolume[BaseGraphIndex];

                float NewLast = 0;
                float NewOtherBound = 0;

                if (UpperOrLowerTrend == 1) // Upper Trend
                {
                    LowerBox = UpperBox;
                    UpperBox += Input_RenkoBoxSize.GetFloat();
                    UpperBox = static_cast<float>(sc.RoundToTickSize(UpperBox, Input_RenkoBoxSize.GetFloat()));

                    NewLast = UpperBox;
                    NewOtherBound = LowerBox;

                    if (sc.FormattedEvaluateUsingDoubles(static_cast<double>(HigherPrice), ValueFormat, GREATER_EQUAL_OPERATOR, static_cast<double>(UpperBox + Input_RenkoBoxSize.GetFloat()), ValueFormat))
                        NewEntry = 1;
                }
                else
                {
                    UpperBox = LowerBox;
                    LowerBox -= Input_RenkoBoxSize.GetFloat();
                    LowerBox = static_cast<float>(sc.RoundToTickSize(LowerBox, Input_RenkoBoxSize.GetFloat()));

                    NewLast = LowerBox;
                    NewOtherBound = UpperBox;

                    if (sc.FormattedEvaluateUsingDoubles(static_cast<double>(LowerPrice), ValueFormat, LESS_EQUAL_OPERATOR, static_cast<double>(LowerBox - Input_RenkoBoxSize.GetFloat()), ValueFormat))
                        NewEntry = 1;
                }

                Subgraph_Low[NewBoxIndex] = LowerBox;
                Subgraph_High[NewBoxIndex] = UpperBox;
                Subgraph_RenkoLast[NewBoxIndex] = NewLast;
                Subgraph_RenkoUpDownTrend[NewBoxIndex] = static_cast<float>(UpperOrLowerTrend);
                if (UpperOrLowerTrend == 1)
                {
                    Subgraph_Open[NewBoxIndex] = LowerBox;
                    Subgraph_Last[NewBoxIndex] = UpperBox;
                }
                else
                {
                    Subgraph_Open[NewBoxIndex] = UpperBox;
                    Subgraph_Last[NewBoxIndex] = LowerBox;
                }
            }

            sc.CalculateOHLCAverages(sc.OutArraySize - 1);
        }

        int RenkoIndex = sc.OutArraySize - 1;
        if (RenkoIndex >= 0)
        {
            Subgraph_Volume[RenkoIndex] = CumulativeVolume;
            Subgraph_NumTrades[RenkoIndex] = CumulativeOIOrNT;
            Subgraph_AskVol[RenkoIndex] = CumulativeAskVolume;
            Subgraph_BidVol[RenkoIndex] = CumulativeBidVolume;
        }
    }

    /*==========================================================================*/
    SCSFExport scsf_MillisecondsExample(SCStudyInterfaceRef sc)
    {
        if (sc.SetDefaults)
        {
            // Set the configuration and defaults

            sc.GraphName = "Milliseconds Example";

            sc.AutoLoop = 1;

            return;
        }
        //When working with milliseconds it is necessary to define variables of type SCDateTimeMS
        SCDateTimeMS DateTimeMS , DateTimeMSRefChart;

        // Get the milliseconds for the current bar.  This will be 0 if the chart bars are based upon a specific time by using the 'Days-Minutes-Seconds' Bar Period Type since the start time for a bar is always evenly aligned to a second based upon the Session Start Time and the time period of the bar. Otherwise, the milliseconds can be obtained for other Bar Period Types.
        DateTimeMS = sc.BaseDateTimeIn[sc.Index];
        int Millisecond = DateTimeMS.GetMillisecond();

        //Get the Date-Times from another chart.
        SCDateTimeArray RefChartDateTime;
        sc.GetChartDateTimeArray(2, RefChartDateTime );

        if(RefChartDateTime.GetArraySize() != 0)
        {
            //Get milliseconds for last bar in the other chart being referenced
            DateTimeMSRefChart = RefChartDateTime[RefChartDateTime.GetArraySize() - 1];
            int Millisecond = DateTimeMSRefChart.GetMillisecond();

        }

        //Compare the Date-Times from the 2 charts with millisecond precision
        if(DateTimeMS ==DateTimeMSRefChart)
        {
            //There is a match down to the millisecond
        }

    }

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

        SCSubgraphRef Subgraph_RVI = sc.Subgraph[0];
        SCSubgraphRef Subgraph_SmoothedRVI = sc.Subgraph[1];
        SCSubgraphRef Subgraph_Signal = sc.Subgraph[2];
        SCSubgraphRef Subgraph_Buy = sc.Subgraph[3];
        SCSubgraphRef Subgraph_Sell = sc.Subgraph[4];

        SCInputRef   Input_SmoothedRVILength = sc.Input[0];
        SCInputRef   Input_SmoothedRVIAvgType = sc.Input[1];
        SCInputRef   Input_SignalLength = sc.Input[2];
        SCInputRef   Input_SignalAvgType = sc.Input[3];
        SCInputRef   Input_OffsetPercentInput = sc.Input[4];

        if (sc.SetDefaults)
        {
            sc.GraphName = "Relative Vigor Index 1";

            sc.AutoLoop = 1;

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

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

            Subgraph_SmoothedRVI.Name = "Smoothed RVI Line";
            Subgraph_SmoothedRVI.DrawStyle = DRAWSTYLE_LINE;
            Subgraph_SmoothedRVI.PrimaryColor = RGB(0, 255, 0);
            Subgraph_SmoothedRVI.DrawZeros = true;

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

            Subgraph_Buy.Name = "Buy";
            Subgraph_Buy.PrimaryColor = RGB(0, 255, 0); // green
            Subgraph_Buy.DrawStyle = DRAWSTYLE_ARROW_UP;
            Subgraph_Buy.LineWidth = 2; //Width of arrow
            Subgraph_Buy.DrawZeros = 0;

            Subgraph_Sell.Name = "Sell";
            Subgraph_Sell.DrawStyle = DRAWSTYLE_ARROW_DOWN;
            Subgraph_Sell.PrimaryColor = RGB(255, 0, 0);    // red
            Subgraph_Sell.LineWidth = 2; //Width of arrow
            Subgraph_Sell.DrawZeros = 0;

            Input_SmoothedRVILength.Name = "Smoothed RVI Length";
            Input_SmoothedRVILength.SetInt(10);
            Input_SmoothedRVILength.SetIntLimits(1, MAX_STUDY_LENGTH);

            Input_SmoothedRVIAvgType.Name = "Smoothed RVI Average Type";
            Input_SmoothedRVIAvgType.SetMovAvgType(MOVAVGTYPE_SIMPLE);

            Input_SignalLength.Name = "Signal Length";
            Input_SignalLength.SetInt(4);
            Input_SignalLength.SetIntLimits(1, MAX_STUDY_LENGTH);

            Input_SignalAvgType.Name = "Signal Average Type";
            Input_SignalAvgType.SetMovAvgType(MOVAVGTYPE_SIMPLE);

            Input_OffsetPercentInput.Name = "Arrow Offset Percentage";
            Input_OffsetPercentInput.SetFloat(8);

            return;
        }

        sc.DataStartIndex = max(Input_SmoothedRVILength.GetInt(), Input_SignalLength.GetInt()) - 1;

        float BarRange = (sc.High[sc.Index] - sc.Low[sc.Index]);
        if (BarRange != 0)
            Subgraph_RVI[sc.Index] = (sc.Close[sc.Index] - sc.Open[sc.Index]) / BarRange;
        else
            Subgraph_RVI[sc.Index] = Subgraph_RVI.Arrays[0][sc.Index - 1];

        sc.MovingAverage(Subgraph_RVI, Subgraph_SmoothedRVI, Input_SmoothedRVIAvgType.GetMovAvgType(), Input_SmoothedRVILength.GetInt());
        sc.MovingAverage(Subgraph_RVI, Subgraph_Signal, Input_SignalAvgType.GetMovAvgType(), Input_SignalLength.GetInt());

        float OffsetPercent = Input_OffsetPercentInput.GetFloat() * 0.01f;

        if (sc.CrossOver(Subgraph_SmoothedRVI, Subgraph_Signal) == CROSS_FROM_BOTTOM)
        {

            Subgraph_Buy[sc.Index] = Subgraph_Signal[sc.Index] - OffsetPercent * Subgraph_Signal[sc.Index];

            Subgraph_Sell[sc.Index] = 0;
        }
        else if (sc.CrossOver(Subgraph_SmoothedRVI, Subgraph_Signal) == CROSS_FROM_TOP)
        {
            Subgraph_Sell[sc.Index] = Subgraph_Signal[sc.Index] + OffsetPercent * Subgraph_Signal[sc.Index];
            Subgraph_Buy[sc.Index] = 0;
        }
        else
        {
            Subgraph_Buy[sc.Index] = 0;
            Subgraph_Sell[sc.Index] = 0;
        }
    }
    /*==========================================================================*/

    SCSFExport scsf_RelativeVigorIndex2(SCStudyInterfaceRef sc)
    {
        SCSubgraphRef Subgraph_RVI = sc.Subgraph[0];
        SCSubgraphRef Subgraph_SmoothedRVI = sc.Subgraph[1];
        SCSubgraphRef Subgraph_Signal = sc.Subgraph[2];
        SCSubgraphRef Subgraph_Buy = sc.Subgraph[3];
        SCSubgraphRef Subgraph_Sell = sc.Subgraph[4];

        SCFloatArrayRef Array_CloseOpenAvg = Subgraph_RVI.Arrays[0];
        SCFloatArrayRef Array_HighLowAvg = Subgraph_RVI.Arrays[1];
        SCFloatArrayRef Array_SmoothedRVINumerator = Subgraph_RVI.Arrays[2];
        SCFloatArrayRef Array_SmoothedRVIDenominator = Subgraph_RVI.Arrays[3];

        SCInputRef   Input_SmoothedRVILength = sc.Input[0];
        SCInputRef   Input_SmoothedRVIAvgType = sc.Input[1];
        SCInputRef   Input_OffsetPercentInput = sc.Input[2];

        if (sc.SetDefaults)
        {
            sc.GraphName = "Relative Vigor Index 2";

            sc.AutoLoop = 1;

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

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

            Subgraph_SmoothedRVI.Name = "Smoothed RVI Line";
            Subgraph_SmoothedRVI.DrawStyle = DRAWSTYLE_LINE;
            Subgraph_SmoothedRVI.PrimaryColor = RGB(0, 255, 0);
            Subgraph_SmoothedRVI.DrawZeros = true;

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

            Subgraph_Buy.Name = "Buy";
            Subgraph_Buy.PrimaryColor = RGB(0, 255, 0); // green
            Subgraph_Buy.DrawStyle = DRAWSTYLE_ARROW_UP;
            Subgraph_Buy.LineWidth = 2; //Width of arrow
            Subgraph_Buy.DrawZeros = 0;

            Subgraph_Sell.Name = "Sell";
            Subgraph_Sell.DrawStyle = DRAWSTYLE_ARROW_DOWN;
            Subgraph_Sell.PrimaryColor = RGB(255, 0, 0);    // red
            Subgraph_Sell.LineWidth = 2; //Width of arrow
            Subgraph_Sell.DrawZeros = 0;

            Input_SmoothedRVILength.Name = "Smoothed RVI Length";
            Input_SmoothedRVILength.SetInt(10);
            Input_SmoothedRVILength.SetIntLimits(1, MAX_STUDY_LENGTH);

            Input_SmoothedRVIAvgType.Name = "Smoothed RVI Average Type";
            Input_SmoothedRVIAvgType.SetMovAvgType(MOVAVGTYPE_SIMPLE);

            Input_OffsetPercentInput.Name = "Arrow Offset Percentage";
            Input_OffsetPercentInput.SetFloat(8);

            return;
        }

        sc.DataStartIndex = Input_SmoothedRVILength.GetInt() + 5;

        Array_CloseOpenAvg[sc.Index] = ((sc.Close[sc.Index - 3] - sc.Open[sc.Index - 3]) + 2 * (sc.Close[sc.Index - 2] - sc.Open[sc.Index - 2]) + 2 * (sc.Close[sc.Index - 1] - sc.Open[sc.Index - 1]) + (sc.Close[sc.Index] - sc.Open[sc.Index])) / 6;

        Array_HighLowAvg[sc.Index] = ((sc.High[sc.Index - 3] - sc.Low[sc.Index - 3]) + 2 * (sc.High[sc.Index - 2] - sc.Low[sc.Index - 2]) + 2 * (sc.High[sc.Index - 1] - sc.Low[sc.Index - 1]) + (sc.High[sc.Index] - sc.Low[sc.Index])) / 6;

        float BarRange = (sc.High[sc.Index] - sc.Low[sc.Index]);
        if (BarRange != 0)
            Subgraph_RVI[sc.Index] = (sc.Close[sc.Index] - sc.Open[sc.Index]) / BarRange;
        else
            Subgraph_RVI[sc.Index] = Array_CloseOpenAvg[sc.Index - 1];

        sc.MovingAverage(Array_CloseOpenAvg, Array_SmoothedRVINumerator, Input_SmoothedRVIAvgType.GetMovAvgType(), Input_SmoothedRVILength.GetInt());

        sc.MovingAverage(Array_HighLowAvg, Array_SmoothedRVIDenominator, Input_SmoothedRVIAvgType.GetMovAvgType(), Input_SmoothedRVILength.GetInt());

        Subgraph_SmoothedRVI[sc.Index] = Array_SmoothedRVINumerator[sc.Index] / Array_SmoothedRVIDenominator[sc.Index];

        Subgraph_Signal[sc.Index] = (Subgraph_SmoothedRVI[sc.Index - 3] + 2 * Subgraph_SmoothedRVI[sc.Index - 2] + 2 * Subgraph_SmoothedRVI[sc.Index - 1] + Subgraph_SmoothedRVI[sc.Index]) / 6;

        float OffsetPercent = Input_OffsetPercentInput.GetFloat() * 0.01f;

        if (sc.CrossOver(Subgraph_SmoothedRVI, Subgraph_Signal) == CROSS_FROM_BOTTOM)
        {

            Subgraph_Buy[sc.Index] = Subgraph_Signal[sc.Index] - OffsetPercent * Subgraph_Signal[sc.Index];

            Subgraph_Sell[sc.Index] = 0;
        }
        else if (sc.CrossOver(Subgraph_SmoothedRVI, Subgraph_Signal) == CROSS_FROM_TOP)
        {
            Subgraph_Sell[sc.Index] = Subgraph_Signal[sc.Index] + OffsetPercent * Subgraph_Signal[sc.Index];
            Subgraph_Buy[sc.Index] = 0;
        }
        else
        {
            Subgraph_Buy[sc.Index] = 0;
            Subgraph_Sell[sc.Index] = 0;
        }
    }

    /*==========================================================================*/
    SCSFExport scsf_GetStudyPersistentVariableFromChartExample(SCStudyInterfaceRef sc)
    {
        SCInputRef  Input_ChartStudyReference = sc.Input[0];

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

            sc.GraphName = "Get Study Persistent Variable from Chart Example";
            sc.AutoLoop = 1;

            Input_ChartStudyReference.Name = "Chart Study Reference";
            Input_ChartStudyReference.SetChartStudyValues(1, 0);

            return;
        }

        //Set persistent float variable with a value of 100 using integer key 1.
        float& r_PersistentFloat = sc.GetPersistentFloat(1);
        r_PersistentFloat = 100;

        // Get a reference to a persistent variable with key value 1 in the chart
        // and study specified by the "Chart Study Reference" input. Assuming the
        // "Chart Study Reference" input is referencing this particular chart and
        // study instance, then this function will return 100.
        const float PersistentValue = sc.GetPersistentFloatFromChartStudy(Input_ChartStudyReference.GetChartNumber(), Input_ChartStudyReference.GetStudyID(), 1);

        if (sc.Index == sc.ArraySize - 1)
        {
            SCString OutputText;
            OutputText.Format("%f", PersistentValue);

            sc.AddMessageToLog(OutputText, 0);
        }
    }

    /*============================================================================
        sc.ResetAllScales example function
    ----------------------------------------------------------------------------*/
    SCSFExport scsf_ResetScalesExample(SCStudyInterfaceRef sc)
    {
        if (sc.SetDefaults)
        {
            // Set the configuration and defaults

            sc.GraphName = "sc.ResetAllScales Example";

            sc.AutoLoop = 0;

            return;
        }

        sc.ResetAllScales = 1;

    }

    /*==========================================================================*/
    SCSFExport scsf_BidAndAskPrices(SCStudyInterfaceRef sc)
    {
        SCSubgraphRef Subgraph_BidPrices = sc.Subgraph[0];
        SCSubgraphRef Subgraph_AskPrices = sc.Subgraph[1];

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

            sc.GraphName = "Bid & Ask Prices";

            sc.StudyDescription = "This study requires 1-tick data in the intraday data file.";

            sc.AutoLoop = 1;
            sc.MaintainAdditionalChartDataArrays = 1;

            sc.GraphRegion = 0;

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

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

            return;
        }

        // Do data processing
        if ((sc.Index  < sc.ArraySize -1) || sc.IsReplayRunning())
        {
            Subgraph_BidPrices[sc.Index] = sc.BaseData[SC_BID_PRICE][sc.Index];
            Subgraph_AskPrices[sc.Index] = sc.BaseData[SC_ASK_PRICE][sc.Index];
        }
        else
        {
            Subgraph_BidPrices[sc.Index] = sc.Bid;
            Subgraph_AskPrices[sc.Index] = sc.Ask;
        }
    }

    /*============================================================================
        Study function to close a single specified chart in the chartbook.
    ----------------------------------------------------------------------------*/
    SCSFExport scsf_CloseChart(SCStudyInterfaceRef sc)
    {
        SCInputRef Input_InChartNumber = sc.Input[0];

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

            sc.GraphName = "Close Chart";

            sc.StudyDescription
                = "Study function to close a single specified chart in the chartbook.";

            sc.AutoLoop = 0;

            sc.GraphRegion = 0;

            Input_InChartNumber.Name = "Chart To Close";
            Input_InChartNumber.SetChartNumber(0);

            return;
        }

        int ChartNumberToClose = Input_InChartNumber.GetChartNumber();

        if (ChartNumberToClose == 0)
            return;

        SCString Message;
        Message.Format("Closing chart #%d.", ChartNumberToClose);
        sc.AddMessageToLog(Message, 0);

        sc.CloseChart(ChartNumberToClose);

        Input_InChartNumber.SetChartNumber(0);
    }

    /*============================================================================
        Study function to close a single specified chartbook.
    ----------------------------------------------------------------------------*/
    SCSFExport scsf_CloseChartbook(SCStudyInterfaceRef sc)
    {
        SCString& r_ChartbookFileName = sc.TextInput;

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

            sc.GraphName = "Close Chartbook";

            sc.StudyDescription
                = "Study function to close a single specified chartbook.";

            sc.AutoLoop = 0;

            sc.GraphRegion = 0;

            sc.TextInputName = "Chartbook File Name To Close";

            return;
        }

        if (r_ChartbookFileName.GetLength() == 0)
            return;

        SCString Message;
        Message.Format("Closing chartbook \"%s\".", r_ChartbookFileName.GetChars());
        sc.AddMessageToLog(Message, 0);

        sc.CloseChartbook(r_ChartbookFileName);

        r_ChartbookFileName = "";
    }

    /*==========================================================================*/
    //
    // PRC - Polynomial Regression Channel
    //
    // 20110329 - written by aslan
    // 20100330 - added redraw option
    //

    SCSFExport scsf_PolynomialRegressionChannel(SCStudyInterfaceRef sc)
    {
        SCInputRef Input_PolyDegree  = sc.Input[0];
        SCInputRef Input_Period      = sc.Input[1];
        SCInputRef Input_StdDev1     = sc.Input[2];
        SCInputRef Input_StdDev2     = sc.Input[3];
        SCInputRef Input_Redraw      = sc.Input[4];

        SCSubgraphRef Subgraph_Fx     = sc.Subgraph[0];
        SCSubgraphRef Subgraph_Upper2 = sc.Subgraph[1];
        SCSubgraphRef Subgraph_Upper1 = sc.Subgraph[2];
        SCSubgraphRef Subgraph_Lower1 = sc.Subgraph[3];
        SCSubgraphRef Subgraph_Lower2 = sc.Subgraph[4];

        if (sc.SetDefaults)
        {
            sc.GraphName = "Polynomial Regression Channel";
            sc.StudyDescription = "Polynomial Regression Channel";

            Input_PolyDegree.Name = "Polynomial Degree (1-4)";
            Input_PolyDegree.SetInt(3);
            Input_PolyDegree.SetIntLimits(1, 4);

            Input_Period.Name = "PRC Period";
            Input_Period.SetInt(150);
            Input_Period.SetIntLimits(1, 10000);

            Input_StdDev1.Name = "Standard Deviation Level 1";
            Input_StdDev1.SetFloat(1.618f);
            Input_StdDev1.SetFloatLimits(0, 1000);

            Input_StdDev2.Name = "Standard Deviation Level 2";
            Input_StdDev2.SetFloat(2.0);
            Input_StdDev2.SetFloatLimits(0, 1000);

            Input_Redraw.Name = "Use Redraw";
            Input_Redraw.SetYesNo(1);

            Subgraph_Fx.Name = "Mid";
            Subgraph_Fx.DrawZeros = false;
            Subgraph_Fx.DrawStyle = DRAWSTYLE_LINE;
            Subgraph_Fx.LineWidth = 1;
            Subgraph_Fx.LineStyle = LINESTYLE_DOT;
            Subgraph_Fx.PrimaryColor = COLOR_GRAY;

            Subgraph_Upper2.Name = "Upper 2";
            Subgraph_Upper2.DrawZeros = false;
            Subgraph_Upper2.DrawStyle = DRAWSTYLE_TRANSPARENT_FILL_TOP;
            Subgraph_Upper2.PrimaryColor = COLOR_RED;

            Subgraph_Upper1.Name = "Upper 1";
            Subgraph_Upper1.DrawZeros = false;
            Subgraph_Upper1.DrawStyle = DRAWSTYLE_TRANSPARENT_FILL_BOTTOM;
            Subgraph_Upper1.PrimaryColor = COLOR_RED;

            Subgraph_Lower1.Name = "Lower 1";
            Subgraph_Lower1.DrawZeros = false;
            Subgraph_Lower1.DrawStyle = DRAWSTYLE_TRANSPARENT_FILL_TOP;
            Subgraph_Lower1.PrimaryColor = COLOR_BLUE;

            Subgraph_Lower2.Name = "Lower 2";
            Subgraph_Lower2.DrawZeros = false;
            Subgraph_Lower2.DrawStyle = DRAWSTYLE_TRANSPARENT_FILL_BOTTOM;
            Subgraph_Lower2.PrimaryColor = COLOR_BLUE;

            sc.AutoLoop = true;
            sc.DrawZeros = false;
            sc.GraphRegion = 0;

            sc.GlobalDisplayStudySubgraphsNameAndValue = 0;
            sc.DisplayStudyName = 0;
            sc.DisplayStudyInputValues = 0;

            return;
        }

        struct s_PRCData
        {
            double ai[10][10];
            double b[10];
            double x[10];
            double sx[20];
        };

        int&  lastIndex = sc.GetPersistentInt(1);
        int&  nn        = sc.GetPersistentInt(2);
        s_PRCData *p_PRCMemory = (s_PRCData *) sc.GetPersistentPointer(1);

        if (sc.LastCallToFunction)
        {
            // This study is being removed from the chart or the chart is being closed - cleanup
            if (p_PRCMemory != 0)
            {
                sc.FreeMemory(p_PRCMemory);
                p_PRCMemory = 0;
                sc.SetPersistentPointer(1, p_PRCMemory);
            }

            return;
        }

        if (sc.Index == 0)
        {
            lastIndex = -1;
            sc.ValueFormat = sc.BaseGraphValueFormat;

            if (p_PRCMemory != 0)
                sc.FreeMemory(p_PRCMemory);

            p_PRCMemory = (s_PRCData*)sc.AllocateMemory(sizeof(s_PRCData));

            sc.SetPersistentPointer(1,p_PRCMemory);

            if (p_PRCMemory == 0)
                return;

            // set up static vars
            s_PRCData& PRCData = *p_PRCMemory;

            nn = Input_PolyDegree.GetInt() + 1;

            //----------------------sx------------
            PRCData.sx[1] = Input_Period.GetInt() + 1;
            for(int i=1;i<=nn*2-2;i++) {
                double sum = 0.0;
                for(int n=0;n<=Input_Period.GetInt();n++) {
                    sum+=pow(static_cast<double>(n),i);
                }
                PRCData.sx[i+1]=sum;
            }
        }

        // make sure we have enough bars to start
        if (sc.Index < Input_Period.GetInt())
            return;

        // erase old data on new bar
        if (sc.Index != lastIndex)
        {
            lastIndex = sc.Index;
            if (Input_Redraw.GetYesNo())
            {
                Subgraph_Fx[sc.Index-Input_Period.GetInt()-1] = 0;
                Subgraph_Upper2[sc.Index-Input_Period.GetInt()-1] = 0;
                Subgraph_Upper1[sc.Index-Input_Period.GetInt()-1] = 0;
                Subgraph_Lower1[sc.Index-Input_Period.GetInt()-1] = 0;
                Subgraph_Lower2[sc.Index-Input_Period.GetInt()-1] = 0;
            }
        }

        // now lets do the real work
        if (p_PRCMemory == 0)
            return;

        s_PRCData& PRCData = *p_PRCMemory;

        //----------------------syx-----------
        for(int i=1;i<=nn;i++) {
            double sum=0.0;
            for(int n=0;n<=Input_Period.GetInt();n++) {
                if(i==1) sum+=sc.Close[sc.Index-n];
                else sum+=sc.Close[sc.Index-n]*pow(static_cast<double>(n),i-1);
            }
            PRCData.b[i]=sum;
        }
        //===============Matrix===============
        for(int j=1;j<=nn;j++) {
            for(int i=1; i<=nn; i++)    {
                int k=i+j-1;
                PRCData.ai[i][j]=PRCData.sx[k];  // reset ai matrix
            }
        }
        //===============Gauss================
        for(int k=1; k<=nn-1; k++) {
            int    l=0;
            double m=0.0;
            for(int i=k; i<=nn; i++) {
                if(abs(PRCData.ai[i][k])>m) {
                    m=abs(PRCData.ai[i][k]);
                    l=i;
                }
            }
            if(l==0) return;
            if (l!=k)   {
                double tt = 0.0;
                for(int j=1; j<=nn; j++)    {
                    tt=PRCData.ai[k][j];
                    PRCData.ai[k][j]=PRCData.ai[l][j];
                    PRCData.ai[l][j]=tt;
                }
                tt=PRCData.b[k];
                PRCData.b[k]=PRCData.b[l];
                PRCData.b[l]=tt;
            }
            for(int i=k+1;i<=nn;i++) {
                double qq=PRCData.ai[i][k]/PRCData.ai[k][k];
                for(int j=1;j<=nn;j++) {
                    if(j==k) PRCData.ai[i][j]=0;
                    else PRCData.ai[i][j]=PRCData.ai[i][j]-qq*PRCData.ai[k][j];
                }
                PRCData.b[i]=PRCData.b[i]-qq*PRCData.b[k];
            }
        }
        PRCData.x[nn]=PRCData.b[nn]/PRCData.ai[nn][nn];
        for(int i=nn-1;i>=1;i--)    {
            double tt=0.0;
            for(int j=1;j<=nn-i;j++) {
                tt=tt+PRCData.ai[i][i+j]*PRCData.x[i+j];
                PRCData.x[i]=(1/PRCData.ai[i][i])*(PRCData.b[i]-tt);
            }
        }
        //====================================
        for(int n=0;n<=Input_Period.GetInt();n++) {
            double sum=0.0;
            for(int k=1;k<=Input_PolyDegree.GetInt();k++) {
                sum+=PRCData.x[k+1]*pow(static_cast<double>(n),k);
            }
            if (n==0 || Input_Redraw.GetYesNo())
                Subgraph_Fx[sc.Index-n] = static_cast<float>(PRCData.x[1]+sum);
        }
        //-------------------Std--------------
        double sq=0.0, sq1=0.0, sq2=0.0;
        for(int n=0;n<=Input_Period.GetInt();n++) {
            sq+=pow(sc.Close[sc.Index-n]-Subgraph_Fx[sc.Index-n],2);
        }
        sq=sqrt(sq/(Input_Period.GetInt()+1));
        sq1=sq*Input_StdDev1.GetFloat();
        sq2=sq*Input_StdDev2.GetFloat();

        for(int n=0;n<=Input_Period.GetInt();n++) {
            if (n==0 || Input_Redraw.GetYesNo())
            {
                Subgraph_Upper1[sc.Index-n] = static_cast<float>(Subgraph_Fx[sc.Index-n]+sq1);
                Subgraph_Lower1[sc.Index-n] = static_cast<float>(Subgraph_Fx[sc.Index-n]-sq1);
                Subgraph_Upper2[sc.Index-n] = static_cast<float>(Subgraph_Fx[sc.Index-n]+sq2);
                Subgraph_Lower2[sc.Index-n] = static_cast<float>(Subgraph_Fx[sc.Index-n]-sq2);
            }
        }
    }

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

        SCInputRef Input_AverageFormula = sc.Input[0];

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

            sc.GraphName = "Average Price For Bar";
            sc.GraphRegion = 0;
            sc.AutoLoop = 1;

            Subgraph_Average.Name = "Average";
            Subgraph_Average.DrawStyle = DRAWSTYLE_DASH;
            Subgraph_Average.LineWidth = 2;
            Subgraph_Average.PrimaryColor = RGB(255, 128, 0);

            Input_AverageFormula.Name = "Average Formula";
            Input_AverageFormula.SetCustomInputStrings
                ( "(High+Low)/2"
                    ";(High+Low+Close)/3"
                    ";(Open+High+Low+Close)/4"
                    ";(High+Low+Close+Close)/4"
                );
            Input_AverageFormula.SetCustomInputIndex(0);

            return;
        }

        // Do data processing.

        const int SelectedIndex = Input_AverageFormula.GetIndex();
        switch (SelectedIndex)
        {
            case 0:
            {
                Subgraph_Average.Data[sc.Index]
                    = (sc.High[sc.Index] + sc.Low[sc.Index]) / 2.0f;
            }
            break;

            case 1:
            {
                Subgraph_Average.Data[sc.Index]
                    = (sc.High[sc.Index] + sc.Low[sc.Index] + sc.Close[sc.Index])
                    / 3.0f;
            }
            break;

            case 2:
            {
                Subgraph_Average.Data[sc.Index]
                    = (sc.Open[sc.Index]
                        + sc.High[sc.Index]
                        + sc.Low[sc.Index]
                        + sc.Close[sc.Index]
                    )
                    / 4.0f;
            }
            break;

            case 3:
            {
                Subgraph_Average.Data[sc.Index]
                    = (sc.High[sc.Index]
                        + sc.Low[sc.Index]
                        + sc.Close[sc.Index] * 2
                    )
                    / 4.0f;
            }
            break;
        }
    }

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

    ----------------------------------------------------------------------------*/
    SCSFExport scsf_ActionWhenTimeEncountered(SCStudyInterfaceRef sc)
    {
        if (sc.SetDefaults)
        {
            // Set the configuration and defaults

            sc.GraphName = "Action When Time is Encountered";

            sc.StudyDescription = "This study function demonstrates performing an action when a certain time is encountered in the most recent chart bar.";

            sc.AutoLoop = 1;

            return;
        }

        // Do data processing

        SCDateTime TimeToCheckFor;

        //The first step is to get the current date.
        int CurrentDate = sc.BaseDateTimeIn[sc.ArraySize - 1].GetDate();

        //Apply the time. For this example we will use 12 PM
        TimeToCheckFor.SetDate(CurrentDate);
        TimeToCheckFor.SetTimeHMS(12, 0, 0);

        // TimeToCheckFor is contained within the current bar.
        if (sc.IsDateTimeContainedInBarIndex(TimeToCheckFor, sc.Index))
        {
            //perform the action here
        }

    }

    /*============================================================================
        Symbol Display on chart
    ----------------------------------------------------------------------------*/
    SCSFExport scsf_SymbolDisplay(SCStudyInterfaceRef sc)
    {

        SCSubgraphRef Subgraph_SymbolText = sc.Subgraph[0];

        SCInputRef Input_HorizontalPosition = sc.Input[0];
        SCInputRef Input_VerticalPosition = sc.Input[1];
        SCInputRef Input_LockPosition = sc.Input[2];
        SCInputRef Input_TransparentLabelBackground = sc.Input[3];
        SCInputRef Input_UseSymbolDescription = sc.Input[5];
        SCInputRef Input_DrawAboveMainPriceGraph = sc.Input[6];
        SCInputRef Input_AlsoDisplayTradeAndCurrentQuoteSymbol = sc.Input[7];

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

            sc.GraphName = "Symbol Display";
            sc.AutoLoop = 0;//Manual looping
            sc.GraphRegion = 0;
            sc.ValueFormat = 0;

            Subgraph_SymbolText.Name = "Symbol Text";
            Subgraph_SymbolText.LineWidth = 20;
            Subgraph_SymbolText.DrawStyle = DRAWSTYLE_CUSTOM_TEXT;
            Subgraph_SymbolText.PrimaryColor = RGB(0, 0, 0); //black
            Subgraph_SymbolText.SecondaryColor = RGB(255, 127, 0); //Orange
            Subgraph_SymbolText.SecondaryColorUsed = true;
            Subgraph_SymbolText.DisplayNameValueInWindowsFlags = 1;

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

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

            Input_LockPosition.Name = "Lock Symbol Position";
            Input_LockPosition.SetYesNo(false);

            Input_TransparentLabelBackground.Name = "Transparent Label Background";
            Input_TransparentLabelBackground.SetYesNo(false);

            Input_UseSymbolDescription.Name = "Use Symbol Description";
            Input_UseSymbolDescription.SetYesNo(false);

            Input_DrawAboveMainPriceGraph.Name = "Draw Above Main Price Graph";
            Input_DrawAboveMainPriceGraph.SetYesNo(false);

            Input_AlsoDisplayTradeAndCurrentQuoteSymbol.Name = "Also Display Trade and Current Quote Symbol";
            Input_AlsoDisplayTradeAndCurrentQuoteSymbol.SetYesNo(false);

            sc.TextInputName = "Alternate Symbol Text";

            return;
        }

        SCString& PriorTextToDisplay = sc.GetPersistentSCString(1);

        SCString SymbolDescription;
        sc.GetSymbolDescription(SymbolDescription);

        if (SymbolDescription.IsEmpty())
            SymbolDescription = "(none)";

        SCString TextToDisplay;
        if (Input_UseSymbolDescription.GetYesNo())
            TextToDisplay = SymbolDescription;
        else if (sc.TextInput.GetLength() > 0)
            TextToDisplay = sc.TextInput;
        else
            TextToDisplay = sc.Symbol;

        if (Input_AlsoDisplayTradeAndCurrentQuoteSymbol.GetYesNo() && sc.TradeAndCurrentQuoteSymbol.GetLength() > 0)
        {
            TextToDisplay += " ";
            TextToDisplay += sc.TradeAndCurrentQuoteSymbol;
        }

        bool TextHasChanged = PriorTextToDisplay != TextToDisplay;

        if (!TextHasChanged && !sc.IsFullRecalculation && !sc.LastCallToFunction)
            return;

        PriorTextToDisplay = TextToDisplay;

        int HorizontalPosition = Input_HorizontalPosition.GetInt();
        int VerticalPosition = Input_VerticalPosition.GetInt();

        int DrawAboveMainPriceGraph = Input_DrawAboveMainPriceGraph.GetYesNo();
        int TransparentLabelBackground = Input_TransparentLabelBackground.GetYesNo();
        int LockDrawing = Input_LockPosition.GetYesNo();

        sc.AddAndManageSingleTextUserDrawnDrawingForStudy(sc, false, HorizontalPosition, VerticalPosition, Subgraph_SymbolText, TransparentLabelBackground, TextToDisplay, DrawAboveMainPriceGraph, LockDrawing);

    }

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

        SCInputRef Input_HorizontalPosition = sc.Input[0];
        SCInputRef Input_VerticalPosition = sc.Input[1];
        SCInputRef Input_DrawAboveMainPriceGraph = sc.Input[2];
        SCInputRef Input_TransparentLabelBackground = sc.Input[3];

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

            sc.GraphName = "Trading Profit Management Status";
            sc.AutoLoop = 0;//Manual looping
            sc.GraphRegion = 0;
            sc.ValueFormat = 0;

            Subgraph_StatusText.Name = "Status Text";
            Subgraph_StatusText.LineWidth = 10;
            Subgraph_StatusText.DrawStyle = DRAWSTYLE_CUSTOM_TEXT;
            Subgraph_StatusText.PrimaryColor = RGB(255, 255, 255);
            Subgraph_StatusText.SecondaryColor = RGB(0, 0, 160);
            Subgraph_StatusText.SecondaryColorUsed = true;
            Subgraph_StatusText.DisplayNameValueInWindowsFlags = 1;

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

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

            Input_DrawAboveMainPriceGraph.Name = "Draw Above Main Price Graph";
            Input_DrawAboveMainPriceGraph.SetYesNo(false);

            Input_TransparentLabelBackground.Name = "Transparent Label Background";
            Input_TransparentLabelBackground.SetYesNo(false);

            return;
        }

        // Do data processing
        SCString TextToDisplay;
        sc.GetProfitManagementStringForTradeAccount(TextToDisplay);

        int HorizontalPosition = Input_HorizontalPosition.GetInt();
        int VerticalPosition = Input_VerticalPosition.GetInt();

        int DrawAboveMainPriceGraph = Input_DrawAboveMainPriceGraph.GetYesNo();
        int TransparentLabelBackground = Input_TransparentLabelBackground.GetYesNo();

        sc.AddAndManageSingleTextUserDrawnDrawingForStudy(sc, false, HorizontalPosition, VerticalPosition, Subgraph_StatusText, TransparentLabelBackground, TextToDisplay, DrawAboveMainPriceGraph, 0);

    }

    /*==========================================================================*/
    SCSFExport scsf_TimeAndSalesIterationExample(SCStudyInterfaceRef sc)
    {
        if (sc.SetDefaults)
        {
            // Set the configuration and defaults

            sc.GraphName = "Time and Sales Iteration Example";

            sc.StudyDescription = "This is an example of iterating through the time and sales records which have been added since the last study function call.";

            sc.AutoLoop = 0;//Use manual looping

            sc.GraphRegion = 0;

            return;
        }

        //This code depends upon manual looping being set

        int64_t& LastProcessedSequence = sc.GetPersistentInt64(1);

        //reset the sequence number on a full recalculation so we start fresh for each full recalculation.
        if (sc.IsFullRecalculation && sc.UpdateStartIndex == 0)
            LastProcessedSequence = 0;

        // Get the Time and Sales
        c_SCTimeAndSalesArray TimeSales;
        sc.GetTimeAndSales(TimeSales);
        if (TimeSales.Size() == 0)
            return;  // No Time and Sales data available for the symbol

        //Set the initial sequence number
        if (LastProcessedSequence == 0)
            LastProcessedSequence = TimeSales[TimeSales.Size() - 1].Sequence;

        // Loop through the Time and Sales.
        for (int TSIndex = 0; TSIndex < TimeSales.Size(); ++TSIndex)
        {
            //do not reprocess previously processed sequence numbers.
            if (TimeSales[TSIndex].Sequence <= LastProcessedSequence)
                continue;

            //only interested in trade records
            if (TimeSales[TSIndex].Type == SC_TS_BID || TimeSales[TSIndex].Type == SC_TS_ASK)
            {

                float TradePrice = TimeSales[TSIndex].Price;
                float BidPrice = TimeSales[TSIndex].Bid;
                float AskPrice = TimeSales[TSIndex].Ask;

                SCDateTime RecordAdjustedDateTime = TimeSales[TSIndex].DateTime;
                // Apply the time zone offset for the chart. This will result in the actual date-time of the record in the charts time zone.
                RecordAdjustedDateTime += sc.TimeScaleAdjustment;

            }
        }

    }

    /*==========================================================================*/
    SCSFExport scsf_ServerConnectionStateExample(SCStudyInterfaceRef sc)
    {
        if (sc.SetDefaults)
        {
            // Set the configuration and defaults

            sc.GraphName = "ServerConnectionState Example";

            sc.AutoLoop = 0;

            return;
        }

        SCString MessageText = "Current Data/Trade Service connection state: ";

        switch (sc.ServerConnectionState)
        {
        case SCS_DISCONNECTED:
            MessageText += "SCS_DISCONNECTED";
            break;

        case SCS_CONNECTING:
            MessageText += "SCS_CONNECTING";
            break;

        case SCS_CONNECTED:
            MessageText += "SCS_CONNECTED";
            break;

        case SCS_CONNECTION_LOST:
            MessageText += "SCS_CONNECTION_LOST";
            break;

        case SCS_DISCONNECTING:
            MessageText += "SCS_DISCONNECTING";
            break;

        case SCS_RECONNECTING:
            MessageText += "SCS_RECONNECTING";
            break;

        default:
            MessageText += "INVALID";
            break;
        }

        sc.AddMessageToLog(MessageText, 0);
    }

    /*==========================================================================*/
    SCSFExport scsf_StudySubgraphDailyHighLow(SCStudyInterfaceRef sc)
    {
        SCSubgraphRef Subgraph_HighOfDay = sc.Subgraph[0];
        SCSubgraphRef Subgraph_LowOfDay = sc.Subgraph[1];
        SCInputRef Input_StudySubgraphReference = sc.Input[0];

        if (sc.SetDefaults)
        {
            sc.GraphName            = "Study Subgraph Daily High Low";
            sc.GraphRegion          = 1;
            sc.AutoLoop             = 0;

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

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

            sc.CalculationPrecedence = LOW_PREC_LEVEL;

            Input_StudySubgraphReference.Name = "Study Subgraph Reference";

            Input_StudySubgraphReference.SetStudySubgraphValues(1, 0);

            return;
        }

        float& r_CurrentDailyHigh = sc.GetPersistentFloat(1);
        float& r_CurrentDailyLow = sc.GetPersistentFloat(2);

        //Loop
        for (int BarIndex = sc.UpdateStartIndex; BarIndex < sc.ArraySize; BarIndex++ )
        {

            if (BarIndex > 0)
            {
                SCDateTime PreviousTradingDayStartDateTimeOfBar = sc.GetTradingDayStartDateTimeOfBar (sc.BaseDateTimeIn[BarIndex - 1]);
                SCDateTime TradingDayStartDateTimeOfBar = sc.GetTradingDayStartDateTimeOfBar (sc.BaseDateTimeIn[BarIndex]);

                if (PreviousTradingDayStartDateTimeOfBar != TradingDayStartDateTimeOfBar)
                {
                    r_CurrentDailyHigh = 0;
                    r_CurrentDailyLow = 0;
                }
            }
            else
            {
                r_CurrentDailyHigh = 0;
                r_CurrentDailyLow = 0;
            }

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

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

            if (r_CurrentDailyHigh == 0 || r_CurrentDailyHigh < StudySubgraph[BarIndex])
                r_CurrentDailyHigh = StudySubgraph[BarIndex];

            if (r_CurrentDailyLow == 0 || r_CurrentDailyLow > StudySubgraph[BarIndex])
                r_CurrentDailyLow = StudySubgraph[BarIndex];

            Subgraph_HighOfDay[BarIndex] = r_CurrentDailyHigh;
            Subgraph_LowOfDay[BarIndex] = r_CurrentDailyLow;
        }
    }

    /*==========================================================================*/
    SCSFExport scsf_TimeSeriesForecast(SCStudyInterfaceRef sc)
    {
        SCSubgraphRef Subgraph_TimeSeriesForecast = sc.Subgraph[0];
        SCFloatArrayRef Array_LinearRegressionSlope = sc.Subgraph[0].Arrays[0];
        SCFloatArrayRef Array_LinearRegressionIndicator = sc.Subgraph[0].Arrays[1];

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

        if (sc.SetDefaults)
        {
            sc.GraphName = "Time Series Forecast";

            sc.AutoLoop = 1;

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

            Subgraph_TimeSeriesForecast.Name = "TSF";
            Subgraph_TimeSeriesForecast.DrawStyle = DRAWSTYLE_LINE;
            Subgraph_TimeSeriesForecast.PrimaryColor = RGB(0,255,0);
            Subgraph_TimeSeriesForecast.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;

        int CalculationLength=Input_Length.GetInt();
        double SumBars = CalculationLength*(CalculationLength-1)/2.0;
        double SumSqrBars = (CalculationLength-1)*CalculationLength*(2*CalculationLength-1)/6.0;

        double Sum1 = 0;
        double SumY = 0;
        for(int Index=sc.Index; Index > (sc.Index - CalculationLength); Index--)
        {
            int IndexDifference = sc.Index - Index;
            Sum1 = Sum1 + IndexDifference * sc.BaseData[Input_Data.GetInputDataIndex()][Index];
            SumY += sc.BaseData[Input_Data.GetInputDataIndex()][Index];
        }

        double Sum2 = SumBars * SumY;
        double Num1 = CalculationLength*Sum1 - Sum2;
        double Num2 = SumBars*SumBars - CalculationLength*SumSqrBars;
        Array_LinearRegressionSlope[sc.Index] = static_cast<float>(Num1 / Num2);

        sc.LinearRegressionIndicator(sc.BaseData[Input_Data.GetInputDataIndex()], Array_LinearRegressionIndicator, CalculationLength);

        Subgraph_TimeSeriesForecast[sc.Index] = Array_LinearRegressionIndicator[sc.Index] + Array_LinearRegressionSlope[sc.Index];

        return;
    }

    /*==========================================================================*/
    SCSFExport scsf_ExtendClosesUntilFutureIntersection(SCStudyInterfaceRef sc)
    {
        SCSubgraphRef Subgraph_LineProperties = sc.Subgraph[0];
        SCInputRef Input_DisplayValueLabel = sc.Input[0];
        SCInputRef Input_NameLabel = sc.Input[1];

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

            sc.GraphName = "Extend Closes Until Future Intersection";

            Subgraph_LineProperties.Name = "Line Properties";
            Subgraph_LineProperties.DrawStyle = DRAWSTYLE_SUBGRAPH_NAME_AND_VALUE_LABELS_ONLY;
            Subgraph_LineProperties.LineWidth = 1;
            Subgraph_LineProperties.PrimaryColor = COLOR_RED;
            Subgraph_LineProperties.DrawZeros = false;

            Input_DisplayValueLabel.Name = "Display Value Label";
            Input_DisplayValueLabel.SetYesNo(true);

            Input_NameLabel.Name = "Name Label";
            Input_NameLabel.SetString("");

            sc.ValueFormat = VALUEFORMAT_INHERITED;

            sc.GraphRegion = 0;

            sc.AutoLoop = 1;

            return;
        }

        if (sc.Index == 0)
            return;

        const SCDateTime CurrentBarStartDateTimeForDay
            = sc.GetTradingDayStartDateTimeOfBar(sc.BaseDateTimeIn[sc.Index]);

        const SCDateTime PriorBarStartDateTimeForDay
            = sc.GetTradingDayStartDateTimeOfBar(sc.BaseDateTimeIn[sc.Index - 1]);

        const bool IsNewDay = (CurrentBarStartDateTimeForDay != PriorBarStartDateTimeForDay);

        if (!IsNewDay)
            return;

        const float ClosePriceOfPriorBar = sc.Close[sc.Index - 1];
        const char* NameLabelString = Input_NameLabel.GetString();

        bool DisplayNameLabel = false;

        if (NameLabelString != NULL && strlen(NameLabelString) > 0)
            DisplayNameLabel = true;
        else
            NameLabelString = "";

        sc.AddLineUntilFutureIntersection
            ( sc.Index - 1
            , 0  // LineIDForBar
            , ClosePriceOfPriorBar
            , Subgraph_LineProperties.PrimaryColor
            , Subgraph_LineProperties.LineWidth
            , Subgraph_LineProperties.LineStyle
            , Input_DisplayValueLabel.GetYesNo()
            , DisplayNameLabel
            , NameLabelString
            );
    }

    /*==========================================================================*/
    SCSFExport scsf_ExtendBarValueUntilFutureIntersection(SCStudyInterfaceRef sc)
    {
        SCSubgraphRef Subgraph_LineProperties = sc.Subgraph[0];
        SCInputRef Input_Data = sc.Input[0];
        SCInputRef Input_DisplayValueLabel = sc.Input[1];
        SCInputRef Input_NameLabel = sc.Input[2];

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

            sc.GraphName = "Extend Bar Value Until Future Intersection";

            Subgraph_LineProperties.Name = "Line Properties";
            Subgraph_LineProperties.DrawStyle = DRAWSTYLE_SUBGRAPH_NAME_AND_VALUE_LABELS_ONLY;
            Subgraph_LineProperties.LineWidth = 1;
            Subgraph_LineProperties.PrimaryColor = COLOR_RED;
            Subgraph_LineProperties.DrawZeros = false;

            Input_Data.Name = "Input Data from Bar for Extension Lines";
            Input_Data.SetInputDataIndex(SC_LAST);

            Input_DisplayValueLabel.Name = "Display Value Label";
            Input_DisplayValueLabel.SetYesNo(true);

            Input_NameLabel.Name = "Name Label";
            Input_NameLabel.SetString("");

            sc.ValueFormat = VALUEFORMAT_INHERITED;

            sc.GraphRegion = 0;

            sc.AutoLoop = 1;

            return;
        }

        const char* NameLabelString = Input_NameLabel.GetString();

        bool DisplayNameLabel = false;

        if (NameLabelString != NULL && strlen(NameLabelString) > 0)
            DisplayNameLabel = true;
        else
            NameLabelString = "";

        sc.AddLineUntilFutureIntersection
            ( sc.Index
            , 0  // LineIDForBar
            , sc.BaseData[ Input_Data.GetInputDataIndex()][sc.Index]
            , Subgraph_LineProperties.PrimaryColor
            , Subgraph_LineProperties.LineWidth
            , Subgraph_LineProperties.LineStyle
            , Input_DisplayValueLabel.GetYesNo()
            , DisplayNameLabel
            , NameLabelString
            );
    }

    /*==========================================================================*/
    SCSFExport scsf_ExtendBarGapUntilFutureIntersection(SCStudyInterfaceRef sc)
    {
        SCSubgraphRef Subgraph_LinePropertiesSubgraph = sc.Subgraph[0];
        SCInputRef Input_DisplayValueLabel = sc.Input[0];
        SCInputRef Input_NameLabel = sc.Input[1];
        SCInputRef Input_CompareToOpentoCloseRangeOnly = sc.Input[2];

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

            sc.GraphName = "Extend Bar Gap Until Future Intersection";

            Subgraph_LinePropertiesSubgraph.Name = "Line Properties";
            Subgraph_LinePropertiesSubgraph.DrawStyle = DRAWSTYLE_SUBGRAPH_NAME_AND_VALUE_LABELS_ONLY;
            Subgraph_LinePropertiesSubgraph.LineWidth = 1;
            Subgraph_LinePropertiesSubgraph.PrimaryColor = COLOR_RED;
            Subgraph_LinePropertiesSubgraph.DrawZeros = false;

            Input_DisplayValueLabel.Name = "Display Value Label";
            Input_DisplayValueLabel.SetYesNo(true);

            Input_NameLabel.Name = "Name Label";
            Input_NameLabel.SetString("");

            Input_CompareToOpentoCloseRangeOnly.Name = "Compare to Open to Close Range Only";
            Input_CompareToOpentoCloseRangeOnly.SetYesNo(false);

            sc.ValueFormat = VALUEFORMAT_INHERITED;

            sc.GraphRegion = 0;

            sc.AutoLoop = 1;

            return;
        }

        if (sc.Index == 0)
            return;

        float ExtendPrice = 0.0;

        if (!Input_CompareToOpentoCloseRangeOnly.GetYesNo())
        {
            //Check for up gap
            if (sc.FormattedEvaluate(sc.High[sc.Index - 1], sc.BaseGraphValueFormat, LESS_OPERATOR, sc.Low[sc.Index], sc.BaseGraphValueFormat))
            {
                ExtendPrice = sc.High[sc.Index - 1];
            }
            //Check for  down gap
            else if (sc.FormattedEvaluate(sc.Low[sc.Index - 1], sc.BaseGraphValueFormat, GREATER_OPERATOR, sc.High[sc.Index], sc.BaseGraphValueFormat))
            {
                ExtendPrice = sc.Low[sc.Index - 1];
            }
            else
            {
                return;
            }
        }
        else
        {
            float PriorMaxValue = max(sc.Open[sc.Index - 1], sc.Close[sc.Index - 1]);
            float PriorMinValue = min(sc.Open[sc.Index - 1], sc.Close[sc.Index - 1]);
            float MaxValue = max(sc.Open[sc.Index], sc.Close[sc.Index]);
            float MinValue = min(sc.Open[sc.Index], sc.Close[sc.Index]);

            //Check for up gap
            if (sc.FormattedEvaluate(PriorMaxValue, sc.BaseGraphValueFormat, LESS_OPERATOR, MinValue, sc.BaseGraphValueFormat))
            {
                ExtendPrice = PriorMaxValue;
            }
            //Check for  down gap
            else if (sc.FormattedEvaluate(PriorMinValue, sc.BaseGraphValueFormat, GREATER_OPERATOR, MaxValue, sc.BaseGraphValueFormat))
            {
                ExtendPrice = PriorMinValue;
            }
            else
            {
                return;
            }
        }

        SCString NameLabelString = Input_NameLabel.GetString();

        bool DisplayNameLabel = false;

        if (NameLabelString != NULL && strlen(NameLabelString) > 0)
            DisplayNameLabel = true;
        else
            NameLabelString.Clear();

        sc.AddLineUntilFutureIntersection
            ( sc.Index - 1
            , 0  // LineIDForBar. Use 0 since there is only one line per bar.
            , ExtendPrice
            , Subgraph_LinePropertiesSubgraph.PrimaryColor
            , Subgraph_LinePropertiesSubgraph.LineWidth
            , Subgraph_LinePropertiesSubgraph.LineStyle
            , Input_DisplayValueLabel.GetYesNo()
            , DisplayNameLabel
            , NameLabelString
            );
    }
    /*==========================================================================*/
    SCSFExport scsf_MarketDepthPullingStackingValuesExample(SCStudyInterfaceRef sc)
    {
        SCSubgraphRef Subgraph_BidPullingStacking = sc.Subgraph[0];
        SCSubgraphRef Subgraph_AskPullingStacking = sc.Subgraph[1];

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

            sc.GraphName = "Market Depth Pulling/Stacking Values Example";

            sc.GraphRegion = 1;

            sc.AutoLoop = 0;

            Subgraph_BidPullingStacking.Name = "Bid";
            Subgraph_BidPullingStacking.DrawStyle = DRAWSTYLE_LINE;

            Subgraph_AskPullingStacking.Name = "Ask";
            Subgraph_AskPullingStacking.DrawStyle = DRAWSTYLE_LINE;

            return;
        }

        //The following two functions will return 0 if there is no pulling and stacking value at the specified price
        Subgraph_BidPullingStacking[sc.ArraySize - 1] = static_cast<float>(sc.GetBidMarketDepthStackPullValueAtPrice(sc.Bid));
        Subgraph_AskPullingStacking[sc.ArraySize - 1] = static_cast<float>(sc.GetAskMarketDepthStackPullValueAtPrice(sc.Ask));
    }

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

    SCSFExport scsf_Repulse(SCStudyGraphRef sc)
    {
        SCSubgraphRef Subgraph_Repulse = sc.Subgraph[0];
        SCInputRef Input_Length = sc.Input[0];

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

            sc.GraphName = "Repulse";

            sc.AutoLoop = 1;

            sc.GraphRegion = 1;

            Subgraph_Repulse.Name = "Repulse";
            Subgraph_Repulse.PrimaryColor = RGB(0, 255, 0);
            Subgraph_Repulse.DrawStyle = DRAWSTYLE_LINE;
            Subgraph_Repulse.LineWidth = 2;

            Input_Length.Name = "Length";
            Input_Length.SetInt(10);

            return;
        }

        // Do data processing
        /*
        lo = LOWEST(LOW)
        hi = HIGHEST(HIGH)
        a = 100 * ( 3 * CLOSE - 2 * lo - OPEN[p-1] ) / CLOSE
        b = 100 * ( OPEN[p-1] + 2 * hi - 3 * CLOSE ) / CLOSE
        d = EXPONENTIALAVERAGE[5*p](a) - EXPONENTIALAVERAGE[5*p](b)
        RETURN d*/
        int Length = Input_Length.GetInt();

        sc.Highest(sc.High, Subgraph_Repulse.Arrays[0], Length);
        sc.Lowest(sc.Low, Subgraph_Repulse.Arrays[1], Length);

        Subgraph_Repulse.Arrays[2][sc.Index] = 100 * (3 * sc.Close[sc.Index] - 2 * Subgraph_Repulse.Arrays[1][sc.Index] - sc.Open[sc.Index - Length + 1]) / sc.Close[sc.Index];

        Subgraph_Repulse.Arrays[3][sc.Index] = 100 * (sc.Open[sc.Index - Length + 1] + 2 * Subgraph_Repulse.Arrays[0][sc.Index] - 3 * sc.Close[sc.Index]) / sc.Close[sc.Index];

        sc.MovingAverage(Subgraph_Repulse.Arrays[2], Subgraph_Repulse.Arrays[4], MOVAVGTYPE_EXPONENTIAL, 5*Length);
        sc.MovingAverage(Subgraph_Repulse.Arrays[3], Subgraph_Repulse.Arrays[5], MOVAVGTYPE_EXPONENTIAL, 5*Length);

        Subgraph_Repulse.Data[sc.Index] = Subgraph_Repulse.Arrays[4][sc.Index] - Subgraph_Repulse.Arrays[5][sc.Index];
    }

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

        SCInputRef Input_Data = sc.Input[0];
        SCInputRef Input_DrawZeros = sc.Input[1];

        if (sc.SetDefaults)
        {
            sc.GraphName = "Full Contract Value";
            sc.ValueFormat = VALUEFORMAT_2_DIGITS;
            sc.AutoLoop = 0;// Needed when using sc.GetCalculationStartIndexForStudy

            Subgraph_Result.Name = "Result";
            Subgraph_Result.DrawStyle = DRAWSTYLE_LINE;
            Subgraph_Result.PrimaryColor = RGB(0, 255, 0);

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

            Input_DrawZeros.Name = "Draw Zeros";
            Input_DrawZeros.SetYesNo(false);

            return;
        }

        Subgraph_Result.DrawZeros = Input_DrawZeros.GetYesNo();

        int CalculationStartIndex = sc.GetCalculationStartIndexForStudy();

        for (int Index = CalculationStartIndex; Index < sc.ArraySize; Index++)
        {

            Subgraph_Result[Index] = sc.BaseData[Input_Data.GetInputDataIndex()][Index] / sc.TickSize * max(sc.CurrencyValuePerTick, sc.TickSize);
        }

        sc.EarliestUpdateSubgraphDataArrayIndex = CalculationStartIndex;
    }

    /*==========================================================================*/
    SCSFExport scsf_KeyboardModifierStatesExample(SCStudyInterfaceRef sc)
    {
        if (sc.SetDefaults)
        {
            // Set the configuration and defaults

            sc.GraphName = "Keyboard Modifier States Example";

            sc.AutoLoop = 0;///Manual looping

            sc.GraphRegion = 0;

            sc.UpdateAlways = 1;
            sc.SupportKeyboardModifierStates = 1;

            return;
        }

        if (sc.IsKeyPressed_Alt)
        {
            sc.AddMessageToLog("Alt key pressed", 0);
        }

        if (sc.IsKeyPressed_Shift)
        {
            sc.AddMessageToLog("Shift key pressed", 0);
        }

        if (sc.IsKeyPressed_Control)
        {
            sc.AddMessageToLog("Control key pressed", 0);
        }
    }
    /*==========================================================================*/

    SCSFExport scsf_BalanceOfPower(SCStudyInterfaceRef sc)
    {
        SCSubgraphRef Subgraph_BalanceOfPower = sc.Subgraph[0];
        SCSubgraphRef Subgraph_BalanceOfPowerAverage = sc.Subgraph[1];

        SCInputRef Input_MovingAverageLength = sc.Input[0];

        if (sc.SetDefaults)
        {
            sc.GraphName = "Balance of Power";
            sc.GraphRegion = 1;
            sc.ValueFormat = 2;

            Subgraph_BalanceOfPower.Name = "BOP";
            Subgraph_BalanceOfPower.DrawStyle = DRAWSTYLE_LINE;
            Subgraph_BalanceOfPower.PrimaryColor = RGB(0, 255, 0);
            Subgraph_BalanceOfPower.LineWidth = 2;

            Subgraph_BalanceOfPowerAverage.Name = "BOP Average";
            Subgraph_BalanceOfPowerAverage.DrawStyle = DRAWSTYLE_LINE;
            Subgraph_BalanceOfPowerAverage.PrimaryColor = RGB(0, 0, 255);
            Subgraph_BalanceOfPowerAverage.LineWidth = 2;

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

            return;
        }

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

        Subgraph_BalanceOfPower.Data[sc.Index] = (sc.BaseData[SC_LAST][sc.Index] - sc.BaseData[SC_OPEN][sc.Index]) / (sc.BaseData[SC_HIGH][sc.Index] - sc.BaseData[SC_LOW][sc.Index]);

        sc.SimpleMovAvg(Subgraph_BalanceOfPower, Subgraph_BalanceOfPowerAverage, Input_MovingAverageLength.GetInt());

    }
    /*==========================================================================*/
    SCSFExport scsf_MACDBollingerBandsImproved(SCStudyInterfaceRef sc)
    {
        SCSubgraphRef Subgraph_MACD = sc.Subgraph[0];
        SCSubgraphRef Subgraph_MovAvgOfMACD = sc.Subgraph[1];
        SCSubgraphRef Subgraph_MACDDiff = sc.Subgraph[2];
        SCSubgraphRef Subgraph_TopBand = sc.Subgraph[3];
        SCSubgraphRef Subgraph_BottomBand = sc.Subgraph[4];
        SCSubgraphRef Subgraph_RefLine = sc.Subgraph[5];

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

        if (sc.SetDefaults)
        {
            sc.GraphName = "MACD Bollinger Bands - Improved";
            sc.AutoLoop = 1;

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

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

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

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

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

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

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

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

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

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

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

            return;
        }

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

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

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

        Subgraph_MACD.Arrays[6][sc.Index] = fabs(Subgraph_MACDDiff[sc.Index]);

        sc.MovingAverage(Subgraph_MACD.Arrays[6], Subgraph_MACD.Arrays[7], Input_MovingAverageType.GetMovAvgType(), Input_MACDLength.GetInt());

        float MovAvgAbsValMACDDiff = Subgraph_MACD.Arrays[7][sc.Index];

        sc.StdDeviation(Subgraph_MACD.Arrays[6], Subgraph_MACD.Arrays[8], Input_MACDLength.GetInt());

        float StdDevAbsValMACDDiff = Subgraph_MACD.Arrays[8][sc.Index];

        Subgraph_TopBand[sc.Index] = Subgraph_MovAvgOfMACD[sc.Index] + MovAvgAbsValMACDDiff + Input_NumberOfStdDevs.GetInt()*StdDevAbsValMACDDiff;
        Subgraph_BottomBand[sc.Index] = Subgraph_MovAvgOfMACD[sc.Index] - MovAvgAbsValMACDDiff - Input_NumberOfStdDevs.GetInt()*StdDevAbsValMACDDiff;

        Subgraph_RefLine[sc.Index] = 0;
    }
    /*==========================================================================*/
    SCSFExport scsf_MACDBollingerBandsStandard(SCStudyInterfaceRef sc)
    {
        SCSubgraphRef Subgraph_MACD = sc.Subgraph[0];
        SCSubgraphRef Subgraph_MovAvgOfMACD = sc.Subgraph[1];
        SCSubgraphRef Subgraph_TopBand = sc.Subgraph[2];
        SCSubgraphRef Subgraph_BottomBand = sc.Subgraph[3];
        SCSubgraphRef Subgraph_RefLine = sc.Subgraph[4];

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

        if (sc.SetDefaults)
        {
            sc.GraphName = "MACD Bollinger Bands - Standard";
            sc.AutoLoop = 1;

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

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

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

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

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

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

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

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

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

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

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

            return;
        }

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

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

        Subgraph_MovAvgOfMACD[sc.Index] = Subgraph_MACD.Arrays[2][sc.Index];

        sc.StdDeviation(Subgraph_MACD, Subgraph_MACD.Arrays[6], Input_MACDLength.GetInt());
        float StdDevOfMACD = Subgraph_MACD.Arrays[6][sc.Index];

        Subgraph_TopBand[sc.Index] = Subgraph_MovAvgOfMACD[sc.Index] + Input_NumberOfStdDevs.GetInt()*StdDevOfMACD;
        Subgraph_BottomBand[sc.Index] = Subgraph_MovAvgOfMACD[sc.Index] - Input_NumberOfStdDevs.GetInt()*StdDevOfMACD;

        Subgraph_RefLine[sc.Index] = 0;
    }

    /*==========================================================================*/
    SCSFExport scsf_GreatestSwingValue(SCStudyInterfaceRef sc)
    {
        SCSubgraphRef Subgraph_BuySwing = sc.Subgraph[0];
        SCSubgraphRef Subgraph_SellSwing = sc.Subgraph[1];
        SCSubgraphRef Subgraph_AvgBuySwing = sc.Subgraph[2];
        SCSubgraphRef Subgraph_AvgSellSwing = sc.Subgraph[3];
        SCSubgraphRef Subgraph_BuyPrice = sc.Subgraph[4];
        SCSubgraphRef Subgraph_SellPrice = sc.Subgraph[5];

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

        if (sc.SetDefaults)
        {
            sc.GraphName = "Greatest Swing Value";

            sc.AutoLoop = 1;

            Subgraph_BuySwing.Name = "Buy Swing";
            Subgraph_BuySwing.DrawStyle = DRAWSTYLE_IGNORE;

            Subgraph_SellSwing.Name = "Sell Swing";
            Subgraph_SellSwing.DrawStyle = DRAWSTYLE_IGNORE;

            Subgraph_AvgBuySwing.Name = "Average Buy Swing";
            Subgraph_AvgBuySwing.DrawStyle = DRAWSTYLE_IGNORE;

            Subgraph_AvgSellSwing.Name = "Average Sell Swing";
            Subgraph_AvgSellSwing.DrawStyle = DRAWSTYLE_IGNORE;

            Subgraph_BuyPrice.Name = "Buy Price";
            Subgraph_BuyPrice.DrawStyle = DRAWSTYLE_LINE;
            Subgraph_BuyPrice.PrimaryColor = RGB(0, 0, 255);

            Subgraph_SellPrice.Name = "Sell Price";
            Subgraph_SellPrice.DrawStyle = DRAWSTYLE_LINE;
            Subgraph_SellPrice.PrimaryColor = RGB(255, 0, 0);

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

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

            return;
        }

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

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

        if (sc.Close[sc.Index] < sc.Open[sc.Index])
            Subgraph_BuySwing[sc.Index] = sc.High[sc.Index] - sc.Open[sc.Index];
        else
            Subgraph_BuySwing[sc.Index] = 0;

        if (sc.Close[sc.Index] > sc.Open[sc.Index])
            Subgraph_SellSwing[sc.Index] = sc.Open[sc.Index] - sc.Low[sc.Index];
        else
            Subgraph_SellSwing[sc.Index] = 0;

        sc.MovingAverage(Subgraph_BuySwing, Subgraph_AvgBuySwing, MOVAVGTYPE_SIMPLE_SKIP_ZEROS, Length);
        sc.MovingAverage(Subgraph_SellSwing, Subgraph_AvgSellSwing, MOVAVGTYPE_SIMPLE_SKIP_ZEROS, Length);

        Subgraph_BuyPrice[sc.Index] = sc.Open[sc.Index] + Multiplier * Subgraph_AvgBuySwing[sc.Index - 1];
        Subgraph_SellPrice[sc.Index] = sc.Open[sc.Index] - Multiplier * Subgraph_AvgSellSwing[sc.Index - 1];
    }

    /*==========================================================================*/
    SCSFExport scsf_KDJ(SCStudyInterfaceRef sc)
    {
        SCSubgraphRef Subgraph_SlowK = sc.Subgraph[0];
        SCSubgraphRef Subgraph_SlowD = sc.Subgraph[1];
        SCSubgraphRef Subgraph_Line1 = sc.Subgraph[2];
        SCSubgraphRef Subgraph_Line2 = sc.Subgraph[3];
        SCSubgraphRef Subgraph_StochasticOutput = sc.Subgraph[4];
        SCSubgraphRef Subgraph_JLine = sc.Subgraph[5];

        SCInputRef Input_FastKLength = sc.Input[2];
        SCInputRef Input_FastDLength = sc.Input[3];
        SCInputRef Input_SlowDLength = sc.Input[4];
        SCInputRef Input_Line1Value = sc.Input[5];
        SCInputRef Input_Line2Value = sc.Input[6];
        SCInputRef Input_MovAvgType = sc.Input[7];
        SCInputRef Input_DataHigh = sc.Input[8];
        SCInputRef Input_DataLow = sc.Input[9];
        SCInputRef Input_DataLast = sc.Input[10];

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

            sc.ValueFormat = 2;

            Subgraph_SlowK.Name = "Slow %K";
            Subgraph_SlowK.DrawStyle = DRAWSTYLE_LINE;
            Subgraph_SlowK.PrimaryColor = RGB(0, 255, 0);
            Subgraph_SlowK.DrawZeros = true;

            Subgraph_SlowD.Name = "Slow %D";
            Subgraph_SlowD.DrawStyle = DRAWSTYLE_LINE;
            Subgraph_SlowD.PrimaryColor = RGB(255, 0, 255);
            Subgraph_SlowD.DrawZeros = true;

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

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

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

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

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

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

            Input_Line1Value.Name = "Line1 Value";
            Input_Line1Value.SetFloat(70);

            Input_Line2Value.Name = "Line2 Value";
            Input_Line2Value.SetFloat(30);

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

            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_DataLast.Name = "Input Data for Last";
            Input_DataLast.SetInputDataIndex(SC_LAST);

            sc.AutoLoop = true;
            return;
        }

        sc.DataStartIndex = Input_FastKLength.GetInt() + Input_FastDLength.GetInt() + Input_SlowDLength.GetInt();

        sc.Stochastic(
            sc.BaseData[Input_DataHigh.GetInputDataIndex()],
            sc.BaseData[Input_DataLow.GetInputDataIndex()],
            sc.BaseData[Input_DataLast.GetInputDataIndex()],
            Subgraph_StochasticOutput,  // Data member is Fast %K
            Input_FastKLength.GetInt(),
            Input_FastDLength.GetInt(),
            Input_SlowDLength.GetInt(),
            Input_MovAvgType.GetMovAvgType()
        );

        Subgraph_SlowK[sc.Index] = Subgraph_StochasticOutput.Arrays[0][sc.Index];
        Subgraph_SlowD[sc.Index] = Subgraph_StochasticOutput.Arrays[1][sc.Index];
        Subgraph_JLine[sc.Index] = 3 * Subgraph_SlowK[sc.Index] - 2 * Subgraph_SlowD[sc.Index];

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

        return;
    }

    /*==========================================================================*/
    SCSFExport scsf_NormalizedVolume(SCStudyInterfaceRef sc)
    {
        SCSubgraphRef Subgraph_NormalizedVolume = sc.Subgraph[0];
        SCSubgraphRef Subgraph_HighVolume = sc.Subgraph[1];
        SCSubgraphRef Subgraph_LowVolume = sc.Subgraph[2];

        SCFloatArrayRef Array_AverageVolume = sc.Subgraph[0].Arrays[0];

        SCInputRef Input_Length = sc.Input[0];
        SCInputRef Input_MovingAverageType = sc.Input[1];
        SCInputRef Input_HighVolume = sc.Input[2];
        SCInputRef Input_LowVolume = sc.Input[3];

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

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

            Subgraph_NormalizedVolume.Name = "Normalized Volume";
            Subgraph_NormalizedVolume.DrawStyle = DRAWSTYLE_LINE;
            Subgraph_NormalizedVolume.PrimaryColor = RGB(0, 0, 255);
            Subgraph_NormalizedVolume.DrawZeros = true;

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

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

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

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

            Input_HighVolume.Name = "High Volume";
            Input_HighVolume.SetFloat(150.0f);

            Input_LowVolume.Name = "Low Volume";
            Input_LowVolume.SetFloat(75.0f);

            return;
        }

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

        sc.MovingAverage(sc.BaseData[SC_VOLUME], Array_AverageVolume, Input_MovingAverageType.GetMovAvgType(), Input_Length.GetInt());

        if (Array_AverageVolume[sc.Index] == 0)
            Subgraph_NormalizedVolume[sc.Index] = Subgraph_NormalizedVolume[sc.Index - 1];
        else
            Subgraph_NormalizedVolume[sc.Index] = 100.0f * sc.BaseData[SC_VOLUME][sc.Index] / Array_AverageVolume[sc.Index];

        Subgraph_HighVolume[sc.Index] = Input_HighVolume.GetFloat();
        Subgraph_LowVolume[sc.Index] = Input_LowVolume.GetFloat();
    }

    /*==========================================================================*/
    SCSFExport scsf_DeMarkerOscillatorTypeI(SCStudyInterfaceRef sc)
    {
        SCSubgraphRef Subgraph_DeMaxI = sc.Subgraph[0];
        SCSubgraphRef Subgraph_DeMinI = sc.Subgraph[1];
        SCSubgraphRef Subgraph_DeMI = sc.Subgraph[2];
        SCSubgraphRef Subgraph_OverboughtLine = sc.Subgraph[3];
        SCSubgraphRef Subgraph_OversoldLine = sc.Subgraph[4];
        SCSubgraphRef Subgraph_DurationExceededOverbought = sc.Subgraph[5];
        SCSubgraphRef Subgraph_DurationExceededOversold = sc.Subgraph[6];

        SCFloatArrayRef Array_Temp1 = sc.Subgraph[2].Arrays[0];
        SCFloatArrayRef Array_Temp2 = sc.Subgraph[2].Arrays[1];

        SCInputRef Input_InputDataHigh = sc.Input[0];
        SCInputRef Input_InputDataLow = sc.Input[1];
        SCInputRef Input_DeMLength1 = sc.Input[2];
        SCInputRef Input_DeMLength2 = sc.Input[3];
        SCInputRef Input_UseSmoothing = sc.Input[4];
        SCInputRef Input_SmoothingLength = sc.Input[5];
        SCInputRef Input_SmoothingMAType = sc.Input[6];
        SCInputRef Input_UseMovingAverage = sc.Input[7];
        SCInputRef Input_AverageDeMMALength = sc.Input[8];
        SCInputRef Input_AverageDeMMAType = sc.Input[9];
        SCInputRef Input_DurationLength = sc.Input[10];
        SCInputRef Input_OffsetPercentage = sc.Input[11];
        SCInputRef Input_OverboughtLineValue = sc.Input[12];
        SCInputRef Input_OversoldLineValue = sc.Input[13];

        if (sc.SetDefaults)
        {
            sc.GraphName = "DeMarker Oscillator Type I";

            sc.AutoLoop = 1;

            Subgraph_DeMaxI.Name = "Max DeMarker I";
            Subgraph_DeMaxI.DrawStyle = DRAWSTYLE_IGNORE;

            Subgraph_DeMinI.Name = "Min DeMarker I";
            Subgraph_DeMinI.DrawStyle = DRAWSTYLE_IGNORE;

            Subgraph_DeMI.Name = "DeMarker I";
            Subgraph_DeMI.DrawStyle = DRAWSTYLE_LINE;
            Subgraph_DeMI.PrimaryColor = RGB(0, 0, 255);
            Subgraph_DeMI.DrawZeros = true;

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

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

            Subgraph_DurationExceededOverbought.Name = "Duration Exceeded in Overbought Area";
            Subgraph_DurationExceededOverbought.PrimaryColor = RGB(0, 255, 0);
            Subgraph_DurationExceededOverbought.DrawStyle = DRAWSTYLE_ARROW_DOWN;
            Subgraph_DurationExceededOverbought.LineWidth = 2;
            Subgraph_DurationExceededOverbought.DrawZeros = 0;

            Subgraph_DurationExceededOversold.Name = "Duration Exceeded in Oversold Area";
            Subgraph_DurationExceededOversold.PrimaryColor = RGB(255, 0, 0);
            Subgraph_DurationExceededOversold.DrawStyle = DRAWSTYLE_ARROW_UP;
            Subgraph_DurationExceededOversold.LineWidth = 2;
            Subgraph_DurationExceededOversold.DrawZeros = 0;

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

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

            Input_DeMLength2.Name = "DeM Length 2";
            Input_DeMLength2.SetInt(8);
            Input_DeMLength2.SetIntLimits(1, MAX_STUDY_LENGTH);

            Input_DeMLength1.Name = "DeM Length 1";
            Input_DeMLength1.SetInt(1);
            Input_DeMLength1.SetIntLimits(1, Input_DeMLength2.GetInt());

            Input_UseSmoothing.Name = "Use Smoothing?";
            Input_UseSmoothing.SetYesNo(0);

            Input_SmoothingLength.Name = "Smoothing Length";
            Input_SmoothingLength.SetInt(3);
            Input_SmoothingLength.SetIntLimits(1, Input_DeMLength2.GetInt());

            Input_SmoothingMAType.Name = "Smoothing MA Type";
            Input_SmoothingMAType.SetMovAvgType(MOVAVGTYPE_SIMPLE);

            Input_UseMovingAverage.Name = "Use Moving Average?";
            Input_UseMovingAverage.SetYesNo(0);

            Input_AverageDeMMALength.Name = "Average DeM MA Length";
            Input_AverageDeMMALength.SetInt(8);
            Input_AverageDeMMALength.SetIntLimits(1, MAX_STUDY_LENGTH);

            Input_AverageDeMMAType.Name = "Average DeM MA Type";
            Input_AverageDeMMAType.SetMovAvgType(MOVAVGTYPE_SIMPLE);

            Input_DurationLength.Name = "Duration Length";
            Input_DurationLength.SetInt(16);
            Input_DurationLength.SetIntLimits(1, MAX_STUDY_LENGTH);

            Input_OffsetPercentage.Name = "Arrow Offset Percentage";
            Input_OffsetPercentage.SetFloat(1.0f);

            Input_OverboughtLineValue.Name = "Overbought Line Value";
            Input_OverboughtLineValue.SetFloat(60.0f);

            Input_OversoldLineValue.Name = "Oversold Line Value";
            Input_OversoldLineValue.SetFloat(40.0f);

            return;
        }

        if (Input_UseSmoothing.GetYesNo() == 0 && Input_UseMovingAverage.GetYesNo() == 0)
            sc.DataStartIndex = Input_DeMLength1.GetInt() + Input_DeMLength2.GetInt() - 1;
        else if (Input_UseSmoothing.GetYesNo() == 1 && Input_UseMovingAverage.GetYesNo() == 0)
            sc.DataStartIndex = Input_DeMLength1.GetInt() + Input_DeMLength2.GetInt() + Input_SmoothingLength.GetInt() - 2;
        else if (Input_UseSmoothing.GetYesNo() == 0 && Input_UseMovingAverage.GetYesNo() == 1)
            sc.DataStartIndex = Input_DeMLength1.GetInt() + Input_DeMLength2.GetInt() + Input_AverageDeMMALength.GetInt() - 2;
        else
            sc.DataStartIndex = Input_DeMLength1.GetInt() + Input_DeMLength2.GetInt() + Input_SmoothingLength.GetInt() + Input_AverageDeMMALength.GetInt() - 3;

        if (sc.Index >= Input_DeMLength1.GetInt())
        {
            // Compute Max DeMarker I and Min Demarker I.
            float High = sc.BaseData[Input_InputDataHigh.GetInputDataIndex()][sc.Index];
            float PrevHigh = sc.BaseData[Input_InputDataHigh.GetInputDataIndex()][sc.Index - Input_DeMLength1.GetInt()];
            float Low = sc.BaseData[Input_InputDataLow.GetInputDataIndex()][sc.Index];
            float PrevLow = sc.BaseData[Input_InputDataLow.GetInputDataIndex()][sc.Index - Input_DeMLength1.GetInt()];

            if (High > PrevHigh)
                Subgraph_DeMaxI[sc.Index] = High - PrevHigh;

            if (Low < PrevLow)
                Subgraph_DeMinI[sc.Index] = PrevLow - Low;
        }

        if (sc.Index > 0)
        {
            // Compute DeM-I.
            float SumDeMaxI = 0.0f;
            float SumDeMinI = 0.0f;

            for (int Index = sc.Index - Input_DeMLength2.GetInt() + 1; Index <= sc.Index; Index++)
            {
                SumDeMaxI += Subgraph_DeMaxI[Index];
                SumDeMinI += Subgraph_DeMinI[Index];
            }

            if (SumDeMaxI + SumDeMinI != 0.0f)
                Array_Temp1[sc.Index] = 100.0f * SumDeMaxI / (SumDeMaxI + SumDeMinI);
            else
                Array_Temp1[sc.Index] = Array_Temp1[sc.Index - 1];
        }

        if (Input_UseSmoothing.GetYesNo() == 1)
            sc.MovingAverage(Array_Temp1, Array_Temp2, Input_SmoothingMAType.GetMovAvgType(), Input_SmoothingLength.GetInt());

        if (Input_UseSmoothing.GetYesNo() == 0 && Input_UseMovingAverage.GetYesNo() == 0)
            Subgraph_DeMI[sc.Index] = Array_Temp1[sc.Index];
        else if (Input_UseSmoothing.GetYesNo() == 1 && Input_UseMovingAverage.GetYesNo() == 0)
            Subgraph_DeMI[sc.Index] = Array_Temp2[sc.Index];
        else if (Input_UseSmoothing.GetYesNo() == 0 && Input_UseMovingAverage.GetYesNo() == 1)
            sc.MovingAverage(Array_Temp1, Subgraph_DeMI, Input_AverageDeMMAType.GetMovAvgType(), Input_AverageDeMMALength.GetInt());
        else
            sc.MovingAverage(Array_Temp2, Subgraph_DeMI, Input_AverageDeMMAType.GetMovAvgType(), Input_AverageDeMMALength.GetInt());

        Subgraph_DurationExceededOverbought[sc.Index] = 0.0f;
        Subgraph_DurationExceededOversold[sc.Index] = 0.0f;

        // Perform Duration Analysis.
        if (Subgraph_DeMI[sc.Index] > Input_OverboughtLineValue.GetFloat())
        {
            // Check beginning of chart.
            if (sc.Index == sc.DataStartIndex + Input_DurationLength.GetInt() - 1)
            {
                int OverboughtSum = 1;

                for (int Index = sc.Index - Input_DurationLength.GetInt() + 1; Index <= sc.Index - 1; Index++)
                {
                    if (Subgraph_DeMI[Index] > Input_OverboughtLineValue.GetFloat())
                        OverboughtSum += 1;
                }

                if (OverboughtSum == Input_DurationLength.GetInt())
                {
                    Subgraph_DurationExceededOverbought[sc.Index] =
                        Subgraph_DeMI[sc.Index] + (Input_OffsetPercentage.GetFloat() / 100.0f) *
                        Subgraph_DeMI[sc.Index];
                }
            }

            int OverboughtIndex = 1;

            while (Subgraph_DeMI[sc.Index - OverboughtIndex] > Input_OverboughtLineValue.GetFloat() && OverboughtIndex <= Input_DurationLength.GetInt())
                OverboughtIndex++;

            if (OverboughtIndex == Input_DurationLength.GetInt() && sc.Index >= sc.DataStartIndex + Input_DurationLength.GetInt() - 1)
            {
                Subgraph_DurationExceededOverbought[sc.Index] =
                    Subgraph_DeMI[sc.Index] + (Input_OffsetPercentage.GetFloat() / 100.0f) *
                    Subgraph_DeMI[sc.Index];
            }
        }

        if (Subgraph_DeMI[sc.Index] < Input_OversoldLineValue.GetFloat())
        {
            // Check beginning of chart.
            if (sc.Index == sc.DataStartIndex + Input_DurationLength.GetInt() - 1)
            {
                int OversoldSum = 1;

                for (int Index = sc.Index - Input_DurationLength.GetInt() + 1; Index <= sc.Index - 1; Index++)
                {
                    if (Subgraph_DeMI[Index] < Input_OversoldLineValue.GetFloat())
                        OversoldSum += 1;
                }

                if (OversoldSum == Input_DurationLength.GetInt())
                {
                    Subgraph_DurationExceededOversold[sc.Index] =
                        Subgraph_DeMI[sc.Index] - (Input_OffsetPercentage.GetFloat() / 100.0f) *
                        Subgraph_DeMI[sc.Index];
                    float MyNum = Subgraph_DurationExceededOversold[sc.Index];
                }
            }

            int OversoldIndex = 1;

            while (Subgraph_DeMI[sc.Index - OversoldIndex] < Input_OversoldLineValue.GetFloat() && OversoldIndex <= Input_DurationLength.GetInt())
                OversoldIndex++;

            if (OversoldIndex == Input_DurationLength.GetInt() && sc.Index >= sc.DataStartIndex + Input_DurationLength.GetInt() - 1)
            {
                Subgraph_DurationExceededOversold[sc.Index] =
                    Subgraph_DeMI[sc.Index] - (Input_OffsetPercentage.GetFloat() / 100.0f) *
                    Subgraph_DeMI[sc.Index];
            }

        }

        // Set horizontal lines.
        Subgraph_OverboughtLine[sc.Index] = Input_OverboughtLineValue.GetFloat();
        Subgraph_OversoldLine[sc.Index] = Input_OversoldLineValue.GetFloat();
    }

    /*==========================================================================*/
    SCSFExport scsf_DeMarkerOscillatorTypeII(SCStudyInterfaceRef sc)
    {
        SCSubgraphRef Subgraph_DeMaxII = sc.Subgraph[0];
        SCSubgraphRef Subgraph_DeMinII = sc.Subgraph[1];
        SCSubgraphRef Subgraph_DeMII = sc.Subgraph[2];
        SCSubgraphRef Subgraph_OverboughtLine = sc.Subgraph[3];
        SCSubgraphRef Subgraph_OversoldLine = sc.Subgraph[4];
        SCSubgraphRef Subgraph_DurationExceededOverbought = sc.Subgraph[5];
        SCSubgraphRef Subgraph_DurationExceededOversold = sc.Subgraph[6];

        SCFloatArrayRef Array_Temp1 = sc.Subgraph[2].Arrays[0];
        SCFloatArrayRef Array_Temp2 = sc.Subgraph[2].Arrays[1];

        SCInputRef Input_InputDataHigh = sc.Input[0];
        SCInputRef Input_InputDataLow = sc.Input[1];
        SCInputRef Input_InputDataClose = sc.Input[2];
        SCInputRef Input_DeMLength1 = sc.Input[3];
        SCInputRef Input_DeMLength2 = sc.Input[4];
        SCInputRef Input_UseSmoothing = sc.Input[5];
        SCInputRef Input_SmoothingLength = sc.Input[6];
        SCInputRef Input_SmoothingMAType = sc.Input[7];
        SCInputRef Input_UseMovingAverage = sc.Input[8];
        SCInputRef Input_AverageDeMMALength = sc.Input[9];
        SCInputRef Input_AverageDeMMAType = sc.Input[10];
        SCInputRef Input_DurationLength = sc.Input[11];
        SCInputRef Input_OffsetPercentage = sc.Input[12];
        SCInputRef Input_OverboughtLineValue = sc.Input[13];
        SCInputRef Input_OversoldLineValue = sc.Input[14];

        if (sc.SetDefaults)
        {
            sc.GraphName = "DeMarker Oscillator Type II";

            sc.AutoLoop = 1;

            Subgraph_DeMaxII.Name = "Max DeMarker II";
            Subgraph_DeMaxII.DrawStyle = DRAWSTYLE_IGNORE;

            Subgraph_DeMinII.Name = "Min DeMarker II";
            Subgraph_DeMinII.DrawStyle = DRAWSTYLE_IGNORE;

            Subgraph_DeMII.Name = "DeMarker II";
            Subgraph_DeMII.DrawStyle = DRAWSTYLE_LINE;
            Subgraph_DeMII.PrimaryColor = RGB(0, 0, 255);
            Subgraph_DeMII.DrawZeros = true;

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

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

            Subgraph_DurationExceededOverbought.Name = "Duration Exceeded in Overbought Area";
            Subgraph_DurationExceededOverbought.PrimaryColor = RGB(0, 255, 0);
            Subgraph_DurationExceededOverbought.DrawStyle = DRAWSTYLE_ARROW_DOWN;
            Subgraph_DurationExceededOverbought.LineWidth = 2;
            Subgraph_DurationExceededOverbought.DrawZeros = 0;

            Subgraph_DurationExceededOversold.Name = "Duration Exceeded in Oversold Area";
            Subgraph_DurationExceededOversold.PrimaryColor = RGB(255, 0, 0);
            Subgraph_DurationExceededOversold.DrawStyle = DRAWSTYLE_ARROW_UP;
            Subgraph_DurationExceededOversold.LineWidth = 2;
            Subgraph_DurationExceededOversold.DrawZeros = 0;

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

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

            Input_InputDataClose.Name = "Input Data Close";
            Input_InputDataClose.SetInputDataIndex(SC_LAST);

            Input_DeMLength2.Name = "DeM Length 2";
            Input_DeMLength2.SetInt(8);
            Input_DeMLength2.SetIntLimits(1, MAX_STUDY_LENGTH);

            Input_DeMLength1.Name = "DeM Length 1";
            Input_DeMLength1.SetInt(1);
            Input_DeMLength1.SetIntLimits(1, Input_DeMLength2.GetInt());

            Input_UseSmoothing.Name = "Use Smoothing?";
            Input_UseSmoothing.SetYesNo(0);

            Input_SmoothingLength.Name = "Smoothing Length";
            Input_SmoothingLength.SetInt(3);
            Input_SmoothingLength.SetIntLimits(1, Input_DeMLength2.GetInt());

            Input_SmoothingMAType.Name = "Smoothing MA Type";
            Input_SmoothingMAType.SetMovAvgType(MOVAVGTYPE_SIMPLE);

            Input_UseMovingAverage.Name = "Use Moving Average?";
            Input_UseMovingAverage.SetYesNo(0);

            Input_AverageDeMMALength.Name = "Average DeM MA Length";
            Input_AverageDeMMALength.SetInt(8);
            Input_AverageDeMMALength.SetIntLimits(1, MAX_STUDY_LENGTH);

            Input_AverageDeMMAType.Name = "Average DeM MA Type";
            Input_AverageDeMMAType.SetMovAvgType(MOVAVGTYPE_SIMPLE);

            Input_DurationLength.Name = "Duration Length";
            Input_DurationLength.SetInt(16);
            Input_DurationLength.SetIntLimits(1, MAX_STUDY_LENGTH);

            Input_OffsetPercentage.Name = "Arrow Offset Percentage";
            Input_OffsetPercentage.SetFloat(1.0f);

            Input_OverboughtLineValue.Name = "Overbought Line Value";
            Input_OverboughtLineValue.SetFloat(60.0f);

            Input_OversoldLineValue.Name = "Oversold Line Value";
            Input_OversoldLineValue.SetFloat(40.0f);

            return;
        }

        if (Input_UseSmoothing.GetYesNo() == 0 && Input_UseMovingAverage.GetYesNo() == 0)
            sc.DataStartIndex = Input_DeMLength1.GetInt() + Input_DeMLength2.GetInt() - 1;
        else if (Input_UseSmoothing.GetYesNo() == 1 && Input_UseMovingAverage.GetYesNo() == 0)
            sc.DataStartIndex = Input_DeMLength1.GetInt() + Input_DeMLength2.GetInt() + Input_SmoothingLength.GetInt() - 2;
        else if (Input_UseSmoothing.GetYesNo() == 0 && Input_UseMovingAverage.GetYesNo() == 1)
            sc.DataStartIndex = Input_DeMLength1.GetInt() + Input_DeMLength2.GetInt() + Input_AverageDeMMALength.GetInt() - 2;
        else
            sc.DataStartIndex = Input_DeMLength1.GetInt() + Input_DeMLength2.GetInt() + Input_SmoothingLength.GetInt() + Input_AverageDeMMALength.GetInt() - 3;

        if (sc.Index >= Input_DeMLength1.GetInt())
        {
            // Compute Max DeMarker II and Min Demarker II.
            float High = sc.BaseData[Input_InputDataHigh.GetInputDataIndex()][sc.Index];
            float Low = sc.BaseData[Input_InputDataLow.GetInputDataIndex()][sc.Index];
            float Close = sc.BaseData[Input_InputDataClose.GetInputDataIndex()][sc.Index];
            float PrevClose = sc.BaseData[Input_InputDataClose.GetInputDataIndex()][sc.Index - Input_DeMLength1.GetInt()];

            if (High - PrevClose + Close - Low > 0)
                Subgraph_DeMaxII[sc.Index] = High - PrevClose + Close - Low;

            if (PrevClose - Low + High - Close > 0)
                Subgraph_DeMinII[sc.Index] = PrevClose - Low + High - Close;
        }

        if (sc.Index > 0)
        {
            // Compute DeM-II.
            float SumDeMaxII = 0.0f;
            float SumDeMinII = 0.0f;

            for (int Index = sc.Index - Input_DeMLength2.GetInt() + 1; Index <= sc.Index; Index++)
            {
                SumDeMaxII += Subgraph_DeMaxII[Index];
                SumDeMinII += Subgraph_DeMinII[Index];
            }

            if (SumDeMaxII + SumDeMinII != 0.0f)
                Array_Temp1[sc.Index] = 100.0f * SumDeMaxII / (SumDeMaxII + SumDeMinII);
            else
                Array_Temp1[sc.Index] = Array_Temp1[sc.Index - 1];
        }

        if (Input_UseSmoothing.GetYesNo() == 1)
            sc.MovingAverage(Array_Temp1, Array_Temp2, Input_SmoothingMAType.GetMovAvgType(), Input_SmoothingLength.GetInt());

        if (Input_UseSmoothing.GetYesNo() == 0 && Input_UseMovingAverage.GetYesNo() == 0)
            Subgraph_DeMII[sc.Index] = Array_Temp1[sc.Index];
        else if (Input_UseSmoothing.GetYesNo() == 1 && Input_UseMovingAverage.GetYesNo() == 0)
            Subgraph_DeMII[sc.Index] = Array_Temp2[sc.Index];
        else if (Input_UseSmoothing.GetYesNo() == 0 && Input_UseMovingAverage.GetYesNo() == 1)
            sc.MovingAverage(Array_Temp1, Subgraph_DeMII, Input_AverageDeMMAType.GetMovAvgType(), Input_AverageDeMMALength.GetInt());
        else
            sc.MovingAverage(Array_Temp2, Subgraph_DeMII, Input_AverageDeMMAType.GetMovAvgType(), Input_AverageDeMMALength.GetInt());

        Subgraph_DurationExceededOverbought[sc.Index] = 0.0f;
        Subgraph_DurationExceededOversold[sc.Index] = 0.0f;

        // Perform Duration Analysis.
        if (Subgraph_DeMII[sc.Index] > Input_OverboughtLineValue.GetFloat())
        {
            // Check beginning of chart.
            if (sc.Index == sc.DataStartIndex + Input_DurationLength.GetInt() - 1)
            {
                int OverboughtSum = 1;

                for (int Index = sc.Index - Input_DurationLength.GetInt() + 1; Index <= sc.Index - 1; Index++)
                {
                    if (Subgraph_DeMII[Index] > Input_OverboughtLineValue.GetFloat())
                        OverboughtSum += 1;
                }

                if (OverboughtSum == Input_DurationLength.GetInt())
                {
                    Subgraph_DurationExceededOverbought[sc.Index] =
                        Subgraph_DeMII[sc.Index] + (Input_OffsetPercentage.GetFloat() / 100.0f) *
                        Subgraph_DeMII[sc.Index];
                }
            }

            int OverboughtIndex = 1;

            while (Subgraph_DeMII[sc.Index - OverboughtIndex] > Input_OverboughtLineValue.GetFloat() && OverboughtIndex <= Input_DurationLength.GetInt())
                OverboughtIndex++;

            if (OverboughtIndex == Input_DurationLength.GetInt() && sc.Index >= sc.DataStartIndex + Input_DurationLength.GetInt() - 1)
            {
                Subgraph_DurationExceededOverbought[sc.Index] =
                    Subgraph_DeMII[sc.Index] + (Input_OffsetPercentage.GetFloat() / 100.0f) *
                    Subgraph_DeMII[sc.Index];
            }
        }

        if (Subgraph_DeMII[sc.Index] < Input_OversoldLineValue.GetFloat())
        {
            // Check beginning of chart.
            if (sc.Index == sc.DataStartIndex + Input_DurationLength.GetInt() - 1)
            {
                int OversoldSum = 1;

                for (int Index = sc.Index - Input_DurationLength.GetInt() + 1; Index <= sc.Index - 1; Index++)
                {
                    if (Subgraph_DeMII[Index] < Input_OversoldLineValue.GetFloat())
                        OversoldSum += 1;
                }

                if (OversoldSum == Input_DurationLength.GetInt())
                {
                    Subgraph_DurationExceededOversold[sc.Index] =
                        Subgraph_DeMII[sc.Index] - (Input_OffsetPercentage.GetFloat() / 100.0f) *
                        Subgraph_DeMII[sc.Index];
                }
            }
            int OversoldIndex = 1;

            while (Subgraph_DeMII[sc.Index - OversoldIndex] < Input_OversoldLineValue.GetFloat() && OversoldIndex <= Input_DurationLength.GetInt())
                OversoldIndex++;

            if (OversoldIndex == Input_DurationLength.GetInt() && sc.Index >= sc.DataStartIndex + Input_DurationLength.GetInt() - 1)
            {
                Subgraph_DurationExceededOversold[sc.Index] =
                    Subgraph_DeMII[sc.Index] - (Input_OffsetPercentage.GetFloat() / 100.0f) *
                    Subgraph_DeMII[sc.Index];
            }
        }

        // Set horizontal lines.
        Subgraph_OverboughtLine[sc.Index] = Input_OverboughtLineValue.GetFloat();
        Subgraph_OversoldLine[sc.Index] = Input_OversoldLineValue.GetFloat();
    }

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

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

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

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

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

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

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

            return;
        }

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

        sc.ExponentialRegressionIndicator(sc.BaseDataIn[Input_InputData.GetInputDataIndex()], Subgraph_ERMA, sc.Index, Input_Length.GetInt());
    }

    /*==========================================================================*/
    SCSFExport scsf_InstantaneousTrendline(SCStudyInterfaceRef sc)
    {
        SCSubgraphRef Subgraph_IT = sc.Subgraph[0];
        SCSubgraphRef Subgraph_Trigger = sc.Subgraph[1];

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

        if (sc.SetDefaults)
        {
            sc.GraphName = "Instantaneous Trendline";

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

            Subgraph_IT.Name = "Instantaneous Trendline";
            Subgraph_IT.DrawStyle = DRAWSTYLE_LINE;
            Subgraph_IT.PrimaryColor = RGB(0, 255, 0);
            Subgraph_IT.LineWidth = 1;
            Subgraph_IT.DrawZeros = true;

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

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

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

            return;
        }

        sc.InstantaneousTrendline(sc.BaseDataIn[Input_InputData.GetInputDataIndex()], Subgraph_IT, sc.Index, Input_Length.GetInt());

        Subgraph_Trigger[sc.Index] = 2.0f * Subgraph_IT[sc.Index] - Subgraph_IT[sc.Index - 2];
    }

    /*==========================================================================*/
    SCSFExport scsf_CyberCycle(SCStudyInterfaceRef sc)
    {
        SCSubgraphRef Subgraph_CC = sc.Subgraph[0];
        SCSubgraphRef Subgraph_Trigger = sc.Subgraph[1];
        SCSubgraphRef Subgraph_CenterLine = sc.Subgraph[2];

        SCFloatArrayRef Array_SmoothedData = sc.Subgraph[0].Arrays[0];

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

        if (sc.SetDefaults)
        {
            sc.GraphName = "Cyber Cycle";

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

            Subgraph_CC.Name = "Cyber Cycle";
            Subgraph_CC.DrawStyle = DRAWSTYLE_LINE;
            Subgraph_CC.PrimaryColor = RGB(0, 255, 0);
            Subgraph_CC.LineWidth = 1;
            Subgraph_CC.DrawZeros = true;

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

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

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

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

            Input_Lag.Name = "Lag";
            Input_Lag.SetInt(9);
            Input_Lag.SetIntLimits(1, MAX_STUDY_LENGTH);

            return;
        }

        sc.FourBarSymmetricalFIRFilter(sc.BaseDataIn[Input_InputData.GetInputDataIndex()], Array_SmoothedData, sc.Index);

        sc.CyberCycle(sc.BaseDataIn[Input_InputData.GetInputDataIndex()], Array_SmoothedData, Subgraph_CC, sc.Index, Input_Length.GetInt());

        float lag = static_cast<float>(Input_Lag.GetInt());
        float b = 1 / (lag + 1);

        Subgraph_Trigger[sc.Index] = b * Subgraph_CC[sc.Index] + (1 - b) * Subgraph_Trigger[sc.Index - 1];

        Subgraph_CenterLine[sc.Index] = 0.0f;
    }
    /*==========================================================================*/
    SCSFExport scsf_StochasticCyberCycle(SCStudyInterfaceRef sc)
    {
        SCSubgraphRef Subgraph_CC = sc.Subgraph[0];
        SCSubgraphRef Subgraph_SCC = sc.Subgraph[1];
        SCSubgraphRef Subgraph_Trigger = sc.Subgraph[2];
        SCSubgraphRef Subgraph_CenterLine = sc.Subgraph[3];

        SCFloatArrayRef Array_SmoothedData = sc.Subgraph[0].Arrays[0];
        SCFloatArrayRef Array_Ratio = sc.Subgraph[0].Arrays[1];

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

        if (sc.SetDefaults)
        {
            sc.GraphName = "Stochastic Cyber Cycle";

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

            Subgraph_CC.Name = "Cyber Cycle";
            Subgraph_CC.DrawStyle = DRAWSTYLE_IGNORE;

            Subgraph_SCC.Name = "Stochastic Cyber Cycle";
            Subgraph_SCC.DrawStyle = DRAWSTYLE_LINE;
            Subgraph_SCC.PrimaryColor = RGB(0, 255, 0);
            Subgraph_SCC.LineWidth = 1;
            Subgraph_SCC.DrawZeros = true;

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

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

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

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

            return;
        }

        //Compute Cyber Cycle
        sc.FourBarSymmetricalFIRFilter(sc.BaseDataIn[Input_InputData.GetInputDataIndex()], Array_SmoothedData, sc.Index);

        sc.CyberCycle(sc.BaseDataIn[Input_InputData.GetInputDataIndex()], Array_SmoothedData, Subgraph_CC, sc.Index, Input_Length.GetInt());

        // Compute Stochastic Cyber Cycle
        float MaxCC = sc.GetHighest(Subgraph_CC, sc.Index, Input_Length.GetInt());
        float MinCC = sc.GetLowest(Subgraph_CC, sc.Index, Input_Length.GetInt());

        if (MaxCC - MinCC != 0.0f)
            Array_Ratio[sc.Index] = (Subgraph_CC[sc.Index] - MinCC) / (MaxCC - MinCC);
        else
            Array_Ratio[sc.Index] = 0.0f;

        float SmoothedRatio = (4.0f * Array_Ratio[sc.Index] + 3.0f * Array_Ratio[sc.Index - 1] + 2.0f * Array_Ratio[sc.Index - 2] + Array_Ratio[sc.Index - 3]) / 10.0f;

        Subgraph_SCC[sc.Index] = 2.0f * (SmoothedRatio - 0.5f);

        Subgraph_Trigger[sc.Index] = 0.96f * (Subgraph_SCC[sc.Index - 1] + 0.02f);

        Subgraph_CenterLine[sc.Index] = 0.0f;
    }
    /*==========================================================================*/
    SCSFExport scsf_FisherCyberCycle(SCStudyInterfaceRef sc)
    {
        SCSubgraphRef Subgraph_CC = sc.Subgraph[0];
        SCSubgraphRef Subgraph_SCC = sc.Subgraph[1];
        SCSubgraphRef Subgraph_FCC = sc.Subgraph[2];
        SCSubgraphRef Subgraph_Trigger = sc.Subgraph[3];
        SCSubgraphRef Subgraph_CenterLine = sc.Subgraph[4];

        SCFloatArrayRef Array_SmoothedData = sc.Subgraph[0].Arrays[0];
        SCFloatArrayRef Array_Ratio = sc.Subgraph[0].Arrays[1];

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

        if (sc.SetDefaults)
        {
            sc.GraphName = "Fisher Cyber Cycle";

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

            Subgraph_CC.Name = "Cyber Cycle";
            Subgraph_CC.DrawStyle = DRAWSTYLE_IGNORE;

            Subgraph_SCC.Name = "Stochastic Cyber Cycle";
            Subgraph_SCC.DrawStyle = DRAWSTYLE_IGNORE;

            Subgraph_FCC.Name = "Fisher Cyber Cycle";
            Subgraph_FCC.DrawStyle = DRAWSTYLE_LINE;
            Subgraph_FCC.PrimaryColor = RGB(0, 255, 0);
            Subgraph_FCC.LineWidth = 1;
            Subgraph_FCC.DrawZeros = true;

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

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

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

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

            Input_UseAbsoluteValueWhenLogArgumentIsZero.Name = "Use Absolute Value When Log Argument Is Zero";
            Input_UseAbsoluteValueWhenLogArgumentIsZero.SetYesNo(true);

            return;
        }

        // Compute Cyber Cycle
        sc.FourBarSymmetricalFIRFilter(sc.BaseDataIn[Input_InputData.GetInputDataIndex()], Array_SmoothedData, sc.Index);

        sc.CyberCycle(sc.BaseDataIn[Input_InputData.GetInputDataIndex()], Array_SmoothedData, Subgraph_CC, sc.Index, Input_Length.GetInt());

        // Compute Stochastic Cyber Cycle
        float MaxCC = sc.GetHighest(Subgraph_CC, sc.Index, Input_Length.GetInt());
        float MinCC = sc.GetLowest(Subgraph_CC, sc.Index, Input_Length.GetInt());

        if (MaxCC - MinCC != 0.0f)
            Array_Ratio[sc.Index] = (Subgraph_CC[sc.Index] - MinCC) / (MaxCC - MinCC);
        else
            Array_Ratio[sc.Index] = 0.0f;

        float SmoothedRatio = (4.0f * Array_Ratio[sc.Index] + 3.0f * Array_Ratio[sc.Index - 1] + 2.0f * Array_Ratio[sc.Index - 2] + Array_Ratio[sc.Index - 3]) / 10.0f;

        Subgraph_SCC[sc.Index] = 2.0f * (SmoothedRatio - 0.5f);

        // Compute Fisher Cyber Cycle
        float LogArgument = (1 + 1.98f * (Subgraph_SCC[sc.Index] - 0.5f)) / (1 - 1.98f * (Subgraph_SCC[sc.Index] - 0.5f));
        float LogArgumentDenom = 1 - 1.98f * (Subgraph_SCC[sc.Index] - 0.5f);

        const int SelectedIndex = Input_UseAbsoluteValueWhenLogArgumentIsZero.GetYesNo();

        switch (SelectedIndex)
        {
        case 0:
        {
            if (LogArgument > 0.0f && LogArgumentDenom != 0.0f)
                Subgraph_FCC[sc.Index] = 0.5f * logf(LogArgument);
            else
                Subgraph_FCC[sc.Index] = 0.0f;
        }
        break;

        case 1:
        {
            if (LogArgument != 0.0f && LogArgumentDenom != 0.0f)
            {
                Subgraph_FCC[sc.Index] = 0.5f * logf(fabs(LogArgument));
            }
            else
                Subgraph_FCC[sc.Index] = 0.0f;
        }
        break;
        }

        Subgraph_Trigger[sc.Index] = Subgraph_FCC[sc.Index - 1];

        Subgraph_CenterLine[sc.Index] = 0.0f;
    }

    /*==========================================================================*/
    SCSFExport scsf_CGOscillator(SCStudyInterfaceRef sc)
    {
        SCSubgraphRef Subgraph_CG = sc.Subgraph[0];
        SCSubgraphRef Subgraph_Trigger = sc.Subgraph[1];
        SCSubgraphRef Subgraph_CenterLine = sc.Subgraph[2];

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

        if (sc.SetDefaults)
        {
            sc.GraphName = "Center of Gravity Oscillator";

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

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

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

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

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

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

            return;
        }

        float Num = 0;
        float Den = 0;

        for (int j = 0; j < Input_Length.GetInt(); j++)
        {
            Num += (1 + j) * sc.BaseDataIn[Input_InputData.GetInputDataIndex()][sc.Index - j];
            Den += sc.BaseDataIn[Input_InputData.GetInputDataIndex()][sc.Index - j];
        }

        float Length = static_cast<float>(Input_Length.GetInt());

        if (Den != 0.0f)
            Subgraph_CG[sc.Index] = -1.0f * Num / Den + (Length + 1.0f) / 2.0f;
        else
            Subgraph_CG[sc.Index] = 0.0f;

        Subgraph_Trigger[sc.Index] = Subgraph_CG[sc.Index - 1];

        Subgraph_CenterLine[sc.Index] = 0.0f;
    }

    /*==========================================================================*/
    SCSFExport scsf_StochasticCGOscillator(SCStudyInterfaceRef sc)
    {
        SCSubgraphRef Subgraph_CG = sc.Subgraph[0];
        SCSubgraphRef Subgraph_SCG = sc.Subgraph[1];
        SCSubgraphRef Subgraph_Trigger = sc.Subgraph[2];
        SCSubgraphRef Subgraph_CenterLine = sc.Subgraph[3];

        SCFloatArrayRef Array_Ratio = sc.Subgraph[0].Arrays[0];

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

        if (sc.SetDefaults)
        {
            sc.GraphName = "Stochastic Center of Gravity Oscillator";

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

            Subgraph_CG.Name = "CG";
            Subgraph_CG.DrawStyle = DRAWSTYLE_IGNORE;

            Subgraph_SCG.Name = "Stoch CG";
            Subgraph_SCG.DrawStyle = DRAWSTYLE_LINE;
            Subgraph_SCG.PrimaryColor = RGB(0, 255, 0);
            Subgraph_SCG.LineWidth = 1;
            Subgraph_SCG.DrawZeros = true;

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

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

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

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

            return;
        }

        // Compute Center of Gravity Oscillator

        float Num = 0;
        float Den = 0;

        for (int j = 0; j < Input_Length.GetInt(); j++)
        {
            Num += (1.0f + j) * sc.BaseDataIn[Input_InputData.GetInputDataIndex()][sc.Index - j];
            Den += sc.BaseDataIn[Input_InputData.GetInputDataIndex()][sc.Index - j];
        }

        float Length = static_cast<float>(Input_Length.GetInt());

        if (Den != 0.0f)
            Subgraph_CG[sc.Index] = -1.0f * Num / Den + (Length + 1.0f) / 2.0f;
        else
            Subgraph_CG[sc.Index] = 0.0f;

        // Compute Stochastic Center of Gravity Oscillator
        float MaxCG = sc.GetHighest(Subgraph_CG, sc.Index, Input_Length.GetInt());
        float MinCG = sc.GetLowest(Subgraph_CG, sc.Index, Input_Length.GetInt());

        if (MaxCG - MinCG != 0.0f)
            Array_Ratio[sc.Index] = (Subgraph_CG[sc.Index] - MinCG) / (MaxCG - MinCG);
        else
            Array_Ratio[sc.Index] = 0.0f;

        float SmoothedRatio = (4.0f * Array_Ratio[sc.Index] + 3.0f * Array_Ratio[sc.Index - 1] + 2.0f * Array_Ratio[sc.Index - 2] + Array_Ratio[sc.Index - 3]) / 10.0f;

        Subgraph_SCG[sc.Index] = 2.0f * (SmoothedRatio - 0.5f);

        Subgraph_Trigger[sc.Index] = 0.96f * (Subgraph_SCG[sc.Index - 1] + 0.02f);

        Subgraph_CenterLine[sc.Index] = 0.0f;
    }

    /*==========================================================================*/
    SCSFExport scsf_FisherCGOscillator(SCStudyInterfaceRef sc)
    {
        SCSubgraphRef Subgraph_CG = sc.Subgraph[0];
        SCSubgraphRef Subgraph_SCG = sc.Subgraph[1];
        SCSubgraphRef Subgraph_FCG = sc.Subgraph[2];
        SCSubgraphRef Subgraph_Trigger = sc.Subgraph[3];
        SCSubgraphRef Subgraph_CenterLine = sc.Subgraph[4];

        SCFloatArrayRef Array_Ratio = sc.Subgraph[0].Arrays[0];

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

        if (sc.SetDefaults)
        {
            sc.GraphName = "Fisher Center of Gravity Oscillator";

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

            Subgraph_CG.Name = "CG";
            Subgraph_CG.DrawStyle = DRAWSTYLE_IGNORE;

            Subgraph_SCG.Name = "Stoch CG";
            Subgraph_SCG.DrawStyle = DRAWSTYLE_IGNORE;

            Subgraph_FCG.Name = "Fisher CG";
            Subgraph_FCG.DrawStyle = DRAWSTYLE_LINE;
            Subgraph_FCG.PrimaryColor = RGB(0, 255, 0);
            Subgraph_FCG.LineWidth = 1;
            Subgraph_FCG.DrawZeros = true;

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

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

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

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

            Input_UseAbsoluteValueWhenLogArgumentIsZero.Name = "Use Absolute Value When Log Argument Is Zero";
            Input_UseAbsoluteValueWhenLogArgumentIsZero.SetYesNo(true);

            return;
        }

        // Compute Center of Gravity Oscillator
        float Num = 0;
        float Den = 0;

        for (int j = 0; j < Input_Length.GetInt(); j++)
        {
            Num += (1.0f + j) * sc.BaseDataIn[Input_InputData.GetInputDataIndex()][sc.Index - j];
            Den += sc.BaseDataIn[Input_InputData.GetInputDataIndex()][sc.Index - j];
        }

        float Length = static_cast<float>(Input_Length.GetInt());

        if (Den != 0.0f)
            Subgraph_CG[sc.Index] = -1.0f * Num / Den + (Length + 1.0f) / 2.0f;
        else
            Subgraph_CG[sc.Index] = 0.0f;

        // Compute Stochastic Center of Gravity Oscillator
        float MaxCG = sc.GetHighest(Subgraph_CG, sc.Index, Input_Length.GetInt());
        float MinCG = sc.GetLowest(Subgraph_CG, sc.Index, Input_Length.GetInt());

        if (MaxCG - MinCG != 0.0f)
            Array_Ratio[sc.Index] = (Subgraph_CG[sc.Index] - MinCG) / (MaxCG - MinCG);
        else
            Array_Ratio[sc.Index] = 0.0f;

        float SmoothedRatio = (4.0f * Array_Ratio[sc.Index] + 3.0f * Array_Ratio[sc.Index - 1] + 2.0f * Array_Ratio[sc.Index - 2] + Array_Ratio[sc.Index - 3]) / 10.0f;

        Subgraph_SCG[sc.Index] = 2.0f * (SmoothedRatio - 0.5f);

        // Compute Fisher Center of Gravity Oscillator
        float LogArgument = (1 + 1.98f * (Subgraph_SCG[sc.Index] - 0.5f)) / (1 - 1.98f * (Subgraph_SCG[sc.Index] - 0.5f));
        float LogArgumentDenom = 1 - 1.98f * (Subgraph_SCG[sc.Index] - 0.5f);

        const int SelectedIndex = Input_UseAbsoluteValueWhenLogArgumentIsZero.GetYesNo();

        switch (SelectedIndex)
        {
        case 0:
        {
            if (LogArgument > 0.0f && LogArgumentDenom != 0.0f)
                Subgraph_FCG[sc.Index] = 0.5f * logf(LogArgument);
            else
                Subgraph_FCG[sc.Index] = 0.0f;
        }
        break;

        case 1:
        {
            if (LogArgument != 0.0f && LogArgumentDenom != 0.0f)
            {
                Subgraph_FCG[sc.Index] = 0.5f * logf(fabs(LogArgument));
            }
            else
                Subgraph_FCG[sc.Index] = 0.0f;
        }
        break;
        }

        Subgraph_Trigger[sc.Index] = Subgraph_FCG[sc.Index - 1];

        Subgraph_CenterLine[sc.Index] = 0.0f;
    }
    /*==========================================================================*/
    SCSFExport scsf_RelativeVigorIndex3(SCStudyInterfaceRef sc)
    {
        SCSubgraphRef Subgraph_RVI = sc.Subgraph[0];
        SCSubgraphRef Subgraph_Trigger = sc.Subgraph[1];
        SCSubgraphRef Subgraph_Centerline = sc.Subgraph[2];

        SCFloatArrayRef Array_CloseOpenAvg = Subgraph_RVI.Arrays[0];
        SCFloatArrayRef Array_HighLowAvg = Subgraph_RVI.Arrays[1];
        SCFloatArrayRef Array_SmoothedRVINumerator = Subgraph_RVI.Arrays[2];
        SCFloatArrayRef Array_SmoothedRVIDenominator = Subgraph_RVI.Arrays[3];

        SCInputRef   Input_Length = sc.Input[0];

        if (sc.SetDefaults)
        {
            sc.GraphName = "Relative Vigor Index 3";

            sc.AutoLoop = 1;

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

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

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

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

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

            return;
        }

        Array_CloseOpenAvg[sc.Index] = ((sc.Close[sc.Index - 3] - sc.Open[sc.Index - 3]) + 2 * (sc.Close[sc.Index - 2] - sc.Open[sc.Index - 2]) + 2 * (sc.Close[sc.Index - 1] - sc.Open[sc.Index - 1]) + (sc.Close[sc.Index] - sc.Open[sc.Index])) / 6;

        Array_HighLowAvg[sc.Index] = ((sc.High[sc.Index - 3] - sc.Low[sc.Index - 3]) + 2 * (sc.High[sc.Index - 2] - sc.Low[sc.Index - 2]) + 2 * (sc.High[sc.Index - 1] - sc.Low[sc.Index - 1]) + (sc.High[sc.Index] - sc.Low[sc.Index])) / 6;

        float Numerator = 0.0f;
        float Denominator = 0.0f;

        for (int i = 0; i < Input_Length.GetInt(); i++)
        {
            Numerator += Array_CloseOpenAvg[sc.Index - i];
            Denominator += Array_HighLowAvg[sc.Index - i];
        }

        if (Denominator != 0)
            Subgraph_RVI[sc.Index] = Numerator / Denominator;
        else
            Subgraph_RVI[sc.Index] = 0.0f;

        Subgraph_Trigger[sc.Index] = Subgraph_RVI[sc.Index - 1];

        Subgraph_Centerline[sc.Index] = 0.0f;
    }

    /*==========================================================================*/
    SCSFExport scsf_StochasticRelativeVigorIndex3(SCStudyInterfaceRef sc)
    {
        SCSubgraphRef Subgraph_RVI = sc.Subgraph[0];
        SCSubgraphRef Subgraph_SRVI = sc.Subgraph[1];
        SCSubgraphRef Subgraph_Trigger = sc.Subgraph[2];
        SCSubgraphRef Subgraph_Centerline = sc.Subgraph[3];

        SCFloatArrayRef Array_CloseOpenAvg = Subgraph_RVI.Arrays[0];
        SCFloatArrayRef Array_HighLowAvg = Subgraph_RVI.Arrays[1];
        SCFloatArrayRef Array_SmoothedRVINumerator = Subgraph_RVI.Arrays[2];
        SCFloatArrayRef Array_SmoothedRVIDenominator = Subgraph_RVI.Arrays[3];
        SCFloatArrayRef Array_Ratio = Subgraph_RVI.Arrays[4];

        SCInputRef   Input_Length = sc.Input[0];

        if (sc.SetDefaults)
        {
            sc.GraphName = "Stochastic Relative Vigor Index 3";

            sc.AutoLoop = 1;

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

            Subgraph_RVI.Name = "RVI";
            Subgraph_RVI.DrawStyle = DRAWSTYLE_IGNORE;

            Subgraph_SRVI.Name = "Stochastic Relative Vigor Index 3";
            Subgraph_SRVI.DrawStyle = DRAWSTYLE_LINE;
            Subgraph_SRVI.PrimaryColor = RGB(0, 0, 255);
            Subgraph_SRVI.LineWidth = 1;
            Subgraph_SRVI.DrawZeros = true;

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

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

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

            return;
        }

        // Compute RVI
        Array_CloseOpenAvg[sc.Index] = ((sc.Close[sc.Index - 3] - sc.Open[sc.Index - 3]) + 2 * (sc.Close[sc.Index - 2] - sc.Open[sc.Index - 2]) + 2 * (sc.Close[sc.Index - 1] - sc.Open[sc.Index - 1]) + (sc.Close[sc.Index] - sc.Open[sc.Index])) / 6;

        Array_HighLowAvg[sc.Index] = ((sc.High[sc.Index - 3] - sc.Low[sc.Index - 3]) + 2 * (sc.High[sc.Index - 2] - sc.Low[sc.Index - 2]) + 2 * (sc.High[sc.Index - 1] - sc.Low[sc.Index - 1]) + (sc.High[sc.Index] - sc.Low[sc.Index])) / 6;

        float Numerator = 0.0f;
        float Denominator = 0.0f;

        for (int i = 0; i < Input_Length.GetInt(); i++)
        {
            Numerator += Array_CloseOpenAvg[sc.Index - i];
            Denominator += Array_HighLowAvg[sc.Index - i];
        }

        if (Denominator != 0)
            Subgraph_RVI[sc.Index] = Numerator / Denominator;
        else
            Subgraph_RVI[sc.Index] = 0.0f;

        // Compute Stochastic RVI
        float MaxRVI = sc.GetHighest(Subgraph_RVI, sc.Index, Input_Length.GetInt());
        float MinRVI = sc.GetLowest(Subgraph_RVI, sc.Index, Input_Length.GetInt());

        if (MaxRVI - MinRVI != 0.0f)
            Array_Ratio[sc.Index] = (Subgraph_RVI[sc.Index] - MinRVI) / (MaxRVI - MinRVI);
        else
            Array_Ratio[sc.Index] = 0.0f;

        float SmoothedRatio = (4.0f * Array_Ratio[sc.Index] + 3.0f * Array_Ratio[sc.Index - 1] + 2.0f * Array_Ratio[sc.Index - 2] + Array_Ratio[sc.Index - 3]) / 10.0f;

        Subgraph_SRVI[sc.Index] = 2.0f * (SmoothedRatio - 0.5f);

        Subgraph_Trigger[sc.Index] = 0.96f * (Subgraph_SRVI[sc.Index - 1] + 0.02f);

        Subgraph_Centerline[sc.Index] = 0.0f;
    }

    /*==========================================================================*/
    SCSFExport scsf_FisherRelativeVigorIndex3(SCStudyInterfaceRef sc)
    {
        SCSubgraphRef Subgraph_RVI = sc.Subgraph[0];
        SCSubgraphRef Subgraph_SRVI = sc.Subgraph[1];
        SCSubgraphRef Subgraph_FRVI = sc.Subgraph[2];
        SCSubgraphRef Subgraph_Trigger = sc.Subgraph[3];
        SCSubgraphRef Subgraph_Centerline = sc.Subgraph[4];

        SCFloatArrayRef Array_CloseOpenAvg = Subgraph_RVI.Arrays[0];
        SCFloatArrayRef Array_HighLowAvg = Subgraph_RVI.Arrays[1];
        SCFloatArrayRef Array_SmoothedRVINumerator = Subgraph_RVI.Arrays[2];
        SCFloatArrayRef Array_SmoothedRVIDenominator = Subgraph_RVI.Arrays[3];
        SCFloatArrayRef Array_Ratio = Subgraph_RVI.Arrays[4];

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

        if (sc.SetDefaults)
        {
            sc.GraphName = "Fisher Relative Vigor Index 3";

            sc.AutoLoop = 1;

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

            Subgraph_RVI.Name = "RVI";
            Subgraph_RVI.DrawStyle = DRAWSTYLE_IGNORE;

            Subgraph_SRVI.Name = "Stochastic Relative Vigor Index 3";
            Subgraph_SRVI.DrawStyle = DRAWSTYLE_IGNORE;

            Subgraph_FRVI.Name = "Fisher Relative Vigor Index 3";
            Subgraph_FRVI.DrawStyle = DRAWSTYLE_LINE;
            Subgraph_FRVI.PrimaryColor = RGB(0, 0, 255);
            Subgraph_FRVI.LineWidth = 1;
            Subgraph_FRVI.DrawZeros = true;

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

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

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

            Input_UseAbsoluteValueWhenLogArgumentIsZero.Name = "Use Absolute Value When Log Argument Is Zero";
            Input_UseAbsoluteValueWhenLogArgumentIsZero.SetYesNo(true);

            return;
        }

        // Compute RVI
        Array_CloseOpenAvg[sc.Index] = ((sc.Close[sc.Index - 3] - sc.Open[sc.Index - 3]) + 2 * (sc.Close[sc.Index - 2] - sc.Open[sc.Index - 2]) + 2 * (sc.Close[sc.Index - 1] - sc.Open[sc.Index - 1]) + (sc.Close[sc.Index] - sc.Open[sc.Index])) / 6;

        Array_HighLowAvg[sc.Index] = ((sc.High[sc.Index - 3] - sc.Low[sc.Index - 3]) + 2 * (sc.High[sc.Index - 2] - sc.Low[sc.Index - 2]) + 2 * (sc.High[sc.Index - 1] - sc.Low[sc.Index - 1]) + (sc.High[sc.Index] - sc.Low[sc.Index])) / 6;

        float Numerator = 0.0f;
        float Denominator = 0.0f;

        for (int i = 0; i < Input_Length.GetInt(); i++)
        {
            Numerator += Array_CloseOpenAvg[sc.Index - i];
            Denominator += Array_HighLowAvg[sc.Index - i];
        }

        if (Denominator != 0)
            Subgraph_RVI[sc.Index] = Numerator / Denominator;
        else
            Subgraph_RVI[sc.Index] = 0.0f;

        // Compute Stochastic RVI
        float MaxRVI = sc.GetHighest(Subgraph_RVI, sc.Index, Input_Length.GetInt());
        float MinRVI = sc.GetLowest(Subgraph_RVI, sc.Index, Input_Length.GetInt());

        if (MaxRVI - MinRVI != 0.0f)
            Array_Ratio[sc.Index] = (Subgraph_RVI[sc.Index] - MinRVI) / (MaxRVI - MinRVI);
        else
            Array_Ratio[sc.Index] = 0.0f;

        float SmoothedRatio = (4.0f * Array_Ratio[sc.Index] + 3.0f * Array_Ratio[sc.Index - 1] + 2.0f * Array_Ratio[sc.Index - 2] + Array_Ratio[sc.Index - 3]) / 10.0f;

        Subgraph_SRVI[sc.Index] = 2.0f * (SmoothedRatio - 0.5f);

        // Compute Fisher RVI
        float LogArgument = (1 + 1.98f * (Subgraph_SRVI[sc.Index] - 0.5f)) / (1 - 1.98f * (Subgraph_SRVI[sc.Index] - 0.5f));
        float LogArgumentDenom = 1 - 1.98f * (Subgraph_SRVI[sc.Index] - 0.5f);

        const int SelectedIndex = Input_UseAbsoluteValueWhenLogArgumentIsZero.GetYesNo();

        switch (SelectedIndex)
        {
        case 0:
        {
            if (LogArgument > 0.0f && LogArgumentDenom != 0.0f)
                Subgraph_FRVI[sc.Index] = 0.5f * log(LogArgument);
            else
                Subgraph_FRVI[sc.Index] = 0.0f;
        }
        break;

        case 1:
        {
            if (LogArgument != 0.0f && LogArgumentDenom != 0.0f)
            {
                Subgraph_FRVI[sc.Index] = 0.5f * log(fabs(LogArgument));
            }
            else
                Subgraph_FRVI[sc.Index] = 0.0f;
        }
        break;
        }

        Subgraph_Trigger[sc.Index] = Subgraph_FRVI[sc.Index - 1];

        Subgraph_Centerline[sc.Index] = 0.0f;
    }

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

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

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

            sc.AutoLoop = 1;

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

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

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

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

            return;
        }

        // Compute Direction
        float Direction = fabs(sc.BaseDataIn[Input_InputData.GetInputDataIndex()][sc.Index] - sc.BaseDataIn[Input_InputData.GetInputDataIndex()][sc.Index - Input_Length.GetInt()]);

        // Compute Volatility
        float Volatility = 0.0f;

        for (int i = 0; i < Input_Length.GetInt(); i++)
            Volatility += fabs(sc.BaseDataIn[Input_InputData.GetInputDataIndex()][sc.Index - i] - sc.BaseDataIn[Input_InputData.GetInputDataIndex()][sc.Index - i - 1]);

        // Compute KER
        if (Volatility == 0.0f)
            Subgraph_KER[sc.Index] = 0.0f;
        else
            Subgraph_KER[sc.Index] = Direction / Volatility;
    }

    /*==========================================================================*/
    SCSFExport scsf_StochasticFunction(SCStudyInterfaceRef sc)
    {
        SCSubgraphRef Subgraph_Stochastic = sc.Subgraph[0];
        SCSubgraphRef Subgraph_Trigger = sc.Subgraph[1];
        SCSubgraphRef Subgraph_CenterLine = sc.Subgraph[2];

        SCFloatArrayRef Array_Ratio = sc.Subgraph[0].Arrays[0];

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

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

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

            Subgraph_Stochastic.Name = "Stochastic Function";
            Subgraph_Stochastic.DrawStyle = DRAWSTYLE_LINE;
            Subgraph_Stochastic.PrimaryColor = RGB(0, 255, 0);
            Subgraph_Stochastic.LineWidth = 1;
            Subgraph_Stochastic.DrawZeros = true;

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

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

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

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

            return;
        }

        // Compute Stochastic Function
        float MaxOsc = sc.GetHighest(sc.BaseDataIn[Input_InputData.GetInputDataIndex()], sc.Index, Input_Length.GetInt());
        float MinOsc = sc.GetLowest(sc.BaseDataIn[Input_InputData.GetInputDataIndex()], sc.Index, Input_Length.GetInt());

        if (MaxOsc - MinOsc != 0.0f)
            Array_Ratio[sc.Index] = (sc.BaseDataIn[Input_InputData.GetInputDataIndex()][sc.Index] - MinOsc) / (MaxOsc - MinOsc);
        else
            Array_Ratio[sc.Index] = 0.0f;

        float SmoothedRatio = (4.0f * Array_Ratio[sc.Index] + 3.0f * Array_Ratio[sc.Index - 1] + 2.0f * Array_Ratio[sc.Index - 2] + Array_Ratio[sc.Index - 3]) / 10.0f;

        Subgraph_Stochastic[sc.Index] = 2.0f * (SmoothedRatio - 0.5f);

        Subgraph_Trigger[sc.Index] = 0.96f * (Subgraph_Stochastic[sc.Index - 1] + 0.02f);

        Subgraph_CenterLine[sc.Index] = 0.0f;
    }

    /*==========================================================================*/
    SCSFExport scsf_FisherFunction(SCStudyInterfaceRef sc)
    {
        SCSubgraphRef Subgraph_Stochastic = sc.Subgraph[0];
        SCSubgraphRef Subgraph_Fisher = sc.Subgraph[1];
        SCSubgraphRef Subgraph_Trigger = sc.Subgraph[2];
        SCSubgraphRef Subgraph_CenterLine = sc.Subgraph[3];

        SCFloatArrayRef Array_Ratio = sc.Subgraph[0].Arrays[0];

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

        if (sc.SetDefaults)
        {
            sc.GraphName = "Fisher Function";

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

            Subgraph_Stochastic.Name = "Stochastic Function";
            Subgraph_Stochastic.DrawStyle = DRAWSTYLE_IGNORE;

            Subgraph_Fisher.Name = "Fisher Function";
            Subgraph_Fisher.DrawStyle = DRAWSTYLE_LINE;
            Subgraph_Fisher.PrimaryColor = RGB(0, 255, 0);
            Subgraph_Fisher.LineWidth = 1;
            Subgraph_Fisher.DrawZeros = true;

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

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

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

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

            Input_UseAbsoluteValueWhenLogArgumentIsZero.Name = "Use Absolute Value When Log Argument Is Zero";
            Input_UseAbsoluteValueWhenLogArgumentIsZero.SetYesNo(true);

            return;
        }

        // Compute Stochastic Function
        float MaxOsc = sc.GetHighest(sc.BaseDataIn[Input_InputData.GetInputDataIndex()], sc.Index, Input_Length.GetInt());
        float MinOsc = sc.GetLowest(sc.BaseDataIn[Input_InputData.GetInputDataIndex()], sc.Index, Input_Length.GetInt());

        if (MaxOsc - MinOsc != 0.0f)
            Array_Ratio[sc.Index] = (sc.BaseDataIn[Input_InputData.GetInputDataIndex()][sc.Index] - MinOsc) / (MaxOsc - MinOsc);
        else
            Array_Ratio[sc.Index] = 0.0f;

        float SmoothedRatio = (4.0f * Array_Ratio[sc.Index] + 3.0f * Array_Ratio[sc.Index - 1] + 2.0f * Array_Ratio[sc.Index - 2] + Array_Ratio[sc.Index - 3]) / 10.0f;

        Subgraph_Stochastic[sc.Index] = 2.0f * (SmoothedRatio - 0.5f);

        // Compute Fisher Function
        float LogArgument = (1 + 1.98f * (Subgraph_Stochastic[sc.Index] - 0.5f)) / (1 - 1.98f * (Subgraph_Stochastic[sc.Index] - 0.5f));
        float LogArgumentDenom = 1 - 1.98f * (Subgraph_Stochastic[sc.Index] - 0.5f);

        const int SelectedIndex = Input_UseAbsoluteValueWhenLogArgumentIsZero.GetYesNo();

        switch (SelectedIndex)
        {
        case 0:
        {
            if (LogArgument > 0.0f && LogArgumentDenom != 0.0f)
                Subgraph_Fisher[sc.Index] = 0.5f * logf(LogArgument);
            else
                Subgraph_Fisher[sc.Index] = 0.0f;
        }
        break;

        case 1:
        {
            if (LogArgument != 0.0f && LogArgumentDenom != 0.0f)
            {
                Subgraph_Fisher[sc.Index] = 0.5f * logf(fabs(LogArgument));
            }
            else
                Subgraph_Fisher[sc.Index] = 0.0f;
        }
        break;
        }

        Subgraph_Trigger[sc.Index] = Subgraph_Fisher[sc.Index - 1];

        Subgraph_CenterLine[sc.Index] = 0.0f;
    }