#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(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(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(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(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(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(Subgraph_GapUpIndex[sc.Index]) - 1], sc.High[static_cast(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(Subgraph_GapUpIndex[sc.Index]); BarIndex < static_cast(Subgraph_GapDownIndex[sc.Index]); BarIndex++) { if (sc.Low[BarIndex] < GapLevel) AreBarsAboveGapLevel = 0; } if (AreBarsAboveGapLevel == 1) { Subgraph_IslandReversal[static_cast(Subgraph_GapUpIndex[sc.Index])] = GapLevel; Subgraph_IslandReversal[static_cast(Subgraph_GapDownIndex[sc.Index]) - 1] = GapLevel; } //Disallow single-bar islands if (Subgraph_GapUpIndex[sc.Index] == Subgraph_GapDownIndex[sc.Index] - 1) Subgraph_IslandReversal[static_cast(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(Subgraph_GapDownIndex[sc.Index]) - 1], sc.Low[static_cast(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(Subgraph_GapDownIndex[sc.Index]); BarIndex < static_cast(Subgraph_GapUpIndex[sc.Index]); BarIndex++) { if (sc.High[BarIndex] > GapLevel) AreBarsBelowGapLevel = 0; } if (AreBarsBelowGapLevel == 1) { Subgraph_IslandReversal[static_cast(Subgraph_GapUpIndex[sc.Index]) - 1] = GapLevel; Subgraph_IslandReversal[static_cast(Subgraph_GapDownIndex[sc.Index])] = GapLevel; } //Disallow single-bar islands if (Subgraph_GapDownIndex[sc.Index] == Subgraph_GapUpIndex[sc.Index] - 1) Subgraph_IslandReversal[static_cast(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(Input_Data.GetInputDataIndex())], Subgraph_Temp1, Input_SlowAvgLength.GetInt()); sc.WeightedMovingAverage(sc.BaseDataIn[static_cast(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(Input_Data.GetInputDataIndex())][sc.Index] - sc.BaseDataIn[static_cast(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(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(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(sc.NumberOfBarsSinceHighestValue(In, sc.Index, Input_HighestLength.GetInt())); Subgraph_Lowest[sc.Index] = static_cast(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(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(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(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(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(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(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(sc.RoundToTickSize(LowerBox, Input_RenkoBoxSize.GetFloat())); } else { LowerBox = Subgraph_RenkoLast[RenkoIndex]; UpperBox = LowerBox + Input_RenkoBoxSize.GetFloat(); UpperBox = static_cast(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(HigherPrice), ValueFormat, GREATER_EQUAL_OPERATOR, static_cast(UpperBox + Input_RenkoBoxSize.GetFloat()), ValueFormat)) { NewEntry = 1; UpperOrLowerTrend = 1; } else if (sc.FormattedEvaluateUsingDoubles(static_cast(LowerPrice), ValueFormat, LESS_EQUAL_OPERATOR, static_cast(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(sc.RoundToTickSize(UpperBox, Input_RenkoBoxSize.GetFloat())); NewLast = UpperBox; NewOtherBound = LowerBox; if (sc.FormattedEvaluateUsingDoubles(static_cast(HigherPrice), ValueFormat, GREATER_EQUAL_OPERATOR, static_cast(UpperBox + Input_RenkoBoxSize.GetFloat()), ValueFormat)) NewEntry = 1; } else { UpperBox = LowerBox; LowerBox -= Input_RenkoBoxSize.GetFloat(); LowerBox = static_cast(sc.RoundToTickSize(LowerBox, Input_RenkoBoxSize.GetFloat())); NewLast = LowerBox; NewOtherBound = UpperBox; if (sc.FormattedEvaluateUsingDoubles(static_cast(LowerPrice), ValueFormat, LESS_EQUAL_OPERATOR, static_cast(LowerBox - Input_RenkoBoxSize.GetFloat()), ValueFormat)) NewEntry = 1; } Subgraph_Low[NewBoxIndex] = LowerBox; Subgraph_High[NewBoxIndex] = UpperBox; Subgraph_RenkoLast[NewBoxIndex] = NewLast; Subgraph_RenkoUpDownTrend[NewBoxIndex] = static_cast(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(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(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(n),k); } if (n==0 || Input_Redraw.GetYesNo()) Subgraph_Fx[sc.Index-n] = static_cast(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(Subgraph_Fx[sc.Index-n]+sq1); Subgraph_Lower1[sc.Index-n] = static_cast(Subgraph_Fx[sc.Index-n]-sq1); Subgraph_Upper2[sc.Index-n] = static_cast(Subgraph_Fx[sc.Index-n]+sq2); Subgraph_Lower2[sc.Index-n] = static_cast(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(CHART_DRAWING_MAX_HORIZONTAL_AXIS_RELATIVE_POSITION)); Input_HorizontalPosition.SetInt(20); Input_HorizontalPosition.SetIntLimits(1, static_cast(CHART_DRAWING_MAX_HORIZONTAL_AXIS_RELATIVE_POSITION)); Input_VerticalPosition.Name.Format("Initial Vertical Position From Bottom (1-%d)", static_cast(CHART_DRAWING_MAX_VERTICAL_AXIS_RELATIVE_POSITION)); Input_VerticalPosition.SetInt(90); Input_VerticalPosition.SetIntLimits(1, static_cast(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(CHART_DRAWING_MAX_HORIZONTAL_AXIS_RELATIVE_POSITION)); Input_HorizontalPosition.SetInt(20); Input_HorizontalPosition.SetIntLimits(1, static_cast(CHART_DRAWING_MAX_HORIZONTAL_AXIS_RELATIVE_POSITION)); Input_VerticalPosition.Name.Format("Initial Vertical Position From Bottom (1-%d)", static_cast(CHART_DRAWING_MAX_VERTICAL_AXIS_RELATIVE_POSITION)); Input_VerticalPosition.SetInt(90); Input_VerticalPosition.SetIntLimits(1, static_cast(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(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(sc.GetBidMarketDepthStackPullValueAtPrice(sc.Bid)); Subgraph_AskPullingStacking[sc.ArraySize - 1] = static_cast(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(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(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(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(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; }