#include "sierrachart.h" #include "scstudyfunctions.h" /*==========================================================================*/ SCSFExport scsf_Accumulate(SCStudyInterfaceRef sc) { SCSubgraphRef Summation = sc.Subgraph[0]; SCInputRef InputData = sc.Input[0]; if(sc.SetDefaults) { sc.GraphName = "Summation"; sc.GraphRegion = 1; sc.ValueFormat = 2; Summation.Name = "Sum"; Summation.DrawStyle = DRAWSTYLE_LINE; Summation.PrimaryColor = RGB(0,255,0); InputData.Name = "Input Data"; InputData.SetInputDataIndex(SC_LAST); sc.AutoLoop = 1; return; } sc.CumulativeSummation(sc.BaseData[InputData.GetInputDataIndex()], 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 CMF = sc.Subgraph[0]; SCInputRef Length = sc.Input[3]; if(sc.SetDefaults) { sc.GraphName = "Chaikin Money Flow"; sc.GraphRegion = 1; sc.ValueFormat = 2; CMF.Name = "CMF"; CMF.DrawStyle = DRAWSTYLE_LINE; CMF.PrimaryColor = RGB(0,255,0); CMF.DrawZeros = false; Length.Name = "Length"; Length.SetInt(10); Length.SetIntLimits(1,MAX_STUDY_LENGTH); sc.AutoLoop = 1; return; } sc.ChaikinMoneyFlow(sc.BaseDataIn, CMF, Length.GetInt()); } /*==========================================================================*/ SCSFExport scsf_Dispersion(SCStudyInterfaceRef sc) { SCSubgraphRef Dispersion = sc.Subgraph[0]; SCInputRef InputData = sc.Input[0]; SCInputRef Length = sc.Input[3]; if(sc.SetDefaults) { sc.GraphName = "Dispersion"; sc.GraphRegion = 1; sc.ValueFormat = 2; Dispersion.Name = "Dispersion"; Dispersion.DrawStyle = DRAWSTYLE_LINE; Dispersion.PrimaryColor = RGB(0,255,0); Dispersion.DrawZeros = false; InputData.Name = "Input Data"; InputData.SetInputDataIndex(SC_LAST); Length.Name = "Length"; Length.SetInt(10); Length.SetIntLimits(1,MAX_STUDY_LENGTH); sc.AutoLoop = 1; return; } sc.Dispersion(sc.BaseDataIn[(int)InputData.GetInputDataIndex()], Dispersion, sc.Index, Length.GetInt()); } /*==========================================================================*/ SCSFExport scsf_Envelope(SCStudyInterfaceRef sc) { SCSubgraphRef TopBand = sc.Subgraph[0]; SCSubgraphRef BottomBand = sc.Subgraph[1]; SCInputRef InputData = sc.Input[0]; SCInputRef Value = sc.Input[3]; SCInputRef BandsType = sc.Input[4]; if(sc.SetDefaults) { sc.GraphName = "Bands/Envelope"; sc.GraphRegion = 0; sc.ValueFormat = VALUEFORMAT_INHERITED; TopBand.Name = "TopBand"; TopBand.DrawStyle = DRAWSTYLE_LINE; TopBand.PrimaryColor = RGB(0,255,0); TopBand.DrawZeros = false; BottomBand.Name = "BottomBand"; BottomBand.DrawStyle = DRAWSTYLE_LINE; BottomBand.PrimaryColor = RGB(255,0,255); BottomBand.DrawZeros = false; InputData.Name = "Input Data"; InputData.SetInputDataIndex(SC_LAST); Value.Name = "Percentage/Fixed Value/Ticks"; Value.SetFloat(0.05f); Value.SetFloatLimits(0.00001f,(float)MAX_STUDY_LENGTH); BandsType.Name = "Bands Type"; BandsType.SetCustomInputStrings("Percentage;Fixed Value;Number of Ticks"); BandsType.SetCustomInputIndex(0); sc.AutoLoop = 1; return; } SCFloatArrayRef In = sc.BaseDataIn[InputData.GetInputDataIndex()]; if(BandsType.GetIndex() == 0) { sc.EnvelopePct(In, TopBand, Value.GetFloat()); BottomBand[sc.Index] = TopBand.Arrays[0][sc.Index]; } else if(BandsType.GetIndex() == 1) { sc.EnvelopeFixed(In, TopBand, Value.GetFloat()); BottomBand[sc.Index] = TopBand.Arrays[0][sc.Index]; } else { sc.EnvelopeFixed(In, TopBand, Value.GetFloat() * sc.TickSize); BottomBand[sc.Index] = TopBand.Arrays[0][sc.Index]; } } /*==========================================================================*/ SCSFExport scsf_VerticalHorizontalFilter(SCStudyInterfaceRef sc) { SCSubgraphRef VHF = sc.Subgraph[0]; SCInputRef InputData = sc.Input[0]; SCInputRef Length = sc.Input[3]; if(sc.SetDefaults) { sc.GraphName = "Vertical Horizontal Filter"; sc.GraphRegion = 1; sc.ValueFormat = 2; VHF.Name = "VHF"; VHF.DrawStyle = DRAWSTYLE_LINE; VHF.PrimaryColor = RGB(0,255,0); VHF.DrawZeros = false; InputData.Name = "Input Data"; InputData.SetInputDataIndex(SC_LAST); Length.Name = "Length"; Length.SetInt(28); Length.SetIntLimits(1,MAX_STUDY_LENGTH); sc.AutoLoop = 1; return; } if(sc.Index < Length.GetInt()) return; SCFloatArrayRef In = sc.BaseDataIn[(int)InputData.GetInputDataIndex()]; sc.VHF(In, VHF, sc.Index, Length.GetInt()); } /*==========================================================================*/ SCSFExport scsf_RWI(SCStudyInterfaceRef sc) { SCSubgraphRef RWIHigh = sc.Subgraph[0]; SCSubgraphRef RWILow = sc.Subgraph[1]; SCSubgraphRef Temp2 = sc.Subgraph[2]; SCSubgraphRef Temp3 = sc.Subgraph[3]; SCSubgraphRef Temp4 = sc.Subgraph[4]; SCInputRef Length = sc.Input[3]; if(sc.SetDefaults) { sc.GraphName = "Random Walk Index"; sc.GraphRegion = 1; RWIHigh.Name = "RWI High"; RWIHigh.PrimaryColor = RGB(0,255,0); RWIHigh.DrawStyle = DRAWSTYLE_LINE; RWILow.Name = "RWI Low"; RWILow.PrimaryColor = RGB(255,0,255); RWILow.DrawStyle = DRAWSTYLE_LINE; Length.Name = "Length"; Length.SetInt(10); Length.SetIntLimits(1,MAX_STUDY_LENGTH); sc.AutoLoop = 1; return; } sc.DataStartIndex = Length.GetInt() - 1; sc.InternalRWI(sc.BaseDataIn, RWIHigh, RWILow, Temp2, Temp3, Temp4, sc.Index, Length.GetInt()); } /*==========================================================================*/ SCSFExport scsf_UltimateOscillator(SCStudyInterfaceRef sc) { SCSubgraphRef UltimateOscillatorOut1 = sc.Subgraph[0]; SCSubgraphRef UltimateOscillatorOut2 = sc.Subgraph[1]; SCInputRef Length1 = sc.Input[3]; SCInputRef Length2 = sc.Input[4]; SCInputRef Length3 = sc.Input[5]; if(sc.SetDefaults) { sc.GraphName = "Ultimate Oscillator"; sc.GraphRegion = 1; sc.ValueFormat = 2; UltimateOscillatorOut1.Name = "UO"; UltimateOscillatorOut1.DrawZeros = false; UltimateOscillatorOut1.DrawStyle = DRAWSTYLE_LINE; UltimateOscillatorOut1.PrimaryColor = RGB(0,255,0); Length1.Name = "Length 1"; Length1.SetInt(7); Length1.SetIntLimits(1,MAX_STUDY_LENGTH); Length2.Name = "Length 2"; Length2.SetInt(14); Length2.SetIntLimits(1,MAX_STUDY_LENGTH); Length3.Name = " Length 3"; Length3.SetInt(28); Length3.SetIntLimits(1,MAX_STUDY_LENGTH); sc.AutoLoop = 1; return; } sc.DataStartIndex = max(Length1.GetInt(), max(Length2.GetInt(),Length3.GetInt())); sc.UltimateOscillator(sc.BaseData, UltimateOscillatorOut1, UltimateOscillatorOut2, Length1.GetInt(), Length2.GetInt(), Length3.GetInt()); } /*==========================================================================*/ SCSFExport scsf_WilliamsAD(SCStudyInterfaceRef sc) { SCSubgraphRef AccumulationDistribution = sc.Subgraph[0]; if(sc.SetDefaults) { sc.GraphName="Accumulation/Distribution (Williams)"; sc.GraphRegion = 1; sc.ValueFormat = 2; AccumulationDistribution.Name = "AD"; AccumulationDistribution.DrawStyle = DRAWSTYLE_LINE; AccumulationDistribution.PrimaryColor = RGB(0,255,0); sc.AutoLoop = 1; return; } sc.DataStartIndex = 1; sc.WilliamsAD(sc.BaseDataIn, AccumulationDistribution, sc.Index); } /*==========================================================================*/ SCSFExport scsf_WilliamsR(SCStudyInterfaceRef sc) { SCSubgraphRef PercentR = sc.Subgraph[0]; SCInputRef Length = sc.Input[3]; SCInputRef Invert = sc.Input[4]; SCInputRef InputDataHigh = sc.Input[5]; SCInputRef InputDataLow = sc.Input[6]; SCInputRef InputDataLast = sc.Input[7]; SCInputRef UpdateFlag = sc.Input[8]; if(sc.SetDefaults) { sc.GraphName = "Williams %R"; sc.GraphRegion= 1; sc.ValueFormat = 2; PercentR.Name = "%R"; PercentR.DrawZeros = true; PercentR.DrawStyle = DRAWSTYLE_LINE; PercentR.PrimaryColor = RGB(0,255,0); Length.Name = "Length"; Length.SetInt(10); Length.SetIntLimits(1,MAX_STUDY_LENGTH); Invert.Name = "Invert Output"; Invert.SetYesNo(1); InputDataHigh.Name = "Input Data for High"; InputDataHigh.SetInputDataIndex(SC_HIGH); InputDataLow.Name = "Input Data for Low"; InputDataLow.SetInputDataIndex(SC_LOW); InputDataLast.Name = "Input Data for Last"; InputDataLast.SetInputDataIndex(SC_LAST); UpdateFlag.SetInt(1); //update flag sc.AutoLoop = 1; return; } if (UpdateFlag.GetInt() == 0) { InputDataHigh.SetInputDataIndex(SC_HIGH); InputDataLow.SetInputDataIndex(SC_LOW); InputDataLast.SetInputDataIndex(SC_LAST); UpdateFlag.SetInt(1); } sc.DataStartIndex = Length.GetInt(); sc.WilliamsR( sc.BaseData[InputDataHigh.GetInputDataIndex()], sc.BaseData[InputDataLow.GetInputDataIndex()], sc.BaseData[InputDataLast.GetInputDataIndex()], PercentR, sc.Index, Length.GetInt() ); if (Invert.GetYesNo()) 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] = (float)sc.Index; Subgraph_GapDownIndex[sc.Index] = Subgraph_GapDownIndex[sc.Index - 1]; } //Gap Down else if (sc.High[sc.Index] < sc.Low[sc.Index - 1]) { Subgraph_GapUp[sc.Index] = Subgraph_GapUp[sc.Index - 1]; Subgraph_GapDown[sc.Index] = 1; Subgraph_GapUpIndex[sc.Index] = Subgraph_GapUpIndex[sc.Index - 1]; Subgraph_GapDownIndex[sc.Index] = (float)sc.Index; } //No Gap (Overlapping Bars) else { Subgraph_GapUp[sc.Index] = Subgraph_GapUp[sc.Index - 1]; Subgraph_GapDown[sc.Index] = Subgraph_GapDown[sc.Index - 1]; Subgraph_GapUpIndex[sc.Index] = Subgraph_GapUpIndex[sc.Index - 1]; Subgraph_GapDownIndex[sc.Index] = Subgraph_GapDownIndex[sc.Index - 1]; } } //Detect Island Reversal if (Subgraph_GapUp[sc.Index] == 1 && Subgraph_GapDown[sc.Index] == 1) { //Gap Up occurs before Gap Down if (Subgraph_GapUpIndex[sc.Index] <= Subgraph_GapDownIndex[sc.Index] - 1) { float GapLevel = max(sc.High[(int)Subgraph_GapUpIndex[sc.Index] - 1], sc.High[(int)Subgraph_GapDownIndex[sc.Index]]); int AreBarsAboveGapLevel = 1; //Check each bar between Up Gap and Down Gap to make sure it does not go below the Gap Up Level for (int BarIndex = (int)Subgraph_GapUpIndex[sc.Index]; BarIndex < (int)Subgraph_GapDownIndex[sc.Index]; BarIndex++) { if (sc.Low[BarIndex] < GapLevel) AreBarsAboveGapLevel = 0; } if (AreBarsAboveGapLevel == 1) { Subgraph_IslandReversal[(int)Subgraph_GapUpIndex[sc.Index]] = GapLevel; Subgraph_IslandReversal[(int)Subgraph_GapDownIndex[sc.Index] - 1] = GapLevel; } //Disallow single-bar islands if (Subgraph_GapUpIndex[sc.Index] == Subgraph_GapDownIndex[sc.Index] - 1) Subgraph_IslandReversal[(int)Subgraph_GapUpIndex[sc.Index]] = 0; //Reset these variables to check for next pair of Gaps Subgraph_GapUp[sc.Index] = 0; Subgraph_GapUpIndex[sc.Index] = 0; } //Gap Down occurs before Gap Up else if (Subgraph_GapDownIndex[sc.Index] <= Subgraph_GapUpIndex[sc.Index] - 1) { float GapLevel = min(sc.Low[(int)Subgraph_GapDownIndex[sc.Index] - 1], sc.Low[(int)Subgraph_GapUpIndex[sc.Index]]); int AreBarsBelowGapLevel = 1; //Check each bar between Down Gap and Up Gap to make sure it does not go above the Gap Down Level for (int BarIndex = (int)Subgraph_GapDownIndex[sc.Index]; BarIndex < (int)Subgraph_GapUpIndex[sc.Index]; BarIndex++) { if (sc.High[BarIndex] > GapLevel) AreBarsBelowGapLevel = 0; } if (AreBarsBelowGapLevel == 1) { Subgraph_IslandReversal[(int)Subgraph_GapUpIndex[sc.Index] - 1] = GapLevel; Subgraph_IslandReversal[(int)Subgraph_GapDownIndex[sc.Index]] = GapLevel; } //Disallow single-bar islands if (Subgraph_GapDownIndex[sc.Index] == Subgraph_GapUpIndex[sc.Index] - 1) Subgraph_IslandReversal[(int)Subgraph_GapDownIndex[sc.Index]] = 0; //Reset these variables to check for next pair of Gaps Subgraph_GapDown[sc.Index] = 0; Subgraph_GapDownIndex[sc.Index] = 0; } } } /*==========================================================================*/ SCSFExport scsf_WeightedAverageOscillator(SCStudyInterfaceRef sc) { SCSubgraphRef Oscillator = sc.Subgraph[0]; SCSubgraphRef Temp1 = sc.Subgraph[1]; SCSubgraphRef Temp2 = sc.Subgraph[2]; SCInputRef InputData = sc.Input[0]; SCInputRef SlowAvgLength = sc.Input[3]; SCInputRef FastAvgLength = sc.Input[4]; if(sc.SetDefaults) { sc.GraphName = "Weighted Average Oscillator"; sc.GraphRegion = 1; sc.ValueFormat = 3; Oscillator.Name = "Oscillator"; Oscillator.DrawStyle = DRAWSTYLE_LINE; Oscillator.PrimaryColor = RGB(0,255,0); Oscillator.DrawZeros = false; InputData.Name = "Input Data"; InputData.SetInputDataIndex(SC_LAST); SlowAvgLength.Name = "Slow Average Length"; SlowAvgLength.SetInt(10); SlowAvgLength.SetIntLimits(1,MAX_STUDY_LENGTH); FastAvgLength.Name = "Fast Average Length"; FastAvgLength.SetInt(3); FastAvgLength.SetIntLimits(1,MAX_STUDY_LENGTH); sc.AutoLoop = 1; return; } sc.DataStartIndex = max( SlowAvgLength.GetInt(),FastAvgLength.GetInt()); sc.WeightedMovingAverage(sc.BaseDataIn[(int)InputData.GetInputDataIndex()], Temp1, SlowAvgLength.GetInt()); sc.WeightedMovingAverage(sc.BaseDataIn[(int)InputData.GetInputDataIndex()], Temp2, FastAvgLength.GetInt()); sc.Oscillator(Temp2, Temp1, Oscillator); } /*==========================================================================*/ SCSFExport scsf_PreferredStochasticDiNapoli(SCStudyInterfaceRef sc) { SCSubgraphRef PercentK = sc.Subgraph[0]; SCSubgraphRef PercentD = sc.Subgraph[1]; SCSubgraphRef Line1 = sc.Subgraph[2]; SCSubgraphRef Line2 = sc.Subgraph[3]; SCInputRef FastKLength = sc.Input[3]; SCInputRef FastDMovAvgLength = sc.Input[4]; SCInputRef ModifiedMovAvgLength = sc.Input[5]; SCInputRef Line1Value = sc.Input[6]; SCInputRef Line2Value = sc.Input[7]; if(sc.SetDefaults) { sc.GraphName = "Preferred Stochastic - DiNapoli"; sc.GraphRegion = 1; sc.ValueFormat = 3; PercentK.Name = "%K"; PercentK.PrimaryColor = RGB(0,255,0); PercentK.DrawStyle = DRAWSTYLE_LINE; PercentK.DrawZeros = false; PercentD.Name = "%D"; PercentD.PrimaryColor = RGB(255,0,255); PercentD.DrawStyle = DRAWSTYLE_LINE; PercentD.DrawZeros = false; Line1.Name = "Line1"; Line1.PrimaryColor = RGB(255,255,0); Line1.DrawStyle = DRAWSTYLE_LINE; Line1.DrawZeros = false; Line2.Name = "Line2"; Line2.PrimaryColor = RGB(255,127,0); Line2.DrawStyle = DRAWSTYLE_LINE; Line2.DrawZeros = false; FastKLength.Name = "Fast %K Length"; FastKLength.SetInt(10); FastKLength.SetIntLimits(1,MAX_STUDY_LENGTH); FastDMovAvgLength.Name = "Fast %D Mov Avg Length (Slow %K)"; FastDMovAvgLength.SetInt(3); FastDMovAvgLength.SetIntLimits(1,MAX_STUDY_LENGTH); ModifiedMovAvgLength.Name = "Modified Mov Avg Length (Slow %D)"; ModifiedMovAvgLength.SetInt(3); ModifiedMovAvgLength.SetIntLimits(1,MAX_STUDY_LENGTH); Line1Value.Name = "Line1 Value"; Line1Value.SetFloat(70); Line2Value.Name = "Line2 Value"; Line2Value.SetFloat(30); sc.AutoLoop = 1; return; } int Index = sc.Index; sc.DataStartIndex = FastKLength.GetInt() + FastDMovAvgLength.GetInt() + 1; sc.Stochastic(sc.BaseDataIn, sc.Subgraph[4], FastKLength.GetInt(), 3, 3, MOVAVGTYPE_SIMPLE); sc.ExponentialMovAvg(sc.Subgraph[4], PercentK, Index, FastDMovAvgLength.GetInt()); PercentD[Index] = PercentD[Index - 1] + ((PercentK[Index] - PercentD[Index - 1]) / ModifiedMovAvgLength.GetInt()); Line1[Index] = Line1Value.GetFloat(); Line2[Index] = Line2Value.GetFloat(); } /*==========================================================================*/ SCSFExport scsf_ElderRay(SCStudyInterfaceRef sc) { SCSubgraphRef BullPower = sc.Subgraph[0]; SCSubgraphRef BearPower = sc.Subgraph[1]; SCSubgraphRef Zero = sc.Subgraph[2]; SCSubgraphRef MovAvgTemp = sc.Subgraph[3]; SCInputRef MovAvgLength = sc.Input[3]; if(sc.SetDefaults) { sc.GraphName = "Elder Ray"; sc.GraphRegion = 1; sc.ValueFormat = 3; BullPower.Name = "Bull Power"; BullPower.DrawStyle = DRAWSTYLE_LINE; BullPower.PrimaryColor = RGB(0,255,0); BullPower.DrawZeros = true; BearPower.Name = "Bear Power"; BearPower.DrawStyle = DRAWSTYLE_LINE; BearPower.PrimaryColor = RGB(255,0,255); BearPower.DrawZeros = true; Zero.Name = "0"; Zero.DrawStyle = DRAWSTYLE_LINE; Zero.PrimaryColor = RGB(255,255,0); Zero.DrawZeros = true; MovAvgLength.SetInt(10); MovAvgLength.SetIntLimits(1,MAX_STUDY_LENGTH); MovAvgLength.Name = "Moving Average Length"; sc.AutoLoop = 1; return; } sc.DataStartIndex = MovAvgLength.GetInt() - 1; int i = sc.Index; sc.ExponentialMovAvg(sc.Close, MovAvgTemp, i, MovAvgLength.GetInt()); BullPower[i] = sc.High[i] - MovAvgTemp[i]; BearPower[i] = sc.Low[i] - MovAvgTemp[i]; } /*==========================================================================*/ SCSFExport scsf_MomentumWithMovingAverage(SCStudyInterfaceRef sc) { SCSubgraphRef Momentum = sc.Subgraph[0]; SCSubgraphRef MovingAverage = sc.Subgraph[1]; SCInputRef InputData = sc.Input[0]; SCInputRef MomentumLength = sc.Input[3]; SCInputRef MovAvgLength = sc.Input[4]; if(sc.SetDefaults) { sc.GraphName = "Momentum with Moving Average"; sc.GraphRegion = 1; sc.ValueFormat = 3; Momentum.Name = "Momentum"; Momentum.DrawStyle = DRAWSTYLE_LINE; Momentum.PrimaryColor = RGB(0,255,0); Momentum.DrawZeros = false; MovingAverage.Name = "Moving Average"; MovingAverage.DrawStyle = DRAWSTYLE_LINE; MovingAverage.PrimaryColor = RGB(128,128,128); MovingAverage.DrawZeros = false; InputData.Name = "Input Data"; InputData.SetInputDataIndex(SC_LAST); MomentumLength.SetInt(10); MomentumLength.SetIntLimits(1,MAX_STUDY_LENGTH); MomentumLength.Name = "Momentum Length"; MovAvgLength.SetInt(5); MovAvgLength.SetIntLimits(1,MAX_STUDY_LENGTH); MovAvgLength.Name = "Moving Average Length"; sc.AutoLoop = 1; return; } sc.DataStartIndex = MomentumLength.GetInt() + MovAvgLength.GetInt(); int i = sc.Index; if(i < MomentumLength.GetInt()) return; Momentum[i]= ( sc.BaseDataIn[(int)InputData.GetInputDataIndex()][i] / sc.BaseDataIn[(int)InputData.GetInputDataIndex()][i - MomentumLength.GetInt()] ) * 100; sc.SimpleMovAvg(Momentum, MovingAverage, i, MovAvgLength.GetInt()); } /*==========================================================================*/ SCSFExport scsf_VolatilityChaikin(SCStudyInterfaceRef sc) { SCSubgraphRef Volatility = sc.Subgraph[0]; SCSubgraphRef Temp1 = sc.Subgraph[1]; SCSubgraphRef Temp2 = sc.Subgraph[2]; SCInputRef Length = sc.Input[3]; if(sc.SetDefaults) { sc.GraphName = "Volatility - Chaikin's"; sc.GraphRegion = 1; sc.ValueFormat = 3; Volatility.Name = "Volatility"; Volatility.DrawStyle = DRAWSTYLE_LINE; Volatility.PrimaryColor = RGB(0,255,0); Length.Name= "Length"; Length.SetInt(10); Length.SetIntLimits(1,MAX_STUDY_LENGTH); sc.AutoLoop = 1; return; } sc.DataStartIndex = Length.GetInt() + 4; int i = sc.Index; Temp2[i] = sc.High[i] - sc.Low[i]; sc.ExponentialMovAvg(Temp2, Temp1, i, Length.GetInt()); Volatility[i] = ((Temp1[i] - Temp1[i - Length.GetInt()]) / Temp1[i-Length.GetInt()]) * 100; } /*==========================================================================*/ SCSFExport scsf_RateOfChangePoints(SCStudyInterfaceRef sc) { SCSubgraphRef ROC = sc.Subgraph[0]; SCInputRef InputData = sc.Input[0]; SCInputRef Length = sc.Input[3]; if(sc.SetDefaults) { sc.GraphName = "Rate Of Change - Points"; sc.GraphRegion = 1; sc.ValueFormat = 2; ROC.Name = "ROC"; ROC.DrawStyle = DRAWSTYLE_LINE; ROC.PrimaryColor = RGB(0,255,0); InputData.Name = "Input Data"; InputData.SetInputDataIndex(SC_LAST); Length.Name = "Length"; Length.SetInt(10); Length.SetIntLimits(1,MAX_STUDY_LENGTH); sc.AutoLoop=1; return; } sc.DataStartIndex = Length.GetInt(); ROC[sc.Index] = (sc.BaseDataIn[(int)InputData.GetInputDataIndex()][sc.Index] - sc.BaseDataIn[(int)InputData.GetInputDataIndex()][sc.Index - Length.GetInt()]); } /*==========================================================================*/ SCSFExport scsf_SquareOfNine(SCStudyInterfaceRef sc) { SCSubgraphRef AnchorSubgraph = sc.Subgraph[0]; SCSubgraphRef L1PlusSubgraph = sc.Subgraph[1]; SCSubgraphRef L1MinusSubgraph = sc.Subgraph[2]; SCSubgraphRef L1Subgraph = sc.Subgraph[3]; SCFloatArrayRef BaseUpperArray = sc.Subgraph[0].Arrays[0]; SCFloatArrayRef BaseLowerArray = sc.Subgraph[0].Arrays[1]; SCFloatArrayRef OffsetArray = sc.Subgraph[0].Arrays[2]; SCInputRef NumberOfDaysToCalculate = sc.Input[0]; SCInputRef AnchorValue = sc.Input[2]; SCInputRef Degree = sc.Input[3]; SCInputRef Level = sc.Input[4]; SCInputRef AutoAdjust = sc.Input[5]; SCInputRef 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 ); AnchorSubgraph.Name = "Anchor"; AnchorSubgraph.DrawStyle = DRAWSTYLE_DASH;// Set line style to Dash AnchorSubgraph.PrimaryColor = RGB(0,255,255); AnchorSubgraph.DrawZeros = false; AnchorSubgraph.LineLabel = LineLabelFlags; L1PlusSubgraph.Name = "L1+"; L1PlusSubgraph.DrawStyle = DRAWSTYLE_DASH; L1PlusSubgraph.PrimaryColor = RGB(0,255,0); L1PlusSubgraph.DrawZeros = false; L1PlusSubgraph.LineLabel = LineLabelFlags; L1MinusSubgraph.Name = "L1-"; L1MinusSubgraph.DrawStyle = DRAWSTYLE_DASH; L1MinusSubgraph.PrimaryColor = RGB(255,0,0); L1MinusSubgraph.DrawZeros = false; L1MinusSubgraph.LineLabel = LineLabelFlags; L1Subgraph.Name = "L1"; L1Subgraph.DrawStyle = DRAWSTYLE_DASH; L1Subgraph.PrimaryColor = RGB(255,127,0); L1Subgraph.DrawZeros = false; L1Subgraph.LineLabel = LineLabelFlags; NumberOfDaysToCalculate.Name = "Number of Days to Calculate"; NumberOfDaysToCalculate.SetInt(10); NumberOfDaysToCalculate.SetIntLimits(1, MAX_STUDY_LENGTH); AnchorValue.SetFloat(0); AnchorValue.Name = "Anchor Value"; AnchorValue.SetFloatLimits(0,(float)MAX_STUDY_LENGTH); Degree.SetFloat(22.5); Degree.Name = "Degrees"; Degree.SetFloatLimits(0,360); Level.SetFloat(1); Level.Name = "Level"; Level.SetFloatLimits(1,10); AutoAdjust.SetYesNo(false); AutoAdjust.Name = "Auto Adjust"; InMultiplier.SetFloat(1.0f); InMultiplier.Name = "Price Multiplier"; sc.ScaleRangeType = SCALE_SAMEASREGION; sc.AutoLoop=1; return; } float MultiplierValue = InMultiplier.GetFloat(); if (MultiplierValue == 0) MultiplierValue = 1; if (AnchorValue.GetFloat() == 0) { AnchorValue.SetFloat(sc.Close[sc.ArraySize - 1]*MultiplierValue); } int LevelInput = (int)(Level.GetFloat() + 0.5f); if (sc.BaseDateTimeIn[sc.Index].GetDate() < sc.BaseDateTimeIn[sc.ArraySize - 1].GetDate() - NumberOfDaysToCalculate.GetInt() + 1) return; if (AutoAdjust.GetYesNo()) { float SquareRoot = sqrt(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 + Degree.GetFloat()/180) * (SquareRoot + Degree.GetFloat()/180); BaseLower = (SquareRoot - Degree.GetFloat()/180) * (SquareRoot - Degree.GetFloat()/180); Mid = AnchorValue.GetFloat(); Upper = (SquareRoot + LevelInput * Degree.GetFloat()/180) * (SquareRoot + LevelInput * Degree.GetFloat()/180); Lower = (SquareRoot - LevelInput * Degree.GetFloat()/180) * (SquareRoot - LevelInput * Degree.GetFloat()/180); } else { Upper = L1PlusSubgraph[sc.Index-1] * MultiplierValue; Lower = L1MinusSubgraph[sc.Index-1] * MultiplierValue; Mid = L1Subgraph[sc.Index-1] * MultiplierValue; BaseUpper = BaseUpperArray[sc.Index-1]; BaseLower = BaseLowerArray[sc.Index-1]; Offset = OffsetArray[sc.Index-1]; } SCString TempStr; TempStr.Format("+%g deg", LevelInput * Degree.GetFloat()); L1PlusSubgraph.Name = TempStr; TempStr.Format("-%g deg", LevelInput * Degree.GetFloat()); L1MinusSubgraph.Name = TempStr; L1Subgraph.Name = "Mid"; float PriceInput = sc.Close[sc.Index] * MultiplierValue; while (PriceInput > BaseUpper) { Offset += Degree.GetFloat(); BaseUpper = (SquareRoot + (Offset + Degree.GetFloat())/180) * (SquareRoot + (Offset + Degree.GetFloat())/180); BaseLower = (SquareRoot + (Offset - Degree.GetFloat())/180) * (SquareRoot + (Offset - Degree.GetFloat())/180); Upper = (SquareRoot + (Offset + LevelInput * Degree.GetFloat())/180) * (SquareRoot + (Offset + LevelInput * Degree.GetFloat())/180); Lower = (SquareRoot + (Offset - LevelInput * Degree.GetFloat())/180) * (SquareRoot + (Offset - LevelInput * Degree.GetFloat())/180); Mid = (SquareRoot + Offset/180) * (SquareRoot + Offset/180); } while (PriceInput < BaseLower) { Offset -= Degree.GetFloat(); BaseUpper = (SquareRoot + (Offset + Degree.GetFloat())/180) * (SquareRoot + (Offset + Degree.GetFloat())/180); BaseLower = (SquareRoot + (Offset - Degree.GetFloat())/180) * (SquareRoot + (Offset - Degree.GetFloat())/180); Upper = (SquareRoot + (Offset + LevelInput * Degree.GetFloat())/180) * (SquareRoot + (Offset + LevelInput * Degree.GetFloat())/180); Lower = (SquareRoot + (Offset - LevelInput * Degree.GetFloat())/180) * (SquareRoot + (Offset - LevelInput * Degree.GetFloat())/180); Mid = (SquareRoot + Offset/180) * (SquareRoot + Offset/180); } AnchorSubgraph[sc.Index] = AnchorValue.GetFloat() / MultiplierValue; L1PlusSubgraph[sc.Index] = Upper / MultiplierValue; L1MinusSubgraph[sc.Index] = Lower / MultiplierValue; L1Subgraph[sc.Index] = Mid / MultiplierValue; BaseUpperArray[sc.Index] = BaseUpper; BaseLowerArray[sc.Index] = BaseLower; OffsetArray[sc.Index] = Offset; } else { float L1 = 0.0f; float L2 = 0.0f; SCString PositiveDegrees; SCString NegativeDegrees; float squareRoot = sqrt(AnchorValue.GetFloat()); float localDegree = 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); AnchorSubgraph[sc.Index] = AnchorValue.GetFloat() / MultiplierValue; L1PlusSubgraph[sc.Index] = L1 / MultiplierValue; L1MinusSubgraph[sc.Index] = L2 / MultiplierValue; } } /*==========================================================================*/ SCSFExport scsf_LinearRegressionEndChannel(SCStudyInterfaceRef sc) { SCSubgraphRef LinearRegression = sc.Subgraph[0]; SCSubgraphRef StdDevHigh = sc.Subgraph[1]; SCSubgraphRef StdDevLow = sc.Subgraph[2]; SCInputRef InputData = sc.Input[0]; SCInputRef Input_PeriodType = sc.Input[1]; SCInputRef Input_NumberOfBarsToCalculate = sc.Input[2]; SCInputRef NumberDeviations = sc.Input[3]; SCInputRef UseStartDateTime = sc.Input[4]; SCInputRef StartDateTime = sc.Input[5]; SCInputRef 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; LinearRegression.Name = "Linear Regression"; LinearRegression.DrawStyle = DRAWSTYLE_LINE; LinearRegression.PrimaryColor = RGB(0,255,0); LinearRegression.DrawZeros = false; StdDevHigh.Name = "StdDev High"; StdDevHigh.DrawStyle = DRAWSTYLE_LINE; StdDevHigh.PrimaryColor = RGB(255,0,255); StdDevHigh.DrawZeros = false; StdDevLow.Name = "StdDev Low"; StdDevLow.DrawStyle = DRAWSTYLE_LINE; StdDevLow.PrimaryColor = RGB(255,255,0); StdDevLow.DrawZeros = false; InputData.Name = "Input Data"; InputData.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); NumberDeviations.Name = "Number of Deviations"; NumberDeviations.SetFloat(2.0f); NumberDeviations.SetFloatLimits(0.001f, 2000); //UseStartDateTime.Name = "Use Start Date-Time instead of Number of Bars"; UseStartDateTime.SetYesNo(false); StartDateTime.Name = "Start Date and Time"; StartDateTime.SetDateTime(0); CalculateOnBarClose.Name = "Calculate On Bar Close"; CalculateOnBarClose.SetYesNo(false); Input_Version.SetInt(1); return; } if (Input_Version.GetInt() < 1) { if (UseStartDateTime.GetYesNo()) Input_PeriodType.SetCustomInputIndex(1); Input_Version.SetInt(1); } int NumberOfBarsToCalculate = Input_NumberOfBarsToCalculate.GetInt(); int InputDataOffset = 0; if(CalculateOnBarClose.GetYesNo()) InputDataOffset = 1; int ArraySize = 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, a, b; int n = 0; int StartIndex = 0; switch (Input_PeriodType.GetIndex()) { case PERIOD_TYPE_NUMBER_OF_BARS: StartIndex = max(0, ArraySize - NumberOfBarsToCalculate - InputDataOffset); break; case PERIOD_TYPE_FROM_START_DATE_TIME: { NumberOfBarsToCalculate = MAX_BARS_TO_CALCULATE; StartIndex = sc.GetContainingIndexForSCDateTime(sc.ChartNumber, StartDateTime.GetDateTime()); if (StartIndex < ArraySize - MAX_BARS_TO_CALCULATE) StartIndex = ArraySize - MAX_BARS_TO_CALCULATE; else NumberOfBarsToCalculate = ArraySize - StartIndex; } break; case PERIOD_TYPE_FROM_START_TIME: { const int LastBarDate = sc.BaseDateTimeIn[sc.ArraySize - 1].GetDate(); const int StartTime = StartDateTime.GetTime(); const SCDateTime CurrentDayStartDateTime(LastBarDate, StartTime); StartIndex = sc.GetContainingIndexForSCDateTime(sc.ChartNumber, CurrentDayStartDateTime); NumberOfBarsToCalculate = ArraySize - StartIndex; } break; }; for (int Index = StartIndex; Index < StartIndex + NumberOfBarsToCalculate && Index < ArraySize; Index++) { tempY = sc.BaseDataIn[InputData.GetInputDataIndex()][Index]; n++; sumY += tempY; sumX += n; sumXY += (tempY*n); sumXX += n*n; } b = (n*sumXY - (sumX*sumY))/((n*sumXX) - (sumX*sumX)); a = (sumY - (b*sumX))/n; // Solve StandardDev sqrt( sum((Xi-Xbar)^2)/n ) float tempX = 0; for (int Index = StartIndex; Index < StartIndex + NumberOfBarsToCalculate && Index < ArraySize; Index++) { float diff = sc.BaseDataIn[InputData.GetInputDataIndex()][Index] - (a + b * (Index-StartIndex+1)); tempX += (diff * diff); } StandardDev = sqrt(tempX/n); // Fill in the Linear Regression data for(int Index = 0; Index < n; Index++) { LinearRegression[StartIndex+Index] = a + b * (Index+1); StdDevHigh[StartIndex+Index] = LinearRegression[StartIndex+Index] + (StandardDev * NumberDeviations.GetFloat()); StdDevLow[StartIndex+Index] = LinearRegression[StartIndex+Index] - (StandardDev * NumberDeviations.GetFloat()); } if (!UseStartDateTime.GetYesNo()) { // Zero out points that are not within the scope int nNewElements = sc.Open.GetArraySize() - 1 - sc.Index; for (int i = ArraySize - 1 - NumberOfBarsToCalculate - InputDataOffset; i >= 0 && nNewElements > 0; i--) { LinearRegression[i] = 0; StdDevHigh[i] = 0; StdDevLow[i] = 0; nNewElements--; } } } /*==========================================================================*/ SCSFExport scsf_PriceVolumeTrend(SCStudyInterfaceRef sc) { SCSubgraphRef PVT = sc.Subgraph[0]; if(sc.SetDefaults) { sc.GraphName = "Price Volume Trend"; sc.GraphRegion = 1; PVT.Name = "PVT"; PVT.DrawStyle = DRAWSTYLE_LINE; PVT.PrimaryColor = RGB(0,255,0); sc.AutoLoop = 1; return; } sc.DataStartIndex = 1; sc.PriceVolumeTrend(sc.BaseDataIn, PVT); } /*==========================================================================*/ SCSFExport scsf_StandardDeviationBands(SCStudyInterfaceRef sc) { SCSubgraphRef TopBand = sc.Subgraph[0]; SCSubgraphRef BottomBand = sc.Subgraph[1]; SCSubgraphRef TopMovAvg = sc.Subgraph[2]; SCSubgraphRef BottomMovAvg = sc.Subgraph[3]; SCSubgraphRef Temp4 = sc.Subgraph[4]; SCSubgraphRef Temp5 = sc.Subgraph[5]; SCInputRef TopBandInputData = sc.Input[0]; SCInputRef BottomBandInputData = sc.Input[1]; SCInputRef Length = sc.Input[3]; SCInputRef MultFactor = sc.Input[5]; SCInputRef MovAvgType = sc.Input[6]; if (sc.SetDefaults) { sc.GraphName = "Standard Deviation Bands"; sc.GraphRegion = 0; TopBand.Name = "Top"; TopBand.DrawStyle = DRAWSTYLE_LINE; TopBand.PrimaryColor = RGB(0,255,0); BottomBand.Name = "Bottom"; BottomBand.DrawStyle = DRAWSTYLE_LINE; BottomBand.PrimaryColor = RGB(0,255,0); TopMovAvg.Name = "Top MovAvg"; TopMovAvg.DrawStyle = DRAWSTYLE_LINE; TopMovAvg.PrimaryColor = RGB(0,0,255); BottomMovAvg.Name = "Bottom MovAvg"; BottomMovAvg.DrawStyle = DRAWSTYLE_LINE; BottomMovAvg.PrimaryColor = RGB(0,0,255); TopBandInputData.Name = "Top Band Input Data"; TopBandInputData.SetInputDataIndex(SC_HIGH); BottomBandInputData.Name = "Bottom Band Input Data"; BottomBandInputData.SetInputDataIndex(SC_LOW); Length.Name = "Length"; Length.SetInt(10); Length.SetIntLimits(1,MAX_STUDY_LENGTH); MultFactor.Name = "Multiplication Factor"; MultFactor.SetFloat(1.8f); MultFactor.SetFloatLimits(0.1f, 20.0f); MovAvgType.Name = "Moving Average Type"; MovAvgType.SetMovAvgType(MOVAVGTYPE_SIMPLE); sc.AutoLoop = true; return; } sc.DataStartIndex = Length.GetInt() - 1; int Index = sc.Index; SCFloatArrayRef HighArray = sc.BaseDataIn[TopBandInputData.GetInputDataIndex()]; SCFloatArrayRef LowArray = sc.BaseDataIn[BottomBandInputData.GetInputDataIndex()]; sc.MovingAverage(HighArray, TopMovAvg, MovAvgType.GetMovAvgType(), Index, Length.GetInt()); sc.MovingAverage(LowArray, BottomMovAvg, MovAvgType.GetMovAvgType(), Index, Length.GetInt()); sc.StdDeviation(HighArray, Temp4, Index, Length.GetInt()); sc.StdDeviation(LowArray, Temp5, Index, Length.GetInt()); TopBand[Index] = (Temp4[Index] * MultFactor.GetFloat()) + TopMovAvg[Index]; BottomBand[Index] = (Temp5[Index] * -MultFactor.GetFloat()) + BottomMovAvg[Index]; } /*==========================================================================*/ SCSFExport scsf_HighestLowestBars(SCStudyInterfaceRef sc) { SCSubgraphRef Highest = sc.Subgraph[0]; SCSubgraphRef Lowest = sc.Subgraph[1]; SCInputRef HighestLength = sc.Input[0]; SCInputRef LowestLength = sc.Input[1]; SCInputRef InputData = sc.Input[2]; if(sc.SetDefaults) { sc.GraphName = "NumberOfBarsSinceHighestValue / NumberOfBarsSinceLowestValue"; sc.GraphRegion = 2; Highest.Name = "Highest"; Highest.DrawStyle = DRAWSTYLE_LINE; Highest.PrimaryColor = RGB(0,255,0); Lowest.Name = "Lowest"; Lowest.DrawStyle = DRAWSTYLE_LINE; Lowest.PrimaryColor = RGB(255,0,255); HighestLength.Name = "HighestLength"; HighestLength.SetInt(10); HighestLength.SetIntLimits(2,MAX_STUDY_LENGTH); LowestLength.Name = "LowestLength"; LowestLength.SetInt(10); LowestLength.SetIntLimits(2,MAX_STUDY_LENGTH); InputData.Name = "Input Data"; InputData.SetInputDataIndex(SC_LAST); sc.AutoLoop = 1; return; } SCFloatArrayRef In = sc.BaseDataIn[InputData.GetInputDataIndex()]; sc.DataStartIndex = max(HighestLength.GetInt(), LowestLength.GetInt()) - 1; Highest[sc.Index] = (float)sc.NumberOfBarsSinceHighestValue(In, sc.Index, HighestLength.GetInt()); Lowest[sc.Index] = (float)sc.NumberOfBarsSinceLowestValue(In, sc.Index, LowestLength.GetInt()); } /*==========================================================================*/ SCSFExport scsf_VolumeUp(SCStudyInterfaceRef sc) { SCSubgraphRef Volume = sc.Subgraph[0]; SCInputRef 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; Volume.Name = "Volume"; Volume.DrawStyle = DRAWSTYLE_BAR; Volume.PrimaryColor = RGB(0,255,0); Volume.DrawZeros = false; CompareType.Name = "Compare Close with: 0=PrevClose, 1=Open"; CompareType.SetInt(0); CompareType.SetIntLimits(0,1); return; } // Do data processing bool IsUpBar = false; switch (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) Volume[sc.Index] = sc.Volume[sc.Index]; else Volume[sc.Index] = 0; } /*==========================================================================*/ SCSFExport scsf_VolumeDown(SCStudyInterfaceRef sc) { SCSubgraphRef Volume = sc.Subgraph[0]; SCInputRef 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; Volume.Name = "Volume"; Volume.DrawStyle = DRAWSTYLE_BAR; Volume.PrimaryColor = RGB(0,255,0); Volume.DrawZeros = false; CompareType.Name = "Compare Close with: 0=PrevClose, 1=Open"; CompareType.SetInt(0); CompareType.SetIntLimits(0,1); return; } // Do data processing bool IsDownBar = false; switch (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) Volume[sc.Index] = sc.Volume[sc.Index]; else Volume[sc.Index] = 0; } /*==========================================================================*/ SCSFExport scsf_BarEndTime(SCStudyInterfaceRef sc) { SCSubgraphRef BET = sc.Subgraph[0]; if(sc.SetDefaults) { sc.GraphName = "Bar End Time"; sc.GraphRegion = 1; sc.ValueFormat = VALUEFORMAT_TIME; BET.Name = "BET"; BET.DrawStyle = DRAWSTYLE_BAR; BET.PrimaryColor = RGB(0,255,0); BET.DrawZeros = false; sc.AutoLoop = 1; sc.MaintainAdditionalChartDataArrays = 1; return; } BET[sc.Index] = static_cast(sc.BaseDataEndDateTime[sc.Index].GetTimeAsSCDateTimeMS().GetAsDouble()); } /*==========================================================================*/ SCSFExport scsf_CorrelationCoefficient(SCStudyInterfaceRef sc) { SCSubgraphRef Subgraph_CorrelationCoefficient = sc.Subgraph[0]; SCInputRef InputArray1 = sc.Input[0]; SCInputRef InputArray2 = sc.Input[1]; SCInputRef 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; InputArray1.Name = "Input Array 1"; InputArray1.SetStudySubgraphValues(0,0); InputArray2.Name = "Input Array 2"; InputArray2.SetStudySubgraphValues(0,0); Length.Name = "Length"; Length.SetInt(200); sc.AutoLoop = 1; sc.CalculationPrecedence = LOW_PREC_LEVEL; return; } sc.DataStartIndex = Length.GetInt(); SCFloatArray Array1; SCFloatArray Array2; sc.GetStudyArrayUsingID(InputArray1.GetStudyID(),InputArray1.GetSubgraphIndex(),Array1); if(Array1.GetArraySize() < sc.ArraySize) return; sc.GetStudyArrayUsingID(InputArray2.GetStudyID(),InputArray2.GetSubgraphIndex(),Array2); if(Array2.GetArraySize() < sc.ArraySize) return; Subgraph_CorrelationCoefficient[sc.Index] = sc.GetCorrelationCoefficient(Array1, Array2, Length.GetInt()); } /*==========================================================================*/ SCSFExport scsf_SierraSqueeze(SCStudyInterfaceRef sc) { SCSubgraphRef MomentumHist = sc.Subgraph[0]; SCSubgraphRef SqueezeDots = sc.Subgraph[1]; SCSubgraphRef MomentumHistUpColors = sc.Subgraph[2]; SCSubgraphRef MomentumHistDownColors = sc.Subgraph[3]; SCSubgraphRef Temp4 = sc.Subgraph[4]; //SCSubgraphRef Temp5 = sc.Subgraph[5]; SCSubgraphRef SignalValues = sc.Subgraph[6]; SCSubgraphRef Temp8 = sc.Subgraph[8]; SCInputRef InputData = sc.Input[0]; SCInputRef HistogramLenFirstData = sc.Input[1]; SCInputRef SqueezeLength = sc.Input[2]; SCInputRef NK = sc.Input[3]; SCInputRef NB = sc.Input[4]; SCInputRef FirstMovAvgType = sc.Input[5]; SCInputRef HistogramLenSecondData = sc.Input[6]; SCInputRef SecondMovAvgType = sc.Input[7]; SCInputRef VersionUpdate = sc.Input[8]; if (sc.SetDefaults) { sc.GraphName = "Squeeze Indicator 2"; sc.StudyDescription = "Developed by the user Tony C."; MomentumHist.Name = "Momentum HISTOGRAM"; MomentumHist.DrawStyle = DRAWSTYLE_BAR; MomentumHist.PrimaryColor = RGB(0,255,0); MomentumHist.LineWidth = 5; MomentumHist.DrawZeros = true; SqueezeDots.Name = "Squeeze Dots"; SqueezeDots.DrawStyle = DRAWSTYLE_POINT; SqueezeDots.PrimaryColor = RGB(255,0,255); SqueezeDots.LineWidth = 4; SqueezeDots.DrawZeros = true; MomentumHistUpColors.Name = "Momentum HISTOGRAM Up Colors"; MomentumHistUpColors.DrawStyle = DRAWSTYLE_IGNORE; MomentumHistUpColors.SecondaryColorUsed = 1; MomentumHistUpColors.PrimaryColor = RGB(0, 0, 255); MomentumHistUpColors.SecondaryColor = RGB(0, 0, 130); MomentumHistUpColors.DrawZeros = true; MomentumHistDownColors.Name = "Momentum HISTOGRAM Down Colors"; MomentumHistDownColors.DrawStyle = DRAWSTYLE_IGNORE; MomentumHistDownColors.SecondaryColorUsed = 1; MomentumHistDownColors.PrimaryColor = RGB(255, 0, 0); MomentumHistDownColors.SecondaryColor = RGB(130, 0, 0); MomentumHistDownColors.DrawZeros = true; SignalValues.Name = "Signal Values"; SignalValues.DrawStyle = DRAWSTYLE_IGNORE; SignalValues.PrimaryColor = RGB(127,0,255); SignalValues.DrawZeros = true; InputData.Name = "Input Data"; InputData.SetInputDataIndex(SC_LAST); // default data field HistogramLenFirstData.Name = "Histogram Length First Data"; HistogramLenFirstData.SetInt(20); HistogramLenFirstData.SetIntLimits(1,MAX_STUDY_LENGTH); SqueezeLength.Name = "Squeeze Length"; SqueezeLength.SetFloat(20); NK.Name = "NK.GetFloat()"; NK.SetFloat(1.5); NB.Name = "NB.GetFloat()"; NB.SetFloat(2); FirstMovAvgType.Name = "First MA Type"; FirstMovAvgType.SetMovAvgType(MOVAVGTYPE_EXPONENTIAL); HistogramLenSecondData.Name = "Histogram Length Second Data"; HistogramLenSecondData.SetInt(20); HistogramLenSecondData.SetIntLimits(1,MAX_STUDY_LENGTH); SecondMovAvgType.Name = "Second MA Type"; SecondMovAvgType.SetMovAvgType(MOVAVGTYPE_LINEARREGRESSION); // hidden input for old versions support VersionUpdate.SetInt(1); sc.AutoLoop = 1; return; } // upgrading the default settings if (VersionUpdate.GetInt() != 1) { MomentumHistUpColors.Name = "Momentum Histogram Up Colors"; MomentumHistUpColors.DrawStyle = DRAWSTYLE_IGNORE; MomentumHistUpColors.SecondaryColorUsed = 1; MomentumHistUpColors.PrimaryColor = RGB(0, 0, 255); MomentumHistUpColors.SecondaryColor = RGB(0, 0, 130); MomentumHistDownColors.Name = "Momentum Histogram Down Colors"; MomentumHistDownColors.DrawStyle = DRAWSTYLE_IGNORE; MomentumHistDownColors.SecondaryColorUsed = 1; MomentumHistDownColors.PrimaryColor = RGB(255, 0, 0); MomentumHistDownColors.SecondaryColor = RGB(130, 0, 0); SignalValues.Name = "Signal Values"; SignalValues.DrawStyle = DRAWSTYLE_IGNORE; VersionUpdate.SetInt(1); } // Inputs int i = sc.Index; const DWORD inside = RGB(255, 0, 0); const DWORD outside = RGB(0, 255, 0); MomentumHistUpColors[i] = 0; MomentumHistDownColors[i] = 0; // First output elements are not valid sc.DataStartIndex = HistogramLenSecondData.GetInt(); SCFloatArrayRef close = sc.Close; sc.ExponentialMovAvg(close, MomentumHistUpColors, HistogramLenSecondData.GetInt()); // Note: EMA returns close when index is < HistogramLenSecondData.GetInt() sc.MovingAverage(close, MomentumHistUpColors, FirstMovAvgType.GetMovAvgType(), HistogramLenFirstData.GetInt()); float hlh = sc.GetHighest(sc.High, HistogramLenSecondData.GetInt()); float lll = sc.GetLowest(sc.Low, HistogramLenSecondData.GetInt()); SCFloatArrayRef price = sc.Open; MomentumHistDownColors[sc.Index] = price[sc.Index] - ((hlh + lll)/2.0f + MomentumHistUpColors[sc.Index])/2.0f; sc.LinearRegressionIndicator(MomentumHistDownColors, MomentumHist, HistogramLenSecondData.GetInt()); sc.MovingAverage(close, MomentumHistUpColors, SecondMovAvgType.GetMovAvgType(), HistogramLenSecondData.GetInt()); if( (MomentumHist[i]<0) &&(MomentumHist[i] < MomentumHist[i-1]) ) { MomentumHist.DataColor[sc.Index] = MomentumHistDownColors.PrimaryColor; } else if( (MomentumHist[i]<=0) &&(MomentumHist[i] > MomentumHist[i-1]) ) { MomentumHist.DataColor[sc.Index] = MomentumHistDownColors.SecondaryColor; } else if( (MomentumHist[i]>0) &&(MomentumHist[i] > MomentumHist[i-1]) ) { MomentumHist.DataColor[sc.Index] = MomentumHistUpColors.PrimaryColor; } else if( (MomentumHist[i]>=0) &&(MomentumHist[i] < MomentumHist[i-1]) ) { MomentumHist.DataColor[sc.Index] = MomentumHistUpColors.SecondaryColor; } //Squeeze sc.Keltner( sc.BaseDataIn, sc.Close, Temp8, SqueezeLength.GetInt(), MOVAVGTYPE_SMOOTHED, SqueezeLength.GetInt(), MOVAVGTYPE_SMOOTHED, NK.GetFloat(), NK.GetFloat() ); float TopBandOut = Temp8.Arrays[0][sc.Index]; float BottomBandOut = Temp8.Arrays[1][sc.Index]; sc.BollingerBands(sc.Close, Temp4, SqueezeLength.GetInt(), NB.GetFloat(), MOVAVGTYPE_SMOOTHED); float BU =Temp4.Arrays[0][sc.Index]; float BL =Temp4.Arrays[1][sc.Index]; if ( (BU < TopBandOut) || (BL > BottomBandOut) ) { SqueezeDots[sc.Index] = 0.0; SqueezeDots.DataColor[sc.Index] = inside; SignalValues[sc.Index] = 0.0; SignalValues.DataColor[sc.Index] = inside; } else { SqueezeDots[sc.Index] = 0.0; SqueezeDots.DataColor[sc.Index] = outside; SignalValues[sc.Index] = 1.0; SignalValues.DataColor[sc.Index] = outside; } } /*==========================================================================*/ SCSFExport scsf_R_Squared(SCStudyInterfaceRef sc) { SCSubgraphRef RSquared = sc.Subgraph[0]; SCInputRef Length = sc.Input[0]; SCInputRef InputData = sc.Input[1]; if(sc.SetDefaults) { sc.GraphName="R Squared"; sc.StudyDescription="R Squared Indicator by ertrader."; sc.AutoLoop = 1; sc.GraphRegion = 1; RSquared.Name="R Squared"; RSquared.DrawStyle = DRAWSTYLE_LINE; RSquared.LineWidth = 2; RSquared.PrimaryColor = COLOR_GREEN; RSquared.SecondaryColor = COLOR_RED; RSquared.DrawZeros = false; Length.Name="Length"; Length.SetInt(14); Length.SetIntLimits(1,MAX_STUDY_LENGTH); InputData.Name = "Input Data"; InputData.SetInputDataIndex(SC_LAST); return; } // Start plotting after good output elements are valid sc.DataStartIndex = 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[InputData.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 RSquared.Arrays[0][sc.Index] = (float)(sc.Index + 1); //Get the correlation coefficient. Correlate Price Data against the cumulation float coef = sc.GetCorrelationCoefficient(RSquared.Arrays[0], PriceData, sc.Index, Length.GetInt()); // Calculate and Draw R squared //Pwr(Corr(Cum( 1 ),C,14,0),2) or Correlation_Coefficient^2 RSquared[sc.Index]=coef*coef; } /*==========================================================================*/ //http://en.wikipedia.org/wiki/Exponential_function SCSFExport scsf_RSIInverseFisherTransform(SCStudyInterfaceRef sc) { SCSubgraphRef RSI_IFT = sc.Subgraph[0]; SCSubgraphRef Line1 = sc.Subgraph[1]; SCSubgraphRef Line2 = sc.Subgraph[2]; SCSubgraphRef RSI = sc.Subgraph[3]; SCInputRef RSILength = sc.Input[0]; SCInputRef RSIInternalMovAvgType = sc.Input[1]; SCInputRef RSIMovAvgType = sc.Input[2]; SCInputRef RSIMovAvgLength = sc.Input[3]; SCInputRef 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; RSI_IFT.Name="RSI IFT"; RSI_IFT.DrawStyle = DRAWSTYLE_LINE; RSI_IFT.LineWidth = 2; RSI_IFT.PrimaryColor = COLOR_GREEN; RSI_IFT.DrawZeros = true; Line1.Name="Line 1"; Line1.DrawStyle = DRAWSTYLE_LINE; Line1.LineWidth = 1; Line1.PrimaryColor = COLOR_RED; Line1.DrawZeros = true; Line2.Name="Line 2"; Line2.DrawStyle = DRAWSTYLE_LINE; Line2.LineWidth = 1; Line2.PrimaryColor = COLOR_BLUE; Line2.DrawZeros = true; RSILength.Name="RSI Length"; RSILength.SetInt(5); RSILength.SetIntLimits(1,MAX_STUDY_LENGTH); RSIInternalMovAvgType.Name="RSI Internal MovAvg Type"; RSIInternalMovAvgType.SetMovAvgType(MOVAVGTYPE_SIMPLE); RSIMovAvgType.Name="RSI MovAvg Type"; RSIMovAvgType.SetMovAvgType(MOVAVGTYPE_WEIGHTED); RSIMovAvgLength.Name="RSI MovAvg Length"; RSIMovAvgLength.SetInt(9); RSIMovAvgLength.SetIntLimits(1,MAX_STUDY_LENGTH); LineValue.Name="Line Value"; LineValue.SetFloat(0.5); return; } sc.DataStartIndex = RSILength.GetInt()+RSIMovAvgLength.GetInt(); sc.InverseFisherTransformRSI(sc.Close, RSI_IFT, RSILength.GetInt(), RSIInternalMovAvgType.GetMovAvgType(), RSIMovAvgLength.GetInt(), RSIMovAvgType.GetMovAvgType()); Line1[sc.Index] = LineValue.GetFloat(); Line2[sc.Index] = -LineValue.GetFloat(); } /*==========================================================================*/ SCSFExport scsf_InverseFisherTransform(SCStudyInterfaceRef sc) { SCSubgraphRef InverseFisherTransform = sc.Subgraph[0]; SCSubgraphRef Line1 = sc.Subgraph[1]; SCSubgraphRef Line2 = sc.Subgraph[2]; SCSubgraphRef IFTAvg = sc.Subgraph[3]; SCInputRef InputData = sc.Input[0]; SCInputRef LineValue = sc.Input[1]; SCInputRef OutputMovAvgLength = sc.Input[2]; SCInputRef OutputMovAvgType = sc.Input[3]; SCInputRef InputMovAvgLength = sc.Input[4]; SCInputRef InputMovAvgType = sc.Input[5]; SCInputRef HighestLowestLength = sc.Input[6]; if(sc.SetDefaults) { sc.GraphName="Inverse Fisher Transform"; sc.StudyDescription="Inverse Fisher Transform."; sc.AutoLoop = 1; sc.GraphRegion = 1; InverseFisherTransform.Name="IFT"; InverseFisherTransform.DrawStyle = DRAWSTYLE_LINE; InverseFisherTransform.LineWidth = 2; InverseFisherTransform.PrimaryColor = COLOR_GREEN; InverseFisherTransform.DrawZeros = true; Line1.Name="Line 1"; Line1.DrawStyle = DRAWSTYLE_LINE; Line1.LineWidth = 1; Line1.PrimaryColor = COLOR_RED; Line1.DrawZeros = true; Line2.Name="Line 2"; Line2.DrawStyle = DRAWSTYLE_LINE; Line2.LineWidth = 1; Line2.PrimaryColor = COLOR_BLUE; Line2.DrawZeros = true; IFTAvg.Name="IFT Avg"; IFTAvg.DrawStyle = DRAWSTYLE_LINE; IFTAvg.LineWidth = 1; IFTAvg.PrimaryColor = RGB(255,255,0); IFTAvg.DrawZeros = true; InputData.Name="Input Data"; InputData.SetInputDataIndex(0); LineValue.Name="Line Value"; LineValue.SetFloat(0.5); OutputMovAvgLength.Name="Output Mov Avg Length"; OutputMovAvgLength.SetInt(3); OutputMovAvgType.Name="Output Mov Avg Type"; OutputMovAvgType.SetMovAvgType(MOVAVGTYPE_SIMPLE); InputMovAvgLength.Name="Input Data Mov Avg Length"; InputMovAvgLength.SetInt(9); InputMovAvgType.Name="Input Data Mov Avg Type"; InputMovAvgType.SetMovAvgType(MOVAVGTYPE_WEIGHTED); HighestLowestLength.Name = "Highest Value/Lowest Value Length"; HighestLowestLength.SetInt(10); return; } sc.DataStartIndex = InputMovAvgLength.GetInt()+OutputMovAvgLength.GetInt(); sc.InverseFisherTransform(sc.BaseData[InputData.GetInputDataIndex()], InverseFisherTransform, HighestLowestLength.GetInt(), InputMovAvgLength.GetInt(), InputMovAvgType.GetMovAvgType()); sc.MovingAverage(InverseFisherTransform, IFTAvg, OutputMovAvgType.GetMovAvgType(),OutputMovAvgLength.GetInt()); Line1[sc.Index] = LineValue.GetFloat(); Line2[sc.Index] = -LineValue.GetFloat(); } /*============================================================================ Sine-Wave Weighted Moving Average ----------------------------------------------------------------------------*/ SCSFExport scsf_SineWaveWMA(SCStudyInterfaceRef sc) { SCSubgraphRef WMA = sc.Subgraph[0]; SCInputRef InputData = sc.Input[0]; if (sc.SetDefaults) { sc.GraphName="Sine Wave Weighted Moving Average"; sc.AutoLoop = 1; sc.GraphRegion = 0; WMA.Name="SWA"; WMA.DrawStyle = DRAWSTYLE_LINE; WMA.LineWidth = 1; WMA.PrimaryColor = RGB(0,255,0); WMA.DrawZeros = true; InputData.Name = "Input Data"; InputData.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 = InputData.GetInputDataIndex(); const float SD = (float)(M_PI/6); // Note: the sin function takes radians, not degrees float S1 = sin(1*SD) * sc.BaseData[InputDataIndex][sc.Index - 0]; float S2 = sin(2*SD) * sc.BaseData[InputDataIndex][sc.Index - 1]; float S3 = sin(3*SD) * sc.BaseData[InputDataIndex][sc.Index - 2]; float S4 = sin(4*SD) * sc.BaseData[InputDataIndex][sc.Index - 3]; float S5 = sin(5*SD) * sc.BaseData[InputDataIndex][sc.Index - 4]; float Num = S1 + S2 + S3 + S4 + S5; float Den = sin(1*SD) + sin(2*SD) + sin(3*SD) + sin(4*SD) + sin(5*SD); WMA[sc.Index] = Num / Den; } /*==========================================================================*/ /* Bollinger bands squeeze. Proportion = (kUpper - kLower) / (bbUpper - bbLower); */ SCSFExport scsf_BollingerSqueeze(SCStudyInterfaceRef sc) { SCSubgraphRef BandsRatio = sc.Subgraph[0]; SCSubgraphRef SqueezeIndicator = sc.Subgraph[1]; SCSubgraphRef Keltner = sc.Subgraph[2]; SCSubgraphRef BollingerBands = sc.Subgraph[3]; SCInputRef InputData = sc.Input[0]; SCInputRef InternalMovAvgType = sc.Input[1]; SCInputRef KeltnerBandsLength = sc.Input[2]; SCInputRef KeltnerTrueRangeMALength = sc.Input[3]; SCInputRef KeltnerBandsMultiplier = sc.Input[4]; SCInputRef BollingerBandsLength = sc.Input[5]; SCInputRef BollingerBandsMultiplier = sc.Input[6]; if (sc.SetDefaults) { sc.GraphName="Bollinger Squeeze"; sc.StudyDescription="Bollinger Squeeze"; sc.AutoLoop = 1; sc.GraphRegion = 1; BandsRatio.Name = "Bands Ratio"; BandsRatio.DrawStyle = DRAWSTYLE_BAR; BandsRatio.PrimaryColor = RGB(0,255,0); BandsRatio.SecondaryColor = RGB(255,0,0); BandsRatio.SecondaryColorUsed = true; BandsRatio.DrawZeros = true; SqueezeIndicator.Name = "Squeeze Indicator"; SqueezeIndicator.DrawStyle = DRAWSTYLE_POINT; SqueezeIndicator.LineWidth = 3; SqueezeIndicator.PrimaryColor = RGB(0,255,0); SqueezeIndicator.SecondaryColor = RGB(255,0,0); SqueezeIndicator.SecondaryColorUsed = true; SqueezeIndicator.DrawZeros = true; InputData.Name = "Input Data"; InputData.SetInputDataIndex(SC_LAST); InternalMovAvgType.Name="Moving Average Type for Internal Calculations"; InternalMovAvgType.SetMovAvgType(MOVAVGTYPE_SIMPLE); KeltnerBandsLength.Name="Keltner Bands Length"; KeltnerBandsLength.SetInt(20); KeltnerBandsLength.SetIntLimits(1,MAX_STUDY_LENGTH); KeltnerTrueRangeMALength.Name = "Keltner True Range MovAvg Length"; KeltnerTrueRangeMALength.SetInt(20); KeltnerTrueRangeMALength.SetIntLimits(1,MAX_STUDY_LENGTH); KeltnerBandsMultiplier.Name="Keltner Bands Multiplier"; KeltnerBandsMultiplier.SetFloat(2.0f); BollingerBandsLength.Name="Bollinger Bands Length"; BollingerBandsLength.SetInt(20); BollingerBandsLength.SetIntLimits(1,MAX_STUDY_LENGTH); BollingerBandsMultiplier.Name="Bollinger Bands Multiplier"; BollingerBandsMultiplier.SetFloat(2.0f); return; } sc.DataStartIndex = max(BollingerBandsLength.GetInt(), max(KeltnerBandsLength.GetInt(), KeltnerTrueRangeMALength.GetInt())) - 1; // calculate Bollinger Bands sc.BollingerBands(sc.BaseData[InputData.GetInputDataIndex()],BollingerBands,BollingerBandsLength.GetInt(),BollingerBandsMultiplier.GetFloat(),InternalMovAvgType.GetMovAvgType()); // calculate Keltner sc.Keltner( sc.BaseData,sc.BaseData[InputData.GetInputDataIndex()],Keltner,KeltnerBandsLength.GetInt(), InternalMovAvgType.GetMovAvgType(),BollingerBandsLength.GetInt(),InternalMovAvgType.GetMovAvgType(), KeltnerBandsMultiplier.GetFloat(),KeltnerBandsMultiplier.GetFloat()); float KUp = Keltner.Arrays[0][sc.CurrentIndex]; float KDown = Keltner.Arrays[1][sc.CurrentIndex]; float UBB = BollingerBands.Arrays[0][sc.CurrentIndex]; float LBB = BollingerBands.Arrays[1][sc.CurrentIndex]; if ((UBB > KUp) && (LBB < KDown)) SqueezeIndicator.DataColor[sc.CurrentIndex] = SqueezeIndicator.PrimaryColor; else SqueezeIndicator.DataColor[sc.CurrentIndex] = SqueezeIndicator.SecondaryColor; BandsRatio[sc.CurrentIndex] = (KUp-KDown)/(UBB - LBB) - 1.0f; if (BandsRatio[sc.CurrentIndex] >= 0) BandsRatio.DataColor[sc.CurrentIndex] = BandsRatio.PrimaryColor; else BandsRatio.DataColor[sc.CurrentIndex] = BandsRatio.SecondaryColor; } /*==========================================================================*/ SCSFExport scsf_StudySubgraphsDifference(SCStudyInterfaceRef sc) { SCSubgraphRef Diff = sc.Subgraph[0]; SCInputRef StudySugbraph1 = sc.Input[5]; SCInputRef StudySugbraph2 = sc.Input[6]; SCInputRef Study2SubgraphOffset = sc.Input[7]; SCInputRef VersionUpdate = sc.Input[8]; SCInputRef DrawZeros = sc.Input[9]; SCInputRef 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; Diff.Name = "Diff"; Diff.DrawStyle = DRAWSTYLE_LINE; Diff.PrimaryColor = RGB(0,255,0); Diff.LineWidth = 1; StudySugbraph1.Name = "Input Study 1"; StudySugbraph1.SetStudySubgraphValues(0, 0); StudySugbraph2.Name = "Input Study 2"; StudySugbraph2.SetStudySubgraphValues(0, 0); Study2SubgraphOffset.Name = "Study 2 Subgraph Offset";// This is always converted to a positive value and is the number of bars back Study2SubgraphOffset.SetInt(0); DrawZeros.Name = "Draw Zeros"; DrawZeros.SetYesNo(false); VersionUpdate.SetInt(2); PerformSubtractWithZeroValue.Name = "Perform Subtract With Zero Value"; PerformSubtractWithZeroValue.SetYesNo(true); return; } if (VersionUpdate.GetInt() < 2) { PerformSubtractWithZeroValue.SetYesNo(true); VersionUpdate.SetInt(2); } if (sc.IsFullRecalculation && sc.UpdateStartIndex == 0) sc.GraphName = "Study Subgraphs Difference"; Diff.DrawZeros = DrawZeros.GetYesNo(); SCFloatArray Study1Array; sc.GetStudyArrayUsingID(StudySugbraph1.GetStudyID(), StudySugbraph1.GetSubgraphIndex(), Study1Array); SCFloatArray Study2Array; sc.GetStudyArrayUsingID(StudySugbraph2.GetStudyID(), StudySugbraph2.GetSubgraphIndex(), Study2Array); int CalculationStartIndex = sc.GetCalculationStartIndexForStudy(); for (int Index = CalculationStartIndex; Index < sc.ArraySize; Index++) { float Value1 = Study1Array[Index]; float Value2 = Study2Array[Index - labs(Study2SubgraphOffset.GetInt())]; if (PerformSubtractWithZeroValue.GetYesNo() || (Value1 != 0.0 && Value2 != 0.0)) { Diff[Index] = Value1 - Value2; } else { Diff[Index] = 0.0; } } sc.EarliestUpdateSubgraphDataArrayIndex = CalculationStartIndex; } /*==========================================================================*/ SCSFExport scsf_LRS(SCStudyInterfaceRef sc) { SCSubgraphRef LRS = sc.Subgraph[0]; SCInputRef InputData = sc.Input[0]; SCInputRef Length = sc.Input[3]; if (sc.SetDefaults) { sc.GraphName = "Linear Regressive Slope"; sc.AutoLoop = 1; sc.GraphRegion = 1; sc.ValueFormat = 3; LRS.Name = "LRS"; LRS.DrawStyle = DRAWSTYLE_LINE; LRS.PrimaryColor = RGB(0,255,0); LRS.DrawZeros = true; InputData.Name = "Input Data"; InputData.SetInputDataIndex(SC_LAST); Length.Name = "Length"; Length.SetInt(10); Length.SetIntLimits(1,MAX_STUDY_LENGTH); return; } sc.DataStartIndex = Length.GetInt(); int Len=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[InputData.GetInputDataIndex()][Index]; SumY += sc.BaseData[InputData.GetInputDataIndex()][Index]; } double Sum2 = SumBars * SumY; double Num1 = Len*Sum1 - Sum2; double Num2 = SumBars*SumBars - Len*SumSqrBars; LRS[sc.Index] = (float)(Num1 / Num2); return; } /*==========================================================================*/ SCSFExport scsf_SummationPeriodic(SCStudyInterfaceRef sc) { SCSubgraphRef Sum = sc.Subgraph[0]; SCInputRef InputData = sc.Input[0]; SCInputRef 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; Sum.Name = "Sum"; Sum.DrawStyle = DRAWSTYLE_LINE; Sum.PrimaryColor = RGB(0,255,0); Sum.DrawZeros = false; InputData.Name = "Input Data"; InputData.SetInputDataIndex(SC_LAST); Length.Name = "Length"; Length.SetInt(10); Length.SetIntLimits(1, MAX_STUDY_LENGTH); return; } sc.Summation(sc.BaseData[InputData.GetInputDataIndex()], Sum, Length.GetInt()); } /*==========================================================================*/ SCSFExport scsf_SummationOfStudySubgraphPeriodic(SCStudyInterfaceRef sc) { SCSubgraphRef Sum = sc.Subgraph[0]; SCInputRef Length = sc.Input[0]; SCInputRef StudySubgraphReference = sc.Input[1]; if (sc.SetDefaults) { sc.GraphName = "Summation of Study Subgraph - Periodic"; sc.AutoLoop = 1; sc.GraphRegion = 1; sc.ValueFormat = 3; Sum.Name = "Sum"; Sum.DrawStyle = DRAWSTYLE_LINE; Sum.PrimaryColor = RGB(0, 255, 0); Sum.DrawZeros = false; Length.Name = "Length"; Length.SetInt(10); Length.SetIntLimits(1, MAX_STUDY_LENGTH); StudySubgraphReference.Name = "Study and Subgraph To Reference"; StudySubgraphReference.SetStudySubgraphValues(1,0); return; } SCFloatArray StudyArray; sc.GetStudyArrayUsingID(StudySubgraphReference.GetStudyID(), 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(StudySubgraphReference.GetStudyID()); sc.Summation(StudyArray, Sum, 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_MinimumRequiredTP = 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; 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_MinimumRequiredTP.Name = "Minimum Required Time Period as %"; Input_MinimumRequiredTP.SetFloat(5.0f); Input_MinimumRequiredTP.SetFloatLimits(1.0f, 100.0f); Input_MinimumRequiredTP.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(); SCDateTime FirstBarDateTime = sc.BaseDateTimeIn[0]; SCDateTime ChartStartTime = sc.StartTime1; if (sc.UseSecondStartEndTimes) ChartStartTime = sc.StartTime2; 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); SCDateTime LastDateInChart = sc.GetTradingDayDate(sc.BaseDateTimeIn[sc.ArraySize - 1]); SCDateTime FirstDateToCalculate = LastDateInChart; FirstDateToCalculate.SubtractDays(Input_NumberOfDaysToCalculate.GetInt() - 1); float Open = 0, High = 0, Low = 0, Close = 0, NextOpen = 0; SCDateTime BeginOfRefDateTime,EndOfRefDateTime; SCDateTime CurrentPeriodBeginDateTime; SCDateTime CurrentPeriodEndDateTime; SCDateTime PriorCurrentPeriodStartDateTime; for (int BarIndex = sc.UpdateStartIndex; BarIndex < sc.ArraySize + NumberOfForwardBars; BarIndex++) { const SCDateTime 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 { SCDateTime PriorBarPeriodStartDateTime = sc.GetStartOfPeriodForDateTime(sc.BaseDateTimeIn[BarIndex - 1], Input_TimePeriodType.GetTimePeriodType(), PeriodLength, 0); IsStartOfNewPeriod = PriorBarPeriodStartDateTime != CurrentPeriodBeginDateTime; } } SCDateTime 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) { BeginOfRefDateTime= sc.GetStartOfPeriodForDateTime(CurrentPeriodBeginDateTime, Input_TimePeriodType.GetTimePeriodType(), PeriodLength, -1); EndOfRefDateTime = CurrentPeriodBeginDateTime - (1 * SECONDS); CurrentPeriodEndDateTime = sc.GetStartOfPeriodForDateTime(CurrentPeriodBeginDateTime, Input_TimePeriodType.GetTimePeriodType(), PeriodLength, 1) - (1 * SECONDS); if (Input_DisplayDebuggingOutput.GetYesNo() != 0) { SCString Message; Message.Format("Current Bar: %s, BeginOfRefDateTime: %s, EndOfRefDateTime: %s, CurrentPeriodBeginDateTime: %s, CurrentPeriodEndDateTime: %s", sc.FormatDateTime(CurrentBarDateTime).GetChars(),sc.FormatDateTime(BeginOfRefDateTime).GetChars(), sc.FormatDateTime(EndOfRefDateTime).GetChars(),sc.FormatDateTime(CurrentPeriodBeginDateTime).GetChars(), sc.FormatDateTime(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. { SCDateTime PriorBeginOfRefDateTime = BeginOfRefDateTime; BeginOfRefDateTime = sc.GetStartOfPeriodForDateTime(BeginOfRefDateTime, Input_TimePeriodType.GetTimePeriodType(), PeriodLength, -1); EndOfRefDateTime = PriorBeginOfRefDateTime- (1*SECONDS); if (Input_DisplayDebuggingOutput.GetYesNo() != 0) { SCString Message; Message.Format("Moving back 1 period. BeginOfRefDateTime: %s, EndOfRefDateTime: %s.", sc.FormatDateTime(BeginOfRefDateTime).GetChars(),sc.FormatDateTime(EndOfRefDateTime).GetChars()); sc.AddMessageToLog(Message,0); } } int NumberOfBars = 0; SCDateTime 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,(int)(TotalTimeSpan/MINUTES+0.5)); 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; SCDateTime MinimumTimeSpan = (TimeIncrement * Input_MinimumRequiredTP.GetFloat()/100.0f); if (TotalTimeSpan >= MinimumTimeSpan) break; } } if (!sc.IsFullRecalculation && Input_UseCurrentPeriod.GetYesNo()) { const int StartingBackIndex = sc.GetContainingIndexForSCDateTime(sc.ChartNumber, CurrentPeriodBeginDateTime); 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 Open = sc.Subgraph[0]; SCSubgraphRef High = sc.Subgraph[1]; SCSubgraphRef Low = sc.Subgraph[2]; SCSubgraphRef Last = sc.Subgraph[3]; SCSubgraphRef Volume = sc.Subgraph[4]; SCSubgraphRef NumTrades = sc.Subgraph[5]; SCSubgraphRef OHLCAvg = sc.Subgraph[6]; SCSubgraphRef HLCAvg = sc.Subgraph[7]; SCSubgraphRef HLAvg = sc.Subgraph[8]; SCSubgraphRef BidVol = sc.Subgraph[9]; SCSubgraphRef AskVol = sc.Subgraph[10]; SCSubgraphRef RenkoUpDownTrend = sc.Subgraph[11]; SCSubgraphRef RenkoLast = sc.Subgraph[12]; SCInputRef RenkoBoxSize = sc.Input[0]; SCInputRef UseHighLowInsteadOfLast = sc.Input[1]; SCInputRef 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; Open.Name = "Open"; Open.DrawStyle = DRAWSTYLE_LINE; Open.PrimaryColor = RGB(0, 255, 0); Open.DrawZeros = false; High.Name = "High"; High.DrawStyle = DRAWSTYLE_LINE; High.PrimaryColor = RGB(0, 127, 0); High.DrawZeros = false; Low.Name = "Low"; Low.DrawStyle = DRAWSTYLE_LINE; Low.PrimaryColor = RGB(255, 0, 0); Low.DrawZeros = false; Last.Name = "Last"; Last.DrawStyle = DRAWSTYLE_LINE; Last.PrimaryColor = RGB(127, 0, 0); Last.DrawZeros = false; Volume.Name = "Volume"; Volume.DrawStyle = DRAWSTYLE_IGNORE; Volume.PrimaryColor = RGB(255,255,255); Volume.DrawZeros = false; NumTrades.Name = "# of Trades / OI"; NumTrades.DrawStyle = DRAWSTYLE_IGNORE; NumTrades.PrimaryColor = RGB(255,255,255); NumTrades.DrawZeros = false; OHLCAvg.Name = "OHLC Avg"; OHLCAvg.DrawStyle = DRAWSTYLE_IGNORE; OHLCAvg.PrimaryColor = RGB(255,255,255); OHLCAvg.DrawZeros = false; HLCAvg.Name = "HLC Avg"; HLCAvg.DrawStyle = DRAWSTYLE_IGNORE; HLCAvg.PrimaryColor = RGB(255,255,255); HLCAvg.DrawZeros = false; HLAvg.Name = "HL Avg"; HLAvg.DrawStyle = DRAWSTYLE_IGNORE; HLAvg.PrimaryColor = RGB(255,255,255); HLAvg.DrawZeros = false; BidVol.Name = "Bid Vol"; BidVol.DrawStyle = DRAWSTYLE_IGNORE; BidVol.PrimaryColor = RGB(255,255,255); BidVol.DrawZeros = false; AskVol.Name = "Ask Vol"; AskVol.DrawStyle = DRAWSTYLE_IGNORE; AskVol.PrimaryColor = RGB(255,255,255); AskVol.DrawZeros = false; RenkoBoxSize.Name = "Renko Box Size"; RenkoBoxSize.SetFloat(0.0f); RenkoBoxSize.SetFloatLimits(0.0f,(float)MAX_STUDY_LENGTH); UseHighLowInsteadOfLast.Name = "Use High/Low Values instead of Last Value"; UseHighLowInsteadOfLast.SetYesNo(0); IgnoreLatestBarUntilClose.Name = "Ignore Latest Underlying Bar until Close"; IgnoreLatestBarUntilClose.SetYesNo(0); return; } sc.ValueFormat = sc.BaseGraphValueFormat; int ValueFormat = sc.BaseGraphValueFormat; if (RenkoBoxSize.GetFloat() == 0.0f) { RenkoBoxSize.SetFloat(sc.TickSize*4); } sc.GraphName.Format("%s Renko - BoxSize: %s", sc.GetStudyName(0).GetChars(), sc.FormatGraphValue(RenkoBoxSize.GetFloat(), ValueFormat).GetChars()); int BaseGraphIndex = sc.UpdateStartIndex; if (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]; RenkoLast[0] = sc.Close[BaseGraphIndex]; Open[0] = sc.Close[BaseGraphIndex]; Last[0] = sc.Close[BaseGraphIndex]; High[0] = sc.Close[BaseGraphIndex]; 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 (RenkoUpDownTrend[RenkoIndex] > 0) // Uptrend Box { UpperBox = RenkoLast[RenkoIndex]; LowerBox = UpperBox - RenkoBoxSize.GetFloat(); LowerBox = (float)sc.RoundToTickSize(LowerBox, RenkoBoxSize.GetFloat()); } else { LowerBox = RenkoLast[RenkoIndex]; UpperBox = LowerBox + RenkoBoxSize.GetFloat(); UpperBox = (float)sc.RoundToTickSize(UpperBox, 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 (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 (UseHighLowInsteadOfLast.GetYesNo() != 0) { HigherPrice = sc.High[BaseGraphIndex]; LowerPrice = sc.Low[BaseGraphIndex]; } if (sc.FormattedEvaluateUsingDoubles((double)HigherPrice, ValueFormat, GREATER_EQUAL_OPERATOR, (double)(UpperBox + RenkoBoxSize.GetFloat()), ValueFormat)) { NewEntry = 1; UpperOrLowerTrend = 1; } else if (sc.FormattedEvaluateUsingDoubles((double)LowerPrice, ValueFormat, LESS_EQUAL_OPERATOR, (double)(LowerBox - 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]; Volume[NewBoxIndex-1] = CumulativeVolume - sc.Volume[BaseGraphIndex]; NumTrades[NewBoxIndex-1] = CumulativeOIOrNT - sc.OpenInterest[BaseGraphIndex]; AskVol[NewBoxIndex-1] = CumulativeAskVolume - sc.AskVolume[BaseGraphIndex]; 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 += RenkoBoxSize.GetFloat(); UpperBox = (float)sc.RoundToTickSize(UpperBox, RenkoBoxSize.GetFloat()); NewLast = UpperBox; NewOtherBound = LowerBox; if (sc.FormattedEvaluateUsingDoubles((double)HigherPrice, ValueFormat, GREATER_EQUAL_OPERATOR, (double)(UpperBox + RenkoBoxSize.GetFloat()), ValueFormat)) NewEntry = 1; } else { UpperBox = LowerBox; LowerBox -= RenkoBoxSize.GetFloat(); LowerBox = (float)sc.RoundToTickSize(LowerBox, RenkoBoxSize.GetFloat()); NewLast = LowerBox; NewOtherBound = UpperBox; if (sc.FormattedEvaluateUsingDoubles((double)LowerPrice, ValueFormat, LESS_EQUAL_OPERATOR, (double)(LowerBox - RenkoBoxSize.GetFloat()), ValueFormat)) NewEntry = 1; } Low[NewBoxIndex] = LowerBox; High[NewBoxIndex] = UpperBox; RenkoLast[NewBoxIndex] = NewLast; RenkoUpDownTrend[NewBoxIndex] = (float)UpperOrLowerTrend; if (UpperOrLowerTrend == 1) { Open[NewBoxIndex] = LowerBox; Last[NewBoxIndex] = UpperBox; } else { Open[NewBoxIndex] = UpperBox; Last[NewBoxIndex] = LowerBox; } } sc.CalculateOHLCAverages(sc.OutArraySize - 1); } int RenkoIndex = sc.OutArraySize - 1; if (RenkoIndex >= 0) { Volume[RenkoIndex] = CumulativeVolume; NumTrades[RenkoIndex] = CumulativeOIOrNT; AskVol[RenkoIndex] = CumulativeAskVolume; 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_ImmediateCallExample(SCStudyInterfaceRef sc) { if (sc.SetDefaults) { // Set the configuration and defaults sc.GraphName = "Immediate Call Example"; sc.AutoLoop = 1; //Increases CPU load. Not recommended. Use only for special purposes. sc.Unused_OnExternalDataImmediateStudyCall= true; return; } if(sc.Index == sc.ArraySize - 1) { // Log the current time SCString DateTimeString = sc.DateTimeToString(sc.CurrentSystemDateTime,FLAG_DT_COMPLETE_DATETIME_MS); sc.AddMessageToLog(DateTimeString, 0); } } /*============================================================================*/ SCSFExport scsf_GetStudyPersistentVariableFromChartExample(SCStudyInterfaceRef sc) { SCInputRef ChartStudyReference = sc.Input[0]; if (sc.SetDefaults) { // Set the configuration and defaults sc.GraphName = "Get Study Persistent Variable from Chart Example"; sc.AutoLoop = 1; ChartStudyReference.Name = "Chart Study Reference"; 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(ChartStudyReference.GetChartNumber(), 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 BidPrices = sc.Subgraph[0]; SCSubgraphRef 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; BidPrices.Name = "Bid"; BidPrices.DrawStyle = DRAWSTYLE_LINE; BidPrices.PrimaryColor = RGB(255, 127, 0); BidPrices.DrawZeros = false; AskPrices.Name = "Ask"; AskPrices.DrawStyle = DRAWSTYLE_LINE; AskPrices.PrimaryColor = RGB(255, 255, 0); AskPrices.DrawZeros = false; return; } // Do data processing if ((sc.Index < sc.ArraySize -1) || sc.IsReplayRunning()) { BidPrices[sc.Index] = sc.BaseData[SC_BID_PRICE][sc.Index]; AskPrices[sc.Index] = sc.BaseData[SC_ASK_PRICE][sc.Index]; } else { BidPrices[sc.Index] = sc.Bid; AskPrices[sc.Index] = sc.Ask; } } /*============================================================================ Study function to close a single specified chart in the chartbook. ----------------------------------------------------------------------------*/ SCSFExport scsf_CloseChart(SCStudyInterfaceRef sc) { SCInputRef 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; InChartNumber.Name = "Chart To Close"; InChartNumber.SetChartNumber(0); return; } int ChartNumberToClose = InChartNumber.GetChartNumber(); if (ChartNumberToClose == 0) return; SCString Message; Message.Format("Closing chart #%d.", ChartNumberToClose); sc.AddMessageToLog(Message, 0); sc.CloseChart(ChartNumberToClose); 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 PolyDegree = sc.Input[0]; SCInputRef Period = sc.Input[1]; SCInputRef StdDev1 = sc.Input[2]; SCInputRef StdDev2 = sc.Input[3]; SCInputRef Redraw = sc.Input[4]; SCSubgraphRef Fx = sc.Subgraph[0]; SCSubgraphRef Upper2 = sc.Subgraph[1]; SCSubgraphRef Upper1 = sc.Subgraph[2]; SCSubgraphRef Lower1 = sc.Subgraph[3]; SCSubgraphRef Lower2 = sc.Subgraph[4]; if (sc.SetDefaults) { sc.GraphName = "Polynomial Regression Channel"; sc.StudyDescription = "Polynomial Regression Channel"; PolyDegree.Name = "Polynomial Degree (1-4)"; PolyDegree.SetInt(3); PolyDegree.SetIntLimits(1, 4); Period.Name = "PRC Period"; Period.SetInt(150); Period.SetIntLimits(1, 10000); StdDev1.Name = "Standard Deviation Level 1"; StdDev1.SetFloat(1.618f); StdDev1.SetFloatLimits(0, 1000); StdDev2.Name = "Standard Deviation Level 2"; StdDev2.SetFloat(2.0); StdDev2.SetFloatLimits(0, 1000); Redraw.Name = "Use Redraw"; Redraw.SetYesNo(1); Fx.Name = "Mid"; Fx.DrawZeros = false; Fx.DrawStyle = DRAWSTYLE_LINE; Fx.LineWidth = 1; Fx.LineStyle = LINESTYLE_DOT; Fx.PrimaryColor = COLOR_GRAY; Upper2.Name = "Upper 2"; Upper2.DrawZeros = false; Upper2.DrawStyle = DRAWSTYLE_TRANSPARENT_FILL_TOP; Upper2.PrimaryColor = COLOR_RED; Upper1.Name = "Upper 1"; Upper1.DrawZeros = false; Upper1.DrawStyle = DRAWSTYLE_TRANSPARENT_FILL_BOTTOM; Upper1.PrimaryColor = COLOR_RED; Lower1.Name = "Lower 1"; Lower1.DrawZeros = false; Lower1.DrawStyle = DRAWSTYLE_TRANSPARENT_FILL_TOP; Lower1.PrimaryColor = COLOR_BLUE; Lower2.Name = "Lower 2"; Lower2.DrawZeros = false; Lower2.DrawStyle = DRAWSTYLE_TRANSPARENT_FILL_BOTTOM; 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 = PolyDegree.GetInt() + 1; //----------------------sx------------ PRCData.sx[1] = Period.GetInt() + 1; for(int i=1;i<=nn*2-2;i++) { double sum = 0.0; for(int n=0;n<=Period.GetInt();n++) { sum+=pow((double)n,i); } PRCData.sx[i+1]=sum; } } // make sure we have enough bars to start if (sc.Index < Period.GetInt()) return; // erase old data on new bar if (sc.Index != lastIndex) { lastIndex = sc.Index; if (Redraw.GetYesNo()) { Fx[sc.Index-Period.GetInt()-1] = 0; Upper2[sc.Index-Period.GetInt()-1] = 0; Upper1[sc.Index-Period.GetInt()-1] = 0; Lower1[sc.Index-Period.GetInt()-1] = 0; Lower2[sc.Index-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<=Period.GetInt();n++) { if(i==1) sum+=sc.Close[sc.Index-n]; else sum+=sc.Close[sc.Index-n]*pow((double)n,i-1); } PRCData.b[i]=sum; } //===============Matrix=============== for(int j=1;j<=nn;j++) { for(int i=1; i<=nn; i++) { int k=i+j-1; PRCData.ai[i][j]=PRCData.sx[k]; // reset ai matrix } } //===============Gauss================ for(int k=1; k<=nn-1; k++) { int l=0; double m=0.0; for(int i=k; i<=nn; i++) { if(abs(PRCData.ai[i][k])>m) { m=abs(PRCData.ai[i][k]); l=i; } } if(l==0) return; if (l!=k) { double tt = 0.0; for(int j=1; j<=nn; j++) { tt=PRCData.ai[k][j]; PRCData.ai[k][j]=PRCData.ai[l][j]; PRCData.ai[l][j]=tt; } tt=PRCData.b[k]; PRCData.b[k]=PRCData.b[l]; PRCData.b[l]=tt; } for(int i=k+1;i<=nn;i++) { double qq=PRCData.ai[i][k]/PRCData.ai[k][k]; for(int j=1;j<=nn;j++) { if(j==k) PRCData.ai[i][j]=0; else PRCData.ai[i][j]=PRCData.ai[i][j]-qq*PRCData.ai[k][j]; } PRCData.b[i]=PRCData.b[i]-qq*PRCData.b[k]; } } PRCData.x[nn]=PRCData.b[nn]/PRCData.ai[nn][nn]; for(int i=nn-1;i>=1;i--) { double tt=0.0; for(int j=1;j<=nn-i;j++) { tt=tt+PRCData.ai[i][i+j]*PRCData.x[i+j]; PRCData.x[i]=(1/PRCData.ai[i][i])*(PRCData.b[i]-tt); } } //==================================== for(int n=0;n<=Period.GetInt();n++) { double sum=0.0; for(int k=1;k<=PolyDegree.GetInt();k++) { sum+=PRCData.x[k+1]*pow((double)n,k); } if (n==0 || Redraw.GetYesNo()) Fx[sc.Index-n] = (float)(PRCData.x[1]+sum); } //-------------------Std-------------- double sq=0.0, sq1=0.0, sq2=0.0; for(int n=0;n<=Period.GetInt();n++) { sq+=pow(sc.Close[sc.Index-n]-Fx[sc.Index-n],2); } sq=sqrt(sq/(Period.GetInt()+1)); sq1=sq*StdDev1.GetFloat(); sq2=sq*StdDev2.GetFloat(); for(int n=0;n<=Period.GetInt();n++) { if (n==0 || Redraw.GetYesNo()) { Upper1[sc.Index-n] = (float)(Fx[sc.Index-n]+sq1); Lower1[sc.Index-n] = (float)(Fx[sc.Index-n]-sq1); Upper2[sc.Index-n] = (float)(Fx[sc.Index-n]+sq2); Lower2[sc.Index-n] = (float)(Fx[sc.Index-n]-sq2); } } } /*==========================================================================*/ SCSFExport scsf_AveragePriceForBar(SCStudyInterfaceRef sc) { SCSubgraphRef AverageSubgraph = sc.Subgraph[0]; SCInputRef AverageFormulaInput = sc.Input[0]; if (sc.SetDefaults) { // Set the configuration and defaults. sc.GraphName = "Average Price For Bar"; sc.GraphRegion = 0; sc.AutoLoop = 1; AverageSubgraph.Name = "Average"; AverageSubgraph.DrawStyle = DRAWSTYLE_DASH; AverageSubgraph.LineWidth = 2; AverageSubgraph.PrimaryColor = RGB(255, 128, 0); AverageFormulaInput.Name = "Average Formula"; AverageFormulaInput.SetCustomInputStrings ( "(High+Low)/2" ";(High+Low+Close)/3" ";(Open+High+Low+Close)/4" ";(High+Low+Close+Close)/4" ); AverageFormulaInput.SetCustomInputIndex(0); return; } // Do data processing. const int SelectedIndex = AverageFormulaInput.GetIndex(); switch (SelectedIndex) { case 0: { AverageSubgraph.Data[sc.Index] = (sc.High[sc.Index] + sc.Low[sc.Index]) / 2.0f; } break; case 1: { AverageSubgraph.Data[sc.Index] = (sc.High[sc.Index] + sc.Low[sc.Index] + sc.Close[sc.Index]) / 3.0f; } break; case 2: { AverageSubgraph.Data[sc.Index] = (sc.Open[sc.Index] + sc.High[sc.Index] + sc.Low[sc.Index] + sc.Close[sc.Index] ) / 4.0f; } break; case 3: { AverageSubgraph.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 SymbolText = sc.Subgraph[0]; SCInputRef Input_HorizontalPosition = sc.Input[0]; SCInputRef Input_VerticalPosition = sc.Input[1]; SCInputRef Input_TransparentLabelBackground = sc.Input[3]; SCInputRef Input_UseSymbolDescription = sc.Input[5]; SCInputRef Input_DrawAboveMainPriceGraph = sc.Input[6]; if (sc.SetDefaults) { // Set the configuration and defaults sc.GraphName = "Symbol Display"; sc.AutoLoop = 0;//Manual looping sc.GraphRegion = 0; sc.ValueFormat = 0; SymbolText.Name = "Symbol Text"; SymbolText.LineWidth = 20; SymbolText.DrawStyle = DRAWSTYLE_CUSTOM_TEXT; SymbolText.PrimaryColor = RGB(0, 0, 0); //black SymbolText.SecondaryColor = RGB(255, 127, 0); //Orange SymbolText.SecondaryColorUsed = true; SymbolText.DisplayNameValueInWindowsFlags = 1; Input_HorizontalPosition.Name.Format("Initial Horizontal Position From Left (1-%d)", (int)CHART_DRAWING_MAX_HORIZONTAL_AXIS_RELATIVE_POSITION); Input_HorizontalPosition.SetInt(20); Input_HorizontalPosition.SetIntLimits(1, (int)CHART_DRAWING_MAX_HORIZONTAL_AXIS_RELATIVE_POSITION); Input_VerticalPosition.Name.Format("Initial Vertical Position From Bottom (1-%d)", (int)CHART_DRAWING_MAX_VERTICAL_AXIS_RELATIVE_POSITION); Input_VerticalPosition.SetInt(90); Input_VerticalPosition.SetIntLimits(1, (int)CHART_DRAWING_MAX_VERTICAL_AXIS_RELATIVE_POSITION); Input_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); sc.TextInputName = "Alternate Symbol Text"; return; } SCString TextToDisplay; if (Input_UseSymbolDescription.GetYesNo()) TextToDisplay = sc.SymbolData->Description; else if (sc.TextInput.GetLength() > 0) TextToDisplay = sc.TextInput; else TextToDisplay = sc.Symbol; 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, SymbolText, TransparentLabelBackground, TextToDisplay, DrawAboveMainPriceGraph); } /*==========================================================================*/ SCSFExport scsf_TradingProfitManagementStatus(SCStudyInterfaceRef sc) { SCSubgraphRef 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; StatusText.Name = "Status Text"; StatusText.LineWidth = 10; StatusText.DrawStyle = DRAWSTYLE_CUSTOM_TEXT; StatusText.PrimaryColor = RGB(255, 255, 255); StatusText.SecondaryColor = RGB(0, 0, 160); StatusText.SecondaryColorUsed = true; StatusText.DisplayNameValueInWindowsFlags = 1; Input_HorizontalPosition.Name.Format("Initial Horizontal Position From Left (1-%d)", (int)CHART_DRAWING_MAX_HORIZONTAL_AXIS_RELATIVE_POSITION); Input_HorizontalPosition.SetInt(20); Input_HorizontalPosition.SetIntLimits(1, (int)CHART_DRAWING_MAX_HORIZONTAL_AXIS_RELATIVE_POSITION); Input_VerticalPosition.Name.Format("Initial Vertical Position From Bottom (1-%d)", (int)CHART_DRAWING_MAX_VERTICAL_AXIS_RELATIVE_POSITION); Input_VerticalPosition.SetInt(90); Input_VerticalPosition.SetIntLimits(1, (int)CHART_DRAWING_MAX_VERTICAL_AXIS_RELATIVE_POSITION); Input_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, StatusText, TransparentLabelBackground, TextToDisplay, DrawAboveMainPriceGraph); } /*============================================================================*/ 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 HighOfDay = sc.Subgraph[0]; SCSubgraphRef LowOfDay = sc.Subgraph[1]; SCInputRef StudySubgraphReference = sc.Input[0]; if (sc.SetDefaults) { sc.GraphName = "Study Subgraph Daily High Low"; sc.GraphRegion = 1; sc.AutoLoop = 0; HighOfDay.Name = "High"; HighOfDay.DrawStyle = DRAWSTYLE_STAIR_STEP; HighOfDay.PrimaryColor = RGB(0,255,0); HighOfDay. DrawZeros = false; LowOfDay.Name = "Low"; LowOfDay.DrawStyle = DRAWSTYLE_STAIR_STEP; LowOfDay.PrimaryColor = RGB(255,0,255); LowOfDay. DrawZeros = false; sc.CalculationPrecedence = LOW_PREC_LEVEL; StudySubgraphReference.Name = "Study Subgraph Reference"; 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(StudySubgraphReference.GetStudyID(), 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]; HighOfDay[BarIndex] = r_CurrentDailyHigh; LowOfDay[BarIndex] = r_CurrentDailyLow; } } /*==========================================================================*/ SCSFExport scsf_TimeSeriesForecast(SCStudyInterfaceRef sc) { SCSubgraphRef TimeSeriesForecast = sc.Subgraph[0]; SCFloatArrayRef LinearRegressionSlope = sc.Subgraph[0].Arrays[0]; SCFloatArrayRef LinearRegressionIndicator = sc.Subgraph[0].Arrays[1]; SCInputRef InputData = sc.Input[0]; SCInputRef Length = sc.Input[1]; if (sc.SetDefaults) { sc.GraphName = "Time Series Forecast"; sc.AutoLoop = 1; sc.GraphRegion = 1; sc.ValueFormat = 3; TimeSeriesForecast.Name = "TSF"; TimeSeriesForecast.DrawStyle = DRAWSTYLE_LINE; TimeSeriesForecast.PrimaryColor = RGB(0,255,0); TimeSeriesForecast.DrawZeros = true; InputData.Name = "Input Data"; InputData.SetInputDataIndex(SC_LAST); Length.Name = "Length"; Length.SetInt(10); Length.SetIntLimits(1,MAX_STUDY_LENGTH); return; } sc.DataStartIndex = Length.GetInt()-1; int CalculationLength=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[InputData.GetInputDataIndex()][Index]; SumY += sc.BaseData[InputData.GetInputDataIndex()][Index]; } double Sum2 = SumBars * SumY; double Num1 = CalculationLength*Sum1 - Sum2; double Num2 = SumBars*SumBars - CalculationLength*SumSqrBars; LinearRegressionSlope[sc.Index] = (float)(Num1 / Num2); sc.LinearRegressionIndicator(sc.BaseData[InputData.GetInputDataIndex()], LinearRegressionIndicator, CalculationLength); TimeSeriesForecast[sc.Index] = LinearRegressionIndicator[sc.Index] + LinearRegressionSlope[sc.Index]; return; } /*==========================================================================*/ SCSFExport scsf_ExtendClosesUntilFutureIntersection(SCStudyInterfaceRef sc) { SCSubgraphRef LinePropertiesSubgraph = sc.Subgraph[0]; SCInputRef DisplayValueLabel = sc.Input[0]; SCInputRef NameLabel = sc.Input[1]; if (sc.SetDefaults) { // Set the configuration and defaults. sc.GraphName = "Extend Closes Until Future Intersection"; LinePropertiesSubgraph.Name = "Line Properties"; LinePropertiesSubgraph.DrawStyle = DRAWSTYLE_SUBGRAPH_NAME_AND_VALUE_LABELS_ONLY; LinePropertiesSubgraph.LineWidth = 1; LinePropertiesSubgraph.PrimaryColor = COLOR_RED; LinePropertiesSubgraph.DrawZeros = false; DisplayValueLabel.Name = "Display Value Label"; DisplayValueLabel.SetYesNo(true); NameLabel.Name = "Name Label"; 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 = NameLabel.GetString(); bool DisplayNameLabel = false; if (NameLabelString != NULL && strlen(NameLabelString) > 0) DisplayNameLabel = true; else NameLabelString = ""; sc.AddLineUntilFutureIntersection ( sc.Index - 1 , 0 // LineIDForBar , ClosePriceOfPriorBar , LinePropertiesSubgraph.PrimaryColor , LinePropertiesSubgraph.LineWidth , LinePropertiesSubgraph.LineStyle , DisplayValueLabel.GetYesNo() , DisplayNameLabel , NameLabelString ); } /*==========================================================================*/ SCSFExport scsf_ExtendBarValueUntilFutureIntersection(SCStudyInterfaceRef sc) { SCSubgraphRef LinePropertiesSubgraph = sc.Subgraph[0]; SCInputRef InputData = sc.Input[0]; SCInputRef DisplayValueLabel = sc.Input[1]; SCInputRef NameLabel = sc.Input[2]; if (sc.SetDefaults) { // Set the configuration and defaults. sc.GraphName = "Extend Bar Value Until Future Intersection"; LinePropertiesSubgraph.Name = "Line Properties"; LinePropertiesSubgraph.DrawStyle = DRAWSTYLE_SUBGRAPH_NAME_AND_VALUE_LABELS_ONLY; LinePropertiesSubgraph.LineWidth = 1; LinePropertiesSubgraph.PrimaryColor = COLOR_RED; LinePropertiesSubgraph.DrawZeros = false; InputData.Name = "Input Data from Bar for Extension Lines"; InputData.SetInputDataIndex(SC_LAST); DisplayValueLabel.Name = "Display Value Label"; DisplayValueLabel.SetYesNo(true); NameLabel.Name = "Name Label"; NameLabel.SetString(""); sc.ValueFormat = VALUEFORMAT_INHERITED; sc.GraphRegion = 0; sc.AutoLoop = 1; return; } const char* NameLabelString = NameLabel.GetString(); bool DisplayNameLabel = false; if (NameLabelString != NULL && strlen(NameLabelString) > 0) DisplayNameLabel = true; else NameLabelString = ""; sc.AddLineUntilFutureIntersection ( sc.Index , 0 // LineIDForBar , sc.BaseData[ InputData.GetInputDataIndex()][sc.Index] , LinePropertiesSubgraph.PrimaryColor , LinePropertiesSubgraph.LineWidth , LinePropertiesSubgraph.LineStyle , DisplayValueLabel.GetYesNo() , DisplayNameLabel , NameLabelString ); } /*==========================================================================*/ SCSFExport scsf_ExtendBarGapUntilFutureIntersection(SCStudyInterfaceRef sc) { SCSubgraphRef LinePropertiesSubgraph = sc.Subgraph[0]; SCInputRef DisplayValueLabel = sc.Input[0]; SCInputRef NameLabel = sc.Input[1]; SCInputRef CompareToOpentoCloseRangeOnly = sc.Input[2]; if (sc.SetDefaults) { // Set the configuration and defaults. sc.GraphName = "Extend Bar Gap Until Future Intersection"; LinePropertiesSubgraph.Name = "Line Properties"; LinePropertiesSubgraph.DrawStyle = DRAWSTYLE_SUBGRAPH_NAME_AND_VALUE_LABELS_ONLY; LinePropertiesSubgraph.LineWidth = 1; LinePropertiesSubgraph.PrimaryColor = COLOR_RED; LinePropertiesSubgraph.DrawZeros = false; DisplayValueLabel.Name = "Display Value Label"; DisplayValueLabel.SetYesNo(true); NameLabel.Name = "Name Label"; NameLabel.SetString(""); CompareToOpentoCloseRangeOnly.Name = "Compare to Open to Close Range Only"; CompareToOpentoCloseRangeOnly.SetYesNo(false); sc.ValueFormat = VALUEFORMAT_INHERITED; sc.GraphRegion = 0; sc.AutoLoop = 1; return; } if (sc.Index == 0) return; float ExtendPrice = 0.0; if (!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; } const char* NameLabelString = NameLabel.GetString(); bool DisplayNameLabel = false; if (NameLabelString != NULL && strlen(NameLabelString) > 0) DisplayNameLabel = true; else NameLabelString = ""; sc.AddLineUntilFutureIntersection ( sc.Index - 1 , 0 // LineIDForBar. Use 0 since there is only one line per bar. , ExtendPrice , LinePropertiesSubgraph.PrimaryColor , LinePropertiesSubgraph.LineWidth , LinePropertiesSubgraph.LineStyle , DisplayValueLabel.GetYesNo() , DisplayNameLabel , NameLabelString ); } /*==========================================================================*/ SCSFExport scsf_MarketDepthPullingStackingValuesExample(SCStudyInterfaceRef sc) { SCSubgraphRef BidPullingStackingSubgraph = sc.Subgraph[0]; SCSubgraphRef AskPullingStackingSubgraph = 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; BidPullingStackingSubgraph.Name = "Bid"; BidPullingStackingSubgraph.DrawStyle = DRAWSTYLE_LINE; AskPullingStackingSubgraph.Name = "Ask"; AskPullingStackingSubgraph.DrawStyle = DRAWSTYLE_LINE; return; } //The following two functions will return 0 if there is no pulling and stacking value at the specified price BidPullingStackingSubgraph[sc.ArraySize - 1] = (float)sc.GetBidMarketDepthStackPullValueAtPrice(sc.Bid); AskPullingStackingSubgraph[sc.ArraySize - 1] = (float)sc.GetAskMarketDepthStackPullValueAtPrice(sc.Ask); } /*==========================================================================*/ SCSFExport scsf_Repulse(SCStudyGraphRef sc) { SCSubgraphRef RepulseSubgraph = sc.Subgraph[0]; SCInputRef LengthInput = sc.Input[0]; if (sc.SetDefaults) { // Set the configuration and defaults sc.GraphName = "Repulse"; sc.AutoLoop = 1; sc.GraphRegion = 1; RepulseSubgraph.Name = "Repulse"; RepulseSubgraph.PrimaryColor = RGB(0, 255, 0); RepulseSubgraph.DrawStyle = DRAWSTYLE_LINE; RepulseSubgraph.LineWidth = 2; LengthInput.Name = "Length"; LengthInput.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 = LengthInput.GetInt(); sc.Highest(sc.High, RepulseSubgraph.Arrays[0], Length); sc.Lowest(sc.Low, RepulseSubgraph.Arrays[1], Length); RepulseSubgraph.Arrays[2][sc.Index] = 100 * (3 * sc.Close[sc.Index] - 2 * RepulseSubgraph.Arrays[1][sc.Index] - sc.Open[sc.Index - Length + 1]) / sc.Close[sc.Index]; RepulseSubgraph.Arrays[3][sc.Index] = 100 * (sc.Open[sc.Index - Length + 1] + 2 * RepulseSubgraph.Arrays[0][sc.Index] - 3 * sc.Close[sc.Index]) / sc.Close[sc.Index]; sc.MovingAverage(RepulseSubgraph.Arrays[2], RepulseSubgraph.Arrays[4], MOVAVGTYPE_EXPONENTIAL, 5*Length); sc.MovingAverage(RepulseSubgraph.Arrays[3], RepulseSubgraph.Arrays[5], MOVAVGTYPE_EXPONENTIAL, 5*Length); RepulseSubgraph.Data[sc.Index] = RepulseSubgraph.Arrays[4][sc.Index] - RepulseSubgraph.Arrays[5][sc.Index]; } /*==========================================================================*/ SCSFExport scsf_FullContractValue(SCStudyInterfaceRef sc) { SCSubgraphRef Result = sc.Subgraph[0]; SCInputRef InputData = sc.Input[0]; SCInputRef 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 Result.Name = "Result"; Result.DrawStyle = DRAWSTYLE_LINE; Result.PrimaryColor = RGB(0, 255, 0); InputData.Name = "Input Data"; InputData.SetInputDataIndex(SC_LAST); DrawZeros.Name = "Draw Zeros"; DrawZeros.SetYesNo(false); return; } Result.DrawZeros = DrawZeros.GetYesNo(); int CalculationStartIndex = sc.GetCalculationStartIndexForStudy(); for (int Index = CalculationStartIndex; Index < sc.ArraySize; Index++) { Result[Index] = sc.BaseData[InputData.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 SlowK = sc.Subgraph[0]; SCSubgraphRef SlowD = sc.Subgraph[1]; SCSubgraphRef Line1 = sc.Subgraph[2]; SCSubgraphRef Line2 = sc.Subgraph[3]; SCSubgraphRef StochasticOutput = sc.Subgraph[4]; SCSubgraphRef JLine = sc.Subgraph[5]; SCInputRef FastKLength = sc.Input[2]; SCInputRef FastDLength = sc.Input[3]; SCInputRef SlowDLength = sc.Input[4]; SCInputRef Line1Value = sc.Input[5]; SCInputRef Line2Value = sc.Input[6]; SCInputRef MovAvgType = sc.Input[7]; SCInputRef InputDataHigh = sc.Input[8]; SCInputRef InputDataLow = sc.Input[9]; SCInputRef InputDataLast = sc.Input[10]; if (sc.SetDefaults) { sc.GraphName = "KDJ"; sc.ValueFormat = 2; SlowK.Name = "Slow %K"; SlowK.DrawStyle = DRAWSTYLE_LINE; SlowK.PrimaryColor = RGB(0, 255, 0); SlowK.DrawZeros = true; SlowD.Name = "Slow %D"; SlowD.DrawStyle = DRAWSTYLE_LINE; SlowD.PrimaryColor = RGB(255, 0, 255); SlowD.DrawZeros = true; Line1.Name = "Line1"; Line1.DrawStyle = DRAWSTYLE_LINE; Line1.PrimaryColor = RGB(255, 255, 0); Line1.DrawZeros = true; Line2.Name = "Line2"; Line2.DrawStyle = DRAWSTYLE_LINE; Line2.PrimaryColor = RGB(255, 127, 0); Line2.DrawZeros = true; JLine.Name = "J Line"; JLine.DrawStyle = DRAWSTYLE_LINE; JLine.PrimaryColor = RGB(255, 0, 0); JLine.DrawZeros = true; FastKLength.Name = "Fast %K Length"; FastKLength.SetInt(10); FastKLength.SetIntLimits(1, MAX_STUDY_LENGTH); FastDLength.Name = "Fast %D Length (Slow %K)"; FastDLength.SetInt(3); FastDLength.SetIntLimits(1, MAX_STUDY_LENGTH); SlowDLength.Name = "Slow %D Length"; SlowDLength.SetInt(3); SlowDLength.SetIntLimits(1, MAX_STUDY_LENGTH); Line1Value.Name = "Line1 Value"; Line1Value.SetFloat(70); Line2Value.Name = "Line2 Value"; Line2Value.SetFloat(30); MovAvgType.Name = "Moving Average Type"; MovAvgType.SetMovAvgType(MOVAVGTYPE_SIMPLE); InputDataHigh.Name = "Input Data for High"; InputDataHigh.SetInputDataIndex(SC_HIGH); InputDataLow.Name = "Input Data for Low"; InputDataLow.SetInputDataIndex(SC_LOW); InputDataLast.Name = "Input Data for Last"; InputDataLast.SetInputDataIndex(SC_LAST); sc.AutoLoop = true; return; } sc.DataStartIndex = FastKLength.GetInt() + FastDLength.GetInt() + SlowDLength.GetInt(); sc.Stochastic( sc.BaseData[InputDataHigh.GetInputDataIndex()], sc.BaseData[InputDataLow.GetInputDataIndex()], sc.BaseData[InputDataLast.GetInputDataIndex()], StochasticOutput, // Data member is Fast %K FastKLength.GetInt(), FastDLength.GetInt(), SlowDLength.GetInt(), MovAvgType.GetMovAvgType() ); SlowK[sc.Index] = StochasticOutput.Arrays[0][sc.Index]; SlowD[sc.Index] = StochasticOutput.Arrays[1][sc.Index]; JLine[sc.Index] = 3 * SlowK[sc.Index] - 2 * SlowD[sc.Index]; Line1[sc.Index] = Line1Value.GetFloat(); Line2[sc.Index] = 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(); }