#include "sierrachart.h" #include "scstudyfunctions.h" /***********************************************************************/ SCSFExport scsf_ChaikinOsc(SCStudyInterfaceRef sc) { SCSubgraphRef Subgraph_Oscillator = sc.Subgraph[0]; SCSubgraphRef Subgraph_Overbought = sc.Subgraph[2]; SCSubgraphRef Subgraph_Oversold = sc.Subgraph[3]; SCInputRef Input_LongMALength = sc.Input[2]; SCInputRef Input_ShortMALength = sc.Input[3]; SCInputRef Input_Divisor = sc.Input[4]; SCInputRef Input_OverboughtValue = sc.Input[5]; SCInputRef Input_OversoldValue = sc.Input[6]; if(sc.SetDefaults) { sc.GraphName = "Chaikin Oscillator"; Subgraph_Oscillator.Name = "Oscillator"; Subgraph_Oscillator.DrawStyle = DRAWSTYLE_LINE; Subgraph_Oscillator.PrimaryColor = RGB(0,255,0); Subgraph_Overbought.Name = "Overbought"; Subgraph_Overbought.DrawStyle = DRAWSTYLE_LINE; Subgraph_Overbought.PrimaryColor = RGB(255,255,0); Subgraph_Overbought.DrawZeros = false; Subgraph_Oversold.Name = "Oversold"; Subgraph_Oversold.DrawStyle = DRAWSTYLE_LINE; Subgraph_Oversold.PrimaryColor = RGB(255,127,0); Subgraph_Oversold.DrawZeros = false; Input_LongMALength.Name = "Long MovAvg Length"; Input_LongMALength.SetInt(10); Input_LongMALength.SetIntLimits(1,MAX_STUDY_LENGTH); Input_ShortMALength.Name = "Short MovAvg Length"; Input_ShortMALength.SetInt(3); Input_ShortMALength.SetIntLimits(1,MAX_STUDY_LENGTH); Input_Divisor.Name = "Divisor"; Input_Divisor.SetFloat(1); Input_Divisor.SetFloatLimits(.00001f, static_cast(MAX_STUDY_LENGTH)); Input_OverboughtValue.Name = "Overbought"; Input_OverboughtValue.SetInt(0); Input_OversoldValue.Name = "Oversold"; Input_OversoldValue.SetInt(0); sc.AutoLoop = 1; return; } sc.DataStartIndex = max(Input_LongMALength.GetInt(),Input_ShortMALength.GetInt()) - 1; sc.AccumulationDistribution(sc.BaseDataIn, Subgraph_Oscillator.Arrays[0], sc.Index); sc.ExponentialMovAvg(Subgraph_Oscillator.Arrays[0], Subgraph_Oscillator.Arrays[1], sc.Index, Input_LongMALength.GetInt()); sc.ExponentialMovAvg(Subgraph_Oscillator.Arrays[0], Subgraph_Oscillator.Arrays[2], sc.Index, Input_ShortMALength.GetInt()); Subgraph_Oscillator[sc.Index] = (Subgraph_Oscillator.Arrays[2][sc.Index] - Subgraph_Oscillator.Arrays[1][sc.Index]) / Input_Divisor.GetInt(); Subgraph_Overbought[sc.Index] = static_cast(Input_OverboughtValue.GetInt()); Subgraph_Oversold[sc.Index] = static_cast(Input_OversoldValue.GetInt()); } /*==========================================================================*/ SCSFExport scsf_HistoricalVolatilityRatio(SCStudyInterfaceRef sc) { SCSubgraphRef Subgraph_HVR = sc.Subgraph[0]; SCFloatArrayRef Array_TempLog = sc.Subgraph[0].Arrays[0]; SCFloatArrayRef Array_TempShort = sc.Subgraph[0].Arrays[1]; SCFloatArrayRef Array_TempLong = sc.Subgraph[0].Arrays[2]; SCInputRef Input_ShortLength = sc.Input[2]; SCInputRef Input_LongLength = sc.Input[3]; SCFloatArrayRef Array_Close = sc.Close; // Configuration if (sc.SetDefaults) { sc.GraphName = "Historical Volatility Ratio"; Subgraph_HVR.Name = "HVR"; Subgraph_HVR.DrawStyle = DRAWSTYLE_LINE; Subgraph_HVR.PrimaryColor = RGB(0,255,0); Input_ShortLength.Name = "Short Length"; Input_ShortLength.SetInt(6); Input_ShortLength.SetIntLimits(1, INT_MAX); Input_LongLength.Name = "Long Length"; Input_LongLength.SetInt(100); Input_LongLength.SetIntLimits(1, INT_MAX); sc.AutoLoop = 1; return; } // Data Processing sc.DataStartIndex = max(Input_LongLength.GetInt(), Input_ShortLength.GetInt()); if (sc.Index == 0) return; if (Array_Close[sc.Index - 1] != 0.0) Array_TempLog[sc.Index] = logf(Array_Close[sc.Index] / Array_Close[sc.Index - 1]); else Array_TempLog[sc.Index] = 0; sc.StdDeviation(Array_TempLog, Array_TempShort, sc.Index, Input_ShortLength.GetInt()); sc.StdDeviation(Array_TempLog, Array_TempLong, sc.Index, Input_LongLength.GetInt()); if (Array_TempLog[sc.Index] != 0) Subgraph_HVR[sc.Index] = Array_TempShort[sc.Index] / Array_TempLong[sc.Index]; else Subgraph_HVR[sc.Index] = Subgraph_HVR[sc.Index-1]; } /*==========================================================================*/ SCSFExport scsf_CurrentPriceLine(SCStudyInterfaceRef sc) { SCSubgraphRef Subgraph_CurrentPriceLine = sc.Subgraph[0]; SCInputRef Input_NumberOfBarsBack = sc.Input[0]; SCInputRef Input_InputData = sc.Input[1]; SCInputRef Input_Version = sc.Input[2]; SCInputRef Input_DisplayCPLOnBars = sc.Input[3]; SCInputRef Input_ProjectForward = sc.Input[4]; SCInputRef Input_UseLastFromCurrentQuoteData = sc.Input [5]; SCInputRef Input_NumberOfForwardProjectionBars = sc.Input[6]; SCInputRef Input_NumberOfBarsBackToReference = sc.Input[7]; if(sc.SetDefaults) { sc.GraphName = "Current Price Line"; Subgraph_CurrentPriceLine.Name = "CPL"; Subgraph_CurrentPriceLine.DrawStyle = DRAWSTYLE_LINE; Subgraph_CurrentPriceLine.PrimaryColor = RGB(0,255,0); Subgraph_CurrentPriceLine.DrawZeros = false; Subgraph_CurrentPriceLine.LineStyle = LINESTYLE_DOT; sc.ScaleRangeType = SCALE_SAMEASREGION; sc.GraphRegion = 0; Input_NumberOfBarsBack.Name = "Number of Bars to Display On. 0 = Current Day"; Input_NumberOfBarsBack.SetInt(0); Input_NumberOfBarsBack.SetIntLimits(0,MAX_STUDY_LENGTH); Input_InputData.Name = "Input Data"; Input_InputData.SetInputDataIndex(SC_LAST); Input_DisplayCPLOnBars.Name = "Display Current Price Line on Chart Bars"; Input_DisplayCPLOnBars.SetYesNo(true); Input_ProjectForward.Name = "Forward Project Current Price Line"; Input_ProjectForward.SetYesNo(false); Input_UseLastFromCurrentQuoteData.Name = "Use Last Trade Price From Current Quote Data"; Input_UseLastFromCurrentQuoteData.SetYesNo(false); Input_NumberOfForwardProjectionBars.Name = "Number of Forward Projection Bars"; Input_NumberOfForwardProjectionBars.SetInt(10); Input_NumberOfBarsBackToReference.Name = "Number of Bars Back to Reference"; Input_NumberOfBarsBackToReference.SetInt(0); Input_NumberOfBarsBackToReference.SetIntLimits(0, MAX_STUDY_LENGTH); Input_Version.SetInt(2); sc.AutoLoop = 0; //Manual looping return; } if (Input_NumberOfForwardProjectionBars.GetInt() == 0) Input_NumberOfForwardProjectionBars.SetInt(10); SCFloatArrayRef InputDataArray = sc.BaseData[Input_InputData.GetInputDataIndex()]; float LineValue = 0; if(Input_UseLastFromCurrentQuoteData.GetYesNo()) LineValue = sc.LastTradePrice; else { LineValue = InputDataArray[sc.ArraySize - 1 - Input_NumberOfBarsBackToReference.GetInt()]; } int &r_PriorLineStartIndex = sc.GetPersistentInt(1); float &r_PriorValue = sc.GetPersistentFloat(2); int &r_PriorArraySize = sc.GetPersistentInt(3); if (sc.IsFullRecalculation) { r_PriorValue = 0; r_PriorArraySize = 0; } bool LineNeedsUpdating = false; if (LineValue != r_PriorValue || sc.ArraySize != r_PriorArraySize) LineNeedsUpdating = true; r_PriorValue = LineValue; r_PriorArraySize = sc.ArraySize; if (!LineNeedsUpdating)//for efficiency return; if(Input_DisplayCPLOnBars.GetYesNo()) { int BarsBack = Input_NumberOfBarsBack.GetInt(); if (BarsBack == 0)// Current Day { SCDateTime TradingDayStartDateTime = sc.GetTradingDayStartDateTimeOfBar(sc.BaseDateTimeIn[sc.ArraySize - 1]); int BarIndex = 0; for (BarIndex = sc.ArraySize - 1; sc.BaseDateTimeIn[BarIndex] >= TradingDayStartDateTime && BarIndex >= 0; BarIndex--) { Subgraph_CurrentPriceLine[BarIndex] = LineValue; sc.EarliestUpdateSubgraphDataArrayIndex = BarIndex; } } else { int StartingIndex = max(0, sc.ArraySize - BarsBack); sc.EarliestUpdateSubgraphDataArrayIndex = sc.UpdateStartIndex; for (int Index = max(0, sc.UpdateStartIndex - BarsBack); Index < sc.ArraySize; ++Index) { if(Index >= StartingIndex) break; Subgraph_CurrentPriceLine[Index] = 0; if (Index < sc.EarliestUpdateSubgraphDataArrayIndex) sc.EarliestUpdateSubgraphDataArrayIndex = Index; } for (int Index = sc.ArraySize - 1; BarsBack > 0 && Index >= 0; Index--) { Subgraph_CurrentPriceLine[Index] = LineValue; BarsBack--; if (Index < sc.EarliestUpdateSubgraphDataArrayIndex) sc.EarliestUpdateSubgraphDataArrayIndex = Index; } } } else if (r_PriorLineStartIndex != 0) { //Clear prior array elements for when projecting forward for(int Index = r_PriorLineStartIndex; Index < sc.ArraySize; Index++) Subgraph_CurrentPriceLine[Index] = 0.0; } // Zero out prior values int StartClearIndex = 0; if (Input_DisplayCPLOnBars.GetYesNo()) StartClearIndex = sc.EarliestUpdateSubgraphDataArrayIndex - 1; else StartClearIndex = sc.ArraySize - 1; for (int BarIndex = StartClearIndex; BarIndex >= 0; --BarIndex) { if (Subgraph_CurrentPriceLine[BarIndex] == 0.0f) break; Subgraph_CurrentPriceLine[BarIndex] = 0.0f; sc.EarliestUpdateSubgraphDataArrayIndex = BarIndex; } if (Input_ProjectForward.GetYesNo()) { int NumberOfBars = Input_NumberOfForwardProjectionBars.GetInt(); Subgraph_CurrentPriceLine.ExtendedArrayElementsToGraph = NumberOfBars; for(int Index = 0; Index < NumberOfBars; Index++) { Subgraph_CurrentPriceLine[sc.ArraySize + Index] = LineValue; } r_PriorLineStartIndex = sc.ArraySize; } else Subgraph_CurrentPriceLine.ExtendedArrayElementsToGraph = 0; } /*==========================================================================*/ SCSFExport scsf_CurrentBidAskLines(SCStudyInterfaceRef sc) { SCSubgraphRef Subgraph_CurrentBidLine = sc.Subgraph[0]; SCSubgraphRef Subgraph_CurrentAskLine = sc.Subgraph[1]; SCInputRef Input_NumberOfBarsBack = sc.Input[0]; SCInputRef Input_DisplayLinesOnBars = sc.Input[1]; SCInputRef Input_ProjectForward = sc.Input[2]; SCInputRef Input_NumberOfForwardProjectionBars = sc.Input[3]; if (sc.SetDefaults) { sc.GraphName = "Current Bid Ask Lines"; Subgraph_CurrentBidLine.Name = "Bid"; Subgraph_CurrentBidLine.DrawStyle = DRAWSTYLE_LINE; Subgraph_CurrentBidLine.PrimaryColor = RGB(0, 255, 0); Subgraph_CurrentBidLine.DrawZeros = false; Subgraph_CurrentBidLine.LineStyle = LINESTYLE_SOLID; Subgraph_CurrentBidLine.LineWidth = 2; Subgraph_CurrentAskLine.Name = "Ask"; Subgraph_CurrentAskLine.DrawStyle = DRAWSTYLE_LINE; Subgraph_CurrentAskLine.PrimaryColor = RGB(255, 0, 0); Subgraph_CurrentAskLine.DrawZeros = false; Subgraph_CurrentAskLine.LineStyle = LINESTYLE_SOLID; Subgraph_CurrentAskLine.LineWidth = 2; sc.ScaleRangeType = SCALE_SAMEASREGION; sc.GraphRegion = 0; Input_NumberOfBarsBack.Name = "Number of Bars to Display On. 0=Current Day"; Input_NumberOfBarsBack.SetInt(0); Input_NumberOfBarsBack.SetIntLimits(0, MAX_STUDY_LENGTH); Input_DisplayLinesOnBars.Name = "Display Current Lines on Chart Bars"; Input_DisplayLinesOnBars.SetYesNo(true); Input_ProjectForward.Name = "Forward Project Bid and Ask Lines"; Input_ProjectForward.SetYesNo(false); Input_NumberOfForwardProjectionBars.Name = "Number of Forward Projection Bars"; Input_NumberOfForwardProjectionBars.SetInt(10); sc.AutoLoop = 0; return; } if (Input_NumberOfForwardProjectionBars.GetInt() == 0) Input_NumberOfForwardProjectionBars.SetInt(10); float BidLineValue = sc.Bid; float AskLineValue = sc.Ask; int &r_PriorLineStartIndex = sc.GetPersistentInt(1); int EarliestUpdateSubgraphDataArrayIndex = sc.ArraySize; if (Input_DisplayLinesOnBars.GetYesNo()) { const int BarsBack = Input_NumberOfBarsBack.GetInt(); if (BarsBack == 0) { SCDateTime TradingDayStartDateTime = sc.GetTradingDayStartDateTimeOfBar(sc.BaseDateTimeIn[sc.ArraySize - 1]); int BarIndex = 0; for (BarIndex = sc.ArraySize - 1; sc.BaseDateTimeIn[BarIndex] >= TradingDayStartDateTime && BarIndex >= 0; BarIndex--) { Subgraph_CurrentBidLine[BarIndex] = BidLineValue; Subgraph_CurrentAskLine[BarIndex] = AskLineValue; EarliestUpdateSubgraphDataArrayIndex = BarIndex; } } else { int StartingIndex = sc.ArraySize - BarsBack; for (int Index = sc.ArraySize - 1; Index >= StartingIndex; Index--) { Subgraph_CurrentBidLine[Index] = BidLineValue; Subgraph_CurrentAskLine[Index] = AskLineValue; EarliestUpdateSubgraphDataArrayIndex = Index; } } } if (Input_ProjectForward.GetYesNo()) { int NumberOfBars = Input_NumberOfForwardProjectionBars.GetInt(); Subgraph_CurrentBidLine.ExtendedArrayElementsToGraph = NumberOfBars; Subgraph_CurrentAskLine.ExtendedArrayElementsToGraph = NumberOfBars; for (int Index = 0; Index < NumberOfBars; Index++) { Subgraph_CurrentBidLine[sc.ArraySize + Index] = BidLineValue; Subgraph_CurrentAskLine[sc.ArraySize + Index] = AskLineValue; } } else { Subgraph_CurrentBidLine.ExtendedArrayElementsToGraph = 0; Subgraph_CurrentAskLine.ExtendedArrayElementsToGraph = 0; } for (int Index = r_PriorLineStartIndex; Index < EarliestUpdateSubgraphDataArrayIndex; ++Index) { Subgraph_CurrentBidLine[Index] = 0.0; Subgraph_CurrentAskLine[Index] = 0.0; } //if (r_PriorLineStartIndex != 0 // && r_PriorLineStartIndex < EarliestUpdateSubgraphDataArrayIndex) //{ // EarliestUpdateSubgraphDataArrayIndex = r_PriorLineStartIndex; //} //else r_PriorLineStartIndex = EarliestUpdateSubgraphDataArrayIndex; if (EarliestUpdateSubgraphDataArrayIndex < sc.EarliestUpdateSubgraphDataArrayIndex) sc.EarliestUpdateSubgraphDataArrayIndex = EarliestUpdateSubgraphDataArrayIndex; } /*==========================================================================*/ SCSFExport scsf_OutOfOrderTimestampsDetector(SCStudyInterfaceRef sc) { SCSubgraphRef Subgraph_OutOfOrderTimestamp = sc.Subgraph[0]; if(sc.SetDefaults) { sc.GraphName = "Out of Order Timestamps Detector"; Subgraph_OutOfOrderTimestamp.Name = "Out of Order Timestamp"; Subgraph_OutOfOrderTimestamp.PrimaryColor = RGB(255,64,32); Subgraph_OutOfOrderTimestamp.DrawStyle = DRAWSTYLE_BACKGROUND; Subgraph_OutOfOrderTimestamp.LineWidth = 5; Subgraph_OutOfOrderTimestamp.DrawZeros = false; sc.GraphRegion = 0; sc.DisplayStudyInputValues= false; sc.ScaleRangeType = SCALE_INDEPENDENT; sc.DrawStudyUnderneathMainPriceGraph; sc.AutoLoop = 1; return; } sc.DataStartIndex = 0; if (sc.Index <= 0) return; SCDateTime PreviousBarDateTime = sc.BaseDateTimeIn[sc.Index-1]; SCDateTime CurrentBarDateTime = sc.BaseDateTimeIn[sc.Index]; if(CurrentBarDateTime < PreviousBarDateTime) Subgraph_OutOfOrderTimestamp.Data[sc.Index] = 1; else Subgraph_OutOfOrderTimestamp.Data[sc.Index] = 0; return; } /*==========================================================================*/ SCSFExport scsf_DuplicateTimestampsDetector(SCStudyInterfaceRef sc) { SCSubgraphRef Subgraph_DuplicateTimestamp = sc.Subgraph[0]; if (sc.SetDefaults) { sc.GraphName = "Duplicate Timestamps Detector"; Subgraph_DuplicateTimestamp.Name = "DuplicateTimestamp"; Subgraph_DuplicateTimestamp.PrimaryColor = RGB(255, 64, 32); Subgraph_DuplicateTimestamp.DrawStyle = DRAWSTYLE_BACKGROUND; Subgraph_DuplicateTimestamp.LineWidth = 5; Subgraph_DuplicateTimestamp.DrawZeros = false; sc.GraphRegion = 0; sc.DisplayStudyInputValues = false; sc.ScaleRangeType = SCALE_INDEPENDENT; sc.DrawStudyUnderneathMainPriceGraph; sc.AutoLoop = 0; return; } sc.DataStartIndex = 1; int FirstValidIndex = 1; for(int BarIndex = max(FirstValidIndex, sc.UpdateStartIndex); BarIndex < sc.ArraySize; BarIndex++) { SCDateTimeMS PreviousBarDateTime = sc.BaseDateTimeIn[BarIndex -1]; SCDateTimeMS CurrentBarDateTime = sc.BaseDateTimeIn[BarIndex]; if (CurrentBarDateTime == PreviousBarDateTime) Subgraph_DuplicateTimestamp.Data[BarIndex] = 1; else Subgraph_DuplicateTimestamp.Data[BarIndex] = 0; } } /************************************************************ * MoneyFlowIndex * * typical price: (high + low + close )/3 * money flow: typical price * volume * money ratio: positive money flow / negative money flow ************************************************************/ SCSFExport scsf_MoneyFlowIndex(SCStudyInterfaceRef sc) { SCSubgraphRef Subgraph_MFI = sc.Subgraph[0]; SCInputRef Input_Length = sc.Input[2]; if (sc.SetDefaults) { sc.GraphName = "Money Flow Index"; sc.GraphRegion = 1; sc.ValueFormat = 3; Subgraph_MFI.DrawStyle = DRAWSTYLE_LINE; Subgraph_MFI.Name = "MFI"; Subgraph_MFI.PrimaryColor = RGB(0, 255, 0); Subgraph_MFI.DrawZeros = true; Input_Length.Name = "Length"; Input_Length.SetInt(14); Input_Length.SetIntLimits(1, MAX_STUDY_LENGTH); sc.AutoLoop = 1; return; } const double BIAS_DIVISION_DOUBLE = static_cast(10e-20); double typ_price = 0.0, prev_typ_price = 0.0, money_flow = 0.0, volume = 0.0, N_pos_mon_flow = 0.0, N_neg_mon_flow = 0.0, MoneyFlowIndex = 0.0, money_ratio = 0.0; sc.DataStartIndex = Input_Length.GetInt(); if ((sc.Index - Input_Length.GetInt() + 1) != 0) prev_typ_price = sc.HLCAvg[sc.Index - Input_Length.GetInt()]; for(int IndexOffset= 0; IndexOffset < Input_Length.GetInt(); IndexOffset++) { volume = sc.Volume[sc.Index - Input_Length.GetInt() + 1 + IndexOffset]; typ_price = sc.HLCAvg[sc.Index - Input_Length.GetInt() + 1 + IndexOffset]; money_flow = typ_price * volume; N_pos_mon_flow += typ_price > prev_typ_price ? money_flow : 0; N_neg_mon_flow += typ_price < prev_typ_price ? money_flow : 0; prev_typ_price = typ_price; } money_ratio = N_pos_mon_flow / (N_neg_mon_flow + BIAS_DIVISION_DOUBLE); MoneyFlowIndex = 100.0 - (100.0 / (1.0 + money_ratio)); Subgraph_MFI[sc.Index] = static_cast(MoneyFlowIndex); } /*==========================================================================*/ SCSFExport scsf_VolumeWeightedAveragePrice(SCStudyInterfaceRef sc) { SCSubgraphRef Subgraph_VWAPSubgraph = sc.Subgraph[0]; SCFloatArrayRef Array_BarSumPriceTimesVolume = Subgraph_VWAPSubgraph.Arrays[0]; SCFloatArrayRef Array_BarSumPriceSquaredTimesVolume = Subgraph_VWAPSubgraph.Arrays[1]; SCFloatArrayRef Array_StandardDeviationArray = Subgraph_VWAPSubgraph.Arrays[2]; SCFloatArrayRef Array_BarSumPriceVWAPDifferenceSquaredTimesVolume = Subgraph_VWAPSubgraph.Arrays[3]; SCFloatArrayRef Array_CalculatedBarVolume = Subgraph_VWAPSubgraph.Arrays[4]; SCSubgraphRef Subgraph_SD1Top = sc.Subgraph[1]; SCSubgraphRef Subgraph_SD1Bottom = sc.Subgraph[2]; SCSubgraphRef Subgraph_SD2Top = sc.Subgraph[3]; SCSubgraphRef Subgraph_SD2Bottom = sc.Subgraph[4]; SCSubgraphRef Subgraph_SD3Top = sc.Subgraph[5]; SCSubgraphRef Subgraph_SD3Bottom = sc.Subgraph[6]; SCSubgraphRef Subgraph_SD4Top = sc.Subgraph[7]; SCSubgraphRef Subgraph_SD4Bottom = sc.Subgraph[8]; SCInputRef Input_InputData = sc.Input[0]; SCInputRef Input_BandCalculationMethod = sc.Input[1]; SCInputRef Input_VolumeTypeToUse = sc.Input[2]; SCInputRef Input_TimePeriodType = sc.Input[3]; SCInputRef Input_TimePeriodLength = sc.Input[4]; SCInputRef Input_Version = sc.Input[5]; SCInputRef Input_DistanceMultiplier_V3 = sc.Input[6]; SCInputRef Input_IgnoreTimePeriodTypeAndLength = sc.Input[7]; SCInputRef Input_BaseOnUnderlyingData = sc.Input[9]; SCInputRef Input_UseFixedOffset = sc.Input[10]; SCInputRef Input_StartDateTime = sc.Input[11]; SCInputRef Input_Band1OffsetMultiplier = sc.Input[12]; SCInputRef Input_Band2OffsetMultiplier = sc.Input[13]; SCInputRef Input_Band3OffsetMultiplier = sc.Input[14]; SCInputRef Input_Band4OffsetMultiplier = sc.Input[15]; if(sc.SetDefaults) { sc.GraphName = "Volume Weighted Average Price"; sc.GraphRegion = 0; sc.ValueFormat = VALUEFORMAT_INHERITED; sc.AutoLoop = 1; sc.ScaleRangeType=SCALE_SAMEASREGION; Subgraph_VWAPSubgraph.Name = "VWAP"; Subgraph_VWAPSubgraph.DrawStyle = DRAWSTYLE_DASH; Subgraph_VWAPSubgraph.LineWidth = 2; Subgraph_VWAPSubgraph.PrimaryColor = RGB (237, 13, 255); Subgraph_VWAPSubgraph.DrawZeros = false; Subgraph_SD1Top.Name = "Top Band 1"; Subgraph_SD1Top.DrawStyle = DRAWSTYLE_DASH; Subgraph_SD1Top.LineWidth = 2; Subgraph_SD1Top.PrimaryColor = RGB (192, 192, 192); Subgraph_SD1Top.DrawZeros = false; Subgraph_SD1Bottom.Name = "Bottom Band 1"; Subgraph_SD1Bottom.DrawStyle = DRAWSTYLE_DASH; Subgraph_SD1Bottom.LineWidth = 2; Subgraph_SD1Bottom.PrimaryColor = RGB (192, 192, 192); Subgraph_SD1Bottom.DrawZeros = false; Subgraph_SD2Top.Name = "Top Band 2"; Subgraph_SD2Top.DrawStyle = DRAWSTYLE_IGNORE; Subgraph_SD2Top.LineWidth = 2; Subgraph_SD2Top.PrimaryColor = RGB (192, 192, 192); Subgraph_SD2Top.DrawZeros = false; Subgraph_SD2Bottom.Name = "Bottom Band 2"; Subgraph_SD2Bottom.DrawStyle = DRAWSTYLE_IGNORE; Subgraph_SD2Bottom.LineWidth = 2; Subgraph_SD2Bottom.PrimaryColor = RGB (192, 192, 192); Subgraph_SD2Bottom.DrawZeros = false; Subgraph_SD3Top.Name = "Top Band 3"; Subgraph_SD3Top.DrawStyle = DRAWSTYLE_IGNORE; Subgraph_SD3Top.LineWidth = 2; Subgraph_SD3Top.PrimaryColor = RGB (192, 192, 192); Subgraph_SD3Top.DrawZeros = false; Subgraph_SD3Bottom.Name = "Bottom Band 3"; Subgraph_SD3Bottom.DrawStyle = DRAWSTYLE_IGNORE; Subgraph_SD3Bottom.LineWidth = 2; Subgraph_SD3Bottom.PrimaryColor = RGB (192, 192, 192); Subgraph_SD3Bottom.DrawZeros = false; Subgraph_SD4Top.Name = "Top Band 4"; Subgraph_SD4Top.DrawStyle = DRAWSTYLE_IGNORE; Subgraph_SD4Top.LineWidth = 2; Subgraph_SD4Top.PrimaryColor = RGB (192, 192, 192); Subgraph_SD4Top.DrawZeros = false; Subgraph_SD4Bottom.Name = "Bottom Band 4"; Subgraph_SD4Bottom.DrawStyle = DRAWSTYLE_IGNORE; Subgraph_SD4Bottom.LineWidth = 2; Subgraph_SD4Bottom.PrimaryColor = RGB (192, 192, 192); Subgraph_SD4Bottom.DrawZeros = false; int DisplayOrder = 1; Input_InputData.Name = "Input Data"; Input_InputData.SetInputDataIndex(SC_LAST); Input_InputData.DisplayOrder = DisplayOrder++; Input_VolumeTypeToUse.Name = "Volume Type to Use"; Input_VolumeTypeToUse.SetCustomInputStrings("Total Volume;Bid Volume;Ask Volume"); Input_VolumeTypeToUse.SetCustomInputIndex(0); Input_VolumeTypeToUse.DisplayOrder = DisplayOrder++; Input_BaseOnUnderlyingData.Name = "Base On Underlying Data"; Input_BaseOnUnderlyingData.SetYesNo(0); Input_BaseOnUnderlyingData.DisplayOrder = DisplayOrder++; Input_TimePeriodType.Name = "Time Period Type"; Input_TimePeriodType.SetTimePeriodType(TIME_PERIOD_LENGTH_UNIT_DAYS); Input_TimePeriodType.DisplayOrder = DisplayOrder++; Input_TimePeriodLength.Name = "Time Period Length"; Input_TimePeriodLength.SetInt(1); Input_TimePeriodLength.DisplayOrder = DisplayOrder++; Input_StartDateTime.Name = "Start Date-Time"; Input_StartDateTime.SetDateTime(0.0); Input_StartDateTime.DisplayOrder = DisplayOrder++; Input_IgnoreTimePeriodTypeAndLength.Name = "Ignore Time Period Type And Length"; Input_IgnoreTimePeriodTypeAndLength.SetYesNo(false); Input_IgnoreTimePeriodTypeAndLength.DisplayOrder = DisplayOrder++; Input_DistanceMultiplier_V3.SetFloat(0.5); //UseFixedOffset.Name = "Use Fixed Offset Instead of Std. Deviation"; Input_UseFixedOffset.SetYesNo(0); //UseFixedOffset.DisplayOrder = DisplayOrder++; Input_BandCalculationMethod.Name = "Std. Deviation Band Calculation Method"; Input_BandCalculationMethod.SetCustomInputStrings("VWAP Variance;Fixed Offset;Standard Deviation;Percentage"); Input_BandCalculationMethod.SetCustomInputIndex(0); Input_BandCalculationMethod.DisplayOrder = DisplayOrder++; Input_Band1OffsetMultiplier.Name = "Band 1 Std. Deviation Multiplier/Fixed Offset"; Input_Band1OffsetMultiplier.SetFloat(0.5); Input_Band1OffsetMultiplier.DisplayOrder = DisplayOrder++; Input_Band2OffsetMultiplier.Name = "Band 2 Std. Deviation Multiplier/Fixed Offset"; Input_Band2OffsetMultiplier.SetFloat(1.0); Input_Band2OffsetMultiplier.DisplayOrder = DisplayOrder++; Input_Band3OffsetMultiplier.Name = "Band 3 Std. Deviation Multiplier/Fixed Offset"; Input_Band3OffsetMultiplier.SetFloat(1.5); Input_Band3OffsetMultiplier.DisplayOrder = DisplayOrder++; Input_Band4OffsetMultiplier.Name = "Band 4 Std. Deviation Multiplier/Fixed Offset"; Input_Band4OffsetMultiplier.SetFloat(2.0); Input_Band4OffsetMultiplier.DisplayOrder = DisplayOrder++; Input_Version.SetInt(6); return; } if(Input_Version.GetInt() < 2) { Input_TimePeriodType.SetTimePeriodType(TIME_PERIOD_LENGTH_UNIT_DAYS); Input_TimePeriodLength.SetInt(1); Input_Version.SetInt(2); } if(Input_Version.GetInt() < 3) { Input_DistanceMultiplier_V3.SetFloat(0.5); Input_Version.SetInt(3); } if (Input_Version.GetInt() < 4) { Input_Band1OffsetMultiplier.SetFloat(Input_DistanceMultiplier_V3.GetFloat()); Input_Band2OffsetMultiplier.SetFloat(Input_DistanceMultiplier_V3.GetFloat()*2.0f); Input_Band3OffsetMultiplier.SetFloat(Input_DistanceMultiplier_V3.GetFloat()*3.0f); Input_Band4OffsetMultiplier.SetFloat(Input_DistanceMultiplier_V3.GetFloat()*4.0f); Input_Version.SetInt(4); } if (Input_Version.GetInt() < 5) { Input_BandCalculationMethod.SetCustomInputIndex(Input_UseFixedOffset.GetYesNo() ? 1 : 0); Input_Version.SetInt(5); } if (Input_Version.GetInt() < 6) { Input_IgnoreTimePeriodTypeAndLength.SetYesNo(false); Input_Version.SetInt(6); } sc.DataStartIndex = 1; int& r_LastIndexProcessed = sc.GetPersistentInt(1); int& r_StartIndexOfCurrentPeriod = sc.GetPersistentInt(3); double& r_PriorSumPriceTimesVolume = sc.GetPersistentDouble(1); double& r_PriorSumPriceSquaredTimesVolume = sc.GetPersistentDouble(2); double& r_PriorCumulativeVolume = sc.GetPersistentDouble(3); if (sc.Index == 0) { Array_BarSumPriceTimesVolume[sc.Index] = 0; Array_BarSumPriceSquaredTimesVolume[sc.Index] = 0; if (Input_BaseOnUnderlyingData.GetYesNo()) { if (sc.MaintainVolumeAtPriceData == 0) { sc.MaintainVolumeAtPriceData = 1; sc.FlagToReloadChartData = 1; } } else sc.MaintainVolumeAtPriceData = 0; } if (Input_StartDateTime.GetDate() != 0 && sc.BaseDateTimeIn[sc.Index] < Input_StartDateTime.GetDateTime()) return; bool PriorBarIndexExcludedBasedOnDateTime = sc.Index > 0 && Input_StartDateTime.GetDate() != 0 && sc.BaseDateTimeIn[sc.Index - 1] < Input_StartDateTime.GetDateTime(); SCDateTime PriorCurrentPeriodStartDateTime; SCDateTime CurrentPeriodStartDateTime; if(!Input_IgnoreTimePeriodTypeAndLength.GetYesNo()) { CurrentPeriodStartDateTime = sc.GetStartOfPeriodForDateTime(sc.BaseDateTimeIn[sc.Index], Input_TimePeriodType.GetTimePeriodType(), Input_TimePeriodLength.GetInt(), 0); PriorCurrentPeriodStartDateTime = sc.GetStartOfPeriodForDateTime(sc.BaseDateTimeIn[sc.Index - 1], Input_TimePeriodType.GetTimePeriodType(), Input_TimePeriodLength.GetInt(), 0); } bool IsStartOfNewPeriod = false; //Reset at start of new period if (sc.Index == 0 || CurrentPeriodStartDateTime != PriorCurrentPeriodStartDateTime || PriorBarIndexExcludedBasedOnDateTime) { r_PriorSumPriceTimesVolume = 0; r_PriorSumPriceSquaredTimesVolume = 0; r_PriorCumulativeVolume = 0; r_LastIndexProcessed = sc.Index; r_StartIndexOfCurrentPeriod = sc.Index; IsStartOfNewPeriod = true; } else if (sc.Index != r_LastIndexProcessed) { // add in last values for (; r_LastIndexProcessed < sc.Index; ++r_LastIndexProcessed) { r_PriorSumPriceTimesVolume += Array_BarSumPriceTimesVolume[r_LastIndexProcessed]; r_PriorSumPriceSquaredTimesVolume += Array_BarSumPriceSquaredTimesVolume[r_LastIndexProcessed]; r_PriorCumulativeVolume += Array_CalculatedBarVolume[r_LastIndexProcessed]; } } double BarVolume = 0; float CurrentPrice = sc.BaseDataIn[Input_InputData.GetInputDataIndex()][sc.Index]; if (Input_BaseOnUnderlyingData.GetYesNo()) { Array_BarSumPriceTimesVolume[sc.Index] = 0; Array_BarSumPriceSquaredTimesVolume[sc.Index] = 0; if (static_cast(sc.VolumeAtPriceForBars->GetNumberOfBars()) < sc.ArraySize) return; const s_VolumeAtPriceV2 *p_VolumeAtPrice = nullptr; const int NumVAPElementsAtBarIndex = sc.VolumeAtPriceForBars->GetSizeAtBarIndex(sc.Index); for (int VAPIndex = 0; VAPIndex < NumVAPElementsAtBarIndex; VAPIndex++) { sc.VolumeAtPriceForBars->GetVAPElementAtIndex(sc.Index, VAPIndex, &p_VolumeAtPrice); float Price = p_VolumeAtPrice->PriceInTicks * sc.TickSize; uint32_t VolumeToUse = 0; if (Input_VolumeTypeToUse.GetIndex() == 1) VolumeToUse = p_VolumeAtPrice->BidVolume; else if (Input_VolumeTypeToUse.GetIndex() == 2) VolumeToUse = p_VolumeAtPrice->AskVolume; else VolumeToUse = p_VolumeAtPrice->Volume; Array_BarSumPriceTimesVolume[sc.Index] += (Price * VolumeToUse); Array_BarSumPriceSquaredTimesVolume[sc.Index] += (Price * Price * VolumeToUse); BarVolume += VolumeToUse; } } else { Array_BarSumPriceTimesVolume[sc.Index] = CurrentPrice * sc.Volume[sc.Index]; Array_BarSumPriceSquaredTimesVolume[sc.Index] = CurrentPrice * CurrentPrice * sc.Volume[sc.Index]; BarVolume = sc.Volume[sc.Index]; } Array_CalculatedBarVolume[sc.Index] = static_cast (BarVolume); double PriceTimesVolume = r_PriorSumPriceTimesVolume + Array_BarSumPriceTimesVolume[sc.Index]; double PriceSquaredTimesVolume = r_PriorSumPriceSquaredTimesVolume + Array_BarSumPriceSquaredTimesVolume[sc.Index]; double CumulativeVolume = r_PriorCumulativeVolume + BarVolume; double VolumeWeightedAveragePrice = 0; if (CumulativeVolume != 0) VolumeWeightedAveragePrice = PriceTimesVolume / CumulativeVolume; Subgraph_VWAPSubgraph[sc.Index] = static_cast(VolumeWeightedAveragePrice); float BandDistance = 1.0f; if (Input_BandCalculationMethod.GetIndex() == 1)//Fixed offset { BandDistance = 1.0f; } else if (Input_BandCalculationMethod.GetIndex() == 0)//VWAP variance { double PriceVWAPDifferenceSquaredTimesVolume = (CurrentPrice - Subgraph_VWAPSubgraph[sc.Index])*(CurrentPrice - Subgraph_VWAPSubgraph[sc.Index])* sc.Volume[sc.Index]; if (IsStartOfNewPeriod) { Array_BarSumPriceVWAPDifferenceSquaredTimesVolume[sc.Index] = static_cast(PriceVWAPDifferenceSquaredTimesVolume); } else { Array_BarSumPriceVWAPDifferenceSquaredTimesVolume[sc.Index] = static_cast(Array_BarSumPriceVWAPDifferenceSquaredTimesVolume[sc.Index - 1] + PriceVWAPDifferenceSquaredTimesVolume); } if (CumulativeVolume != 0) BandDistance = static_cast(sqrt(Array_BarSumPriceVWAPDifferenceSquaredTimesVolume[sc.Index]/CumulativeVolume)); else BandDistance = 1.0f; } else if (Input_BandCalculationMethod.GetIndex() == 2)//VWAP variance//Standard deviation { sc.StdDeviation(Subgraph_VWAPSubgraph, Array_StandardDeviationArray, sc.Index - r_StartIndexOfCurrentPeriod + 1); BandDistance = Array_StandardDeviationArray[sc.Index]; } else //Percentage { BandDistance = static_cast(VolumeWeightedAveragePrice / 100.0f); } Subgraph_SD1Top[sc.Index] = Subgraph_VWAPSubgraph[sc.Index] + Input_Band1OffsetMultiplier.GetFloat() * BandDistance; Subgraph_SD1Bottom[sc.Index] = Subgraph_VWAPSubgraph[sc.Index] - Input_Band1OffsetMultiplier.GetFloat() * BandDistance; Subgraph_SD2Top[sc.Index] = Subgraph_VWAPSubgraph[sc.Index] + Input_Band2OffsetMultiplier.GetFloat() * BandDistance; Subgraph_SD2Bottom[sc.Index] = Subgraph_VWAPSubgraph[sc.Index] - Input_Band2OffsetMultiplier.GetFloat() * BandDistance; Subgraph_SD3Top[sc.Index] = Subgraph_VWAPSubgraph[sc.Index] + Input_Band3OffsetMultiplier.GetFloat() * BandDistance; Subgraph_SD3Bottom[sc.Index] = Subgraph_VWAPSubgraph[sc.Index] - Input_Band3OffsetMultiplier.GetFloat() * BandDistance; Subgraph_SD4Top[sc.Index] = Subgraph_VWAPSubgraph[sc.Index] + Input_Band4OffsetMultiplier.GetFloat() * BandDistance; Subgraph_SD4Bottom[sc.Index] = Subgraph_VWAPSubgraph[sc.Index] - Input_Band4OffsetMultiplier.GetFloat() * BandDistance; } /*==========================================================================*/ void GetIndexForStartofDayPeriodForDaysBack ( SCStudyInterfaceRef sc , const SCDateTime InitialStartDateTime , const int NumDaysToInclude , const bool ExcludeWeekends , const int MinimumRequiredTimePeriodInDayAsPercent , int& r_InitialBarIndex ) { int DaysBack = -1; for (int DaysCount = 0; DaysCount < NumDaysToInclude; ++DaysCount) { for (int Iterations = 10; Iterations > 0; --Iterations) { DaysBack++; SCDateTime PriorPeriodStartDateTime = InitialStartDateTime - SCDateTime::DAYS(DaysBack); SCDateTime PriorPeriodEndDateTime = PriorPeriodStartDateTime + SCDateTime::DAYS(1) - SCDateTime::SECONDS(1); r_InitialBarIndex = sc.GetNearestMatchForSCDateTime(sc.ChartNumber, PriorPeriodStartDateTime.GetAsDouble()); const SCDateTime TradingDayDate = sc.GetTradingDayDate(PriorPeriodStartDateTime); if (ExcludeWeekends && TradingDayDate.IsWeekend()) continue; // for the current day, do not do any check to see if there is sufficient data because there may not be if the day is not complete. if (NumDaysToInclude == 1) break; const int PriorPeriodLastIndex = sc.GetNearestMatchForSCDateTime(sc.ChartNumber, PriorPeriodEndDateTime.GetAsDouble()); const SCDateTime ActualTimeSpan(sc.CalculateTimeSpanAcrossChartBars (r_InitialBarIndex, PriorPeriodLastIndex)); //If there is a sufficient amount of data in this time period if (ActualTimeSpan > SCDateTime::SECONDS_Fraction(MinimumRequiredTimePeriodInDayAsPercent * 0.01 * SECONDS_PER_DAY)) { break; } } } } /*==========================================================================*/ SCSFExport scsf_RollingVolumeWeightedAveragePrice(SCStudyInterfaceRef sc) { SCSubgraphRef Subgraph_VWAPSubgraph = sc.Subgraph[0]; SCFloatArrayRef Array_BarSumPriceTimesVolume = Subgraph_VWAPSubgraph.Arrays[0]; SCFloatArrayRef Array_StandardDeviationArray = Subgraph_VWAPSubgraph.Arrays[1]; SCFloatArrayRef Array_PriceTimesVolumeArray = Subgraph_VWAPSubgraph.Arrays[2]; SCSubgraphRef Subgraph_BackgroundVWAPForCurrentPeriod = sc.Subgraph[9]; SCSubgraphRef Subgraph_PriceVWAPDifferenceSquaredTimesVolume = sc.Subgraph[10]; SCSubgraphRef Subgraph_BarSumPriceVWAPDifferenceSquaredTimesVolumeArray = sc.Subgraph[11]; SCSubgraphRef Subgraph_CumulativeVolumeForPeriodArray = sc.Subgraph[12]; SCSubgraphRef Subgraph_BandDistance = sc.Subgraph[13]; SCSubgraphRef Subgraph_SD1Top = sc.Subgraph[1]; SCSubgraphRef Subgraph_SD1Bottom = sc.Subgraph[2]; SCSubgraphRef Subgraph_SD2Top = sc.Subgraph[3]; SCSubgraphRef Subgraph_SD2Bottom = sc.Subgraph[4]; SCSubgraphRef Subgraph_SD3Top = sc.Subgraph[5]; SCSubgraphRef Subgraph_SD3Bottom = sc.Subgraph[6]; SCSubgraphRef Subgraph_SD4Top = sc.Subgraph[7]; SCSubgraphRef Subgraph_SD4Bottom = sc.Subgraph[8]; SCInputRef Input_InputData = sc.Input[0]; SCInputRef Input_BandCalculationMethod = sc.Input[1]; SCInputRef Input_MinimumRequiredTimePeriodAsPercentForSkipDays = sc.Input[2]; SCInputRef Input_TimePeriodType = sc.Input[3]; SCInputRef Input_TimePeriodLength = sc.Input[4]; SCInputRef Input_Version = sc.Input[5]; SCInputRef Input_DistanceMultiplier_V3 = sc.Input[6]; SCInputRef Input_NumberOfDaysToCalculate = sc.Input[7]; SCInputRef Input_BaseOnUnderlyingData = sc.Input[9]; SCInputRef Input_UseFixedOffset = sc.Input[10]; SCInputRef Input_Band1OffsetMultiplier = sc.Input[12]; SCInputRef Input_Band2OffsetMultiplier = sc.Input[13]; SCInputRef Input_Band3OffsetMultiplier = sc.Input[14]; SCInputRef Input_Band4OffsetMultiplier = sc.Input[15]; SCInputRef Input_ExcludeWeekendInDateCalc = sc.Input[16]; if (sc.SetDefaults) { sc.GraphName = "Volume Weighted Average Price - Rolling"; sc.GraphRegion = 0; sc.ValueFormat = VALUEFORMAT_INHERITED; sc.AutoLoop = 0;//Manual looping sc.MaintainVolumeAtPriceData = 1; sc.ScaleRangeType = SCALE_SAMEASREGION; Subgraph_VWAPSubgraph.Name = "VWAP"; Subgraph_VWAPSubgraph.DrawStyle = DRAWSTYLE_DASH; Subgraph_VWAPSubgraph.LineWidth = 2; Subgraph_VWAPSubgraph.PrimaryColor = RGB(237, 13, 255); Subgraph_VWAPSubgraph.DrawZeros = false; Subgraph_SD1Top.Name = "Top Band 1"; Subgraph_SD1Top.DrawStyle = DRAWSTYLE_DASH; Subgraph_SD1Top.LineWidth = 2; Subgraph_SD1Top.PrimaryColor = RGB(192, 192, 192); Subgraph_SD1Top.DrawZeros = false; Subgraph_SD1Bottom.Name = "Bottom Band 1"; Subgraph_SD1Bottom.DrawStyle = DRAWSTYLE_DASH; Subgraph_SD1Bottom.LineWidth = 2; Subgraph_SD1Bottom.PrimaryColor = RGB(192, 192, 192); Subgraph_SD1Bottom.DrawZeros = false; Subgraph_SD2Top.Name = "Top Band 2"; Subgraph_SD2Top.DrawStyle = DRAWSTYLE_IGNORE; Subgraph_SD2Top.LineWidth = 2; Subgraph_SD2Top.PrimaryColor = RGB(192, 192, 192); Subgraph_SD2Top.DrawZeros = false; Subgraph_SD2Bottom.Name = "Bottom Band 2"; Subgraph_SD2Bottom.DrawStyle = DRAWSTYLE_IGNORE; Subgraph_SD2Bottom.LineWidth = 2; Subgraph_SD2Bottom.PrimaryColor = RGB(192, 192, 192); Subgraph_SD2Bottom.DrawZeros = false; Subgraph_SD3Top.Name = "Top Band 3"; Subgraph_SD3Top.DrawStyle = DRAWSTYLE_IGNORE; Subgraph_SD3Top.LineWidth = 2; Subgraph_SD3Top.PrimaryColor = RGB(192, 192, 192); Subgraph_SD3Top.DrawZeros = false; Subgraph_SD3Bottom.Name = "Bottom Band 3"; Subgraph_SD3Bottom.DrawStyle = DRAWSTYLE_IGNORE; Subgraph_SD3Bottom.LineWidth = 2; Subgraph_SD3Bottom.PrimaryColor = RGB(192, 192, 192); Subgraph_SD3Bottom.DrawZeros = false; Subgraph_SD4Top.Name = "Top Band 4"; Subgraph_SD4Top.DrawStyle = DRAWSTYLE_IGNORE; Subgraph_SD4Top.LineWidth = 2; Subgraph_SD4Top.PrimaryColor = RGB(192, 192, 192); Subgraph_SD4Top.DrawZeros = false; Subgraph_SD4Bottom.Name = "Bottom Band 4"; Subgraph_SD4Bottom.DrawStyle = DRAWSTYLE_IGNORE; Subgraph_SD4Bottom.LineWidth = 2; Subgraph_SD4Bottom.PrimaryColor = RGB(192, 192, 192); Subgraph_SD4Bottom.DrawZeros = false; Subgraph_BackgroundVWAPForCurrentPeriod.Name = "BackgroundVWAPForCurrentPeriod"; Subgraph_BackgroundVWAPForCurrentPeriod.DrawStyle = DRAWSTYLE_IGNORE; Subgraph_BackgroundVWAPForCurrentPeriod.DisplayNameValueInWindowsFlags = 1; Subgraph_PriceVWAPDifferenceSquaredTimesVolume.Name = "PriceVWAPDifferenceSquaredTimesVolume"; Subgraph_PriceVWAPDifferenceSquaredTimesVolume.DrawStyle = DRAWSTYLE_IGNORE; Subgraph_PriceVWAPDifferenceSquaredTimesVolume.DisplayNameValueInWindowsFlags = 1; Subgraph_BarSumPriceVWAPDifferenceSquaredTimesVolumeArray.Name = "BarSumPriceVWAPDifferenceSquaredTimesVolumeArray"; Subgraph_BarSumPriceVWAPDifferenceSquaredTimesVolumeArray.DrawStyle = DRAWSTYLE_IGNORE; Subgraph_BarSumPriceVWAPDifferenceSquaredTimesVolumeArray.DisplayNameValueInWindowsFlags = 1; Subgraph_CumulativeVolumeForPeriodArray.Name = "CumulativeVolumeForPeriodArray"; Subgraph_CumulativeVolumeForPeriodArray.DrawStyle = DRAWSTYLE_IGNORE; Subgraph_CumulativeVolumeForPeriodArray.DisplayNameValueInWindowsFlags = 1; Subgraph_BandDistance.Name = "BandDistance"; Subgraph_BandDistance.DrawStyle = DRAWSTYLE_IGNORE; Subgraph_BandDistance.DisplayNameValueInWindowsFlags = 1; int DisplayOrder = 1; Input_InputData.Name = "Input Data"; Input_InputData.SetInputDataIndex(SC_LAST); Input_InputData.DisplayOrder = DisplayOrder++; Input_BaseOnUnderlyingData.Name = "Base On Underlying Data"; Input_BaseOnUnderlyingData.SetYesNo(0); Input_BaseOnUnderlyingData.DisplayOrder = DisplayOrder++; Input_TimePeriodType.Name = "Time Period Type"; Input_TimePeriodType.SetCustomInputStrings("Days - Trading Days;Days - 24 Hour Period;Minutes;Bars"); Input_TimePeriodType.SetCustomInputIndex(0); Input_TimePeriodType.DisplayOrder = DisplayOrder++; Input_TimePeriodLength.Name = "Time Period Length"; Input_TimePeriodLength.SetInt(1); Input_TimePeriodLength.DisplayOrder = DisplayOrder++; Input_NumberOfDaysToCalculate.Name = "Number of Days to Calculate"; Input_NumberOfDaysToCalculate.SetInt(10); Input_NumberOfDaysToCalculate.DisplayOrder = DisplayOrder++; Input_DistanceMultiplier_V3.SetFloat(0.5); Input_ExcludeWeekendInDateCalc.Name = "Exclude Weekends In Date Look Back"; Input_ExcludeWeekendInDateCalc.SetYesNo(1); Input_ExcludeWeekendInDateCalc.DisplayOrder = DisplayOrder++; Input_MinimumRequiredTimePeriodAsPercentForSkipDays.Name = "Minimum Required Time Period as Percent for Skip Days"; Input_MinimumRequiredTimePeriodAsPercentForSkipDays.SetInt(0); Input_MinimumRequiredTimePeriodAsPercentForSkipDays.DisplayOrder = DisplayOrder++; //UseFixedOffset.Name = "Use Fixed Offset Instead of Std. Deviation"; Input_UseFixedOffset.SetYesNo(0); //UseFixedOffset.DisplayOrder = DisplayOrder++; Input_BandCalculationMethod.Name = "Std. Deviation Band Calculation Method"; Input_BandCalculationMethod.SetCustomInputStrings("VWAP Variance;Fixed Offset;Standard Deviation;Percentage"); Input_BandCalculationMethod.SetCustomInputIndex(0); Input_BandCalculationMethod.DisplayOrder = DisplayOrder++; Input_Band1OffsetMultiplier.Name = "Band 1 Std. Deviation Multiplier/Fixed Offset"; Input_Band1OffsetMultiplier.SetFloat(0.5); Input_Band1OffsetMultiplier.DisplayOrder = DisplayOrder++; Input_Band2OffsetMultiplier.Name = "Band 2 Std. Deviation Multiplier/Fixed Offset"; Input_Band2OffsetMultiplier.SetFloat(1.0); Input_Band2OffsetMultiplier.DisplayOrder = DisplayOrder++; Input_Band3OffsetMultiplier.Name = "Band 3 Std. Deviation Multiplier/Fixed Offset"; Input_Band3OffsetMultiplier.SetFloat(1.5); Input_Band3OffsetMultiplier.DisplayOrder = DisplayOrder++; Input_Band4OffsetMultiplier.Name = "Band 4 Std. Deviation Multiplier/Fixed Offset"; Input_Band4OffsetMultiplier.SetFloat(2.0); Input_Band4OffsetMultiplier.DisplayOrder = DisplayOrder++; Input_Version.SetInt(8); return; } n_ACSIL::s_BarPeriod BarPeriod; sc.GetBarPeriodParameters(BarPeriod); if (Input_NumberOfDaysToCalculate.GetInt() == 0) Input_NumberOfDaysToCalculate.SetInt(10); // calculate the period start index const int PeriodType = Input_TimePeriodType.GetIndex(); if (PeriodType == 0 || PeriodType == 1) { int DaysRequired = Input_TimePeriodLength.GetInt(); if (Input_NumberOfDaysToCalculate.GetInt() < DaysRequired) Input_NumberOfDaysToCalculate.SetInt(DaysRequired); } int& r_LastIndexProcessed = sc.GetPersistentInt(1); int& r_FirstIndexIncluded = sc.GetPersistentInt(2); int& r_PriorFirstIndexIncluded = sc.GetPersistentInt(3); int& r_LastExcludedIndex = sc.GetPersistentInt(4); SCDateTime& r_PriorTradeDate = sc.GetPersistentSCDateTime(1); if (sc.IsFullRecalculation)//reset { r_LastIndexProcessed = -1; r_FirstIndexIncluded = 0; r_PriorFirstIndexIncluded = -1; r_LastExcludedIndex = -1; if (Input_BaseOnUnderlyingData.GetYesNo()) { if (sc.MaintainVolumeAtPriceData == 0) { sc.MaintainVolumeAtPriceData = 1; sc.FlagToReloadChartData = 1; } } else sc.MaintainVolumeAtPriceData = 0; } if (Input_BaseOnUnderlyingData.GetYesNo() && static_cast(sc.VolumeAtPriceForBars->GetNumberOfBars()) < sc.ArraySize) return; const SCDateTime TradingDayDateForLastBar = sc.GetTradingDayDate(sc.BaseDateTimeIn[sc.ArraySize - 1]); for (int Index = sc.UpdateStartIndex; Index < sc.ArraySize; ++Index) { bool NewBar = Index != r_LastIndexProcessed; r_LastIndexProcessed = Index; Array_BarSumPriceTimesVolume[Index] = 0; const SCDateTime TradingDayDateForBar = sc.GetTradingDayDate(sc.BaseDateTimeIn[Index]); if ((TradingDayDateForLastBar.GetDate() - TradingDayDateForBar.GetDate() + 1) > Input_NumberOfDaysToCalculate.GetInt()) { r_LastExcludedIndex = Index; continue; } float CurrentPrice = sc.BaseDataIn[Input_InputData.GetInputDataIndex()][Index]; // Calculate bar values if (Input_BaseOnUnderlyingData.GetYesNo()) { const s_VolumeAtPriceV2 *p_VolumeAtPrice = nullptr; int NumberOfPrices = sc.VolumeAtPriceForBars->GetSizeAtBarIndex(Index); for (int VAPIndex = 0; VAPIndex < NumberOfPrices; VAPIndex++) { sc.VolumeAtPriceForBars->GetVAPElementAtIndex(Index, VAPIndex, &p_VolumeAtPrice); float Price = p_VolumeAtPrice->PriceInTicks * sc.TickSize; float PriceTimesVolume = Price * p_VolumeAtPrice->Volume; Array_BarSumPriceTimesVolume[Index] += PriceTimesVolume; } #ifdef _DEBUG if (Index == sc.ArraySize - 1) { float BarSumPriceTimesVolumeValue = Array_BarSumPriceTimesVolume[Index]; SCString Message; Message.Format("%f", BarSumPriceTimesVolumeValue); sc.AddMessageToLog(Message, 0); } #endif // _DEBUG } else { Array_BarSumPriceTimesVolume[Index] = CurrentPrice * sc.Volume[Index]; } if (NewBar) { if (PeriodType == 0) // Days - trading days { int TradeDate = sc.GetTradingDayDate(sc.BaseDateTimeIn[Index]); SCDateTime CurrentDayStartDateTime = sc.GetStartDateTimeForTradingDate(TradeDate); r_PriorTradeDate = TradeDate; r_FirstIndexIncluded = sc.GetContainingIndexForSCDateTime(sc.ChartNumber, CurrentDayStartDateTime.GetAsDouble()); GetIndexForStartofDayPeriodForDaysBack (sc , CurrentDayStartDateTime , Input_TimePeriodLength.GetInt() , Input_ExcludeWeekendInDateCalc.GetYesNo() != 0 , Input_MinimumRequiredTimePeriodAsPercentForSkipDays.GetInt() , r_FirstIndexIncluded ); } else if (PeriodType == 1) // Days - 24 hour periods { SCDateTime CurrentPeriodStartDateTime = sc.BaseDateTimeIn[Index] - SCDateTime::DAYS(1) + SCDateTime::SECONDS(1); r_FirstIndexIncluded = sc.GetContainingIndexForSCDateTime(sc.ChartNumber, CurrentPeriodStartDateTime.GetAsDouble()); GetIndexForStartofDayPeriodForDaysBack (sc , CurrentPeriodStartDateTime , Input_TimePeriodLength.GetInt() , Input_ExcludeWeekendInDateCalc.GetYesNo() != 0 , Input_MinimumRequiredTimePeriodAsPercentForSkipDays.GetInt() , r_FirstIndexIncluded ); } else if (PeriodType == 2) // Minutes { SCDateTime RollingStartDateTime = 0; if (BarPeriod.IntradayChartBarPeriodType == IBPT_DAYS_MINS_SECS && sc.SecondsPerBar != 0) { RollingStartDateTime = sc.BaseDateTimeIn[Index] + SCDateTime::SECONDS(sc.SecondsPerBar - 1); RollingStartDateTime.SubtractMinutes(Input_TimePeriodLength.GetInt()); } else { if (Index == sc.ArraySize - 1) RollingStartDateTime = sc.LatestDateTimeForLastBar; else RollingStartDateTime = sc.BaseDateTimeIn[Index + 1] - SCDateTime::SECONDS(1); RollingStartDateTime.SubtractMinutes(Input_TimePeriodLength.GetInt()); } for (; r_FirstIndexIncluded <= Index; ++r_FirstIndexIncluded) { if (sc.BaseDateTimeIn[r_FirstIndexIncluded] < RollingStartDateTime) continue; break; } } else // Bars { r_FirstIndexIncluded = max(0, Index - Input_TimePeriodLength.GetInt() + 1); } #ifdef _DEBUG SCString MessageText; SCString IndexDateTime = sc.DateTimeToString(sc.BaseDateTimeIn[Index].GetAsDouble(), FLAG_DT_COMPLETE_DATETIME); SCString FirstIndexIncludedDateTime = sc.DateTimeToString(sc.BaseDateTimeIn[r_FirstIndexIncluded].GetAsDouble(), FLAG_DT_COMPLETE_DATETIME); SCString IndexTradingDate = sc.DateTimeToString(sc.GetTradingDayDate(sc.BaseDateTimeIn[Index]), FLAG_DT_COMPLETE_DATE); MessageText.Format("NewBar. FirstIndexIncluded: %d, CurrentIndex: %d, FirstIndexIncluded_DateTime: %s, CurrentIndex_DateTime: %s, CurrentIndex_TradingDate: %s" , r_FirstIndexIncluded, Index, FirstIndexIncludedDateTime.GetChars(), IndexDateTime.GetChars(), IndexTradingDate.GetChars()); sc.AddMessageToLog(MessageText, 0); #endif } if (r_FirstIndexIncluded <= r_LastExcludedIndex) r_FirstIndexIncluded = r_LastExcludedIndex + 1; int CalculationStartIndex = Index; bool ResetCalculation = false; if (r_PriorFirstIndexIncluded != r_FirstIndexIncluded || r_FirstIndexIncluded == Index) { CalculationStartIndex = r_FirstIndexIncluded; ResetCalculation = true; } r_PriorFirstIndexIncluded = r_FirstIndexIncluded; bool TempResetCalculation = ResetCalculation; for (int AvgIndex = CalculationStartIndex; AvgIndex <= Index; ++AvgIndex) { if (TempResetCalculation) { TempResetCalculation = false; Array_PriceTimesVolumeArray[AvgIndex] = Array_BarSumPriceTimesVolume[AvgIndex]; Subgraph_CumulativeVolumeForPeriodArray[AvgIndex] = sc.Volume[AvgIndex]; } else { Array_PriceTimesVolumeArray[AvgIndex] = Array_PriceTimesVolumeArray[AvgIndex - 1] + Array_BarSumPriceTimesVolume[AvgIndex]; Subgraph_CumulativeVolumeForPeriodArray[AvgIndex] = Subgraph_CumulativeVolumeForPeriodArray[AvgIndex - 1] + sc.Volume[AvgIndex]; } if (Subgraph_CumulativeVolumeForPeriodArray[AvgIndex] != 0) Subgraph_BackgroundVWAPForCurrentPeriod[AvgIndex] = Array_PriceTimesVolumeArray[AvgIndex] / Subgraph_CumulativeVolumeForPeriodArray[AvgIndex]; else Subgraph_BackgroundVWAPForCurrentPeriod[AvgIndex] = 0; } if (Subgraph_CumulativeVolumeForPeriodArray[Index] != 0) Subgraph_VWAPSubgraph[Index] = Array_PriceTimesVolumeArray[Index] / Subgraph_CumulativeVolumeForPeriodArray[Index]; if (Input_BandCalculationMethod.GetIndex() == 1)//Fixed offset { Subgraph_BandDistance[Index] = 1.0f; } else if (Input_BandCalculationMethod.GetIndex() == 0)//VWAP variance { for (int BarIndex = CalculationStartIndex; BarIndex <= Index; ++BarIndex) { Subgraph_PriceVWAPDifferenceSquaredTimesVolume[BarIndex] = (sc.BaseDataIn[Input_InputData.GetInputDataIndex()][BarIndex] - Subgraph_BackgroundVWAPForCurrentPeriod[BarIndex]) * (sc.BaseDataIn[Input_InputData.GetInputDataIndex()][BarIndex] - Subgraph_BackgroundVWAPForCurrentPeriod[BarIndex]) * sc.Volume[BarIndex]; if (ResetCalculation) { ResetCalculation = false; Subgraph_BarSumPriceVWAPDifferenceSquaredTimesVolumeArray[BarIndex] = Subgraph_PriceVWAPDifferenceSquaredTimesVolume[BarIndex]; } else { Subgraph_BarSumPriceVWAPDifferenceSquaredTimesVolumeArray[BarIndex] = Subgraph_BarSumPriceVWAPDifferenceSquaredTimesVolumeArray[BarIndex - 1] + Subgraph_PriceVWAPDifferenceSquaredTimesVolume[BarIndex]; } //float CheckValue1 = BarSumPriceVWAPDifferenceSquaredTimesVolumeArray[BarIndex]; //float CheckValue2 = PriceVWAPDifferenceSquaredTimesVolume[BarIndex]; //float CheckValue3 = 0; } if (Subgraph_CumulativeVolumeForPeriodArray[Index] != 0) { Subgraph_BandDistance[Index] = static_cast(sqrt(Subgraph_BarSumPriceVWAPDifferenceSquaredTimesVolumeArray[Index] / Subgraph_CumulativeVolumeForPeriodArray[Index])); } else Subgraph_BandDistance[Index] = 1.0f; } else if (Input_BandCalculationMethod.GetIndex() == 2) //Standard deviation { sc.StdDeviation(Subgraph_VWAPSubgraph, Array_StandardDeviationArray, Index, Index - r_FirstIndexIncluded + 1); Subgraph_BandDistance[Index] = Array_StandardDeviationArray[Index]; } else //Percentage { Subgraph_BandDistance[Index] = Subgraph_VWAPSubgraph[Index] / 100.0f; } Subgraph_SD1Top[Index] = Subgraph_VWAPSubgraph[Index] + Input_Band1OffsetMultiplier.GetFloat() * Subgraph_BandDistance[Index]; Subgraph_SD1Bottom[Index] = Subgraph_VWAPSubgraph[Index] - Input_Band1OffsetMultiplier.GetFloat() * Subgraph_BandDistance[Index]; Subgraph_SD2Top[Index] = Subgraph_VWAPSubgraph[Index] + Input_Band2OffsetMultiplier.GetFloat() * Subgraph_BandDistance[Index]; Subgraph_SD2Bottom[Index] = Subgraph_VWAPSubgraph[Index] - Input_Band2OffsetMultiplier.GetFloat() * Subgraph_BandDistance[Index]; Subgraph_SD3Top[Index] = Subgraph_VWAPSubgraph[Index] + Input_Band3OffsetMultiplier.GetFloat() * Subgraph_BandDistance[Index]; Subgraph_SD3Bottom[Index] = Subgraph_VWAPSubgraph[Index] - Input_Band3OffsetMultiplier.GetFloat() * Subgraph_BandDistance[Index]; Subgraph_SD4Top[Index] = Subgraph_VWAPSubgraph[Index] + Input_Band4OffsetMultiplier.GetFloat() * Subgraph_BandDistance[Index]; Subgraph_SD4Bottom[Index] = Subgraph_VWAPSubgraph[Index] - Input_Band4OffsetMultiplier.GetFloat() * Subgraph_BandDistance[Index]; } } /*==========================================================================*/ SCSFExport scsf_RollingHighAccuracyMovingAverage(SCStudyInterfaceRef sc) { SCSubgraphRef Subgraph_MovingAverage = sc.Subgraph[0]; SCFloatArrayRef Array_PriceSum = Subgraph_MovingAverage.Arrays[0]; SCFloatArrayRef Array_PriceCount = Subgraph_MovingAverage.Arrays[1]; SCFloatArrayRef Array_StandardDeviation = Subgraph_MovingAverage.Arrays[2]; SCSubgraphRef Subgraph_SD1Top = sc.Subgraph[1]; SCSubgraphRef Subgraph_SD1Bottom = sc.Subgraph[2]; SCSubgraphRef Subgraph_SD2Top = sc.Subgraph[3]; SCSubgraphRef Subgraph_SD2Bottom = sc.Subgraph[4]; SCSubgraphRef Subgraph_SD3Top = sc.Subgraph[5]; SCSubgraphRef Subgraph_SD3Bottom = sc.Subgraph[6]; SCSubgraphRef Subgraph_SD4Top = sc.Subgraph[7]; SCSubgraphRef Subgraph_SD4Bottom = sc.Subgraph[8]; SCInputRef Input_InputData = sc.Input[0]; SCInputRef Input_BandCalculationMethod = sc.Input[1]; SCInputRef Input_MinimumRequiredTimePeriodAsPercentForSkipDays = sc.Input[2]; SCInputRef Input_TimePeriodType = sc.Input[3]; SCInputRef Input_TimePeriodLength = sc.Input[4]; SCInputRef Input_Version = sc.Input[5]; SCInputRef Input_NumberOfDaysToCalculate = sc.Input[7]; SCInputRef Input_BaseOnUnderlyingData = sc.Input[8]; SCInputRef Input_Band1OffsetMultiplier = sc.Input[9]; SCInputRef Input_Band2OffsetMultiplier = sc.Input[10]; SCInputRef Input_Band3OffsetMultiplier = sc.Input[11]; SCInputRef Input_Band4OffsetMultiplier = sc.Input[12]; SCInputRef Input_ExcludeWeekendInDateCalc = sc.Input[13]; if(sc.SetDefaults) { sc.GraphName = "Moving Average - Rolling High Accuracy"; sc.GraphRegion = 0; sc.ValueFormat = VALUEFORMAT_INHERITED; sc.AutoLoop = 0;//Manual looping sc.MaintainVolumeAtPriceData = 1; Subgraph_MovingAverage.Name = "Moving Average"; Subgraph_MovingAverage.DrawStyle = DRAWSTYLE_LINE; Subgraph_MovingAverage.LineWidth = 2; Subgraph_MovingAverage.PrimaryColor = RGB(237, 13, 255); Subgraph_MovingAverage.DrawZeros = false; Subgraph_SD1Top.Name = "Top Band 1"; Subgraph_SD1Top.DrawStyle = DRAWSTYLE_DASH; Subgraph_SD1Top.LineWidth = 2; Subgraph_SD1Top.PrimaryColor = RGB (192, 192, 192); Subgraph_SD1Top.DrawZeros = false; Subgraph_SD1Bottom.Name = "Bottom Band 1"; Subgraph_SD1Bottom.DrawStyle = DRAWSTYLE_DASH; Subgraph_SD1Bottom.LineWidth = 2; Subgraph_SD1Bottom.PrimaryColor = RGB (192, 192, 192); Subgraph_SD1Bottom.DrawZeros = false; Subgraph_SD2Top.Name = "Top Band 2"; Subgraph_SD2Top.DrawStyle = DRAWSTYLE_IGNORE; Subgraph_SD2Top.LineWidth = 2; Subgraph_SD2Top.PrimaryColor = RGB (192, 192, 192); Subgraph_SD2Top.DrawZeros = false; Subgraph_SD2Bottom.Name = "Bottom Band 2"; Subgraph_SD2Bottom.DrawStyle = DRAWSTYLE_IGNORE; Subgraph_SD2Bottom.LineWidth = 2; Subgraph_SD2Bottom.PrimaryColor = RGB (192, 192, 192); Subgraph_SD2Bottom.DrawZeros = false; Subgraph_SD3Top.Name = "Top Band 3"; Subgraph_SD3Top.DrawStyle = DRAWSTYLE_IGNORE; Subgraph_SD3Top.LineWidth = 2; Subgraph_SD3Top.PrimaryColor = RGB (192, 192, 192); Subgraph_SD3Top.DrawZeros = false; Subgraph_SD3Bottom.Name = "Bottom Band 3"; Subgraph_SD3Bottom.DrawStyle = DRAWSTYLE_IGNORE; Subgraph_SD3Bottom.LineWidth = 2; Subgraph_SD3Bottom.PrimaryColor = RGB (192, 192, 192); Subgraph_SD3Bottom.DrawZeros = false; Subgraph_SD4Top.Name = "Top Band 4"; Subgraph_SD4Top.DrawStyle = DRAWSTYLE_IGNORE; Subgraph_SD4Top.LineWidth = 2; Subgraph_SD4Top.PrimaryColor = RGB (192, 192, 192); Subgraph_SD4Top.DrawZeros = false; Subgraph_SD4Bottom.Name = "Bottom Band 4"; Subgraph_SD4Bottom.DrawStyle = DRAWSTYLE_IGNORE; Subgraph_SD4Bottom.LineWidth = 2; Subgraph_SD4Bottom.PrimaryColor = RGB (192, 192, 192); Subgraph_SD4Bottom.DrawZeros = false; int DisplayOrder = 1; Input_InputData.Name = "Input Data"; Input_InputData.SetCustomInputStrings("Price;Volume;Number of Trades;AskVolume-BidVolume"); Input_InputData.SetCustomInputIndex(0); Input_InputData.DisplayOrder = DisplayOrder++; Input_TimePeriodType.Name = "Time Period Type"; Input_TimePeriodType.SetCustomInputStrings("Days - Trading Days;Days - 24 Hour Period;Minutes;Bars"); Input_TimePeriodType.SetCustomInputIndex(0); Input_TimePeriodType.DisplayOrder = DisplayOrder++; Input_TimePeriodLength.Name = "Time Period Length"; Input_TimePeriodLength.SetInt(1); Input_TimePeriodLength.DisplayOrder = DisplayOrder++; Input_NumberOfDaysToCalculate.Name = "Number of Days to Calculate"; Input_NumberOfDaysToCalculate.SetInt(10); Input_NumberOfDaysToCalculate.DisplayOrder = DisplayOrder++; Input_ExcludeWeekendInDateCalc.Name = "Exclude Weekends In Date Look Back"; Input_ExcludeWeekendInDateCalc.SetYesNo(1); Input_ExcludeWeekendInDateCalc.DisplayOrder = DisplayOrder++; Input_MinimumRequiredTimePeriodAsPercentForSkipDays.Name = "Minimum Required Time Period as Percent for Skip Days"; Input_MinimumRequiredTimePeriodAsPercentForSkipDays.SetInt(25); Input_MinimumRequiredTimePeriodAsPercentForSkipDays.DisplayOrder = DisplayOrder++; Input_BandCalculationMethod.Name = "Std. Deviation Band Calculation Method"; Input_BandCalculationMethod.SetCustomInputStrings("Standard Deviation;Fixed Offset"); Input_BandCalculationMethod.SetCustomInputIndex(1); Input_BandCalculationMethod.DisplayOrder = DisplayOrder++; Input_Band1OffsetMultiplier.Name = "Band 1 Std. Deviation Multiplier/Fixed Offset"; Input_Band1OffsetMultiplier.SetFloat(0.5); Input_Band1OffsetMultiplier.DisplayOrder = DisplayOrder++; Input_Band2OffsetMultiplier.Name = "Band 2 Std. Deviation Multiplier/Fixed Offset"; Input_Band2OffsetMultiplier.SetFloat(1.0); Input_Band2OffsetMultiplier.DisplayOrder = DisplayOrder++; Input_Band3OffsetMultiplier.Name = "Band 3 Std. Deviation Multiplier/Fixed Offset"; Input_Band3OffsetMultiplier.SetFloat(1.5); Input_Band3OffsetMultiplier.DisplayOrder = DisplayOrder++; Input_Band4OffsetMultiplier.Name = "Band 4 Std. Deviation Multiplier/Fixed Offset"; Input_Band4OffsetMultiplier.SetFloat(2.0); Input_Band4OffsetMultiplier.DisplayOrder = DisplayOrder++; Input_Version.SetInt(2); return; } n_ACSIL::s_BarPeriod BarPeriod; sc.GetBarPeriodParameters(BarPeriod); if(Input_Version.GetInt() < 2) { Input_Version.SetInt(2); Input_InputData.SetCustomInputIndex(0); } if (static_cast(sc.VolumeAtPriceForBars->GetNumberOfBars()) < sc.ArraySize) return; if (Input_NumberOfDaysToCalculate.GetInt() == 0) Input_NumberOfDaysToCalculate.SetInt(10); // calculate the period start index int PeriodType = Input_TimePeriodType.GetIndex(); if (PeriodType == 0 || PeriodType == 1) { int DaysRequired = Input_TimePeriodLength.GetInt(); if (Input_NumberOfDaysToCalculate.GetInt() < DaysRequired) Input_NumberOfDaysToCalculate.SetInt(DaysRequired); } int& LastIndexProcessed = sc.GetPersistentInt(1); int& FirstIndexIncluded = sc.GetPersistentInt(2); int& LastExcludedIndex = sc.GetPersistentInt(3); if (sc.IsFullRecalculation)//reset { LastIndexProcessed = -1; FirstIndexIncluded = 0; LastExcludedIndex = -1; if (sc.MaintainVolumeAtPriceData == 0) { sc.MaintainVolumeAtPriceData = 1; sc.FlagToReloadChartData = 1; } } for (int Index = sc.UpdateStartIndex; Index < sc.ArraySize; ++Index) { bool NewBar = Index != LastIndexProcessed; LastIndexProcessed = Index; SCDateTime TradingDayDateForBar = sc.GetTradingDayDate( sc.BaseDateTimeIn[Index]); SCDateTime TradingDayDateForLastBar = sc.GetTradingDayDate( sc.BaseDateTimeIn[sc.ArraySize - 1]); if ((TradingDayDateForLastBar.GetDate() - TradingDayDateForBar.GetDate() + 1) > Input_NumberOfDaysToCalculate.GetInt()) { LastExcludedIndex = Index; continue; } Array_PriceSum[Index] = 0; Array_PriceCount[Index] = 0; // calculate bar summation const s_VolumeAtPriceV2* p_VolumeAtPrice = NULL; int NumVAPElementsAtBarIndex = sc.VolumeAtPriceForBars->GetSizeAtBarIndex(Index); for (int VAPIndex = 0; VAPIndex < NumVAPElementsAtBarIndex; VAPIndex++) { sc.VolumeAtPriceForBars->GetVAPElementAtIndex(Index, VAPIndex, &p_VolumeAtPrice); int InputDataIndex = Input_InputData.GetIndex(); if (InputDataIndex == 0) { float Price = p_VolumeAtPrice->PriceInTicks * sc.TickSize; float PriceTimeTrades = Price * p_VolumeAtPrice->NumberOfTrades; Array_PriceSum[Index] += PriceTimeTrades; Array_PriceCount[Index] += p_VolumeAtPrice->NumberOfTrades; } else if (InputDataIndex == 1) { Array_PriceSum[Index] += p_VolumeAtPrice->Volume; Array_PriceCount[Index] += 1; } else if (InputDataIndex == 2) { Array_PriceSum[Index] += p_VolumeAtPrice->NumberOfTrades; Array_PriceCount[Index] += 1; } else if (InputDataIndex == 3) { Array_PriceSum[Index] += labs(p_VolumeAtPrice->AskVolume - p_VolumeAtPrice->BidVolume); Array_PriceCount[Index] += 1; } } if (NewBar) { if (PeriodType == 0) // Days - trading days { int TradeDate = sc.GetTradingDayDate(sc.BaseDateTimeIn[Index]); SCDateTime CurrentDayStartDateTime = sc.GetStartDateTimeForTradingDate(TradeDate); FirstIndexIncluded = sc.GetContainingIndexForSCDateTime(sc.ChartNumber, CurrentDayStartDateTime.GetAsDouble()); GetIndexForStartofDayPeriodForDaysBack ( sc , CurrentDayStartDateTime , Input_TimePeriodLength.GetInt() , Input_ExcludeWeekendInDateCalc.GetYesNo() != 0 , Input_MinimumRequiredTimePeriodAsPercentForSkipDays.GetInt() , FirstIndexIncluded ); } else if (PeriodType == 1) // Days - 24 hour periods { SCDateTime CurrentPeriodStartDateTime = sc.BaseDateTimeIn[Index] - SCDateTime::DAYS(1) + SCDateTime::SECONDS(1); FirstIndexIncluded = sc.GetContainingIndexForSCDateTime(sc.ChartNumber, CurrentPeriodStartDateTime.GetAsDouble()); GetIndexForStartofDayPeriodForDaysBack ( sc , CurrentPeriodStartDateTime , Input_TimePeriodLength.GetInt() , Input_ExcludeWeekendInDateCalc.GetYesNo() != 0 , Input_MinimumRequiredTimePeriodAsPercentForSkipDays.GetInt() , FirstIndexIncluded ); } else if (PeriodType == 2) // Minutes { SCDateTime RollingStartDateTime = 0; if (BarPeriod.IntradayChartBarPeriodType == IBPT_DAYS_MINS_SECS && BarPeriod.IntradayChartBarPeriodParameter1 != 0) { RollingStartDateTime = sc.BaseDateTimeIn[Index] + SCDateTime::SECONDS(sc.SecondsPerBar - 1); RollingStartDateTime.SubtractMinutes(Input_TimePeriodLength.GetInt()); } else { if (Index == sc.ArraySize - 1) RollingStartDateTime = sc.LatestDateTimeForLastBar; else RollingStartDateTime = sc.BaseDateTimeIn[Index+1] - SCDateTime::SECONDS(1); RollingStartDateTime.SubtractMinutes(Input_TimePeriodLength.GetInt()); } for (; FirstIndexIncluded <= Index; ++FirstIndexIncluded) { if (sc.BaseDateTimeIn[FirstIndexIncluded] < RollingStartDateTime) continue; break; } } else // Bars { FirstIndexIncluded = max(0, Index - Input_TimePeriodLength.GetInt()+1); } } if (FirstIndexIncluded <= LastExcludedIndex) FirstIndexIncluded = LastExcludedIndex + 1; // calculate average double CumulativePriceSum = 0; double CumulativePriceCount = 0; for (int AvgIndex=FirstIndexIncluded; AvgIndex <= Index; ++AvgIndex) { CumulativePriceSum += Array_PriceSum[AvgIndex]; CumulativePriceCount += Array_PriceCount[AvgIndex]; } if (CumulativePriceCount != 0) Subgraph_MovingAverage[Index] = static_cast(CumulativePriceSum / CumulativePriceCount); else Subgraph_MovingAverage[Index] = Subgraph_MovingAverage[Index - 1]; float BandDistance = 1.0f; //Standard deviation if (Input_BandCalculationMethod.GetInt() == 0) { const int StandardDeviationLength = Index - FirstIndexIncluded + 1; if (Index - StandardDeviationLength + 1 > LastExcludedIndex) { sc.StdDeviation(Subgraph_MovingAverage, Array_StandardDeviation, Index, StandardDeviationLength); BandDistance = Array_StandardDeviation[Index]; } } Subgraph_SD1Top[Index] = Subgraph_MovingAverage[Index] + Input_Band1OffsetMultiplier.GetFloat() * BandDistance; Subgraph_SD1Bottom[Index] = Subgraph_MovingAverage[Index] - Input_Band1OffsetMultiplier.GetFloat() * BandDistance; Subgraph_SD2Top[Index] = Subgraph_MovingAverage[Index] + Input_Band2OffsetMultiplier.GetFloat() * BandDistance; Subgraph_SD2Bottom[Index] = Subgraph_MovingAverage[Index] - Input_Band2OffsetMultiplier.GetFloat() * BandDistance; Subgraph_SD3Top[Index] = Subgraph_MovingAverage[Index] + Input_Band3OffsetMultiplier.GetFloat() * BandDistance; Subgraph_SD3Bottom[Index] = Subgraph_MovingAverage[Index] - Input_Band3OffsetMultiplier.GetFloat() * BandDistance; Subgraph_SD4Top[Index] = Subgraph_MovingAverage[Index] + Input_Band4OffsetMultiplier.GetFloat() * BandDistance; Subgraph_SD4Bottom[Index] = Subgraph_MovingAverage[Index] - Input_Band4OffsetMultiplier.GetFloat() * BandDistance; } } /*==========================================================================*/ SCSFExport scsf_TrueBarAverage(SCStudyInterfaceRef sc) { SCSubgraphRef Subgraph_Average = sc.Subgraph[0]; if(sc.SetDefaults) { sc.ScaleRangeType = SCALE_SAMEASREGION; sc.GraphName = "True Bar Average"; sc.GraphRegion = 0; sc.ValueFormat = VALUEFORMAT_INHERITED; sc.AutoLoop = 1; sc.MaintainVolumeAtPriceData = 1; Subgraph_Average.Name = "Average"; Subgraph_Average.DrawStyle = DRAWSTYLE_LINE; Subgraph_Average.LineWidth = 2; Subgraph_Average.PrimaryColor = RGB(237, 13, 255); Subgraph_Average.DrawZeros = false; return; } int PriceCount = 0; float Sum = 0.0; const s_VolumeAtPriceV2 *p_VolumeAtPrice = NULL; int NumVAPElementsAtBarIndex = sc.VolumeAtPriceForBars->GetSizeAtBarIndex(sc.Index); for (int VAPIndex = 0; VAPIndex < NumVAPElementsAtBarIndex; VAPIndex++) { sc.VolumeAtPriceForBars->GetVAPElementAtIndex(sc.Index, VAPIndex, &p_VolumeAtPrice); Sum += p_VolumeAtPrice->PriceInTicks * sc.TickSize; ++PriceCount; } if (PriceCount != 0) Subgraph_Average[sc.Index] = Sum / PriceCount; } /*==========================================================================*/ SCSFExport scsf_MovingLinearRegressionLine(SCStudyInterfaceRef sc) { SCSubgraphRef Subgraph_MLR = sc.Subgraph[0]; SCInputRef Input_InputData = sc.Input[0]; SCInputRef Input_Length = sc.Input[2]; if(sc.SetDefaults) { sc.GraphName = "Moving Linear Regression"; sc.GraphRegion = 0; sc.ValueFormat = 3; sc.AutoLoop = 1; Subgraph_MLR.Name = "MLR"; Subgraph_MLR.DrawStyle = DRAWSTYLE_LINE; Subgraph_MLR.PrimaryColor = RGB(0,255,0); Subgraph_MLR.DrawZeros = false; Input_InputData.Name = "Input Data"; Input_InputData.SetInputDataIndex(SC_LAST); Input_Length.Name = "Length"; Input_Length.SetInt(14); Input_Length.SetIntLimits(1, MAX_STUDY_LENGTH); return; } sc.DataStartIndex = Input_Length.GetInt()-1; sc.LinearRegressionIndicator(sc.BaseDataIn[Input_InputData.GetInputDataIndex()], Subgraph_MLR, Input_Length.GetInt()); } /*==========================================================================*/ SCSFExport scsf_MACD(SCStudyInterfaceRef sc) { SCSubgraphRef Subgraph_MACD = sc.Subgraph[0]; SCSubgraphRef Subgraph_MovAvgOfMACD = sc.Subgraph[1]; SCSubgraphRef Subgraph_MACDDiff = sc.Subgraph[2]; SCSubgraphRef Subgraph_RefLine = sc.Subgraph[3]; SCInputRef Input_InputData = sc.Input[0]; SCInputRef Input_FastLength = sc.Input[3]; SCInputRef Input_SlowLength = sc.Input[4]; SCInputRef Input_MACDLength = sc.Input[5]; SCInputRef Input_MovingAverageType = sc.Input[6]; if(sc.SetDefaults) { sc.GraphName = "MACD"; sc.AutoLoop = 1; sc.GraphRegion = 1; sc.ValueFormat = 3; Subgraph_MACD.Name = "MACD"; Subgraph_MACD.DrawStyle = DRAWSTYLE_LINE; Subgraph_MACD.DrawZeros = true; Subgraph_MACD.PrimaryColor = RGB(0,255,0); Subgraph_MovAvgOfMACD.Name = "MA of MACD"; Subgraph_MovAvgOfMACD.DrawStyle = DRAWSTYLE_LINE; Subgraph_MovAvgOfMACD.DrawZeros = true; Subgraph_MovAvgOfMACD.PrimaryColor = RGB(255,0,255); Subgraph_MACDDiff.Name = "MACD Diff"; Subgraph_MACDDiff.DrawStyle = DRAWSTYLE_BAR; Subgraph_MACDDiff.DrawZeros = true; Subgraph_MACDDiff.PrimaryColor = RGB(255,255,0); Subgraph_RefLine.Name = "Line"; Subgraph_RefLine.DrawStyle = DRAWSTYLE_LINE; Subgraph_RefLine.DrawZeros = true; Subgraph_RefLine.PrimaryColor = RGB(255,127,0); Input_InputData.Name = "Input Data"; Input_InputData.SetInputDataIndex(SC_LAST); Input_FastLength.Name ="Fast Moving Average Length"; Input_FastLength.SetInt(12); Input_FastLength.SetIntLimits(1,MAX_STUDY_LENGTH); Input_SlowLength.Name = "Slow Moving Average Length"; Input_SlowLength.SetInt(26); Input_SlowLength.SetIntLimits(1,MAX_STUDY_LENGTH); Input_MACDLength.Name = "MACD Moving Average Length"; Input_MACDLength.SetInt(9); Input_MACDLength.SetIntLimits(1,MAX_STUDY_LENGTH); Input_MovingAverageType.Name = "Moving Average Type"; Input_MovingAverageType.SetMovAvgType(MOVAVGTYPE_EXPONENTIAL); return; } if (Input_MovingAverageType.GetMovAvgType()==MOVAVGTYPE_EXPONENTIAL) sc.DataStartIndex = 2; else sc.DataStartIndex = Input_MACDLength.GetInt() + max(Input_FastLength.GetInt(), Input_SlowLength.GetInt()); sc.MACD(sc.BaseDataIn[Input_InputData.GetInputDataIndex()], Subgraph_MACD, sc.Index, Input_FastLength.GetInt(), Input_SlowLength.GetInt(), Input_MACDLength.GetInt(), Input_MovingAverageType.GetInt()); Subgraph_MovAvgOfMACD[sc.Index] = Subgraph_MACD.Arrays[2][sc.Index]; Subgraph_MACDDiff[sc.Index] = Subgraph_MACD.Arrays[3][sc.Index]; Subgraph_RefLine[sc.Index] = 0; } /*==========================================================================*/ SCSFExport scsf_3_10_Oscillator(SCStudyInterfaceRef sc) { SCSubgraphRef Subgraph_MACD = sc.Subgraph[0]; SCSubgraphRef Subgraph_MovAvgOfMACD = sc.Subgraph[1]; SCSubgraphRef Subgraph_MACDDiff = sc.Subgraph[2]; SCSubgraphRef Subgraph_RefLine = sc.Subgraph[3]; SCInputRef Input_InputData = sc.Input[0]; SCInputRef Input_FastLength = sc.Input[1]; SCInputRef Input_SlowLength = sc.Input[2]; SCInputRef Input_MACDLength = sc.Input[3]; if (sc.SetDefaults) { sc.GraphName = "3/10 Oscillator"; sc.AutoLoop = 1; sc.GraphRegion = 1; sc.ValueFormat = 3; Subgraph_MACD.Name = "3/10"; Subgraph_MACD.DrawStyle = DRAWSTYLE_LINE; Subgraph_MACD.DrawZeros = true; Subgraph_MACD.PrimaryColor = RGB(0, 255, 0); Subgraph_MovAvgOfMACD.Name = "Mov Avg 3/10"; Subgraph_MovAvgOfMACD.DrawStyle = DRAWSTYLE_LINE; Subgraph_MovAvgOfMACD.DrawZeros = true; Subgraph_MovAvgOfMACD.PrimaryColor = RGB(255, 0, 255); Subgraph_MACDDiff.Name = "3/10 Diff"; Subgraph_MACDDiff.DrawStyle = DRAWSTYLE_BAR; Subgraph_MACDDiff.DrawZeros = true; Subgraph_MACDDiff.PrimaryColor = RGB(255, 255, 0); Subgraph_RefLine.Name = "Line"; Subgraph_RefLine.DrawStyle = DRAWSTYLE_LINE; Subgraph_RefLine.DrawZeros = true; Subgraph_RefLine.PrimaryColor = RGB(255, 127, 0); Input_InputData.Name = "Input Data"; Input_InputData.SetInputDataIndex(SC_LAST); Input_FastLength.Name = "Fast Moving Average Length"; Input_FastLength.SetInt(3); Input_FastLength.SetIntLimits(1, MAX_STUDY_LENGTH); Input_SlowLength.Name = "Slow Moving Average Length"; Input_SlowLength.SetInt(10); Input_SlowLength.SetIntLimits(1, MAX_STUDY_LENGTH); Input_MACDLength.Name = "3/10 Moving Average Length"; Input_MACDLength.SetInt(16); Input_MACDLength.SetIntLimits(1, MAX_STUDY_LENGTH); return; } sc.DataStartIndex = Input_MACDLength.GetInt() + max(Input_FastLength.GetInt(), Input_SlowLength.GetInt()); sc.MACD(sc.BaseDataIn[Input_InputData.GetInputDataIndex()], Subgraph_MACD, sc.Index, Input_FastLength.GetInt(), Input_SlowLength.GetInt(), Input_MACDLength.GetInt(), MOVAVGTYPE_SIMPLE); Subgraph_MovAvgOfMACD[sc.Index] = Subgraph_MACD.Arrays[2][sc.Index]; Subgraph_MACDDiff[sc.Index] = Subgraph_MACD.Arrays[3][sc.Index]; Subgraph_RefLine[sc.Index] = 0; } /*==========================================================================*/ SCSFExport scsf_MACDLeader(SCStudyInterfaceRef sc) { SCSubgraphRef Subgraph_MACD = sc.Subgraph[0]; SCFloatArrayRef Array_FastExponential = sc.Subgraph[0].Arrays[0]; SCFloatArrayRef Array_SlowExponential = sc.Subgraph[0].Arrays[1]; SCFloatArrayRef Array_InputDataMinusFastAverage = sc.Subgraph[0].Arrays[2]; SCFloatArrayRef Array_InputDataMinusSlowAverage = sc.Subgraph[0].Arrays[3]; SCFloatArrayRef Array_AvgInputDataMinusFastAverage = sc.Subgraph[0].Arrays[4]; SCFloatArrayRef Array_AvgInputDataMinusSlowAverage = sc.Subgraph[0].Arrays[5]; SCSubgraphRef Subgraph_MovAvgOfMACD = sc.Subgraph[1]; SCSubgraphRef Subgraph_MACDLeader = sc.Subgraph[2]; SCSubgraphRef Subgraph_RefLine = sc.Subgraph[3]; SCInputRef Input_InputData = sc.Input[0]; SCInputRef Input_FastLength = sc.Input[1]; SCInputRef Input_SlowLength = sc.Input[2]; SCInputRef Input_MACDMovingAverageLength = sc.Input[3]; SCInputRef Input_MovingAverageType = sc.Input[4]; SCInputRef Input_MACDMovingAverageType = sc.Input[5]; if (sc.SetDefaults) { sc.GraphName = "MACD Leader"; sc.AutoLoop = 1; sc.GraphRegion = 1; sc.ValueFormat = 3; Subgraph_MACD.Name = "MACD"; Subgraph_MACD.DrawStyle = DRAWSTYLE_LINE; Subgraph_MACD.DrawZeros = true; Subgraph_MACD.PrimaryColor = RGB(0, 255, 0); Subgraph_MovAvgOfMACD.Name = "MA of MACD"; Subgraph_MovAvgOfMACD.DrawStyle = DRAWSTYLE_LINE; Subgraph_MovAvgOfMACD.DrawZeros = true; Subgraph_MovAvgOfMACD.PrimaryColor = RGB(255, 0, 255); Subgraph_MACDLeader.Name = "MACD Leader"; Subgraph_MACDLeader.DrawStyle = DRAWSTYLE_LINE; Subgraph_MACDLeader.LineWidth = 2; Subgraph_MACDLeader.DrawZeros = true; Subgraph_MACDLeader.PrimaryColor = RGB(255, 128, 0); Subgraph_RefLine.Name = "Line"; Subgraph_RefLine.DrawStyle = DRAWSTYLE_LINE; Subgraph_RefLine.DrawZeros = true; Subgraph_RefLine.PrimaryColor = RGB(255, 127, 0); Input_InputData.Name = "Input Data"; Input_InputData.SetInputDataIndex(SC_LAST); Input_FastLength.Name = "Fast Moving Average Length"; Input_FastLength.SetInt(12); Input_FastLength.SetIntLimits(1, MAX_STUDY_LENGTH); Input_SlowLength.Name = "Slow Moving Average Length"; Input_SlowLength.SetInt(26); Input_SlowLength.SetIntLimits(1, MAX_STUDY_LENGTH); Input_MACDMovingAverageLength.Name = "MACD Moving Average Length"; Input_MACDMovingAverageLength.SetInt(9); Input_MACDMovingAverageLength.SetIntLimits(1, MAX_STUDY_LENGTH); Input_MovingAverageType.Name = "Moving Average Type"; Input_MovingAverageType.SetMovAvgType(MOVAVGTYPE_EXPONENTIAL); Input_MACDMovingAverageType.Name = "MACD Moving Average Type"; Input_MACDMovingAverageType.SetMovAvgType(MOVAVGTYPE_SIMPLE); return; } sc.DataStartIndex = Input_MACDMovingAverageLength.GetInt() + max(Input_FastLength.GetInt(), Input_SlowLength.GetInt()); int InputData = Input_InputData.GetInputDataIndex(); sc.MovingAverage(sc.BaseDataIn[InputData], Array_FastExponential, Input_MovingAverageType.GetInt(), Input_FastLength.GetInt() ); sc.MovingAverage(sc.BaseDataIn[InputData], Array_SlowExponential, Input_MovingAverageType.GetInt(), Input_SlowLength.GetInt()); Subgraph_MACD[sc.Index] = Array_FastExponential[sc.Index] - Array_SlowExponential[sc.Index]; sc.MovingAverage(Subgraph_MACD, Subgraph_MovAvgOfMACD, Input_MACDMovingAverageType.GetInt(), Input_MACDMovingAverageLength.GetInt()); Array_InputDataMinusFastAverage[sc.Index] = sc.BaseDataIn[InputData][sc.Index] - Array_FastExponential[sc.Index]; Array_InputDataMinusSlowAverage[sc.Index] = sc.BaseDataIn[InputData][sc.Index] - Array_SlowExponential[sc.Index]; sc.MovingAverage(Array_InputDataMinusFastAverage, Array_AvgInputDataMinusFastAverage, Input_MovingAverageType.GetInt(), Input_FastLength.GetInt()); sc.MovingAverage(Array_InputDataMinusSlowAverage, Array_AvgInputDataMinusSlowAverage, Input_MovingAverageType.GetInt(), Input_SlowLength.GetInt()); Subgraph_MACDLeader[sc.Index] = Subgraph_MACD[sc.Index] + Array_AvgInputDataMinusFastAverage[sc.Index] - Array_AvgInputDataMinusSlowAverage[sc.Index]; Subgraph_RefLine[sc.Index] = 0; } /*==========================================================================*/ SCSFExport scsf_StandardErrorBands(SCStudyInterfaceRef sc) { SCSubgraphRef Subgraph_UpperBand = sc.Subgraph[0]; SCSubgraphRef Subgraph_MidBand = sc.Subgraph[1]; SCSubgraphRef Subgraph_LowerBand = sc.Subgraph[2]; SCInputRef Input_InputData = sc.Input[0]; SCInputRef Input_Length = sc.Input[2]; SCInputRef Input_StandardDeviations = sc.Input[3]; if(sc.SetDefaults) { sc.GraphName = "Standard Error Bands"; sc.AutoLoop = 1; sc.GraphRegion = 0; sc.ValueFormat = 3; Subgraph_MidBand.Name = "Middle Band"; Subgraph_MidBand.DrawStyle = DRAWSTYLE_LINE; Subgraph_MidBand.DrawZeros = false; Subgraph_MidBand.PrimaryColor = RGB(255,0,255); Subgraph_LowerBand.Name = "Bottom Band"; Subgraph_LowerBand.DrawStyle = DRAWSTYLE_LINE; Subgraph_LowerBand.DrawZeros = false; Subgraph_LowerBand.PrimaryColor = RGB(255,255,0); Subgraph_UpperBand.Name = "Top Band"; Subgraph_UpperBand.DrawStyle = DRAWSTYLE_LINE; Subgraph_UpperBand.DrawZeros = false; Subgraph_UpperBand.PrimaryColor = RGB(0,255,0); Input_InputData.Name = "Input Data"; Input_InputData.SetInputDataIndex(SC_LAST); Input_Length.Name = "Length"; Input_Length.SetInt(14); Input_Length.SetIntLimits(1,MAX_STUDY_LENGTH); Input_StandardDeviations.Name = "Standard Deviations"; Input_StandardDeviations.SetFloat(2.0f); Input_StandardDeviations.SetFloatLimits(.001f, static_cast(MAX_STUDY_LENGTH)); return; } sc.DataStartIndex = Input_Length.GetInt()-1; sc.LinearRegressionIndicator(sc.BaseDataIn[Input_InputData.GetInputDataIndex()], Subgraph_MidBand, Input_Length.GetInt()); double StandardErrorValue = sc.GetStandardError(sc.BaseDataIn[Input_InputData.GetInputDataIndex()], Input_Length.GetInt()); Subgraph_UpperBand[sc.Index] = static_cast(Subgraph_MidBand[sc.Index] + StandardErrorValue * Input_StandardDeviations.GetFloat()); Subgraph_LowerBand[sc.Index] = static_cast(Subgraph_MidBand[sc.Index] - StandardErrorValue * Input_StandardDeviations.GetFloat()); } /*==========================================================================*/ SCSFExport scsf_BollingerBands(SCStudyInterfaceRef sc) { SCSubgraphRef Subgraph_UpperBand = sc.Subgraph[0]; SCSubgraphRef Subgraph_MidBand = sc.Subgraph[1]; SCSubgraphRef Subgraph_LowerBand = sc.Subgraph[2]; SCInputRef Input_InputData = sc.Input[0]; SCInputRef Input_Length = sc.Input[3]; SCInputRef Input_StandardDeviations = sc.Input[4]; SCInputRef Input_Version = sc.Input[5]; SCInputRef Input_MAType = sc.Input[6]; if(sc.SetDefaults) { sc.GraphName = "Bollinger Bands"; sc.GraphRegion = 0; sc.ValueFormat = 3; sc.AutoLoop = true; Subgraph_MidBand.Name = "Middle Band"; Subgraph_MidBand.DrawStyle = DRAWSTYLE_LINE; Subgraph_MidBand.PrimaryColor = RGB(255,0,255); Subgraph_UpperBand.Name = "Top Band"; Subgraph_UpperBand.DrawStyle = DRAWSTYLE_LINE; Subgraph_UpperBand.PrimaryColor = RGB(0,255,0); Subgraph_LowerBand.Name = "Bottom Band"; Subgraph_LowerBand.DrawStyle = DRAWSTYLE_LINE; Subgraph_LowerBand.PrimaryColor = RGB(255,255,0); Input_InputData.Name = "Input Data"; Input_InputData.SetInputDataIndex(SC_HLC_AVG); Input_Length.Name = "Length"; Input_Length.SetInt(10); Input_Length.SetIntLimits(1,MAX_STUDY_LENGTH); Input_StandardDeviations.Name = "Standard Deviations"; Input_StandardDeviations.SetFloat(2.0f); Input_StandardDeviations.SetFloatLimits(.0001f, static_cast(MAX_STUDY_LENGTH)); Input_Version.SetInt(2); Input_MAType.Name = "Moving Average Type"; Input_MAType.SetMovAvgType(MOVAVGTYPE_SIMPLE); return; } sc.DataStartIndex = Input_Length.GetInt()-1; sc.BollingerBands(sc.BaseDataIn[Input_InputData.GetInputDataIndex()],Subgraph_MidBand,Input_Length.GetInt(),Input_StandardDeviations.GetFloat(),Input_MAType.GetMovAvgType()); Subgraph_UpperBand[sc.Index] = Subgraph_MidBand.Arrays[0][sc.Index]; Subgraph_LowerBand[sc.Index] = Subgraph_MidBand.Arrays[1][sc.Index]; } /*==========================================================================*/ SCSFExport scsf_BollingerBands_StandardDeviationOfAverage(SCStudyInterfaceRef sc) { SCSubgraphRef Subgraph_UpperBand = sc.Subgraph[0]; SCSubgraphRef Subgraph_MidBand = sc.Subgraph[1]; SCSubgraphRef Subgraph_LowerBand = sc.Subgraph[2]; SCInputRef Input_InputData = sc.Input[0]; SCInputRef Input_Length = sc.Input[1]; SCInputRef Input_StandardDeviations = sc.Input[2]; SCInputRef Input_MAType = sc.Input[3]; if(sc.SetDefaults) { sc.GraphName = "Bollinger Bands - StandardDeviationOfAverage"; sc.GraphRegion = 0; sc.ValueFormat = VALUEFORMAT_INHERITED; sc.AutoLoop = true; Subgraph_MidBand.Name = "Middle Band"; Subgraph_MidBand.DrawStyle = DRAWSTYLE_LINE; Subgraph_MidBand.PrimaryColor = RGB(255,0,255); Subgraph_UpperBand.Name = "Top Band"; Subgraph_UpperBand.DrawStyle = DRAWSTYLE_LINE; Subgraph_UpperBand.PrimaryColor = RGB(0,255,0); Subgraph_LowerBand.Name = "Bottom Band"; Subgraph_LowerBand.DrawStyle = DRAWSTYLE_LINE; Subgraph_LowerBand.PrimaryColor = RGB(255,255,0); Input_InputData.Name = "Input Data"; Input_InputData.SetInputDataIndex(SC_HLC_AVG); Input_Length.Name = "Length"; Input_Length.SetInt(10); Input_Length.SetIntLimits(1,MAX_STUDY_LENGTH); Input_StandardDeviations.Name = "Standard Deviations"; Input_StandardDeviations.SetFloat(2.0f); Input_StandardDeviations.SetFloatLimits(.0001f, static_cast(MAX_STUDY_LENGTH)); Input_MAType.Name = "Moving Average Type"; Input_MAType.SetMovAvgType(MOVAVGTYPE_SIMPLE); return; } sc.DataStartIndex = Input_Length.GetInt()-1; BollingerBands_StandardDeviationOfAverage_S(sc.BaseDataIn[Input_InputData.GetInputDataIndex()], Subgraph_MidBand, Subgraph_UpperBand, Subgraph_LowerBand, Subgraph_MidBand.Arrays[0], sc.Index, Input_Length.GetInt(), Input_StandardDeviations.GetFloat(), Input_MAType.GetMovAvgType()); } /*==========================================================================*/ SCSFExport scsf_PositiveVolumeIndex(SCStudyInterfaceRef sc) { SCSubgraphRef Subgraph_PVI = sc.Subgraph[0]; SCInputRef Input_InputData = sc.Input[0]; SCInputRef Input_InitialValue = sc.Input[2]; if(sc.SetDefaults) { sc.GraphName = "Positive Volume Index"; sc.GraphRegion = 1; sc.ValueFormat = 3; sc.AutoLoop = 1; // true Subgraph_PVI.Name = "PVI"; Subgraph_PVI.DrawStyle = DRAWSTYLE_LINE; Subgraph_PVI.PrimaryColor = RGB(0,255,0); Subgraph_PVI.DrawZeros = false; Input_InputData.Name = "Input Data"; Input_InputData.SetInputDataIndex(SC_LAST); Input_InitialValue.Name = "Initial Value"; Input_InitialValue.SetFloat(2.5f); Input_InitialValue.SetFloatLimits(.01f, static_cast(MAX_STUDY_LENGTH)); return; } float prev_PVI; float prev_data; float data; float PVIval; float volume; float prev_volume; sc.DataStartIndex = 0; int pos = sc.Index; if(pos == 0)// We are starting a new PVI study { Subgraph_PVI[0] = Input_InitialValue.GetFloat(); pos++; } volume = sc.Volume[pos]; prev_volume = sc.Volume[pos-1]; prev_PVI = Subgraph_PVI[pos-1]; if(volume > prev_volume) // current volume less than equal to previous volume. { data = sc.BaseDataIn[Input_InputData.GetInputDataIndex()][pos]; prev_data = sc.BaseDataIn[Input_InputData.GetInputDataIndex()][pos-1]; PVIval = prev_PVI + ((data-prev_data) / prev_data * prev_PVI ); } else { PVIval = prev_PVI; } Subgraph_PVI[pos] = PVIval; } /************************************************************************************************************************/ SCSFExport scsf_NegativeVolumeIndex(SCStudyInterfaceRef sc) { SCSubgraphRef Subgraph_NVI = sc.Subgraph[0]; SCInputRef Input_InputData = sc.Input[0]; SCInputRef Input_InitialValue = sc.Input[2]; if(sc.SetDefaults) { sc.GraphName = "Negative Volume Index"; sc.GraphRegion = 1; sc.ValueFormat = 3; sc.AutoLoop= true; Subgraph_NVI.Name = "NVI"; Subgraph_NVI.DrawStyle = DRAWSTYLE_LINE; Subgraph_NVI.PrimaryColor = RGB(0,255,0); Subgraph_NVI.DrawZeros = false; Input_InputData.Name = "Input Data"; Input_InputData.SetInputDataIndex(SC_LAST); Input_InitialValue.Name = "Initial Value"; Input_InitialValue.SetFloat(2.5f); Input_InitialValue.SetFloatLimits(0.01f, static_cast(MAX_STUDY_LENGTH)); return; } sc.DataStartIndex = 0; float prev_NVI; float prev_data; float data; float NVIval; float volume; float prev_volume; int pos = sc.Index; if(pos == 0)// We are starting a new NVI study { Subgraph_NVI[0] = Input_InitialValue.GetFloat(); pos++; } volume = sc.Volume[pos]; prev_volume = sc.Volume[pos-1]; prev_NVI = Subgraph_NVI[pos-1]; if(volume < prev_volume) // current volume greater then equal to previous volume. { data = sc.BaseDataIn[Input_InputData.GetInputDataIndex()][pos]; prev_data = sc.BaseDataIn[Input_InputData.GetInputDataIndex()][pos-1]; NVIval = prev_NVI + ((data-prev_data) / prev_data * prev_NVI); } else { NVIval = prev_NVI; } Subgraph_NVI[pos] = NVIval; } /************************************************************************************************************************/ SCSFExport scsf_DoubleStochasticNew(SCStudyInterfaceRef sc) { SCSubgraphRef Subgraph_DS = sc.Subgraph[0]; SCSubgraphRef Subgraph_Line1 = sc.Subgraph[5]; SCSubgraphRef Subgraph_Line2 = sc.Subgraph[6]; SCInputRef Input_Length = sc.Input[0]; SCInputRef Input_EMALength = sc.Input[2]; SCInputRef Input_MovAvgType = sc.Input[3]; SCInputRef Input_Line1Value = sc.Input[4]; SCInputRef Input_Line2Value = sc.Input[5]; if(sc.SetDefaults) { sc.GraphName = "Double Stochastic"; sc.GraphRegion = 1; sc.ValueFormat = 3; sc.AutoLoop = true; Subgraph_DS.Name = "DS"; Subgraph_DS.DrawStyle = DRAWSTYLE_LINE; Subgraph_DS.PrimaryColor = RGB(0,255,0); Subgraph_DS.DrawZeros = false; Subgraph_Line1.Name = "Line 1"; Subgraph_Line1.DrawStyle = DRAWSTYLE_LINE; Subgraph_Line1.PrimaryColor = RGB(0,255,0); Subgraph_Line1.DrawZeros = false; Subgraph_Line2.Name = "Line 2"; Subgraph_Line2.DrawStyle = DRAWSTYLE_LINE; Subgraph_Line2.PrimaryColor = RGB(0,255,0); Subgraph_Line2.DrawZeros = false; Input_Length.Name = "Length"; Input_Length.SetInt(10); Input_Length.SetIntLimits(1,MAX_STUDY_LENGTH); Input_EMALength.Name = "Moving Average Length"; Input_EMALength.SetInt(3); Input_EMALength.SetIntLimits(1,MAX_STUDY_LENGTH); Input_MovAvgType.Name = "Moving Average Type"; Input_MovAvgType.SetMovAvgType(MOVAVGTYPE_EXPONENTIAL); Input_Line1Value.Name = "Line 1"; Input_Line1Value.SetInt(10); Input_Line2Value.Name = "Line 2"; Input_Line2Value.SetInt(85); return; } sc.DoubleStochastic(sc.BaseDataIn, Subgraph_DS, Input_Length.GetInt(), Input_EMALength.GetInt(), Input_MovAvgType.GetMovAvgType()); Subgraph_Line1[sc.Index] = static_cast(Input_Line1Value.GetInt()); Subgraph_Line2[sc.Index] = static_cast(Input_Line2Value.GetInt()); } /*==========================================================================*/ SCSFExport scsf_CandlesNoTails(SCStudyInterfaceRef sc) { SCSubgraphRef Subgraph_Open = sc.Subgraph[0]; SCSubgraphRef Subgraph_Last = sc.Subgraph[3]; SCSubgraphRef Subgraph_Volume = sc.Subgraph[4]; SCSubgraphRef Subgraph_NumTrades = sc.Subgraph[5]; SCSubgraphRef Subgraph_OHLCAvg = sc.Subgraph[6]; SCSubgraphRef Subgraph_HLCAvg = sc.Subgraph[7]; SCSubgraphRef Subgraph_HLAvg = sc.Subgraph[8]; SCSubgraphRef Subgraph_BidVol = sc.Subgraph[9]; SCSubgraphRef Subgraph_AskVol = sc.Subgraph[10]; if (sc.SetDefaults) { // Set the configuration and defaults sc.GraphName = "Candles without Tails"; sc.GraphDrawType = GDT_CANDLESTICK; sc.StandardChartHeader = 1; sc.DisplayAsMainPriceGraph = 1; sc.GraphRegion = 0; Subgraph_Open.Name = "Open"; Subgraph_Open.DrawStyle = DRAWSTYLE_LINE; Subgraph_Open.PrimaryColor = RGB(0,255,0); Subgraph_Open.DrawZeros = false; Subgraph_Last.Name = "Last"; Subgraph_Last.DrawStyle = DRAWSTYLE_LINE; Subgraph_Last.PrimaryColor = RGB(255,127,0); Subgraph_Last.DrawZeros = false; Subgraph_Volume.Name = "Volume"; Subgraph_Volume.DrawStyle = DRAWSTYLE_LINE; Subgraph_Volume.PrimaryColor = RGB(255,0,0); Subgraph_Volume.DrawZeros = false; Subgraph_NumTrades.Name = "# of Trades / OI"; Subgraph_NumTrades.DrawStyle = DRAWSTYLE_IGNORE; Subgraph_NumTrades.PrimaryColor = RGB(0,0,255); Subgraph_NumTrades.DrawZeros = false; Subgraph_OHLCAvg.Name = "OHLC Avg"; Subgraph_OHLCAvg.DrawStyle = DRAWSTYLE_IGNORE; Subgraph_OHLCAvg.PrimaryColor = RGB(127,0,255); Subgraph_OHLCAvg.DrawZeros = false; Subgraph_HLCAvg.Name = "HLC Avg"; Subgraph_HLCAvg.DrawStyle = DRAWSTYLE_IGNORE; Subgraph_HLCAvg.PrimaryColor = RGB(0,255,255); Subgraph_HLCAvg.DrawZeros = false; Subgraph_HLAvg.Name = "HL Avg"; Subgraph_HLAvg.DrawStyle = DRAWSTYLE_IGNORE; Subgraph_HLAvg.PrimaryColor = RGB(0,127,255); Subgraph_HLAvg.DrawZeros = false; Subgraph_BidVol.Name = "Bid Vol"; Subgraph_BidVol.DrawStyle = DRAWSTYLE_IGNORE; Subgraph_BidVol.PrimaryColor = RGB(0,255,0); Subgraph_BidVol.DrawZeros = false; Subgraph_AskVol.Name = "Ask Vol"; Subgraph_AskVol.DrawStyle = DRAWSTYLE_IGNORE; Subgraph_AskVol.PrimaryColor = RGB(0,255,0); Subgraph_AskVol.DrawZeros = false; sc.AutoLoop = 1; return; } //create a new name that includes the base graph name. sc.GraphName.Format("%s No Tails", sc.GetStudyName(0).GetChars()); // Do data processing Subgraph_Open[sc.Index] = sc.Open[sc.Index]; Subgraph_Last[sc.Index] = sc.Close[sc.Index]; Subgraph_Volume[sc.Index] = sc.Volume[sc.Index]; Subgraph_NumTrades[sc.Index] = sc.NumberOfTrades[sc.Index]; } /**************************************************************************************************/ SCSFExport scsf_KiwisTrailingStop(SCStudyInterfaceRef sc) { SCSubgraphRef Subgraph_TSUp = sc.Subgraph[0]; SCSubgraphRef Subgraph_TSDown = sc.Subgraph[1]; SCSubgraphRef Subgraph_direction = sc.Subgraph[3]; SCSubgraphRef Subgraph_hiclose = sc.Subgraph[4]; SCSubgraphRef Subgraph_loclose = sc.Subgraph[5]; SCFloatArrayRef Array_e1 = sc.Subgraph[6]; SCFloatArrayRef Array_e2 = sc.Subgraph[7]; SCFloatArrayRef Array_e3 = sc.Subgraph[8]; SCFloatArrayRef Array_e4 = sc.Subgraph[9]; SCFloatArrayRef Array_e5 = sc.Subgraph[10]; SCFloatArrayRef Array_e6 = sc.Subgraph[11]; SCSubgraphRef Subgraph_TempRange = sc.Subgraph[6]; SCSubgraphRef Subgraph_TempAvgRange = sc.Subgraph[7]; SCSubgraphRef Subgraph_diff2 = sc.Subgraph[8]; SCSubgraphRef Subgraph_atrmod = sc.Subgraph[9]; SCInputRef Input_Use2Subgraphs = sc.Input[0]; SCInputRef Input_ATRLength = sc.Input[2]; SCInputRef Input_ATRFactor = sc.Input[3]; SCInputRef Input_Vervoort = sc.Input[4]; SCInputRef Input_ATRMax = sc.Input[5]; if(sc.SetDefaults) { sc.GraphName="Kiwi's Trailing Stop"; sc.StudyDescription = "Kiwi's Trailing Stop (Chandelier) plus Sylvain Vervoort variation"; Subgraph_TSUp.Name="TS"; Subgraph_TSUp.DrawStyle = DRAWSTYLE_LINE_SKIP_ZEROS; Subgraph_TSUp.SecondaryColorUsed = 1; Subgraph_TSUp.PrimaryColor = RGB(0,255,0); Subgraph_TSUp.SecondaryColor = RGB(255,0,0); Subgraph_TSUp.DrawZeros = false; Subgraph_TSDown.Name = "TS"; Subgraph_TSDown.DrawStyle = DRAWSTYLE_LINE_SKIP_ZEROS; Subgraph_TSDown.PrimaryColor = RGB(255,0,0); Subgraph_TSDown.DrawZeros = false; Subgraph_TempRange.Name = "TR"; Subgraph_TempRange.DrawStyle = DRAWSTYLE_IGNORE; Subgraph_TempRange.PrimaryColor = RGB(127,0,255); Subgraph_TempRange.DrawZeros = false; Subgraph_TempAvgRange.Name = "TAR"; Subgraph_TempAvgRange.DrawStyle = DRAWSTYLE_IGNORE; Subgraph_TempAvgRange.PrimaryColor = RGB(0,255,255); Subgraph_TempAvgRange.DrawZeros = false; Subgraph_diff2.Name = "diff2"; Subgraph_diff2.DrawStyle = DRAWSTYLE_IGNORE; Subgraph_diff2.PrimaryColor = RGB(0,127,255); Subgraph_diff2.DrawZeros = false; Subgraph_atrmod.Name = "atrmod"; Subgraph_atrmod.DrawStyle = DRAWSTYLE_IGNORE; Subgraph_atrmod.PrimaryColor = RGB(0,255,0); Subgraph_atrmod.DrawZeros = false; sc.AutoLoop = 0; Input_ATRLength.Name="ATR Length"; Input_ATRLength.SetFloat(9.0); Input_ATRFactor.Name="ATR Factor"; Input_ATRFactor.SetFloat(2.5); Input_Vervoort.Name="Vervoort Variation?"; Input_Vervoort.SetYesNo(false); Input_ATRMax.Name="Vervoort Maximum Range"; Input_ATRMax.SetFloat(1.5); Input_Use2Subgraphs.Name="Use 2 subgraphs"; Input_Use2Subgraphs.SetYesNo(true); sc.GraphRegion = 0; return; } int pos; float Ave; float b,b2,b3,c1,c2,c3,c4,w1=0,w2=0; sc.DataStartIndex=10; if(Input_Use2Subgraphs.GetYesNo()) { Subgraph_TSUp.Name = "TS Up"; Subgraph_TSDown.Name = "TS Down"; Subgraph_TSUp.SecondaryColorUsed = false; } else { Subgraph_TSUp.Name="TS"; Subgraph_TSUp.SecondaryColorUsed = 1; } if (sc.UpdateStartIndex == 0) { Subgraph_direction[sc.UpdateStartIndex] = 1; Subgraph_loclose[sc.UpdateStartIndex] = sc.Close[sc.UpdateStartIndex]; Subgraph_hiclose[sc.UpdateStartIndex] = Subgraph_loclose[sc.UpdateStartIndex]; Array_e1[sc.UpdateStartIndex]=sc.High[sc.UpdateStartIndex]-sc.Low[sc.UpdateStartIndex]; Array_e2[sc.UpdateStartIndex]=Array_e1[sc.UpdateStartIndex]; Array_e3[sc.UpdateStartIndex]=Array_e1[sc.UpdateStartIndex]; Array_e4[sc.UpdateStartIndex]=Array_e1[sc.UpdateStartIndex]; Array_e5[sc.UpdateStartIndex]=Array_e1[sc.UpdateStartIndex]; Array_e6[sc.UpdateStartIndex]=Array_e1[sc.UpdateStartIndex]; } if(!Input_Vervoort.GetYesNo()) { b=0.5; // 0.5 b2=(b*b); // 0.25 b3=(b2*b); // 0.125 c1=-b3; // - 0.125 c2=(3*(b2+b3)); // 0.45 c3=(-3*(2*b2+b+b3)); c4=(1+3*b+b3+3*b2); w1 = 2/(Input_ATRLength.GetFloat()+1); w2 = 1-w1; for (pos=max(sc.UpdateStartIndex, 1); pos < sc.ArraySize; pos++) { float temp = max(sc.High[pos]-sc.Low[pos], sc.High[pos]-sc.Close[pos-1]); float P = max(temp,sc.Close[pos-1]-sc.Low[pos]); Array_e1[pos] = w1*P + w2*Array_e1[pos - 1]; Array_e2[pos] = w1*Array_e1[pos] + w2*Array_e2[pos - 1]; Array_e3[pos] = w1*Array_e2[pos] + w2*Array_e3[pos - 1]; Array_e4[pos] = w1*Array_e3[pos] + w2*Array_e4[pos - 1]; Array_e5[pos] = w1*Array_e4[pos] + w2*Array_e5[pos - 1]; Array_e6[pos] = w1*Array_e5[pos] + w2*Array_e6[pos - 1]; Ave = c1*Array_e6[pos] + c2*Array_e5[pos] + c3*Array_e4[pos] + c4*Array_e3[pos]; if((Subgraph_direction[pos-1]==1 && sc.Close[pos]<(Subgraph_loclose[pos-1])) || (Subgraph_direction[pos-1]==-1 && sc.Close[pos]>(Subgraph_hiclose[pos-1]))) { if(Subgraph_direction[pos-1]==1) { Subgraph_direction[pos] = -1; //reverse short Subgraph_hiclose[pos] = sc.Close[pos]+(Ave*Input_ATRFactor.GetFloat()); Subgraph_loclose[pos] = 0; } else { Subgraph_direction[pos] = 1; //reverse long Subgraph_loclose[pos] = sc.Close[pos]-(Ave*Input_ATRFactor.GetFloat()); Subgraph_hiclose[pos] = 0; } } else { if(Subgraph_direction[pos-1]==1) { if(sc.Close[pos]-(Ave*Input_ATRFactor.GetFloat())>Subgraph_loclose[pos-1]) { Subgraph_loclose[pos] = sc.Close[pos]-(Ave*Input_ATRFactor.GetFloat()); Subgraph_hiclose[pos] = Subgraph_hiclose[pos-1]; } else { Subgraph_loclose[pos] = Subgraph_loclose[pos-1]; Subgraph_hiclose[pos] = Subgraph_hiclose[pos-1]; } } else { if(sc.Close[pos]+(Ave*Input_ATRFactor.GetFloat())=Ref(L,-1),Ref(C,-1)-L,(Ref(C,-1)-L)-(Ref(L,-1)-H)/2); diff1:=Max(HiLo,Href); diff2:=Max(diff1,Lref); atrmod:=Wilders(diff2,period); loss:=atrfact*atrmod; trail:= If(C>PREV AND Ref(C,-1)>PREV, Max(PREV,C-loss), If(CPREV,C-loss,C+loss))); */ for (pos=max(sc.UpdateStartIndex, 1); pos < sc.ArraySize; pos++) { float HiLo,Href,Lref; int period = static_cast(Input_ATRLength.GetFloat()); Subgraph_TempRange[pos] = sc.High[pos]-sc.Low[pos]; sc.MovingAverage(Subgraph_TempRange, Subgraph_TempAvgRange, MOVAVGTYPE_SIMPLE, pos, period); HiLo=min(Subgraph_TempRange[pos],Input_ATRMax.GetFloat()*Subgraph_TempAvgRange[pos]); if(sc.Low[pos]<=sc.High[pos-1]) Href=sc.High[pos]-sc.Close[pos-1]; else Href=(sc.High[pos]-sc.Close[pos-1])-(sc.Low[pos]-sc.High[pos-1])/2; if(sc.High[pos]>=sc.Low[pos-1]) Lref=sc.Close[pos-1]-sc.Low[pos]; else Lref=(sc.Close[pos-1]-sc.Low[pos])- (sc.Low[pos-1]-sc.High[pos])/2; Subgraph_diff2[pos] = max(Lref,max(HiLo,Href)); sc.MovingAverage(Subgraph_diff2, Subgraph_atrmod, MOVAVGTYPE_WILDERS, pos, period); Ave = Subgraph_atrmod[pos]; if((Subgraph_direction[pos-1]==1 && sc.Close[pos]<(Subgraph_loclose[pos-1])) || (Subgraph_direction[pos-1]==-1 && sc.Close[pos]>(Subgraph_hiclose[pos-1]))) { if(Subgraph_direction[pos-1]==1) { Subgraph_direction[pos] = -1; //reverse short Subgraph_hiclose[pos] = sc.Close[pos]+(Ave*Input_ATRFactor.GetFloat()); Subgraph_loclose[pos] = 0; } else { Subgraph_direction[pos] = 1; //reverse long Subgraph_loclose[pos] = sc.Close[pos]-(Ave*Input_ATRFactor.GetFloat()); Subgraph_hiclose[pos] = 0; } } else { if(Subgraph_direction[pos-1]==1) { if(sc.Close[pos]-(Ave*Input_ATRFactor.GetFloat())>Subgraph_loclose[pos-1]) { Subgraph_loclose[pos] = sc.Close[pos]-(Ave*Input_ATRFactor.GetFloat()); Subgraph_hiclose[pos] = Subgraph_hiclose[pos-1]; } else { Subgraph_loclose[pos] = Subgraph_loclose[pos-1]; Subgraph_hiclose[pos] = Subgraph_hiclose[pos-1]; } } else { if(sc.Close[pos]+(Ave*Input_ATRFactor.GetFloat())(CHART_DRAWING_MAX_HORIZONTAL_AXIS_RELATIVE_POSITION)); Input_HorizontalPosition.SetInt(20); Input_HorizontalPosition.SetIntLimits(1, static_cast(CHART_DRAWING_MAX_HORIZONTAL_AXIS_RELATIVE_POSITION)); Input_VerticalPosition.Name.Format("Vertical Position From Bottom (1-%d)", static_cast(CHART_DRAWING_MAX_VERTICAL_AXIS_RELATIVE_POSITION)); Input_VerticalPosition.SetInt(90); Input_VerticalPosition.SetIntLimits(1, static_cast(CHART_DRAWING_MAX_VERTICAL_AXIS_RELATIVE_POSITION)); Input_StudySubgraphReference.Name = "Study And Subgraph To Display"; Input_StudySubgraphReference.SetChartStudySubgraphValues(1, 1, 0); Input_DisplaySubgraphName.Name = "Display Subgraph Name"; Input_DisplaySubgraphName.SetYesNo(false); Input_SubgraphOffset.Name = "Subgraph Columns Back"; Input_SubgraphOffset.SetInt(0); Input_UseTextForNonZeroValue.Name = "Use Text for Non-Zero Value"; Input_UseTextForNonZeroValue.SetYesNo(false); Input_NonZeroValueText.Name = "Non-Zero Value Text"; Input_NonZeroValueText.SetString(""); sc.TextInputName = "Prefix Text for Display Value"; return; } // Do data processing SCFloatArray StudyReference; sc.GetStudyArrayFromChartUsingID(Input_StudySubgraphReference.GetChartNumber(), Input_StudySubgraphReference.GetStudyID(), Input_StudySubgraphReference.GetSubgraphIndex(), StudyReference); SCString ValueText; if (!sc.TextInput.IsEmpty()) { ValueText += sc.TextInput; ValueText += " "; } if (Input_DisplaySubgraphName.GetYesNo()) { SCString SubgraphNameFromChartStudy; sc.GetStudySubgraphNameFromChart(Input_StudySubgraphReference.GetChartNumber(), Input_StudySubgraphReference.GetStudyID(), Input_StudySubgraphReference.GetSubgraphIndex(), SubgraphNameFromChartStudy); ValueText += SubgraphNameFromChartStudy; ValueText += " "; } int ColumnsBack = Input_SubgraphOffset.GetInt(); float StudyValue = StudyReference[StudyReference.GetArraySize() - 1 - ColumnsBack]; //Patch for when referencing data from the Numbers Bars Calculated Values study. This value could be used. if (StudyValue == -FLT_MAX) StudyValue = 0; if (Input_UseTextForNonZeroValue.GetYesNo()) { if (StudyValue != 0) ValueText += Input_NonZeroValueText.GetString(); else ValueText += " "; } else ValueText += sc.FormatGraphValue(StudyValue, sc.GetValueFormat()); sc.AddAndManageSingleTextDrawingForStudy (sc , false , Input_HorizontalPosition.GetInt() , Input_VerticalPosition.GetInt() , Subgraph_TextDisplay , false , ValueText , true ); } /*==========================================================================*/ SCSFExport scsf_LargeTextDisplayForStudy(SCStudyInterfaceRef sc) { SCSubgraphRef Subgraph_TextDisplay = sc.Subgraph[0]; SCInputRef Input_HorizontalPosition = sc.Input[0]; SCInputRef Input_VerticalPosition = sc.Input[1]; SCInputRef Input_StudySubgraphReference = sc.Input[3]; SCInputRef Input_DisplaySubgraphName = sc.Input[4]; SCInputRef Input_SubgraphOffset = sc.Input[5]; SCInputRef Input_PrefixTextForDisplayValue = sc.Input[6]; SCInputRef Input_SuffixTextForDisplayValue = sc.Input[7]; SCInputRef Input_UseTextForNonZeroValue = sc.Input[8]; SCInputRef Input_NonZeroValueText = sc.Input[9]; if (sc.SetDefaults) { // Set the configuration and defaults sc.GraphName = "Text Display For Study"; sc.AutoLoop = 0; sc.GraphRegion = 0; Subgraph_TextDisplay.Name = "Text Display"; Subgraph_TextDisplay.LineWidth = 20; Subgraph_TextDisplay.DrawStyle = DRAWSTYLE_CUSTOM_TEXT; Subgraph_TextDisplay.PrimaryColor = RGB(0, 0, 0); //black Subgraph_TextDisplay.SecondaryColor = RGB(128, 255, 255); Subgraph_TextDisplay.SecondaryColorUsed = true; Subgraph_TextDisplay.DisplayNameValueInWindowsFlags = 0; Input_HorizontalPosition.Name.Format("Horizontal Position From Left (1-%d)", static_cast(CHART_DRAWING_MAX_HORIZONTAL_AXIS_RELATIVE_POSITION)); Input_HorizontalPosition.SetInt(20); Input_HorizontalPosition.SetIntLimits(1, static_cast(CHART_DRAWING_MAX_HORIZONTAL_AXIS_RELATIVE_POSITION)); Input_VerticalPosition.Name.Format("Vertical Position From Bottom (1-%d)", static_cast(CHART_DRAWING_MAX_VERTICAL_AXIS_RELATIVE_POSITION)); Input_VerticalPosition.SetInt(90); Input_VerticalPosition.SetIntLimits(1, static_cast(CHART_DRAWING_MAX_VERTICAL_AXIS_RELATIVE_POSITION)); Input_StudySubgraphReference.Name = "Study and Subgraph to Display"; Input_StudySubgraphReference.SetStudySubgraphValues(1, 0); Input_DisplaySubgraphName.Name = "Display Subgraph Name"; Input_DisplaySubgraphName.SetYesNo(false); Input_SubgraphOffset.Name = "Subgraph Columns Back"; Input_SubgraphOffset.SetInt(0); Input_PrefixTextForDisplayValue.Name = "Prefix Text for Display Value"; Input_PrefixTextForDisplayValue.SetString(""); Input_SuffixTextForDisplayValue.Name = "Suffix Text for Display Value"; Input_SuffixTextForDisplayValue.SetString(""); Input_UseTextForNonZeroValue.Name = "Use Text for Non-Zero Value"; Input_UseTextForNonZeroValue.SetYesNo(false); Input_NonZeroValueText.Name = "Non-Zero Value Text"; Input_NonZeroValueText.SetString(""); return; } // Do data processing SCFloatArray StudyReference; sc.GetStudyArrayUsingID(Input_StudySubgraphReference.GetStudyID(), Input_StudySubgraphReference.GetSubgraphIndex(), StudyReference); int ColumnsBack = Input_SubgraphOffset.GetInt(); SCString ValueText; if (Input_PrefixTextForDisplayValue.GetString()[0] != '\0') { ValueText += Input_PrefixTextForDisplayValue.GetString(); ValueText += " "; } if (Input_DisplaySubgraphName.GetYesNo()) { const char* SubgraphName = sc.GetStudySubgraphName(Input_StudySubgraphReference.GetStudyID(), Input_StudySubgraphReference.GetSubgraphIndex()); if (SubgraphName != NULL) { ValueText += SubgraphName; ValueText += ": "; } } float StudyValue = StudyReference[StudyReference.GetArraySize() - 1 - ColumnsBack]; if (StudyValue == -FLT_MAX)//Patch for when referencing data from the Numbers Bars Calculated Values study. This value could be used. StudyValue = 0; if(Input_UseTextForNonZeroValue.GetYesNo() ) { if (StudyValue != 0) ValueText += Input_NonZeroValueText.GetString(); else ValueText += " "; } else ValueText += sc.FormatGraphValue(StudyValue, sc.GetValueFormat()); ValueText += Input_SuffixTextForDisplayValue.GetString(); sc.AddAndManageSingleTextDrawingForStudy ( sc , false , Input_HorizontalPosition.GetInt() , Input_VerticalPosition.GetInt() , Subgraph_TextDisplay , false , ValueText , sc.DrawStudyUnderneathMainPriceGraph? 0 : 1 ); } /*============================================================================ */ SCSFExport scsf_ProfitLossTextStudy(SCStudyInterfaceRef sc) { SCInputRef Input_HorizontalPosition = sc.Input[0]; SCInputRef Input_VerticalPosition = sc.Input[1]; SCInputRef Input_DisplayInFillSpace = sc.Input[2]; SCInputRef Input_ProfitLossFormat = sc.Input[3]; SCInputRef Input_RoundTurnCommission = sc.Input[4]; SCInputRef Input_ShowOpenPL = sc.Input[5]; SCInputRef Input_ShowClosedPL = sc.Input[6]; SCInputRef Input_ShowDailyPL = sc.Input[7]; SCInputRef Input_IncludeOpenPLInDailyPL = sc.Input[8]; SCInputRef Input_TextSize = sc.Input[10]; SCInputRef Input_TextColor = sc.Input[11]; SCInputRef Input_TextBackColor = sc.Input[12]; SCInputRef Input_ShowTotalTrades = sc.Input[13]; SCInputRef Input_ShowTotalQuantityFilled = sc.Input[14]; SCInputRef Input_ShowDailyTotalTrades = sc.Input[15]; SCInputRef Input_ShowDailyTotalQuantityFilled = sc.Input[16]; SCInputRef Input_ShowMaximumOpenPositionProfit = sc.Input[17]; SCInputRef Input_ShowMaximumOpenPositionLoss = sc.Input[18]; SCInputRef Input_ShowFlatToFlatClosedProfitLoss = sc.Input[19]; SCInputRef Input_ShowCurrentTradeTimeDuration = sc.Input[20]; SCInputRef Input_ShowNetProfitLossForAllSymbolsForTradeAccount = sc.Input[21]; if (sc.SetDefaults) { // Set the configuration and defaults sc.GraphName = "Trading: Profit/Loss Text"; sc.AutoLoop = 0; sc.GraphRegion = 0; sc.MaintainTradeStatisticsAndTradesData = 1; Input_HorizontalPosition.Name.Format("Horizontal Position From Left (1-%d)", static_cast(CHART_DRAWING_MAX_HORIZONTAL_AXIS_RELATIVE_POSITION)); Input_HorizontalPosition.SetInt(20); Input_HorizontalPosition.SetIntLimits(1, static_cast(CHART_DRAWING_MAX_HORIZONTAL_AXIS_RELATIVE_POSITION)); Input_VerticalPosition.Name.Format("Vertical Position From Bottom (1-%d)", static_cast(CHART_DRAWING_MAX_VERTICAL_AXIS_RELATIVE_POSITION)); Input_VerticalPosition.SetInt(90); Input_VerticalPosition.SetIntLimits(1, static_cast(CHART_DRAWING_MAX_VERTICAL_AXIS_RELATIVE_POSITION)); Input_DisplayInFillSpace.Name = "Display in Fill Space"; Input_DisplayInFillSpace.SetYesNo(false); Input_ShowOpenPL.Name = "Show Open Profit/Loss"; Input_ShowOpenPL.SetYesNo(1); Input_ShowClosedPL.Name = "Show Closed Profit/Loss"; Input_ShowClosedPL.SetYesNo(1); Input_ShowDailyPL.Name = "Show Daily Profit/Loss"; Input_ShowDailyPL.SetYesNo(1); Input_IncludeOpenPLInDailyPL.Name = "Include Open Profit/Loss in Daily Profit/Loss"; Input_IncludeOpenPLInDailyPL.SetYesNo(0); Input_TextSize.Name = "Text Size"; Input_TextSize.SetInt(14); Input_TextSize.SetIntLimits(3, 50); Input_TextColor.Name = "Text Color"; Input_TextColor.SetColor(0,0,0); // black Input_TextBackColor.Name = "Text Background Color"; Input_TextBackColor.SetColor(128,255,255); Input_ShowTotalTrades.Name = "Show Total Trades"; Input_ShowTotalTrades.SetYesNo(0); Input_ShowTotalQuantityFilled.Name = "Show Total Quantity Filled"; Input_ShowTotalQuantityFilled.SetYesNo(0); Input_ShowDailyTotalTrades.Name = "Show Daily Total Trades"; Input_ShowDailyTotalTrades.SetYesNo(0); Input_ShowDailyTotalQuantityFilled.Name = "Show Daily Total Quantity Filled"; Input_ShowDailyTotalQuantityFilled.SetYesNo(0); Input_ShowMaximumOpenPositionProfit.Name = "Show Maximum Open Position Profit"; Input_ShowMaximumOpenPositionProfit.SetYesNo(0); Input_ShowMaximumOpenPositionLoss.Name = "Show Maximum Open Position Loss"; Input_ShowMaximumOpenPositionLoss.SetYesNo(0); Input_ShowFlatToFlatClosedProfitLoss.Name = "Show Flat to Flat Closed Profit Loss"; Input_ShowFlatToFlatClosedProfitLoss.SetYesNo(0); Input_ProfitLossFormat.Name = "Profit/Loss Display Format"; Input_ProfitLossFormat.SetCustomInputStrings("Currency Value;Points (P);Points - Ignore Quantity (p);Ticks (T);Ticks - Ignore Quantity (t);Currency Value & Points (P);Currency Value & Points - Ignore Quantity (p);Currency Value & Ticks (T);Currency Value & Ticks - Ignore Quantity (t)"); Input_ProfitLossFormat.SetCustomInputIndex(0); Input_RoundTurnCommission.Name = "Round Turn Commission To Include"; Input_RoundTurnCommission.SetFloat(0); Input_ShowCurrentTradeTimeDuration.Name = "Show Current Trade Time Duration"; Input_ShowCurrentTradeTimeDuration.SetYesNo(0); Input_ShowNetProfitLossForAllSymbolsForTradeAccount.Name = "Show Net Profit/Loss for All Symbols for Trade Account"; Input_ShowNetProfitLossForAllSymbolsForTradeAccount.SetYesNo(0); return; } // This is to ensure that we access the trade data that matches the simulation mode setting. sc.SendOrdersToTradeService = !sc.GlobalTradeSimulationIsOn; if (sc.HideStudy) return; int& r_TextDrawingLineNumber = sc.GetPersistentInt(1); // Do data processing s_UseTool Tool; Tool.Clear(); // Reset tool structure for our next use. Unnecessary in this case, but good practice. Tool.DrawingType = DRAWING_TEXT; Tool.ChartNumber = sc.ChartNumber; Tool.Region = sc.GraphRegion; if (r_TextDrawingLineNumber != 0) Tool.LineNumber = r_TextDrawingLineNumber; Tool.AddMethod = UTAM_ADD_OR_ADJUST; if(Input_DisplayInFillSpace.GetYesNo()) Tool.BeginDateTime = -3; else Tool.BeginDateTime = Input_HorizontalPosition.GetInt(); Tool.BeginValue = static_cast(Input_VerticalPosition.GetInt()); Tool.UseRelativeVerticalValues = true; Tool.Color = Input_TextColor.GetColor(); Tool.FontFace = sc.ChartTextFont(); Tool.FontBackColor = Input_TextBackColor.GetColor(); Tool.FontSize = Input_TextSize.GetInt(); Tool.FontBold = true; Tool.ReverseTextColor = false; Tool.MultiLineLabel = true; Tool.TextAlignment = DT_LEFT; ProfitLossDisplayFormatEnum ProfitLossDisplayFormat = static_cast(Input_ProfitLossFormat.GetIndex()+1); s_SCPositionData PositionData; sc.GetTradePosition(PositionData); const double RoundTurnCommissionRate = sc.CurrencyValuePerTick == 0 ? 0 : Input_RoundTurnCommission.GetFloat(); SCString Text; n_ACSIL::s_TradeStatistics AllStats; n_ACSIL::s_TradeStatistics DailyStats; sc.GetTradeStatisticsForSymbolV2(n_ACSIL::STATS_TYPE_ALL_TRADES, AllStats); sc.GetTradeStatisticsForSymbolV2(n_ACSIL::STATS_TYPE_DAILY_ALL_TRADES, DailyStats); if (Input_ShowOpenPL.GetYesNo()) { SCString PLString; double Commission = RoundTurnCommissionRate * fabs(PositionData.PositionQuantity) / 2.0; sc.CreateProfitLossDisplayString(PositionData.OpenProfitLoss - Commission, PositionData.PositionQuantity, ProfitLossDisplayFormat, PLString); Text.Format("Open PL: %s", PLString.GetChars()); } if (Input_ShowClosedPL.GetYesNo()) { if (!Text.IsEmpty()) Text.Append("\n"); SCString PLString; double Commission = RoundTurnCommissionRate * fabs(AllStats.TotalQuantity); sc.CreateProfitLossDisplayString(AllStats.ClosedTradesProfitLoss - Commission, AllStats.TotalQuantity, ProfitLossDisplayFormat, PLString); SCString ClosedPLText; ClosedPLText.Format("Closed PL: %s", PLString.GetChars()); Text.Append(ClosedPLText); } if (Input_ShowDailyPL.GetYesNo()) { if (!Text.IsEmpty()) Text.Append("\n"); double DailyPL = DailyStats.ClosedTradesProfitLoss; t_OrderQuantity32_64 DailyClosedQuantity = DailyStats.TotalQuantity; double Commission = RoundTurnCommissionRate * fabs(DailyClosedQuantity); if (Input_IncludeOpenPLInDailyPL.GetYesNo()) { DailyPL += PositionData.OpenProfitLoss; const t_OrderQuantity32_64 OpenQuantity = abs(PositionData.PositionQuantity); DailyClosedQuantity += OpenQuantity; Commission += (RoundTurnCommissionRate * OpenQuantity / 2.0); Text.Append("Daily Net PL: "); } else Text.Append("Daily PL: "); SCString PLString; sc.CreateProfitLossDisplayString(DailyPL - Commission, DailyClosedQuantity, ProfitLossDisplayFormat, PLString); Text.Append(PLString); } if (Input_ShowTotalTrades.GetYesNo()) { if (!Text.IsEmpty()) Text.Append("\n"); SCString TotalTradesText; TotalTradesText.Format("Total Trades: %i", AllStats.TotalTrades); Text.Append(TotalTradesText); } if (Input_ShowTotalQuantityFilled.GetYesNo()) { if (!Text.IsEmpty()) Text.Append("\n"); SCString TotalFilledText("Total Filled Qty: "); SCString QuantityString; sc.OrderQuantityToString(AllStats.TotalFilledQuantity, QuantityString); TotalFilledText += QuantityString; Text.Append(TotalFilledText); } if (Input_ShowDailyTotalTrades.GetYesNo()) { if (!Text.IsEmpty()) Text.Append("\n"); SCString TotalTradesText; TotalTradesText.Format("Daily Trades: %i", DailyStats.TotalTrades); Text.Append(TotalTradesText); } if (Input_ShowDailyTotalQuantityFilled.GetYesNo()) { if (!Text.IsEmpty()) Text.Append("\n"); SCString TotalFilledText("Daily Filled Qty: "); SCString QuantityString; sc.OrderQuantityToString(DailyStats.TotalFilledQuantity, QuantityString); TotalFilledText += QuantityString; Text.Append(TotalFilledText); } if (Input_ShowMaximumOpenPositionProfit.GetYesNo()) { if (!Text.IsEmpty()) Text.Append("\n"); SCString PLString; sc.CreateProfitLossDisplayString(PositionData.MaximumOpenPositionProfit, PositionData.PositionQuantity, ProfitLossDisplayFormat, PLString); Text.AppendFormat("Max Open Profit: %s", PLString.GetChars()); } if (Input_ShowMaximumOpenPositionLoss.GetYesNo()) { if (!Text.IsEmpty()) Text.Append("\n"); SCString PLString; sc.CreateProfitLossDisplayString(PositionData.MaximumOpenPositionLoss, PositionData.PositionQuantity, ProfitLossDisplayFormat, PLString); Text.AppendFormat("Max Open Loss: %s", PLString.GetChars()); } if (Input_ShowFlatToFlatClosedProfitLoss.GetYesNo()) { if (!Text.IsEmpty()) Text.Append("\n"); SCString PLString; sc.CreateProfitLossDisplayString(DailyStats.ClosedFlatToFlatTradesProfitLoss, 0, ProfitLossDisplayFormat, PLString); Text.AppendFormat("FTF P/L: %s", PLString.GetChars()); } if (Input_ShowCurrentTradeTimeDuration.GetYesNo()) { if (!Text.IsEmpty()) Text.Append("\n"); s_ACSTrade TradeEntry; int32_t TradesSize = sc.GetFlatToFlatTradeListSize(); if (TradesSize >= 1) { const int Result = sc.GetFlatToFlatTradeListEntry(TradesSize - 1, TradeEntry); if (TradeEntry.CloseDateTime.IsUnset()) { SCDateTime TimeDuration = sc.GetCurrentDateTime() - TradeEntry.OpenDateTime; SCString DurationString; DurationString = sc.DateTimeToString(TimeDuration.GetAsDouble(), FLAG_DT_DATE_TIME_AS_TIME_DURATION_FORMAT); Text += DurationString; } } } if (Input_ShowNetProfitLossForAllSymbolsForTradeAccount.GetYesNo()) { if (!Text.IsEmpty()) Text.Append("\n"); SCString PLString; double NetProfitLoss = sc.GetTotalNetProfitLossForAllSymbols(1); sc.CreateProfitLossDisplayString(NetProfitLoss, 0, ProfitLossDisplayFormat, PLString); Text.AppendFormat("AllSymbols Daily Net P/L: %s", PLString.GetChars()); } Tool.Text = Text; sc.UseTool(Tool); r_TextDrawingLineNumber = Tool.LineNumber; } /*==========================================================================*/ SCSFExport scsf_UpDownVolumeRatio(SCStudyInterfaceRef sc) { SCSubgraphRef Subgraph_UpDownVolumeRatio = sc.Subgraph[0]; SCSubgraphRef Subgraph_ZeroLine = sc.Subgraph[1]; SCInputRef Input_MovingAverageLength = sc.Input[0]; SCInputRef Input_VolumeOrTrades = sc.Input[1]; SCInputRef Input_MovingAverageType = sc.Input [2]; if (sc.SetDefaults) { // Set the configuration and defaults sc.GraphName = "Up/Down Volume Ratio"; sc.MaintainAdditionalChartDataArrays = 1; sc.GraphRegion =1; Subgraph_UpDownVolumeRatio.Name = "VR"; Subgraph_UpDownVolumeRatio.DrawStyle = DRAWSTYLE_BAR; Subgraph_UpDownVolumeRatio.PrimaryColor = RGB(0, 255, 0); Subgraph_UpDownVolumeRatio.SecondaryColor = RGB(255, 0, 0); Subgraph_UpDownVolumeRatio.LineWidth = 3; Subgraph_UpDownVolumeRatio.AutoColoring = AUTOCOLOR_POSNEG; Subgraph_UpDownVolumeRatio.DrawZeros = false; // false Subgraph_ZeroLine.Name = "Zero"; Subgraph_ZeroLine.DrawStyle = DRAWSTYLE_LINE; Subgraph_ZeroLine.PrimaryColor = RGB(128, 128,128); Subgraph_ZeroLine.LineWidth = 2; Subgraph_ZeroLine.DrawZeros = true; // true Input_MovingAverageLength.Name = "Moving Average Length"; Input_MovingAverageLength.SetInt(14); Input_MovingAverageLength.SetIntLimits(1, INT_MAX); Input_VolumeOrTrades.Name = "Calculation Based On"; Input_VolumeOrTrades.SetCustomInputStrings("Up/Down Volume;Ask/Bid Volume;Up/Down Trades"); Input_VolumeOrTrades.SetCustomInputIndex(0); Input_MovingAverageType.Name = "Moving Average Type"; Input_MovingAverageType.SetMovAvgType(MOVAVGTYPE_EXPONENTIAL); sc.AutoLoop = 1; return; } // Do data processing int Up = SC_UPVOL; int Down = SC_DOWNVOL; if(Input_VolumeOrTrades.GetIndex() == 0) { Up = SC_UPVOL; Down = SC_DOWNVOL; } else if(Input_VolumeOrTrades.GetIndex() == 1) { Up = SC_ASKVOL; Down = SC_BIDVOL; } else { Up = SC_ASKNT; Down = SC_BIDNT; } float TotalTrades = sc.BaseData[Up][sc.Index] + sc.BaseData[Down][sc.Index]; if (TotalTrades > 0) Subgraph_UpDownVolumeRatio.Arrays[0][sc.Index] = 100 * (sc.BaseData[Up][sc.Index] - sc.BaseData[Down][sc.Index]) / TotalTrades; else Subgraph_UpDownVolumeRatio.Arrays[0][sc.Index] = 0.0f; sc.MovingAverage(Subgraph_UpDownVolumeRatio.Arrays[0], Subgraph_UpDownVolumeRatio, Input_MovingAverageType.GetMovAvgType(), Input_MovingAverageLength.GetInt()); } /*==========================================================================*/ SCSFExport scsf_MovAvgCross(SCStudyInterfaceRef sc) { SCInputRef Input_MA1Price = sc.Input[0]; SCInputRef Input_MA1Type = sc.Input[1]; SCInputRef Input_MA1Length = sc.Input[2]; SCInputRef Input_MA2Price = sc.Input[3]; SCInputRef Input_MA2Type = sc.Input[4]; SCInputRef Input_MA2Length = sc.Input[5]; SCInputRef Input_DotsSpacing = sc.Input[6]; if (sc.SetDefaults) { // Set the configuration and defaults sc.GraphName = "Moving Average Crossover"; sc.AutoLoop = 1; sc.GraphRegion = 0; sc.Subgraph[0].Name = "Moving Average 1"; sc.Subgraph[0].DrawStyle = DRAWSTYLE_LINE; sc.Subgraph[0].PrimaryColor = RGB(0,255,0); sc.Subgraph[1].Name = "Moving Average 2"; sc.Subgraph[1].DrawStyle = DRAWSTYLE_LINE; sc.Subgraph[1].PrimaryColor = RGB(255,0,255); sc.Subgraph[2].Name = "Buy/Sell"; sc.Subgraph[2].SecondaryColorUsed = 1; sc.Subgraph[2].PrimaryColor = RGB(0,255,0); sc.Subgraph[2].SecondaryColor = RGB(255,0,0); sc.Subgraph[2].DrawStyle = DRAWSTYLE_POINT; sc.Subgraph[2].LineWidth = 4; Input_MA1Price.Name = "Moving Average 1 Input Data"; Input_MA1Price.SetInputDataIndex(SC_LAST); Input_MA1Type.Name = "MA1.Type"; Input_MA1Type.SetMovAvgType(MOVAVGTYPE_EXPONENTIAL); Input_MA1Length.Name = "MA1.Length"; Input_MA1Length.SetInt(5); Input_MA1Length.SetIntLimits(1,MAX_STUDY_LENGTH); Input_MA2Price.Name = "Moving Average 2 Input Data"; Input_MA2Price.SetInputDataIndex(SC_OPEN); Input_MA2Type.Name = "MA2.Type"; Input_MA2Type.SetMovAvgType(MOVAVGTYPE_WEIGHTED); Input_MA2Length.Name = "MA2.Length"; Input_MA2Length.SetInt(6); Input_MA2Length.SetIntLimits(1,MAX_STUDY_LENGTH); return; } // Do data processing sc.MovingAverage(sc.BaseData[Input_MA1Price.GetInputDataIndex()], sc.Subgraph[0],Input_MA1Type.GetMovAvgType(),Input_MA1Length.GetInt()); sc.MovingAverage(sc.BaseData[Input_MA2Price.GetInputDataIndex()], sc.Subgraph[1],Input_MA2Type.GetMovAvgType(),Input_MA2Length.GetInt()); int direction = sc.CrossOver(sc.Subgraph[0],sc.Subgraph[1]); if (direction == CROSS_FROM_TOP) { sc.Subgraph[2][sc.Index] = sc.BaseData[SC_HIGH][sc.Index]; sc.Subgraph[2].DataColor[sc.Index] = sc.Subgraph[2].SecondaryColor; } else if (direction == CROSS_FROM_BOTTOM) { sc.Subgraph[2][sc.Index] = sc.BaseData[SC_LOW][sc.Index]; sc.Subgraph[2].DataColor[sc.Index] = sc.Subgraph[2].PrimaryColor; } else { sc.Subgraph[2][sc.Index] = 0; } } /*==========================================================================*/ SCSFExport scsf_BillWilliamsAC(SCStudyInterfaceRef sc) { SCSubgraphRef Subgraph_Up = sc.Subgraph[0]; SCSubgraphRef Subgraph_Down = sc.Subgraph[1]; SCSubgraphRef Subgraph_Flat = sc.Subgraph[2]; SCSubgraphRef Subgraph_All = sc.Subgraph[3]; SCSubgraphRef Subgraph_Temp4 = sc.Subgraph[4]; SCSubgraphRef Subgraph_Sum1 = sc.Subgraph[5]; SCSubgraphRef Subgraph_Avg1 = sc.Subgraph[6]; SCSubgraphRef Subgraph_Sum2 = sc.Subgraph[7]; SCSubgraphRef Subgraph_Avg2 = sc.Subgraph[8]; SCSubgraphRef Subgraph_Sum4 = sc.Subgraph[9]; SCSubgraphRef Subgraph_Avg4 = sc.Subgraph[10]; SCInputRef Input_LongMaLength = sc.Input[0]; SCInputRef Input_ShortMaLength = sc.Input[1]; SCInputRef Input_SignalMaLength = sc.Input[2]; SCInputRef Input_MaType = sc.Input[3]; if (sc.SetDefaults) { sc.GraphName = "Bill Williams AC"; sc.StudyDescription = ""; Subgraph_Up.Name = "Up"; Subgraph_Up.DrawStyle = DRAWSTYLE_DASH; Subgraph_Up.PrimaryColor = RGB( 0, 255, 0); Subgraph_Up.DrawZeros = false; Subgraph_Down.Name = "Down"; Subgraph_Down.DrawStyle = DRAWSTYLE_DASH; Subgraph_Down.PrimaryColor = RGB( 255, 0, 255); Subgraph_Down.DrawZeros = false; Subgraph_Flat.Name = "Flat"; Subgraph_Flat.DrawStyle = DRAWSTYLE_DASH; Subgraph_Flat.PrimaryColor = RGB( 192, 192, 192); Subgraph_Flat.DrawZeros = false; Subgraph_All.Name = "All"; Subgraph_All.DrawStyle = DRAWSTYLE_IGNORE; Subgraph_All.PrimaryColor = RGB( 255, 127, 0); Subgraph_All.DrawZeros = false; Input_LongMaLength.Name = "Long Moving Average Length"; Input_LongMaLength.SetInt(34); Input_LongMaLength.SetIntLimits(1, INT_MAX); Input_ShortMaLength.Name = "Short Moving Average Length"; Input_ShortMaLength.SetInt(5); Input_ShortMaLength.SetIntLimits(1, INT_MAX); Input_SignalMaLength.Name = "Signal Moving Average Length"; Input_SignalMaLength.SetInt(5); Input_SignalMaLength.SetIntLimits(1, INT_MAX); Input_MaType.Name = "Moving Average Type"; Input_MaType.SetCustomInputStrings("Bill Williams Smoothed;Exponential;Simple"); Input_MaType.SetCustomInputIndex(0); sc.AutoLoop = 1; return; } // Do data processing const float cfactor1 = 2.0f / (Input_LongMaLength.GetInt() + 1); const float cinvfactor1 = 1.0f - cfactor1; const float cfactor2 = 2.0f / (Input_ShortMaLength.GetInt() + 1); const float cinvfactor2 = 1.0f - cfactor2; const float cfactor4 = 2.0f / (Input_SignalMaLength.GetInt() + 1); const float cinvfactor4 = 1.0f - cfactor4; sc.DataStartIndex = 50; int pos = sc.Index; if (pos < 50) return; int j; float avg3, avg4; switch (Input_MaType.GetInt()) { case 0: { Subgraph_Sum1[pos] = Subgraph_Sum1[pos - 1] + sc.Close[pos]; if (pos >= 50 + Input_LongMaLength.GetInt()) Subgraph_Sum1[pos] = Subgraph_Sum1[pos] - Subgraph_Avg1[pos - 1]; Subgraph_Avg1[pos] = Subgraph_Sum1[pos] / Input_LongMaLength.GetInt(); Subgraph_Sum2[pos] = Subgraph_Sum2[pos - 1] + sc.Close[pos]; if (pos >= 50 + Input_ShortMaLength.GetInt()) Subgraph_Sum2[pos] = Subgraph_Sum2[pos] - Subgraph_Avg2[pos - 1]; Subgraph_Avg2[pos] = Subgraph_Sum2[pos] / Input_ShortMaLength.GetInt(); avg3 = Subgraph_Avg2[pos] - Subgraph_Avg1[pos]; Subgraph_Temp4.Data[pos] = avg3; Subgraph_Sum4[pos] = Subgraph_Sum4[pos - 1] + avg3; avg4 = Subgraph_Sum4[pos] / Input_SignalMaLength.GetInt(); j = pos - Input_SignalMaLength.GetInt() + 1; if (pos > 50 + Input_SignalMaLength.GetInt() - 2) Subgraph_Sum4[pos] = Subgraph_Sum4[pos] - Subgraph_Temp4.Data[j]; } break; case 1: { Subgraph_Avg1[pos] = Subgraph_Avg1[pos - 1] * cinvfactor1 + sc.Close[pos] * cfactor1; Subgraph_Avg2[pos] = Subgraph_Avg2[pos - 1] * cinvfactor2 + sc.Close[pos] * cfactor2; avg3 = Subgraph_Avg2[pos] - Subgraph_Avg1[pos]; //Temp4.Data[pos] = avg3; avg4 = Subgraph_Avg4[pos] = Subgraph_Avg4[pos - 1] * cinvfactor4 + avg3 * cfactor4; } break; case 2: default: { Subgraph_Sum1[pos] = Subgraph_Sum1[pos - 1] + sc.Close[pos]; float avg1 = Subgraph_Sum1[pos] / Input_LongMaLength.GetInt(); j = pos - Input_LongMaLength.GetInt() + 1; if (pos > 50 + Input_LongMaLength.GetInt() - 2) Subgraph_Sum1[pos] = Subgraph_Sum1[pos] - sc.Close[j]; Subgraph_Sum2[pos] = Subgraph_Sum2[pos - 1] + sc.Close[pos]; float avg2 = Subgraph_Sum2[pos] / Input_ShortMaLength.GetInt(); j = pos - Input_ShortMaLength.GetInt() + 1; if (pos > 50 + Input_ShortMaLength.GetInt() - 2) Subgraph_Sum2[pos] = Subgraph_Sum2[pos] - sc.Close[j]; avg3 = avg2 - avg1; Subgraph_Temp4.Data[pos] = avg3; Subgraph_Sum4[pos] = Subgraph_Sum4[pos - 1] + avg3; avg4 = Subgraph_Sum4[pos] / Input_SignalMaLength.GetInt(); j = pos - Input_SignalMaLength.GetInt() + 1; if (pos > 50 + Input_SignalMaLength.GetInt() - 2) Subgraph_Sum4[pos] = Subgraph_Sum4[pos] - Subgraph_Temp4.Data[j]; } break; } Subgraph_All.Data[pos] = avg3 - avg4; if (Subgraph_All.Data[pos] > Subgraph_All.Data[pos - 1]) { Subgraph_Up.Data[pos] = Subgraph_All.Data[pos]; Subgraph_Down.Data[pos] = 0; Subgraph_Flat.Data[pos] = 0; } else if(Subgraph_All.Data[pos] < Subgraph_All.Data[pos - 1]) { Subgraph_Up.Data[pos] = 0; Subgraph_Down.Data[pos] = Subgraph_All.Data[pos]; Subgraph_Flat.Data[pos] = 0; } else { Subgraph_Up.Data[pos] = 0; Subgraph_Down.Data[pos] = 0; Subgraph_Flat.Data[pos] = Subgraph_All.Data[pos]; } } /*==========================================================================*/ SCSFExport scsf_BillWilliamsAO(SCStudyInterfaceRef sc) { SCSubgraphRef Subgraph_AO = sc.Subgraph[0]; SCSubgraphRef Subgraph_ZeroLine = sc.Subgraph[1]; SCInputRef Input_InputData = sc.Input[0]; SCInputRef Input_MA1Length = sc.Input[2]; SCInputRef Input_MA2Length = sc.Input[3]; SCInputRef Input_MAType = sc.Input[4]; if (sc.SetDefaults) { sc.GraphName = "Bill Williams Awesome Oscillator"; sc.GraphRegion = 1; sc.ValueFormat = 3; sc.AutoLoop = 1; Subgraph_AO.Name = "AO"; Subgraph_AO.DrawStyle = DRAWSTYLE_BAR; Subgraph_AO.LineWidth = 2; Subgraph_AO.SecondaryColor = RGB(255,0,0); Subgraph_AO.AutoColoring = AUTOCOLOR_SLOPE; Subgraph_AO.DrawZeros = false; Subgraph_ZeroLine.Name ="Zero Line"; Subgraph_ZeroLine.DrawStyle = DRAWSTYLE_LINE; Subgraph_ZeroLine.LineWidth =1; Subgraph_ZeroLine.PrimaryColor = RGB(255,0,255); Subgraph_ZeroLine.DrawZeros = true; Input_InputData.SetInputDataIndex(SC_HL_AVG); Input_MA1Length.Name = "Moving Average 1 Length"; Input_MA1Length.SetInt(34); Input_MA1Length.SetIntLimits(1, MAX_STUDY_LENGTH); Input_MA2Length.Name = "Moving Average 2 Length"; Input_MA2Length.SetInt(5); Input_MA2Length.SetIntLimits(1, MAX_STUDY_LENGTH); Input_MAType.Name = "Moving Average Type"; Input_MAType.SetMovAvgType(MOVAVGTYPE_SIMPLE); return; } sc.DataStartIndex = max(Input_MA1Length.GetInt(), Input_MA2Length.GetInt()); sc.MovingAverage(sc.BaseDataIn[Input_InputData.GetInputDataIndex()], Subgraph_AO.Arrays[0], Input_MAType.GetMovAvgType(), Input_MA1Length.GetInt()); sc.MovingAverage(sc.BaseDataIn[Input_InputData.GetInputDataIndex()], Subgraph_AO.Arrays[1], Input_MAType.GetMovAvgType(), Input_MA2Length.GetInt()); Subgraph_AO.Data[sc.Index] = Subgraph_AO.Arrays[1][sc.Index] - Subgraph_AO.Arrays[0][sc.Index]; } /*==========================================================================*/ SCSFExport scsf_BillWilliamsMA(SCStudyInterfaceRef sc) { SCSubgraphRef Subgraph_MovAvg = sc.Subgraph[0]; SCInputRef Input_InputData = sc.Input[0]; SCInputRef Input_MovingAverageLength = sc.Input[2]; SCInputRef Input_MovingAverageType = sc.Input[4]; SCInputRef Input_Version = sc.Input[5]; if (sc.SetDefaults) { sc.GraphName = "Bill Williams Moving Average"; sc.StudyDescription = "To offset the moving average, use the Displacement setting for the MovAvg Subgraph."; sc.GraphRegion= 0; Subgraph_MovAvg.Name = "MovAvg"; Subgraph_MovAvg.DrawStyle = DRAWSTYLE_LINE; Subgraph_MovAvg.PrimaryColor = RGB(0,255,0); Input_InputData.Name = "Input Data"; Input_InputData.SetInputDataIndex(SC_LAST); Input_MovingAverageLength.Name = "MovAvg Length"; Input_MovingAverageLength.SetInt(34); Input_MovingAverageLength.SetIntLimits(1, INT_MAX); Input_MovingAverageType.Name = "Moving Average Type"; Input_MovingAverageType.SetCustomInputStrings(";Bill Willams EMA;Smoothed Moving Average"); Input_MovingAverageType.SetCustomInputIndex(2); Input_Version.SetInt(1); sc.AutoLoop = 1; return; } // Do data processing sc.DataStartIndex = 0; if (Input_Version.GetInt() < 1) { Input_InputData.SetInputDataIndex(SC_LAST); Input_Version.SetInt(1); } if (Input_MovingAverageType.GetIndex() == 0) Input_MovingAverageType.SetCustomInputIndex(1); uint32_t InputIndex = Input_InputData.GetInputDataIndex(); if (Input_MovingAverageType.GetIndex() == 1) { if (sc.Index == 0) { Subgraph_MovAvg[0] = sc.BaseData[InputIndex][0]; Subgraph_MovAvg.Arrays[4][sc.Index] = sc.BaseData[InputIndex][0]*Input_MovingAverageLength.GetInt(); } else { Subgraph_MovAvg.Arrays[4][sc.Index] = Subgraph_MovAvg.Arrays[4][sc.Index - 1] + sc.BaseData[InputIndex][sc.Index]; Subgraph_MovAvg.Arrays[4][sc.Index] -= Subgraph_MovAvg[sc.Index - 1]; Subgraph_MovAvg[sc.Index] = Subgraph_MovAvg.Arrays[4][sc.Index] / Input_MovingAverageLength.GetInt(); } } else { sc.SmoothedMovingAverage(sc.BaseData[InputIndex], Subgraph_MovAvg, sc.Index, Input_MovingAverageLength.GetInt()); } } /*==========================================================================*/ SCSFExport scsf_BillWilliamsAlligator(SCStudyInterfaceRef sc) { const int jaw = 0; const int teeth = 1; const int lips = 2; SCSubgraphRef Subgraph_Jaw = sc.Subgraph[0]; SCSubgraphRef Subgraph_Teeth = sc.Subgraph[1]; SCSubgraphRef Subgraph_Lips = sc.Subgraph[2]; SCInputRef Input_InputData = sc.Input[0]; SCInputRef Input_JawLength = sc.Input[1]; SCInputRef Input_TeethLength = sc.Input[3]; SCInputRef Input_LipsLength = sc.Input[5]; SCInputRef Input_VersionUpdate1 = sc.Input[7]; SCInputRef Input_MovAvgType = sc.Input[8]; SCInputRef Input_VersionUpdate2 = sc.Input[9]; if (sc.SetDefaults) { sc.GraphName = "Bill Williams Alligator"; sc.StudyDescription = ""; // Set the region to draw the graph in. Region zero is the main // price graph region. sc.GraphRegion = 0; // Set the name of the first subgraph // Set the color and style of the graph line. If these are not set // the default will be used. Subgraph_Jaw.Name = "Jaw"; Subgraph_Jaw.PrimaryColor = RGB(0,0,255); // Blue Subgraph_Jaw.DrawStyle = DRAWSTYLE_LINE; Subgraph_Jaw.GraphicalDisplacement = 8; Subgraph_Jaw.DrawZeros = false; // Set the color and style of the graph line. If these are not set // the default will be used. Subgraph_Teeth.Name = "Teeth"; Subgraph_Teeth.PrimaryColor = RGB(255,0,0); // Red Subgraph_Teeth.DrawStyle = DRAWSTYLE_LINE; Subgraph_Teeth.GraphicalDisplacement = 5; Subgraph_Teeth.DrawZeros = false; // Set the color and style of the graph line. If these are not set // the default will be used. Subgraph_Lips.Name = "Lips"; Subgraph_Lips.PrimaryColor = RGB(0, 255, 0); // Red Subgraph_Lips.DrawStyle = DRAWSTYLE_LINE; Subgraph_Lips.GraphicalDisplacement = 3; Subgraph_Lips.DrawZeros = false; sc.AutoLoop = 1; Input_InputData.Name = "Input Data"; Input_InputData.SetInputDataIndex(SC_HL_AVG); Input_JawLength.Name = "Jaw Length"; Input_JawLength.SetIntLimits(1,MAX_STUDY_LENGTH); Input_JawLength.SetInt(13); Input_TeethLength.Name = "Teeth Length"; Input_TeethLength.SetIntLimits(1,MAX_STUDY_LENGTH); Input_TeethLength.SetInt(8); Input_LipsLength.Name = "Lips Length"; Input_LipsLength.SetIntLimits(1,MAX_STUDY_LENGTH); Input_LipsLength.SetInt(5); Input_VersionUpdate1.SetYesNo(true); //Used For Settings Updating Input_MovAvgType.Name = "Moving Average Type"; Input_MovAvgType.SetMovAvgType(MOVAVGTYPE_SMOOTHED); Input_VersionUpdate2.SetYesNo(true); return; } // data processing if (Input_VersionUpdate2.GetYesNo() == false) Input_MovAvgType.SetMovAvgType(MOVAVGTYPE_SMOOTHED); if (Input_VersionUpdate1.GetYesNo() == false) { Subgraph_Jaw.GraphicalDisplacement = 8; Subgraph_Teeth.GraphicalDisplacement = 5; Subgraph_Lips.GraphicalDisplacement = 3; } // calculate jaw, teeth and lips sc.MovingAverage(sc.BaseData[Input_InputData.GetInputDataIndex()], Subgraph_Jaw, Input_MovAvgType.GetMovAvgType(), Input_JawLength.GetInt()); sc.MovingAverage(sc.BaseData[Input_InputData.GetInputDataIndex()], Subgraph_Teeth, Input_MovAvgType.GetMovAvgType(), Input_TeethLength.GetInt()); sc.MovingAverage(sc.BaseData[Input_InputData.GetInputDataIndex()], Subgraph_Lips, Input_MovAvgType.GetMovAvgType(), Input_LipsLength.GetInt()); } /*==========================================================================*/ SCSFExport scsf_AverageOfAverage(SCStudyInterfaceRef sc) { SCSubgraphRef Subgraph_Avg = sc.Subgraph[0]; SCSubgraphRef Subgraph_Temp1 = sc.Subgraph[1]; SCInputRef Input_Length = sc.Input[0]; SCInputRef Input_EmaLength = sc.Input[1]; if (sc.SetDefaults) { // Set the configuration and defaults sc.GraphName = "Average of Average"; sc.StudyDescription = ""; sc.AutoLoop = 1; // true Subgraph_Avg.Name = "Avg"; Subgraph_Avg.DrawStyle = DRAWSTYLE_LINE; Subgraph_Avg.PrimaryColor = RGB(0,255,0); Input_Length.Name = "Length"; Input_Length.SetInt(10); Input_Length.SetIntLimits(1, INT_MAX); Input_EmaLength.Name = "ExpMA Length"; Input_EmaLength.SetInt(10); Input_EmaLength.SetIntLimits(1, INT_MAX); return; } // Do data processing /* This calculates the Exponential Moving Average of a Linear Regression Indicator by passing the output array from the Linear Regression Indicator function to the Input data parameter of Exponential Moving Average function.*/ sc.LinearRegressionIndicator(sc.Close, Subgraph_Temp1, sc.Index, Input_Length.GetInt()); sc.ExponentialMovAvg(Subgraph_Temp1, Subgraph_Avg, sc.Index, Input_EmaLength.GetInt()); } /*==========================================================================*/ SCSFExport scsf_WoodiesEMA(SCStudyInterfaceRef sc) { SCSubgraphRef Subgraph_EMA = sc.Subgraph[0]; SCSubgraphRef Subgraph_UpDownColors = sc.Subgraph[1]; SCSubgraphRef Subgraph_EMAOutput = sc.Subgraph[2]; SCInputRef Input_NumberOfBars = sc.Input[0]; SCInputRef Input_PriceChange = sc.Input[1]; SCInputRef Input_EMALength = sc.Input[2]; SCInputRef Input_FixedValue = sc.Input[4]; SCInputRef Input_InputData = sc.Input[6]; if(sc.SetDefaults) { sc.GraphName="Woodies EMA"; sc.AutoLoop = 1; sc.GraphRegion = 0; Subgraph_EMA.Name = "EMA"; Subgraph_EMA.DrawStyle = DRAWSTYLE_LINE; Subgraph_EMA.PrimaryColor = RGB(0,255,0); Subgraph_EMA.DrawZeros = false; Subgraph_UpDownColors.Name = "Up / Down Color"; Subgraph_UpDownColors.DrawStyle = DRAWSTYLE_IGNORE; Subgraph_UpDownColors.PrimaryColor = RGB(0,255,0); Subgraph_UpDownColors.SecondaryColor = RGB(255,0,0); Subgraph_UpDownColors.SecondaryColorUsed = 1; Subgraph_UpDownColors.DrawZeros = false; Input_InputData.Name = "Input Data"; Input_InputData.SetInputDataIndex(SC_HLC_AVG); Input_NumberOfBars.Name = "Number of Bars for Angle"; Input_NumberOfBars.SetInt(4); Input_NumberOfBars.SetIntLimits(1,MAX_STUDY_LENGTH); Input_PriceChange.Name = "Price Change for Angle"; Input_PriceChange.SetFloat(0.000001f); Input_EMALength.Name = "EMA Length"; Input_EMALength.SetInt(34); Input_EMALength.SetIntLimits(1,MAX_STUDY_LENGTH); Input_FixedValue.Name = "Fixed Value to Use"; Input_FixedValue.SetFloat(0); return; } sc.DataStartIndex = Input_EMALength.GetInt() + Input_NumberOfBars.GetInt(); sc.ExponentialMovAvg(sc.BaseData[Input_InputData.GetInputDataIndex()], Subgraph_EMAOutput, Input_EMALength.GetInt()); if (sc.Index < Input_NumberOfBars.GetInt()) return; int BarIndex = sc.Index; if(Input_FixedValue.GetFloat() == 0.0f) Subgraph_EMA[BarIndex] = Subgraph_EMAOutput[BarIndex]; else Subgraph_EMA[BarIndex] = Input_FixedValue.GetFloat(); if (Subgraph_EMAOutput[BarIndex] - Subgraph_EMAOutput[BarIndex-Input_NumberOfBars.GetInt()] >= Input_PriceChange.GetFloat()) { Subgraph_EMA.DataColor[BarIndex] = Subgraph_UpDownColors.PrimaryColor; } else if (Subgraph_EMAOutput[BarIndex] - Subgraph_EMAOutput[BarIndex-Input_NumberOfBars.GetInt()] <= -Input_PriceChange.GetFloat()) { Subgraph_EMA.DataColor[BarIndex] = Subgraph_UpDownColors.SecondaryColor; } else { Subgraph_EMA.DataColor[BarIndex] = Subgraph_EMA.PrimaryColor; } } /*==========================================================================*/ SCSFExport scsf_WoodieCCITrend(SCStudyInterfaceRef sc) { SCSubgraphRef Subgraph_Above = sc.Subgraph[0]; SCSubgraphRef Subgraph_Below = sc.Subgraph[1]; SCSubgraphRef Subgraph_AboveColorValues = sc.Subgraph[2]; SCSubgraphRef Subgraph_DoNotDraw1 = sc.Subgraph[3]; SCSubgraphRef Subgraph_DoNotDraw2 = sc.Subgraph[4]; SCSubgraphRef Subgraph_CCI = sc.Subgraph[5]; SCInputRef Input_WarningBar = sc.Input[0]; SCInputRef Input_AlternateColor = sc.Input[1]; SCInputRef Input_CCILength = sc.Input[2]; SCInputRef Input_NumberOfBars = sc.Input[3]; SCInputRef Input_BarsIntertrendState = sc.Input[4]; SCInputRef Input_BarsFixPos = sc.Input[5]; if(sc.SetDefaults) { sc.GraphName="Woodies CCI Trend - Old"; sc.AutoLoop = 0; Subgraph_Above.Name = "Above"; Subgraph_Above.DrawStyle = DRAWSTYLE_BAR; Subgraph_Above.PrimaryColor = RGB(0,0,255); Subgraph_Above.DrawZeros = false; Subgraph_Below.Name = "Below"; Subgraph_Below.DrawStyle = DRAWSTYLE_BAR; Subgraph_Below.PrimaryColor = RGB(255,0,0); Subgraph_Below.DrawZeros = false; Subgraph_AboveColorValues.Name = "Color Value Output"; Subgraph_AboveColorValues.PrimaryColor = RGB(255, 255, 255); Subgraph_AboveColorValues.DrawStyle = DRAWSTYLE_IGNORE; Subgraph_AboveColorValues.DrawZeros = false; Subgraph_DoNotDraw1.DrawStyle = DRAWSTYLE_HIDDEN; Subgraph_DoNotDraw1.PrimaryColor = RGB(255,255,0); Subgraph_DoNotDraw1.DrawZeros = false; Subgraph_DoNotDraw2.DrawStyle = DRAWSTYLE_HIDDEN; Subgraph_DoNotDraw2.PrimaryColor = RGB(98,98,98); Subgraph_DoNotDraw2.DrawZeros = false; Subgraph_CCI.Name = "CCI"; Subgraph_CCI.DrawStyle = DRAWSTYLE_IGNORE; Subgraph_CCI.PrimaryColor = RGB(0,0,255); Subgraph_CCI.DrawZeros = false; Input_WarningBar.Name = "Use a Warning Bar"; Input_WarningBar.SetYesNo(false); Input_AlternateColor.Name = "Alternate Colour for uncertain trend states 0, 1, 2 or 4"; Input_AlternateColor.SetInt(0); Input_AlternateColor.SetIntLimits(0,4); Input_CCILength.Name = "CCI Length"; Input_CCILength.SetInt(14); Input_CCILength.SetIntLimits(1,MAX_STUDY_LENGTH); Input_NumberOfBars.Name = "Number of Bars"; Input_NumberOfBars.SetInt(6); Input_NumberOfBars.SetIntLimits(1,MAX_STUDY_LENGTH); Input_BarsIntertrendState.Name = "# of Bars for Intertrend State"; Input_BarsIntertrendState.SetInt(1); Input_BarsIntertrendState.SetIntLimits(1,MAX_STUDY_LENGTH); Input_BarsFixPos.Name = "0 = Bars or n = Fixed Position (n/1000)"; Input_BarsFixPos.SetFloat(0); return; } Subgraph_AboveColorValues.DrawStyle = DRAWSTYLE_IGNORE; Subgraph_DoNotDraw1.DrawStyle = DRAWSTYLE_HIDDEN; Subgraph_DoNotDraw2.DrawStyle = DRAWSTYLE_HIDDEN; COLORREF Color0 = Subgraph_Above.PrimaryColor; COLORREF Color1 = Subgraph_Below.PrimaryColor; COLORREF Color2 = Subgraph_DoNotDraw1.PrimaryColor; COLORREF Color3 = Subgraph_DoNotDraw2.PrimaryColor; int ArraySize = sc.ArraySize; switch (Input_AlternateColor.GetInt()) { case 4: case 2: Subgraph_DoNotDraw1.Name ="Change on Next Bar"; Subgraph_DoNotDraw2.Name ="Trend & Position Confused"; break; case 1: Subgraph_DoNotDraw1.Name = "Trend Up but below Zero"; Subgraph_DoNotDraw2.Name = "Trend Dn but above Zero"; break; case 0: default: Subgraph_DoNotDraw1.Name = "Change on Next Bar"; } int ud = -2, goingpos = 0, goingneg = 0, posbar = 0, negbar = 0, up = 0, dn = 0, next = 0; for(int i = sc.UpdateStartIndex; i < ArraySize;i++) { sc.CCI(sc.HLCAvg, Subgraph_CCI.Arrays[0], Subgraph_CCI, i, Input_CCILength.GetInt(), 0.015f); } int Start = max (sc.UpdateStartIndex, Input_CCILength.GetInt()*2 - 1); float cci0; for (int i = Start-1; i >= Input_CCILength.GetInt()*2; i--) { cci0 = sc.Subgraph[5][i]; if (cci0 > 0) { dn = 0; up++; } else if (cci0 < 0) { up = 0; dn++; } if(up >= Input_NumberOfBars.GetInt()) { Start = i + Input_NumberOfBars.GetInt(); ud=2; break; } else if(dn >= Input_NumberOfBars.GetInt()) { ud=-2; Start = i + Input_NumberOfBars.GetInt(); break; } } sc.DataStartIndex = Input_CCILength.GetInt()*2 - 1; for (int pos=Start; pos < ArraySize; pos++) { cci0 = Subgraph_CCI[pos]; if (cci0>0) { if(Input_AlternateColor.GetInt() == 4 && Input_BarsIntertrendState.GetInt() <= up+1) dn = 0; if(ud <= 0) { if (goingpos == 0) { goingpos = 1; up = 1; dn = 0; negbar = 0; if(Input_AlternateColor.GetInt() == 4 && Input_BarsIntertrendState.GetInt() == 1) ud=0; } else { up++; if(up == Input_NumberOfBars.GetInt()) dn = 0; if(Input_AlternateColor.GetInt() == 4 && Input_BarsIntertrendState.GetInt() <= up) ud = 0; } } else if(ud >= 2) { if (goingneg == 1) { posbar++; if(posbar >= 2) { goingneg = 0; dn = 0; } } else up++; } } if (cci0<0) { if(Input_AlternateColor.GetInt()==4 && Input_BarsIntertrendState.GetInt()<=dn+1) up=0; if(ud>= 0) { if (goingneg==0) { goingneg=1; dn=1; up=0; posbar=0; if(Input_AlternateColor.GetInt()==4 && Input_BarsIntertrendState.GetInt()==1) ud=0; } else { dn++; if(dn==Input_NumberOfBars.GetInt()) up=0; if(Input_AlternateColor.GetInt()==4 && Input_BarsIntertrendState.GetInt()<=dn) ud=0; } } else if(ud <= -2) { if (goingpos == 1) { negbar++; if(negbar>=2) { goingpos=0; up=0; } } else dn++; } }; next=0; if(up==(Input_NumberOfBars.GetInt()-1) && (ud<=-2 || (ud==0 && Input_AlternateColor.GetInt()==4)) && Input_WarningBar.GetYesNo()!=0) next=1; else if(dn==(Input_NumberOfBars.GetInt()-1) && (ud>= 2 || (ud==0 && Input_AlternateColor.GetInt()==4)) && Input_WarningBar.GetYesNo()!=0) next=1; if(up>=Input_NumberOfBars.GetInt()) ud=2; if(dn>=Input_NumberOfBars.GetInt()) ud=-2; if (Input_BarsFixPos.GetFloat()) Subgraph_Above[pos] = Input_BarsFixPos.GetFloat()/1000; else Subgraph_Above[pos] = cci0; if (next==1) { if(Input_AlternateColor.GetInt()==0 || Input_AlternateColor.GetInt()==2 || Input_AlternateColor.GetInt()==4) { Subgraph_Above.DataColor[pos] = Color2; } else if(Input_AlternateColor.GetInt()==1) { if(Input_BarsFixPos.GetFloat()==0) { Subgraph_Above.DataColor[pos] = Color0; Subgraph_Below[pos]=cci0/2; }; }; } else { if (ud==0 && Input_AlternateColor.GetInt()==4) { Subgraph_Above.DataColor[pos] = Color3; } else if (ud>=2) { if(Input_AlternateColor.GetInt()==0 || cci0>=0) { Subgraph_Above.DataColor[pos] = Color0; } else if(Input_AlternateColor.GetInt()==1) { Subgraph_Above.DataColor[pos] = Color2; } else if(Input_AlternateColor.GetInt()==2 || Input_AlternateColor.GetInt()==4) { Subgraph_Above.DataColor[pos] = Color3; } } else if (ud<=-2) { if(Input_AlternateColor.GetInt()==0 || cci0<=0) { Subgraph_Above.DataColor[pos] = Color1; } else { Subgraph_Above.DataColor[pos] = Color3; } } } if (Subgraph_Above.DataColor[pos] == Color0) { Subgraph_AboveColorValues[pos] = 1; } else if (Subgraph_Above.DataColor[pos] == Color1) { Subgraph_AboveColorValues[pos] = 2; } else if (Subgraph_Above.DataColor[pos] == Color2) { Subgraph_AboveColorValues[pos] = 3; } else if (Subgraph_Above.DataColor[pos] == Color3) { Subgraph_AboveColorValues[pos] = 4; } } } /*==========================================================================*/ SCSFExport scsf_Sidewinder(SCStudyInterfaceRef sc) { SCSubgraphRef Subgraph_SwTop = sc.Subgraph[0]; SCSubgraphRef Subgraph_SwBottom = sc.Subgraph[1]; SCSubgraphRef Subgraph_FlatColor = sc.Subgraph[2]; SCSubgraphRef Subgraph_OutWorksheet = sc.Subgraph[3]; SCSubgraphRef Subgraph_Lsma = sc.Subgraph[4]; SCSubgraphRef Subgraph_LsmaAngle = sc.Subgraph[5]; SCSubgraphRef Subgraph_Ema = sc.Subgraph[6]; SCSubgraphRef Subgraph_EmaAngle = sc.Subgraph[7]; SCInputRef Input_LsmaLength = sc.Input[0]; SCInputRef Input_EmaLength = sc.Input[1]; SCInputRef Input_TrendingThreshold = sc.Input[3]; SCInputRef Input_NormalThreshold = sc.Input[4]; SCInputRef Input_LineValue = sc.Input[5]; SCInputRef Input_TickValueOverride = sc.Input[6]; if(sc.SetDefaults) { sc.GraphName="Sidewinder"; sc.StudyDescription="Sidewinder"; sc.AutoLoop = 0; Subgraph_SwTop.Name = "SW Top"; Subgraph_SwTop.DrawStyle = DRAWSTYLE_LINE; Subgraph_SwTop.LineWidth = 2; Subgraph_SwTop.PrimaryColor = RGB(255,255,0); Subgraph_SwTop.SecondaryColor = RGB(0,255,0); Subgraph_SwTop.SecondaryColorUsed = 1; // true Subgraph_SwTop.DrawZeros = false; Subgraph_SwBottom.Name = "SW Bottom"; Subgraph_SwBottom.DrawStyle = DRAWSTYLE_LINE; Subgraph_SwBottom.LineWidth = 2; Subgraph_SwBottom.PrimaryColor = RGB(255,255,0); Subgraph_SwBottom.SecondaryColor = RGB(0,255,0); Subgraph_SwBottom.SecondaryColorUsed = 1; // true Subgraph_SwBottom.DrawZeros = false; Subgraph_FlatColor.Name = "Flat Color"; Subgraph_FlatColor.DrawStyle = DRAWSTYLE_IGNORE; Subgraph_FlatColor.PrimaryColor = RGB(255,0,0); Subgraph_FlatColor.DrawZeros = false; Subgraph_OutWorksheet.Name = "Output for Spreadsheets"; Subgraph_OutWorksheet.DrawStyle = DRAWSTYLE_IGNORE; Subgraph_OutWorksheet.PrimaryColor = RGB(255,255,255); Subgraph_OutWorksheet.DrawZeros = false; Subgraph_Lsma.DrawStyle = DRAWSTYLE_IGNORE; Subgraph_Lsma.DrawZeros = false; Subgraph_LsmaAngle.DrawStyle = DRAWSTYLE_IGNORE; Subgraph_LsmaAngle.DrawZeros = false; Subgraph_Ema.DrawStyle = DRAWSTYLE_IGNORE; Subgraph_Ema.DrawZeros = false; Subgraph_EmaAngle.DrawStyle = DRAWSTYLE_IGNORE; Subgraph_EmaAngle.DrawZeros = false; Input_LsmaLength.Name = "LSMA Length"; Input_LsmaLength.SetInt(25); Input_LsmaLength.SetIntLimits(1,MAX_STUDY_LENGTH); Input_EmaLength.Name = "EMA Length"; Input_EmaLength.SetInt(34); Input_EmaLength.SetIntLimits(1,MAX_STUDY_LENGTH); Input_TrendingThreshold.Name = "Trending Threshold"; Input_TrendingThreshold.SetFloat(100.0f); Input_NormalThreshold.Name = "Normal Threshold"; Input_NormalThreshold.SetFloat(30.0f); Input_LineValue.Name = "Line Value"; Input_LineValue.SetFloat(200.0f); Input_TickValueOverride.Name = "Tick Value (Enter number to override default)"; Input_TickValueOverride.SetFloat(0.0f); sc.AutoLoop = 1; return; } Subgraph_OutWorksheet.DrawStyle = DRAWSTYLE_IGNORE; Subgraph_OutWorksheet.PrimaryColor = RGB(255,255,255); const float RAD_TO_DEG = (180.0f/3.14159265358979f); // Colors COLORREF colorFlat = Subgraph_FlatColor.PrimaryColor; COLORREF colorNormalUp = Subgraph_SwTop.PrimaryColor; COLORREF colorTrendingUp = Subgraph_SwTop.SecondaryColor; COLORREF colorNormalDown = Subgraph_SwBottom.PrimaryColor; COLORREF colorTrendingDown = Subgraph_SwBottom.SecondaryColor; if (Input_TickValueOverride.GetFloat() == 1) Input_TickValueOverride.SetFloat(0); float inTickSize = sc.TickSize; if(Input_TickValueOverride.GetFloat() != 0) inTickSize = Input_TickValueOverride.GetFloat(); float &PriorTickSize = sc.GetPersistentFloat(1); if(PriorTickSize != inTickSize) { sc.UpdateStartIndex = 0; PriorTickSize = inTickSize; } float InverseTickSize = 1/inTickSize; sc.DataStartIndex = Input_LsmaLength.GetInt() - 1; // Determine the input array element to begin calculation at int Pos = sc.Index; if (Pos < 2) return; // Calculate the EMA sc.ExponentialMovAvg(sc.Close, Subgraph_Ema, Pos, Input_EmaLength.GetInt()); // Calculate the LSMA sc.LinearRegressionIndicator(sc.Close,Subgraph_Lsma,Pos, Input_LsmaLength.GetInt()); // Calculate the LSMA angle float lsma_Angle = static_cast(sc.SlopeToAngleInDegrees((Subgraph_Lsma[Pos]-((Subgraph_Lsma[Pos-1]+Subgraph_Lsma[Pos-2])/2.0f))*InverseTickSize)); Subgraph_LsmaAngle[Pos] = lsma_Angle; // Calculate the EMA angle float ema_Angle = static_cast(sc.SlopeToAngleInDegrees((Subgraph_Ema[Pos]-((Subgraph_Ema[Pos-1]+Subgraph_Ema[Pos-2])/2.0f))*InverseTickSize)); Subgraph_EmaAngle[Pos] = ema_Angle; // Calculate SW COLORREF color; float worksheetValue; if (fabs(Subgraph_EmaAngle[Pos]) >= 15.0f && (Subgraph_EmaAngle[Pos] + Subgraph_LsmaAngle[Pos]) >= Input_TrendingThreshold.GetFloat()) { color = colorTrendingUp; worksheetValue = 2; } else if (fabs(Subgraph_EmaAngle[Pos]) >= 15.0f && (Subgraph_EmaAngle[Pos] + Subgraph_LsmaAngle[Pos]) <= -Input_TrendingThreshold.GetFloat()) { color = colorTrendingDown; worksheetValue = -2; } else if (Subgraph_EmaAngle[Pos] > 5.0f && Subgraph_LsmaAngle[Pos] > 0.0f && (Subgraph_EmaAngle[Pos] + Subgraph_LsmaAngle[Pos]) >= Input_NormalThreshold.GetFloat()) { color = colorNormalUp; worksheetValue = 1; } else if (Subgraph_EmaAngle[Pos] < 5.0f && Subgraph_LsmaAngle[Pos] < 0.0f && (Subgraph_EmaAngle[Pos] + Subgraph_LsmaAngle[Pos]) <= -Input_NormalThreshold.GetFloat()) { color = colorNormalDown; worksheetValue = -1; } else { color = colorFlat; worksheetValue = 0; } Subgraph_SwTop[Pos] = Input_LineValue.GetFloat(); Subgraph_SwBottom[Pos] = -Input_LineValue.GetFloat(); Subgraph_SwTop.DataColor[Pos] = color; Subgraph_SwBottom.DataColor[Pos] = color; Subgraph_OutWorksheet[Pos] = worksheetValue; } /*==========================================================================*/ SCSFExport scsf_LSMAAboveBelowCCI(SCStudyInterfaceRef sc) { SCSubgraphRef Subgraph_LsmaCCI = sc.Subgraph[0]; SCSubgraphRef Subgraph_DoNotDraw1 = sc.Subgraph[1]; SCSubgraphRef Subgraph_DoNotDraw2 = sc.Subgraph[2]; SCSubgraphRef Subgraph_DoNotDraw3 = sc.Subgraph[3]; SCSubgraphRef Subgraph_DoNotDraw4 = sc.Subgraph[4]; SCInputRef Input_LsmaLength = sc.Input[0]; SCInputRef Input_CCILength = sc.Input[2]; SCInputRef Input_BarsPointsLsma = sc.Input[3]; if (sc.SetDefaults) { // Set the configuration and defaults sc.GraphName ="LSMA Above/Below CCI"; sc.GraphRegion = 1; Subgraph_LsmaCCI.DrawStyle = DRAWSTYLE_BAR; Subgraph_LsmaCCI.Name = "LSMA Above/Below CCI"; Subgraph_LsmaCCI.PrimaryColor = RGB(0, 255, 0); Subgraph_LsmaCCI.SecondaryColorUsed = 1; Subgraph_LsmaCCI.SecondaryColor = RGB(255, 0, 255); Subgraph_LsmaCCI.DrawZeros = false; Subgraph_DoNotDraw4.DrawStyle = DRAWSTYLE_IGNORE; Subgraph_DoNotDraw4.Name = "Spreadsheet Output"; Subgraph_DoNotDraw4.PrimaryColor = RGB(255,0,0); Subgraph_DoNotDraw4.DrawZeros = false; Input_LsmaLength.Name = "MA Length"; Input_LsmaLength.SetInt(25); Input_LsmaLength.SetIntLimits(1,MAX_STUDY_LENGTH); Input_CCILength.Name = "CCI Length"; Input_CCILength.SetInt(14); Input_CCILength.SetIntLimits(1,MAX_STUDY_LENGTH); Input_BarsPointsLsma.Name = "Bars (0) or Points (n/1000) or LSMA (9999)"; Input_BarsPointsLsma.SetInt(0); Input_BarsPointsLsma.SetIntLimits(0, 9999); //MovAvgType.Name = "Moving Average Type"; //MovAvgType.SetMovAvgType(MOVAVGTYPE_LINEARREGRESSION); sc.AutoLoop = 1; return; } COLORREF color0 = Subgraph_LsmaCCI.PrimaryColor; COLORREF color1 = Subgraph_LsmaCCI.SecondaryColor; sc.DataStartIndex = max(Input_LsmaLength.GetInt(), Input_CCILength.GetInt()); int MAType = MOVAVGTYPE_LINEARREGRESSION; sc.MovingAverage(sc.Close, Subgraph_DoNotDraw1, MAType,sc.Index, Input_LsmaLength.GetInt()); sc.CCI(sc.HLCAvg, Subgraph_DoNotDraw2, Subgraph_DoNotDraw3, sc.Index, Input_CCILength.GetInt(), 0.015f); float fLSMA = Subgraph_DoNotDraw1[sc.Index]; float fCCI = Subgraph_DoNotDraw3[sc.Index]; if (Input_BarsPointsLsma.GetInt() == 0) Subgraph_LsmaCCI[sc.Index] = fCCI; else if (Input_BarsPointsLsma.GetInt() == 9999) Subgraph_LsmaCCI[sc.Index] = fLSMA; else Subgraph_LsmaCCI[sc.Index] = static_cast(Input_BarsPointsLsma.GetInt()) / 1000.0f; if (sc.Close[sc.Index] > fLSMA) { Subgraph_LsmaCCI.DataColor[sc.Index] = color0; Subgraph_DoNotDraw4[sc.Index] = 1; } else if (sc.Close[sc.Index] < fLSMA) { Subgraph_LsmaCCI.DataColor[sc.Index] = color1; Subgraph_DoNotDraw4[sc.Index] = -1; } } /*==========================================================================*/ SCSFExport scsf_LSMAAboveBelow(SCStudyInterfaceRef sc) { SCSubgraphRef Subgraph_Lsma = sc.Subgraph[0]; SCSubgraphRef Subgraph_DoNotDraw1 = sc.Subgraph[1]; SCSubgraphRef Subgraph_WorksheetOutput = sc.Subgraph[2]; SCInputRef Input_LsmaLength = sc.Input[0]; if (sc.SetDefaults) { // Set the configuration and defaults sc.GraphName ="LSMA Above/Below Last"; sc.GraphRegion = 1; Subgraph_Lsma.DrawStyle = DRAWSTYLE_SQUARE; Subgraph_Lsma.LineWidth = 2; Subgraph_Lsma.Name = "Above/Below"; Subgraph_Lsma.PrimaryColor = RGB(0, 255, 0); Subgraph_Lsma.SecondaryColorUsed = 1; Subgraph_Lsma.SecondaryColor = RGB(255, 0, 0); Subgraph_Lsma.DrawZeros = true; Subgraph_WorksheetOutput.Name = "Spreadsheet Output"; Subgraph_WorksheetOutput.DrawStyle = DRAWSTYLE_IGNORE; Subgraph_WorksheetOutput.PrimaryColor = RGB(255,255,0); Subgraph_WorksheetOutput.DrawZeros = true; Input_LsmaLength.Name = "MovAvg Length"; Input_LsmaLength.SetInt(25); Input_LsmaLength.SetIntLimits(1,MAX_STUDY_LENGTH); sc.AutoLoop = 1; return; } COLORREF color0 = Subgraph_Lsma.PrimaryColor; COLORREF color1 = Subgraph_Lsma.SecondaryColor; sc.DataStartIndex = Input_LsmaLength.GetInt(); int index = sc.Index; sc.MovingAverage(sc.Close, Subgraph_DoNotDraw1, MOVAVGTYPE_LINEARREGRESSION, index, Input_LsmaLength.GetInt()); float fLSMA = Subgraph_DoNotDraw1[index]; if (sc.Close[index] > fLSMA) { Subgraph_Lsma.DataColor[index] = color0; Subgraph_WorksheetOutput[index] = 1; } else if (sc.Close[index] < fLSMA) { Subgraph_Lsma.DataColor[index] = color1; Subgraph_WorksheetOutput[index] = -1; } else { Subgraph_Lsma.DataColor[index] = 0; Subgraph_WorksheetOutput[index] = 0; } } /*==========================================================================*/ SCSFExport scsf_EMAAboveBelow(SCStudyInterfaceRef sc) { SCSubgraphRef Subgraph_ExponentialMovingAverage = sc.Subgraph[0]; SCSubgraphRef Subgraph_DoNotDraw1 = sc.Subgraph[1]; SCSubgraphRef Subgraph_WorksheetOutput = sc.Subgraph[2]; SCInputRef Subgraph_MovingAverageLength = sc.Input[0]; if (sc.SetDefaults) { // Set the configuration and defaults sc.GraphName ="EMA Above/Below Last"; sc.GraphRegion = 1; Subgraph_ExponentialMovingAverage.DrawStyle = DRAWSTYLE_SQUARE; Subgraph_ExponentialMovingAverage.LineWidth = 2; Subgraph_ExponentialMovingAverage.Name = "Above/Below"; Subgraph_ExponentialMovingAverage.PrimaryColor = RGB(0, 255, 0); Subgraph_ExponentialMovingAverage.SecondaryColorUsed = 1; Subgraph_ExponentialMovingAverage.SecondaryColor = RGB(255, 0, 0); Subgraph_ExponentialMovingAverage.DrawZeros = true; Subgraph_WorksheetOutput.Name = "Spreadsheet Output"; Subgraph_WorksheetOutput.DrawStyle= DRAWSTYLE_IGNORE; Subgraph_WorksheetOutput.PrimaryColor = RGB(255, 255, 0); Subgraph_WorksheetOutput.DrawZeros = true; Subgraph_MovingAverageLength.Name = "Moving Average Length"; Subgraph_MovingAverageLength.SetInt(25); Subgraph_MovingAverageLength.SetIntLimits(1,MAX_STUDY_LENGTH); sc.AutoLoop = 1; return; } COLORREF color0 = Subgraph_ExponentialMovingAverage.PrimaryColor; COLORREF color1 = Subgraph_ExponentialMovingAverage.SecondaryColor; sc.DataStartIndex = Subgraph_MovingAverageLength.GetInt(); sc.MovingAverage(sc.Close, Subgraph_DoNotDraw1, MOVAVGTYPE_EXPONENTIAL, sc.Index, Subgraph_MovingAverageLength.GetInt()); if (sc.Close[sc.Index] > Subgraph_DoNotDraw1[sc.Index]) { Subgraph_ExponentialMovingAverage.DataColor[sc.Index] = color0; Subgraph_WorksheetOutput[sc.Index] = 1; } else if (sc.Close[sc.Index] < Subgraph_DoNotDraw1[sc.Index]) { Subgraph_ExponentialMovingAverage.DataColor[sc.Index] = color1; Subgraph_WorksheetOutput[sc.Index] = -1; } else { Subgraph_ExponentialMovingAverage.DataColor[sc.Index] = 0; Subgraph_WorksheetOutput[sc.Index] = 0; } } /*==========================================================================*/ SCSFExport scsf_MurreyMath(SCStudyInterfaceRef sc) { const int NumberOfVisibleLines = 25; SCInputRef Input_SquareWidth = sc.Input[0]; SCInputRef Input_UseLastBarAsEndDateTime = sc.Input[1]; SCInputRef Input_EndDateTime = sc.Input[2]; SCInputRef Input_SquareWidthNew = sc.Input[3]; SCInputRef Input_Version = sc.Input[4]; SCInputRef Input_SquareWidthMultiplier = sc.Input[5]; SCInputRef Input_RoundToTickSize = sc.Input[6]; SCInputRef Input_CustomSquareWidth = sc.Input[7]; // Configuration if (sc.SetDefaults) { sc.GraphName = "Murrey Math"; sc.AutoLoop = 0; sc.GraphRegion = 0; sc.ScaleRangeType = SCALE_SAMEASREGION; for (int SubgraphIndex = 0; SubgraphIndex < NumberOfVisibleLines; SubgraphIndex++) { SCString SubgraphString; if(SubgraphIndex <= 16) SubgraphString.Format("%d/8", SubgraphIndex-8); else SubgraphString.Format("+%d/8", SubgraphIndex-16); sc.Subgraph[SubgraphIndex].Name = SubgraphString; sc.Subgraph[SubgraphIndex].DrawStyle = DRAWSTYLE_DASH; sc.Subgraph[SubgraphIndex].LineWidth = 1; sc.Subgraph[SubgraphIndex].PrimaryColor = RGB(0, 255, 0); sc.Subgraph[SubgraphIndex].LineLabel |= LL_NAME_ALIGN_LEFT | LL_DISPLAY_NAME | LL_NAME_ALIGN_CENTER; } //SquareWidth.Name = "Square Width"; Input_SquareWidth.SetInt(64); Input_SquareWidth.SetIntLimits(1, MAX_STUDY_LENGTH); Input_SquareWidthNew.Name = "Square Width"; Input_SquareWidthNew.SetCustomInputStrings("4;8;16;32;64;128;256;512"); Input_SquareWidthNew.SetCustomInputIndex(0); Input_UseLastBarAsEndDateTime.Name = "Use Last Bar as End Date-Time"; Input_UseLastBarAsEndDateTime.SetYesNo(true); Input_EndDateTime.Name = "End Date-Time"; Input_EndDateTime.SetDateTime(0); Input_Version.SetInt(1); Input_SquareWidthMultiplier.Name = "Square Width Multiplier"; Input_SquareWidthMultiplier.SetFloat(1.5); Input_SquareWidthMultiplier.SetFloatLimits(1.0, 100); Input_RoundToTickSize.Name = "Round to Tick Size"; Input_RoundToTickSize.SetYesNo(false); Input_CustomSquareWidth.Name = "Custom Square Width"; Input_CustomSquareWidth.SetInt(0); Input_CustomSquareWidth.SetIntLimits(0, MAX_STUDY_LENGTH); return; } if(Input_Version.GetInt() < 1) { Input_Version.SetInt(1); int OldSquareWidth = Input_SquareWidth.GetInt(); switch(OldSquareWidth) { case 4: Input_SquareWidthNew.SetCustomInputIndex(0); break; case 8: Input_SquareWidthNew.SetCustomInputIndex(1); break; case 16: Input_SquareWidthNew.SetCustomInputIndex(2); break; case 32: Input_SquareWidthNew.SetCustomInputIndex(3); break; default: case 64: Input_SquareWidthNew.SetCustomInputIndex(4); break; case 128: Input_SquareWidthNew.SetCustomInputIndex(5); break; case 256: Input_SquareWidthNew.SetCustomInputIndex(6); break; case 512: Input_SquareWidthNew.SetCustomInputIndex(7); break; } } int SquareWidthNumber = atoi(Input_SquareWidthNew.GetSelectedCustomString()); if (Input_CustomSquareWidth.GetInt() > 0) SquareWidthNumber = Input_CustomSquareWidth.GetInt(); int BarsBackToReference = sc.Round(SquareWidthNumber * Input_SquareWidthMultiplier.GetFloat()); int &PreviousStartOutputBarIndex = sc.GetPersistentInt(1); //Clear previously used elements for(int BarIndex = PreviousStartOutputBarIndex; BarIndex < sc.ArraySize; BarIndex++) { for (int LineIndex = 0; LineIndex < NumberOfVisibleLines; LineIndex++) { sc.Subgraph[LineIndex][BarIndex] = 0; } } //Determine the starting index if (Input_UseLastBarAsEndDateTime.GetYesNo()) PreviousStartOutputBarIndex = sc.ArraySize - BarsBackToReference; else { PreviousStartOutputBarIndex = sc.GetNearestMatchForSCDateTime(sc.ChartNumber, Input_EndDateTime.GetDateTime().GetAsDouble()) - BarsBackToReference + 1; } double HighestHighOfSquareWidthLength = static_cast(sc.GetHighest(sc.High, PreviousStartOutputBarIndex + BarsBackToReference - 1, BarsBackToReference)); double LowestLowOfSquareWidthLength = static_cast(sc.GetLowest(sc.Low, PreviousStartOutputBarIndex + BarsBackToReference - 1, BarsBackToReference)); double PriceRange = HighestHighOfSquareWidthLength - LowestLowOfSquareWidthLength; double SR = 0.0, OctaveCount = 0.0, Si = 0.0, M = 0.0, B = 0.0, TT = 0.0; int I = 0; if(HighestHighOfSquareWidthLength > 25) { if(log(0.4*HighestHighOfSquareWidthLength)/log(10.0)-int(log(0.4*HighestHighOfSquareWidthLength)/log(10.0))>0) SR = exp(log(10.0)*(int(log(0.4*HighestHighOfSquareWidthLength)/log(10.0))+1)); else SR = exp(log(10.0)*(int(log(0.4*HighestHighOfSquareWidthLength)/log(10.0)))); } else { SR = 100*exp(log(8.0)*(int(log(0.005*HighestHighOfSquareWidthLength)/log(8.0)))); } double RangeMMI = log(SR/PriceRange)/log(8.0); if(RangeMMI<=0) { OctaveCount = 0; } else { if(log(SR/PriceRange)/log(8.0)- fmod(log(SR/PriceRange),log(8.0))== 0) { OctaveCount = int(RangeMMI); } else { OctaveCount = int(RangeMMI)+1.0; } } Si = SR *exp(-OctaveCount * log(8.0)); if(PriceRange == 0) M = 0.0f; else M = int(((1 / log(2.0)) * log(fabs(PriceRange / Si))) + .00001); double ValueToRound = (((HighestHighOfSquareWidthLength + LowestLowOfSquareWidthLength) * .5)/(Si* exp((M-1)*log(2.0)))); I = sc.Round(static_cast(ValueToRound)); B =(I-1) * Si * exp((M-1)* log(2.0)); TT =(I+1) * Si * exp((M-1) * log(2.0)); for (int LineIndex = 0; LineIndex < NumberOfVisibleLines; LineIndex++) { for(int BarIndex = PreviousStartOutputBarIndex; BarIndex < sc.ArraySize; BarIndex++) { float MurreyMathValue = static_cast(B + ((LineIndex-8) * 0.125 * (TT -B))); if (Input_RoundToTickSize.GetYesNo()) MurreyMathValue = sc.RoundToTickSize(MurreyMathValue); sc.Subgraph[LineIndex][BarIndex] = MurreyMathValue; } } } /*==========================================================================*/ SCSFExport scsf_PreviousCloseLine(SCStudyInterfaceRef sc) { SCSubgraphRef Subgraph_PreviousCloseLine = sc.Subgraph[0]; SCInputRef Input_UsePreviousCloseFromQuoteData = sc.Input[0]; if(sc.SetDefaults) { sc.GraphName = "Previous Close Line"; Subgraph_PreviousCloseLine.Name = "PCL"; Subgraph_PreviousCloseLine.DrawStyle = DRAWSTYLE_LINE; Subgraph_PreviousCloseLine.LineStyle = LINESTYLE_DOT; Subgraph_PreviousCloseLine.PrimaryColor = RGB(0, 255, 0); Subgraph_PreviousCloseLine.LineWidth = 2; Subgraph_PreviousCloseLine.DrawZeros = false; Input_UsePreviousCloseFromQuoteData.Name = "Use Previous Close From Quote Data"; Input_UsePreviousCloseFromQuoteData.SetYesNo(0); sc.GraphRegion = 0; sc.AutoLoop = 0; return; } SCDateTime PriorDayCloseDateTime = sc.GetStartDateTimeForTradingDate(sc.GetTradingDayDate(sc.BaseDateTimeIn[sc.ArraySize - 1]) ); PriorDayCloseDateTime.SubtractSeconds(1); int PriorDayCloseDateTimeIndex = sc.GetContainingIndexForSCDateTime(sc.ChartNumber, PriorDayCloseDateTime.GetAsDouble()); float PriorDayCloseValue = 0.0; if (Input_UsePreviousCloseFromQuoteData.GetYesNo()) PriorDayCloseValue = sc.PreviousClose; else PriorDayCloseValue = sc.BaseData[SC_LAST][PriorDayCloseDateTimeIndex]; for (int BarIndex = sc.UpdateStartIndex ; BarIndex < sc.ArraySize; ++BarIndex) { if (BarIndex < PriorDayCloseDateTimeIndex) continue; Subgraph_PreviousCloseLine[BarIndex] = PriorDayCloseValue; } } /*==========================================================================*/ SCSFExport scsf_ValueChartLevels(SCStudyInterfaceRef sc) { SCInputRef Input_ModOBLevel = sc.Input[1]; SCInputRef Input_SigOBLevel = sc.Input[2]; SCSubgraphRef Subgraph_PlusModerateOverboughtLevel = sc.Subgraph[0]; SCSubgraphRef Subgraph_PlusSignificantOverboughtLevel = sc.Subgraph[1]; SCSubgraphRef Subgraph_ZeroLevel= sc.Subgraph[2]; SCSubgraphRef Subgraph_MinusModerateOverboughtLevel= sc.Subgraph[3]; SCSubgraphRef Subgraph_MinusSignificantOverboughtLevel= sc.Subgraph[4]; if (sc.SetDefaults) { // Set the configuration and defaults sc.GraphName ="Value Chart Levels"; sc.GraphDrawType = GDT_CUSTOM; sc.AutoLoop = 1; Input_ModOBLevel.Name = "Moderately Overbought Level"; Input_ModOBLevel.SetFloat(4.0f); Input_ModOBLevel.SetFloatLimits(0,100.0f); Input_SigOBLevel.Name = "Significantly Overbought Level"; Input_SigOBLevel.SetFloat(8.0f); Input_SigOBLevel.SetFloatLimits(0,100.0f); Subgraph_PlusModerateOverboughtLevel.Name = "+ Moderate Overbought Level"; Subgraph_PlusModerateOverboughtLevel.PrimaryColor = RGB(0,255,0); Subgraph_PlusModerateOverboughtLevel.DrawStyle = DRAWSTYLE_LINE; Subgraph_PlusModerateOverboughtLevel.DisplayNameValueInWindowsFlags= 0; Subgraph_PlusSignificantOverboughtLevel.Name = "+ Significant Overbought Level"; Subgraph_PlusSignificantOverboughtLevel.PrimaryColor = RGB(255,0,0); Subgraph_PlusSignificantOverboughtLevel.DrawStyle = DRAWSTYLE_LINE; Subgraph_PlusSignificantOverboughtLevel.DisplayNameValueInWindowsFlags= 0; Subgraph_MinusModerateOverboughtLevel.Name = "- Moderate Overbought Level"; Subgraph_MinusModerateOverboughtLevel.PrimaryColor = RGB(0,255,0); Subgraph_MinusModerateOverboughtLevel.DrawStyle = DRAWSTYLE_LINE; Subgraph_MinusModerateOverboughtLevel.DisplayNameValueInWindowsFlags= 0; Subgraph_MinusSignificantOverboughtLevel.Name = "- Significant Overbought Level"; Subgraph_MinusSignificantOverboughtLevel.PrimaryColor = RGB(255,0,0); Subgraph_MinusSignificantOverboughtLevel.DrawStyle = DRAWSTYLE_LINE; Subgraph_MinusSignificantOverboughtLevel.DisplayNameValueInWindowsFlags= 0; Subgraph_ZeroLevel.Name = "Zero Level"; Subgraph_ZeroLevel.PrimaryColor = RGB(128,128,128); Subgraph_ZeroLevel.DrawStyle = DRAWSTYLE_LINE; Subgraph_ZeroLevel.DisplayNameValueInWindowsFlags= 0; Subgraph_ZeroLevel.DrawZeros = 1; } Subgraph_PlusModerateOverboughtLevel[sc.Index] = Input_ModOBLevel.GetFloat(); Subgraph_PlusSignificantOverboughtLevel[sc.Index] = Input_SigOBLevel.GetFloat(); Subgraph_MinusModerateOverboughtLevel[sc.Index] = Input_ModOBLevel.GetFloat() * -1.0f; Subgraph_MinusSignificantOverboughtLevel[sc.Index] = Input_SigOBLevel.GetFloat() * -1.0f; } /*==========================================================================*/ SCSFExport scsf_ValueChart(SCStudyInterfaceRef sc) { SCInputRef Input_Length = sc.Input[0]; SCSubgraphRef Subgraph_VcOpen = sc.Subgraph[0]; SCSubgraphRef Subgraph_VcHigh = sc.Subgraph[1]; SCSubgraphRef Subgraph_VcLow = sc.Subgraph[2]; SCSubgraphRef Subgraph_VcClose = sc.Subgraph[3]; SCFloatArrayRef Array_VcHLMA = Subgraph_VcOpen.Arrays[1]; SCFloatArrayRef Array_TR = Subgraph_VcOpen.Arrays[2]; SCFloatArrayRef Array_ATR = Subgraph_VcOpen.Arrays[3]; SCFloatArrayRef Array_HH = Subgraph_VcOpen.Arrays[4]; SCFloatArrayRef Array_LL = Subgraph_VcOpen.Arrays[5]; if (sc.SetDefaults) { // Set the configuration and defaults sc.GraphName ="Value Chart"; sc.GraphDrawType = GDT_CANDLESTICK; sc.AutoLoop = 1; // Inputs Input_Length.Name = "Length"; Input_Length.SetInt(5); Input_Length.SetIntLimits(2,10000); // Subgraphs Subgraph_VcOpen.Name = "VC Open"; Subgraph_VcOpen.DrawStyle = DRAWSTYLE_LINE; Subgraph_VcOpen.PrimaryColor = RGB(0,255,0); Subgraph_VcOpen.SecondaryColorUsed = true; Subgraph_VcOpen.SecondaryColor = RGB(0,255,0); Subgraph_VcOpen.DrawZeros = 1; Subgraph_VcHigh.Name = "VC High"; Subgraph_VcHigh.DrawStyle = DRAWSTYLE_LINE; Subgraph_VcHigh.PrimaryColor = RGB(128,255,128); Subgraph_VcHigh.DrawZeros = 1; Subgraph_VcLow.Name = "VC Low"; Subgraph_VcLow.DrawStyle = DRAWSTYLE_LINE; Subgraph_VcLow.PrimaryColor = RGB(255,0,0); Subgraph_VcLow.SecondaryColor = RGB(255,0,0); Subgraph_VcLow.SecondaryColorUsed = true; Subgraph_VcLow.DrawZeros = 1; Subgraph_VcClose.Name = "VC Close"; Subgraph_VcClose.DrawStyle = DRAWSTYLE_LINE; Subgraph_VcClose.PrimaryColor = RGB(255,128,128); Subgraph_VcClose.DrawZeros = 1; return; } int NumBars = Input_Length.GetInt(); float LRange = 1; if (NumBars > 7) { int VarNumBars = sc.Round(static_cast(NumBars) / 5.0f); sc.Highest(sc.High, Array_HH, VarNumBars); sc.Lowest(sc.Low, Array_LL, VarNumBars); float R1 = Array_HH[sc.Index] - Array_LL[sc.Index]; if (R1 == 0 && VarNumBars == 1) R1 = abs(sc.Close[sc.Index] - sc.Close[sc.Index-VarNumBars]); float R2 = Array_HH[sc.Index-VarNumBars-1] - Array_LL[sc.Index-VarNumBars]; if (R2 == 0 && VarNumBars == 1) R2 = abs(sc.Close[sc.Index-VarNumBars] - sc.Close[sc.Index-(VarNumBars*2)]); float R3 = Array_HH[sc.Index-(VarNumBars*2)] - Array_LL[sc.Index-(VarNumBars*2)]; if (R3 == 0 && VarNumBars == 1) R3 = abs(sc.Close[sc.Index-(VarNumBars*2)] - sc.Close[sc.Index-(VarNumBars*3)]); float R4 = Array_HH[sc.Index-(VarNumBars*3)] - Array_LL[sc.Index-(VarNumBars*3)]; if (R4 == 0 && VarNumBars == 1) R4 = abs(sc.Close[sc.Index-(VarNumBars*3)] - sc.Close[sc.Index-(VarNumBars*4)]); float R5 = Array_HH[sc.Index-(VarNumBars*4)] - Array_LL[sc.Index-(VarNumBars*4)]; if (R5 == 0 && VarNumBars == 1) R5 = abs(sc.Close[sc.Index-(VarNumBars*4)] - sc.Close[sc.Index-(VarNumBars*5)]); LRange = (R1 + R2 + R3 + R4 + R5) / 5 / 5; } else { sc.ATR(sc.BaseDataIn, Array_TR, Array_ATR, 5, MOVAVGTYPE_SIMPLE); LRange = Array_ATR[sc.Index] / 5; } sc.MovingAverage(sc.HLAvg, Array_VcHLMA, MOVAVGTYPE_SIMPLE, Input_Length.GetInt()); float AvgVcHL = Array_VcHLMA[sc.Index]; Subgraph_VcOpen[sc.Index] = (sc.Open[sc.Index] - AvgVcHL) / LRange; Subgraph_VcHigh[sc.Index] = (sc.High[sc.Index] - AvgVcHL) / LRange; Subgraph_VcLow[sc.Index] = (sc.Low[sc.Index] - AvgVcHL) / LRange; Subgraph_VcClose[sc.Index] = (sc.Close[sc.Index] - AvgVcHL) / LRange; } /*==========================================================================*/ SCSFExport scsf_GeneralizedDoubleExponentialMovingAverage(SCStudyInterfaceRef sc) { SCSubgraphRef Subgraph_GDEMA = sc.Subgraph[0]; SCInputRef Input_InputData = sc.Input[0]; SCInputRef Input_Length = sc.Input[1]; SCInputRef Input_Multiplier = sc.Input[2]; SCInputRef Input_GDEMACount = sc.Input[3]; if (sc.SetDefaults) { // Set the configuration and defaults sc.GraphName = "Moving Average - Generalized Double Exponential"; sc.GraphRegion = 0; sc.StudyDescription = "Moving Average - Generalized Double Moving Exponential"; Subgraph_GDEMA.Name = "GDEMA"; Subgraph_GDEMA.DrawStyle = DRAWSTYLE_LINE; Subgraph_GDEMA.PrimaryColor = RGB(0, 255, 0); Subgraph_GDEMA.DrawZeros = false; Input_InputData.Name = "Input Data"; Input_InputData.SetInputDataIndex(SC_LAST); Input_Length.Name = "Length"; Input_Length.SetInt(10); Input_Length.SetIntLimits(1, MAX_STUDY_LENGTH); Input_Multiplier.Name = "Multiplier"; Input_Multiplier.SetFloat(1.0f); Input_GDEMACount.Name = "GDEMA Count"; Input_GDEMACount.SetInt(1); Input_GDEMACount.SetIntLimits(1, SC_SUBGRAPHS_AVAILABLE - 1); sc.AutoLoop = 1; return; } int Length = Input_Length.GetInt(); float Multiplier = Input_Multiplier.GetFloat(); int Count = Input_GDEMACount.GetInt(); sc.DataStartIndex = Length * Count; if (sc.Index == 0) { for (int SubgraphIndex = 1; SubgraphIndex <= Count; SubgraphIndex++) { sc.Subgraph[SubgraphIndex].Name.Format("%d", SubgraphIndex); sc.Subgraph[SubgraphIndex].DrawStyle = DRAWSTYLE_IGNORE; sc.Subgraph[SubgraphIndex].DisplayNameValueInWindowsFlags = 0; } } sc.ExponentialMovAvg(sc.BaseDataIn[Input_InputData.GetInputDataIndex()], sc.Subgraph[1].Arrays[0], Length); sc.ExponentialMovAvg(sc.Subgraph[1].Arrays[0], sc.Subgraph[1].Arrays[1], Length); sc.Subgraph[1][sc.Index] = (1 + Multiplier) * sc.Subgraph[1].Arrays[0][sc.Index] - Multiplier * sc.Subgraph[1].Arrays[1][sc.Index]; for (int SubgraphIndex = 2; SubgraphIndex <= Count; SubgraphIndex++) { sc.ExponentialMovAvg(sc.Subgraph[SubgraphIndex - 1], sc.Subgraph[SubgraphIndex].Arrays[0], Length); sc.ExponentialMovAvg(sc.Subgraph[SubgraphIndex].Arrays[0], sc.Subgraph[SubgraphIndex].Arrays[1], Length); sc.Subgraph[SubgraphIndex][sc.Index] = (1 + Multiplier) * sc.Subgraph[SubgraphIndex].Arrays[0][sc.Index] - Multiplier * sc.Subgraph[SubgraphIndex].Arrays[1][sc.Index]; } Subgraph_GDEMA[sc.Index] = sc.Subgraph[Count][sc.Index]; } /*==========================================================================*/ SCSFExport scsf_SchaffTrendCycle(SCStudyInterfaceRef sc) { SCSubgraphRef Subgraph_SchaffTrendCycle = sc.Subgraph[0]; SCSubgraphRef Subgraph_MACD = sc.Subgraph[1]; SCSubgraphRef Subgraph_FastKMACD = sc.Subgraph[2]; SCSubgraphRef Subgraph_FastDMACD = sc.Subgraph[3]; SCSubgraphRef Subgraph_FastKFastDMACD = sc.Subgraph[4]; SCSubgraphRef Subgraph_Overbought = sc.Subgraph[5]; SCSubgraphRef Subgraph_Oversold = sc.Subgraph[6]; SCInputRef Input_InputData = sc.Input[0]; SCInputRef Input_FastLength = sc.Input[2]; SCInputRef Input_SlowLength = sc.Input[3]; SCInputRef Input_MovingAverageType = sc.Input[4]; SCInputRef Input_Length = sc.Input[5]; SCInputRef Input_Multiplier = sc.Input[6]; SCInputRef Input_Overbought = sc.Input[7]; SCInputRef Input_Oversold = sc.Input[8]; if (sc.SetDefaults) { sc.GraphName = "Schaff Trend Cycle"; sc.AutoLoop = 1; sc.GraphRegion = 1; Subgraph_SchaffTrendCycle.Name = "Schaff Trend Cycle"; Subgraph_SchaffTrendCycle.DrawStyle = DRAWSTYLE_LINE; Subgraph_SchaffTrendCycle.DrawZeros = true; Subgraph_SchaffTrendCycle.PrimaryColor = RGB(0, 0, 255); Subgraph_MACD.Name = "MACD"; Subgraph_MACD.DrawStyle = DRAWSTYLE_IGNORE; Subgraph_FastKMACD.Name = "Fast %K of MACD"; Subgraph_FastKMACD.DrawStyle = DRAWSTYLE_IGNORE; Subgraph_FastDMACD.Name = "Fast %D of MACD"; Subgraph_FastDMACD.DrawStyle = DRAWSTYLE_IGNORE; Subgraph_FastKFastDMACD.Name = "Fast %K of Fast %D of MACD"; Subgraph_FastKFastDMACD.DrawStyle = DRAWSTYLE_IGNORE; Subgraph_Overbought.Name = "Overbought Line"; Subgraph_Overbought.DrawStyle = DRAWSTYLE_LINE; Subgraph_Overbought.DrawZeros = true; Subgraph_Overbought.PrimaryColor = RGB(0, 255, 0); Subgraph_Oversold.Name = "Oversold Line"; Subgraph_Oversold.DrawStyle = DRAWSTYLE_LINE; Subgraph_Oversold.DrawZeros = true; Subgraph_Oversold.PrimaryColor = RGB(255, 0, 0); Input_InputData.Name = "Input Data"; Input_InputData.SetInputDataIndex(SC_LAST); Input_FastLength.Name = "Fast Moving Average Length"; Input_FastLength.SetInt(23); Input_FastLength.SetIntLimits(1, MAX_STUDY_LENGTH); Input_SlowLength.Name = "Slow Moving Average Length"; Input_SlowLength.SetInt(50); Input_SlowLength.SetIntLimits(1, MAX_STUDY_LENGTH); Input_MovingAverageType.Name = "Moving Average Type"; Input_MovingAverageType.SetMovAvgType(MOVAVGTYPE_EXPONENTIAL); Input_Length.Name = "Length"; Input_Length.SetInt(10); Input_Length.SetIntLimits(1, MAX_STUDY_LENGTH); Input_Multiplier.Name = "Multiplier"; Input_Multiplier.SetFloat(0.5f); Input_Overbought.Name = "Overbought Level"; Input_Overbought.SetFloat(75.0f); Input_Oversold.Name = "Oversold Level"; Input_Oversold.SetFloat(25.0f); return; } // MACD of Price Data sc.MACD(sc.BaseDataIn[Input_InputData.GetInputDataIndex()], Subgraph_MACD, sc.Index, Input_FastLength.GetInt(), Input_SlowLength.GetInt(), Input_Length.GetInt(), Input_MovingAverageType.GetInt()); // Fast %K of MACD float MaxMACD = sc.GetHighest(Subgraph_MACD, sc.Index, Input_Length.GetInt()); float MinMACD = sc.GetLowest(Subgraph_MACD, sc.Index, Input_Length.GetInt()); float RangeMACD = MaxMACD - MinMACD; if (RangeMACD > 0.0f) Subgraph_FastKMACD[sc.Index] = 100.0f * (Subgraph_MACD[sc.Index] - MinMACD) / RangeMACD; else Subgraph_FastKMACD[sc.Index] = Subgraph_FastKMACD[sc.Index - 1]; // Fast %D of MACD if (sc.Index == 0) Subgraph_FastDMACD[sc.Index] = Subgraph_FastKMACD[sc.Index]; else Subgraph_FastDMACD[sc.Index] = Subgraph_FastDMACD[sc.Index - 1] + Input_Multiplier.GetFloat() * (Subgraph_FastKMACD[sc.Index] - Subgraph_FastDMACD[sc.Index - 1]); // Fast %K of Fast %D of MACD float MaxFastDMACD = sc.GetHighest(Subgraph_FastDMACD, sc.Index, Input_Length.GetInt()); float MinFastDMACD = sc.GetLowest(Subgraph_FastDMACD, sc.Index, Input_Length.GetInt()); float RangeFastDMACD = MaxFastDMACD - MinFastDMACD; if (RangeFastDMACD > 0.0f) Subgraph_FastKFastDMACD[sc.Index] = 100.0f * (Subgraph_FastDMACD[sc.Index] - MinFastDMACD) / RangeFastDMACD; else Subgraph_FastKFastDMACD[sc.Index] = Subgraph_FastKFastDMACD[sc.Index - 1]; // Schaff Trend Cycle if (sc.Index == 0) Subgraph_SchaffTrendCycle[sc.Index] = Subgraph_FastKFastDMACD[sc.Index]; else Subgraph_SchaffTrendCycle[sc.Index] = Subgraph_SchaffTrendCycle[sc.Index - 1] + Input_Multiplier.GetFloat() * (Subgraph_FastKFastDMACD[sc.Index] - Subgraph_SchaffTrendCycle[sc.Index - 1]); // Overbought and Oversold Lines Subgraph_Overbought[sc.Index] = Input_Overbought.GetFloat(); Subgraph_Oversold[sc.Index] = Input_Oversold.GetFloat(); } /*==========================================================================*/ SCSFExport scsf_PremierStochasticOscillator(SCStudyInterfaceRef sc) { SCSubgraphRef Subgraph_FastK = sc.Subgraph[0]; SCSubgraphRef Subgraph_FastD = sc.Subgraph[1]; SCSubgraphRef Subgraph_SlowD = sc.Subgraph[2]; SCSubgraphRef Subgraph_PSO = sc.Subgraph[3]; SCSubgraphRef Subgraph_Line1 = sc.Subgraph[4]; SCSubgraphRef Subgraph_Line2 = sc.Subgraph[5]; SCSubgraphRef Subgraph_Line3 = sc.Subgraph[6]; SCSubgraphRef Subgraph_Line4 = sc.Subgraph[7]; SCSubgraphRef Subgraph_CenterLine = sc.Subgraph[8]; SCFloatArrayRef Array_Stochastic = sc.Subgraph[3].Arrays[0]; SCFloatArrayRef Array_EMAStochastic = sc.Subgraph[3].Arrays[1]; SCFloatArrayRef Array_EMAEMAStochastic = sc.Subgraph[3].Arrays[2]; SCFloatArrayRef Array_ExponentialValue = sc.Subgraph[3].Arrays[3]; SCInputRef Input_InputDataHigh = sc.Input[0]; SCInputRef Input_InputDataLow = sc.Input[1]; SCInputRef Input_InputDataLast = sc.Input[2]; SCInputRef Input_StochasticType = sc.Input[3]; SCInputRef Input_FastKLength = sc.Input[4]; SCInputRef Input_FastDLength = sc.Input[5]; SCInputRef Input_SlowDLength = sc.Input[6]; SCInputRef Input_PercentDMovAvgType = sc.Input[7]; SCInputRef Input_PSOLength = sc.Input[8]; SCInputRef Input_PSOMovAvgType = sc.Input[9]; SCInputRef Input_Line1Value = sc.Input[10]; SCInputRef Input_Line2Value = sc.Input[11]; SCInputRef Input_Line3Value = sc.Input[12]; SCInputRef Input_Line4Value = sc.Input[13]; if (sc.SetDefaults) { sc.GraphName = "Premier Stochastic Oscillator"; sc.ValueFormat = 2; Subgraph_FastK.Name = "Fast %K"; Subgraph_FastK.DrawStyle = DRAWSTYLE_IGNORE; Subgraph_FastD.Name = "Fast %D (Slow %K)"; Subgraph_FastD.DrawStyle = DRAWSTYLE_IGNORE; Subgraph_SlowD.Name = "Slow %D"; Subgraph_SlowD.DrawStyle = DRAWSTYLE_IGNORE; Subgraph_PSO.Name = "Premier Stochastic Oscillator"; Subgraph_PSO.DrawStyle = DRAWSTYLE_LINE; Subgraph_PSO.PrimaryColor = RGB(0, 255, 0); Subgraph_PSO.DrawZeros = true; Subgraph_Line1.Name = "Line 1"; Subgraph_Line1.DrawStyle = DRAWSTYLE_LINE; Subgraph_Line1.PrimaryColor = RGB(0, 0, 255); Subgraph_Line1.DrawZeros = true; Subgraph_Line2.Name = "Line 2"; Subgraph_Line2.DrawStyle = DRAWSTYLE_LINE; Subgraph_Line2.PrimaryColor = RGB(0, 0, 255); Subgraph_Line2.DrawZeros = true; Subgraph_Line3.Name = "Line 3"; Subgraph_Line3.DrawStyle = DRAWSTYLE_LINE; Subgraph_Line3.PrimaryColor = RGB(0, 0, 255); Subgraph_Line3.DrawZeros = true; Subgraph_Line4.Name = "Line 4"; Subgraph_Line4.DrawStyle = DRAWSTYLE_LINE; Subgraph_Line4.PrimaryColor = RGB(0, 0, 255); Subgraph_Line4.DrawZeros = true; Subgraph_CenterLine.Name = "Center Line"; Subgraph_CenterLine.DrawStyle = DRAWSTYLE_LINE; Subgraph_CenterLine.PrimaryColor = RGB(128, 0, 128); Subgraph_CenterLine.DrawZeros = true; Input_InputDataHigh.Name = "Input Data for High"; Input_InputDataHigh.SetInputDataIndex(SC_HIGH); Input_InputDataLow.Name = "Input Data for Low"; Input_InputDataLow.SetInputDataIndex(SC_LOW); Input_InputDataLast.Name = "Input Data for Last"; Input_InputDataLast.SetInputDataIndex(SC_LAST); Input_StochasticType.Name = "Stochastic Type"; Input_StochasticType.SetCustomInputStrings ("Fast %K" ";Fast %D (Slow %K)" ";Slow %D" ); Input_StochasticType.SetCustomInputIndex(0); Input_FastKLength.Name = "Fast %K Length"; Input_FastKLength.SetInt(8); Input_FastKLength.SetIntLimits(1, MAX_STUDY_LENGTH); Input_FastDLength.Name = "Fast %D (Slow %K) Length"; Input_FastDLength.SetInt(8); Input_FastDLength.SetIntLimits(1, MAX_STUDY_LENGTH); Input_SlowDLength.Name = "Slow %D Length"; Input_SlowDLength.SetInt(8); Input_SlowDLength.SetIntLimits(1, MAX_STUDY_LENGTH); Input_PercentDMovAvgType.Name = "Fast/Slow %D Moving Average Type"; Input_PercentDMovAvgType.SetMovAvgType(MOVAVGTYPE_SIMPLE); Input_PSOLength.Name = "PSO Length"; Input_PSOLength.SetInt(5); Input_PSOLength.SetIntLimits(1, MAX_STUDY_LENGTH); Input_PSOMovAvgType.Name = "PSO Moving Average Type"; Input_PSOMovAvgType.SetMovAvgType(MOVAVGTYPE_EXPONENTIAL); Input_Line1Value.Name = "Line 1 Value"; Input_Line1Value.SetFloat(0.5f); Input_Line1Value.SetFloatLimits(-1.0f, 1.0f); Input_Line2Value.Name = "Line 2 Value"; Input_Line2Value.SetFloat(0.25f); Input_Line2Value.SetFloatLimits(-1.0f, 1.0f); Input_Line3Value.Name = "Line 3 Value"; Input_Line3Value.SetFloat(-0.25f); Input_Line3Value.SetFloatLimits(-1.0f, 1.0f); Input_Line4Value.Name = "Line 4 Value"; Input_Line4Value.SetFloat(-0.5f); Input_Line4Value.SetFloatLimits(-1.0f, 1.0f); sc.AutoLoop = true; return; } sc.Stochastic( sc.BaseData[Input_InputDataHigh.GetInputDataIndex()], sc.BaseData[Input_InputDataLow.GetInputDataIndex()], sc.BaseData[Input_InputDataLast.GetInputDataIndex()], Subgraph_FastK, // Data member is Fast %K Input_FastKLength.GetInt(), Input_FastDLength.GetInt(), Input_SlowDLength.GetInt(), Input_PercentDMovAvgType.GetMovAvgType()); Subgraph_FastD[sc.Index] = Subgraph_FastK.Arrays[0][sc.Index]; Subgraph_SlowD[sc.Index] = Subgraph_FastK.Arrays[1][sc.Index]; const int SelectedIndex = Input_StochasticType.GetIndex(); switch (SelectedIndex) { case 0: { sc.DataStartIndex = Input_FastKLength.GetInt() + 2 * Input_PSOMovAvgType.GetInt() - 1; Array_Stochastic[sc.Index] = 0.1f * (Subgraph_FastK[sc.Index] - 50.0f); } break; case 1: { sc.DataStartIndex = Input_FastKLength.GetInt() + Input_FastDLength.GetInt() + 2 * Input_PSOMovAvgType.GetInt() - 1; Array_Stochastic[sc.Index] = 0.1f * (Subgraph_FastD[sc.Index] - 50.0f); } break; case 2: { sc.DataStartIndex = Input_FastKLength.GetInt() + Input_FastDLength.GetInt() + Input_SlowDLength.GetInt() + 2 * Input_PSOMovAvgType.GetInt() - 1; Array_Stochastic[sc.Index] = 0.1f * (Subgraph_SlowD[sc.Index] - 50.0f); } break; } sc.MovingAverage(Array_Stochastic, Array_EMAStochastic, Input_PSOMovAvgType.GetMovAvgType(), Input_PSOLength.GetInt()); sc.MovingAverage(Array_EMAStochastic, Array_EMAEMAStochastic, Input_PSOMovAvgType.GetMovAvgType(), Input_PSOLength.GetInt()); Array_ExponentialValue[sc.Index] = exp(Array_EMAEMAStochastic[sc.Index]); Subgraph_PSO[sc.Index] = (Array_ExponentialValue[sc.Index] - 1) / (Array_ExponentialValue[sc.Index] + 1); Subgraph_Line1[sc.Index] = Input_Line1Value.GetFloat(); Subgraph_Line2[sc.Index] = Input_Line2Value.GetFloat(); Subgraph_Line3[sc.Index] = Input_Line3Value.GetFloat(); Subgraph_Line4[sc.Index] = Input_Line4Value.GetFloat(); Subgraph_CenterLine[sc.Index] = 0.0f; } /*==========================================================================*/ SCSFExport scsf_SuperSmootherFilter(SCStudyInterfaceRef sc) { SCSubgraphRef Subgraph_SuperSmootherFilter = sc.Subgraph[0]; SCInputRef Input_InputData = sc.Input[0]; SCInputRef Input_Length = sc.Input[1]; SCInputRef Input_Poles = sc.Input[2]; if (sc.SetDefaults) { sc.GraphName = "Super Smoother Filter"; sc.AutoLoop = 1; sc.GraphRegion = 1; Subgraph_SuperSmootherFilter.Name = "Super Smoother Filter"; Subgraph_SuperSmootherFilter.DrawStyle = DRAWSTYLE_LINE; Subgraph_SuperSmootherFilter.PrimaryColor = RGB(0, 255, 0); Input_InputData.Name = "Input Data"; Input_InputData.SetInputDataIndex(SC_LAST); Input_Length.Name = "Length"; Input_Length.SetInt(15); Input_Length.SetIntLimits(1, MAX_STUDY_LENGTH); Input_Poles.Name = "Number of Poles"; Input_Poles.SetCustomInputStrings("2;3"); Input_Poles.SetCustomInputIndex(0); return; } const int SelectedIndex = Input_Poles.GetIndex(); switch (SelectedIndex) { case 0: { sc.SuperSmoother2Pole(sc.BaseDataIn[Input_InputData.GetInputDataIndex()], Subgraph_SuperSmootherFilter, sc.Index, Input_Length.GetInt()); } break; case 1: { sc.SuperSmoother3Pole(sc.BaseDataIn[Input_InputData.GetInputDataIndex()], Subgraph_SuperSmootherFilter, sc.Index, Input_Length.GetInt()); } break; } } /*==========================================================================*/ SCSFExport scsf_ButterworthFilter(SCStudyInterfaceRef sc) { SCSubgraphRef Subgraph_ButterworthFilter = sc.Subgraph[0]; SCInputRef Input_InputData = sc.Input[0]; SCInputRef Input_Length = sc.Input[1]; SCInputRef Input_Poles = sc.Input[2]; if (sc.SetDefaults) { sc.GraphName = "Butterworth Filter"; sc.AutoLoop = 1; sc.GraphRegion = 1; Subgraph_ButterworthFilter.Name = "Butterworth Filter"; Subgraph_ButterworthFilter.DrawStyle = DRAWSTYLE_LINE; Subgraph_ButterworthFilter.PrimaryColor = RGB(0, 255, 0); Input_InputData.Name = "Input Data"; Input_InputData.SetInputDataIndex(SC_LAST); Input_Length.Name = "Length"; Input_Length.SetInt(15); Input_Length.SetIntLimits(1, MAX_STUDY_LENGTH); Input_Poles.Name = "Number of Poles"; Input_Poles.SetCustomInputStrings("2;3"); Input_Poles.SetCustomInputIndex(0); return; } const int SelectedIndex = Input_Poles.GetIndex(); switch (SelectedIndex) { case 0: { sc.Butterworth2Pole(sc.BaseDataIn[Input_InputData.GetInputDataIndex()], Subgraph_ButterworthFilter, sc.Index, Input_Length.GetInt()); } break; case 1: { sc.Butterworth3Pole(sc.BaseDataIn[Input_InputData.GetInputDataIndex()], Subgraph_ButterworthFilter, sc.Index, Input_Length.GetInt()); } break; } } /*==========================================================================*/ SCSFExport scsf_ConnorsRSI(SCStudyInterfaceRef sc) { SCSubgraphRef Subgraph_RSI = sc.Subgraph[0]; SCSubgraphRef Subgraph_UpDownLength = sc.Subgraph[1]; SCSubgraphRef Subgraph_RSIUpDownLength = sc.Subgraph[2]; SCSubgraphRef Subgraph_RateOfChange = sc.Subgraph[3]; SCSubgraphRef Subgraph_ConnorsRSI = sc.Subgraph[4]; SCSubgraphRef Subgraph_Line1 = sc.Subgraph[5]; SCSubgraphRef Subgraph_Line2 = sc.Subgraph[6]; SCFloatArrayRef Array_PriceChange = sc.Subgraph[3].Arrays[0]; SCInputRef Input_InputData = sc.Input[0]; SCInputRef Input_RSILength = sc.Input[1]; SCInputRef Input_RSIAvgType = sc.Input[2]; SCInputRef Input_RateOfChangeLength = sc.Input[3]; SCInputRef Input_Line1Value = sc.Input[4]; SCInputRef Input_Line2Value = sc.Input[5]; if (sc.SetDefaults) { sc.GraphName = "RSI - Connors "; sc.GraphRegion = 1; sc.ValueFormat = 2; sc.AutoLoop = 1; Subgraph_RSI.Name = "RSI"; Subgraph_RSI.DrawStyle = DRAWSTYLE_IGNORE; Subgraph_UpDownLength.Name = "Up-Down Streak Length"; Subgraph_UpDownLength.DrawStyle = DRAWSTYLE_IGNORE; Subgraph_RSIUpDownLength.Name = "RSI of Up-Down Streak Length"; Subgraph_RSIUpDownLength.DrawStyle = DRAWSTYLE_IGNORE; Subgraph_RateOfChange.Name = "Rate of Change"; Subgraph_RateOfChange.DrawStyle = DRAWSTYLE_IGNORE; Subgraph_ConnorsRSI.Name = "Connors RSI"; Subgraph_ConnorsRSI.DrawStyle = DRAWSTYLE_LINE; Subgraph_ConnorsRSI.PrimaryColor = RGB(0, 0, 255); Subgraph_ConnorsRSI.DrawZeros = true; Subgraph_Line1.Name = "Line 1"; Subgraph_Line1.DrawStyle = DRAWSTYLE_LINE; Subgraph_Line1.PrimaryColor = RGB(255, 0, 255); Subgraph_Line1.DrawZeros = true; Subgraph_Line2.Name = "Line 2"; Subgraph_Line2.DrawStyle = DRAWSTYLE_LINE; Subgraph_Line2.PrimaryColor = RGB(255, 255, 0); Subgraph_Line2.DrawZeros = true; Input_InputData.Name = "Input Data"; Input_InputData.SetInputDataIndex(SC_LAST); Input_RSILength.Name = "RSI Length"; Input_RSILength.SetInt(3); Input_RSILength.SetIntLimits(1, MAX_STUDY_LENGTH); Input_RSIAvgType.Name = "RSI Average Type"; Input_RSIAvgType.SetMovAvgType(MOVAVGTYPE_WILDERS); Input_RateOfChangeLength.Name = "Rate of Change Length"; Input_RateOfChangeLength.SetInt(100); Input_RateOfChangeLength.SetIntLimits(1, MAX_STUDY_LENGTH); Input_Line1Value.Name = "Line 1 Value"; Input_Line1Value.SetFloat(70.0f); Input_Line2Value.Name = "Line 2 Value"; Input_Line2Value.SetFloat(30.0f); return; } //Compute RSI sc.RSI(sc.BaseDataIn[Input_InputData.GetInputDataIndex()], Subgraph_RSI, Input_RSIAvgType.GetMovAvgType(), Input_RSILength.GetInt()); //Compute RSI of Up-Down Length if (sc.Index == 0) { Subgraph_UpDownLength[sc.Index] = 0; Subgraph_RateOfChange[sc.Index] = 0; } else { int i = 0; int j = 0; float UpDownStreak = 0.0f; while (sc.BaseDataIn[Input_InputData.GetInputDataIndex()][sc.Index - i - 1] < sc.BaseDataIn[Input_InputData.GetInputDataIndex()][sc.Index - i]) { UpDownStreak += 1.0f; i++; } while (sc.BaseDataIn[Input_InputData.GetInputDataIndex()][sc.Index - j - 1] > sc.BaseDataIn[Input_InputData.GetInputDataIndex()][sc.Index - j]) { UpDownStreak -= 1.0f; j++; } Subgraph_UpDownLength[sc.Index] = UpDownStreak; } sc.RSI(Subgraph_UpDownLength, Subgraph_RSIUpDownLength, Input_RSIAvgType.GetMovAvgType(), 2); //Compute Rate of Change Array_PriceChange[sc.Index] = sc.BaseDataIn[Input_InputData.GetInputDataIndex()][sc.Index] - sc.BaseDataIn[Input_InputData.GetInputDataIndex()][sc.Index - 1]; float ROCStreak = 0.0f; for (int i = 1; i <= Input_RateOfChangeLength.GetInt(); i++) { if (Array_PriceChange[sc.Index - i] < Array_PriceChange[sc.Index]) ROCStreak += 1; } float ROCLength = static_cast(Input_RateOfChangeLength.GetInt()); Subgraph_RateOfChange[sc.Index] = 100.0f * ROCStreak / ROCLength; //Compute Connors RSI Subgraph_ConnorsRSI[sc.Index] = (Subgraph_RSI[sc.Index] + Subgraph_RSIUpDownLength[sc.Index] + Subgraph_RateOfChange[sc.Index]) / 3.0f; Subgraph_Line1[sc.Index] = Input_Line1Value.GetFloat(); Subgraph_Line2[sc.Index] = Input_Line2Value.GetFloat(); } /*==========================================================================*/ SCSFExport scsf_RelativeVolumeStandardDeviation(SCStudyInterfaceRef sc) { SCSubgraphRef Subgraph_RelVol = sc.Subgraph[0]; SCFloatArrayRef Array_AvgVol = sc.Subgraph[0].Arrays[0]; SCFloatArrayRef Array_StdDevVol = sc.Subgraph[0].Arrays[1]; SCInputRef Input_Length = sc.Input[0]; SCInputRef Input_NumStDevs = sc.Input[1]; SCInputRef Input_MovAvgType = sc.Input[2]; if (sc.SetDefaults) { sc.GraphName = "Relative Volume Standard Deviation"; sc.GraphRegion = 1; sc.AutoLoop = 1; Subgraph_RelVol.Name = "Relative Volume Standard Deviation"; Subgraph_RelVol.DrawStyle = DRAWSTYLE_BAR; Subgraph_RelVol.PrimaryColor = RGB(0, 255, 0); Subgraph_RelVol.SecondaryColor = RGB(255, 0, 0); Input_Length.Name = "Length"; Input_Length.SetInt(60); Input_Length.SetIntLimits(1, MAX_STUDY_LENGTH); Input_NumStDevs.Name = "Number of Standard Deviations"; Input_NumStDevs.SetInt(2); Input_NumStDevs.SetIntLimits(1, MAX_STUDY_LENGTH); Input_MovAvgType.Name = "Moving Average Type"; Input_MovAvgType.SetMovAvgType(MOVAVGTYPE_SIMPLE); return; } sc.MovingAverage(sc.Volume, Array_AvgVol, Input_MovAvgType.GetMovAvgType(), Input_Length.GetInt()); sc.StdDeviation(sc.Volume, Array_StdDevVol, Input_Length.GetInt()); if (Array_StdDevVol[sc.Index] != 0.0f) Subgraph_RelVol[sc.Index] = (sc.Volume[sc.Index] - Array_AvgVol[sc.Index]) / Array_StdDevVol[sc.Index]; else Subgraph_RelVol[sc.Index] = 0.0f; if (Subgraph_RelVol[sc.Index] > Input_NumStDevs.GetInt()) Subgraph_RelVol.DataColor[sc.Index] = Subgraph_RelVol.PrimaryColor; else Subgraph_RelVol.DataColor[sc.Index] = Subgraph_RelVol.SecondaryColor; } /*==========================================================================*/ SCSFExport scsf_FreedomOfMovement(SCStudyInterfaceRef sc) { SCSubgraphRef Subgraph_NormMove = sc.Subgraph[0]; SCSubgraphRef Subgraph_NormRelVol = sc.Subgraph[1]; SCSubgraphRef Subgraph_FOM = sc.Subgraph[2]; SCFloatArrayRef Array_Move = sc.Subgraph[0].Arrays[0]; SCFloatArrayRef Array_HighMove = sc.Subgraph[0].Arrays[1]; SCFloatArrayRef Array_LowMove = sc.Subgraph[0].Arrays[2]; SCFloatArrayRef Array_RelVol = sc.Subgraph[1].Arrays[0]; SCFloatArrayRef Array_AvgVol = sc.Subgraph[1].Arrays[1]; SCFloatArrayRef Array_StdDevVol = sc.Subgraph[1].Arrays[2]; SCFloatArrayRef Array_HighRelVol = sc.Subgraph[1].Arrays[3]; SCFloatArrayRef Array_LowRelVol = sc.Subgraph[1].Arrays[4]; SCFloatArrayRef Array_RelVolByMove = sc.Subgraph[2].Arrays[0]; SCFloatArrayRef Array_AvgRelVolByMove = sc.Subgraph[2].Arrays[1]; SCFloatArrayRef Array_SDRelVolByMove = sc.Subgraph[2].Arrays[2]; SCInputRef Input_InputData = sc.Input[0]; SCInputRef Input_Length = sc.Input[1]; SCInputRef Input_NumStDevs = sc.Input[2]; SCInputRef Input_MovAvgType = sc.Input[3]; if (sc.SetDefaults) { sc.GraphName = "Freedom of Movement"; sc.GraphRegion = 1; sc.AutoLoop = 1; Subgraph_NormMove.Name = "Normalized Move"; Subgraph_NormMove.DrawStyle = DRAWSTYLE_IGNORE; Subgraph_NormRelVol.Name = "Normalized Relative Volume Standard Deviation"; Subgraph_NormRelVol.DrawStyle = DRAWSTYLE_IGNORE; Subgraph_FOM.Name = "Freedom of Movement"; Subgraph_FOM.DrawStyle = DRAWSTYLE_BAR; Subgraph_FOM.PrimaryColor = RGB(0, 255, 0); Subgraph_FOM.SecondaryColor = RGB(255, 0, 0); Input_InputData.Name = "Input Data"; Input_InputData.SetInputDataIndex(SC_LAST); Input_Length.Name = "Length"; Input_Length.SetInt(60); Input_Length.SetIntLimits(1, MAX_STUDY_LENGTH); Input_NumStDevs.Name = "Number of Standard Deviations"; Input_NumStDevs.SetInt(2); Input_NumStDevs.SetIntLimits(1, MAX_STUDY_LENGTH); Input_MovAvgType.Name = "Moving Average Type"; Input_MovAvgType.SetMovAvgType(MOVAVGTYPE_SIMPLE); return; } // Compute Normalized Move if (sc.BaseDataIn[Input_InputData.GetInputDataIndex()][sc.Index - 1] != 0.0f) Array_Move[sc.Index] = (sc.BaseDataIn[Input_InputData.GetInputDataIndex()][sc.Index] - sc.BaseDataIn[Input_InputData.GetInputDataIndex()][sc.Index - 1]) / sc.BaseDataIn[Input_InputData.GetInputDataIndex()][sc.Index - 1]; else Array_Move[sc.Index] = 0.0f; sc.Highest(Array_Move, Array_HighMove, Input_Length.GetInt()); float HighMove = Array_HighMove[sc.Index]; sc.Lowest(Array_Move, Array_LowMove, Input_Length.GetInt()); float LowMove = Array_LowMove[sc.Index]; if (HighMove - LowMove != 0.0f) Subgraph_NormMove[sc.Index] = 1.0f + 9.0f * (Array_Move[sc.Index] - LowMove) / (HighMove - LowMove); else Subgraph_NormMove[sc.Index] = 0.0f; // Compute Normalized Relative Volume sc.MovingAverage(sc.Volume, Array_AvgVol, Input_MovAvgType.GetMovAvgType(), Input_Length.GetInt()); sc.StdDeviation(sc.Volume, Array_StdDevVol, Input_Length.GetInt()); if (Array_StdDevVol[sc.Index] != 0.0f) Array_RelVol[sc.Index] = (sc.Volume[sc.Index] - Array_AvgVol[sc.Index]) / Array_StdDevVol[sc.Index]; else Array_RelVol[sc.Index] = 0.0f; sc.MovingAverage(sc.Volume, Array_AvgVol, Input_MovAvgType.GetMovAvgType(), Input_Length.GetInt()); sc.StdDeviation(sc.Volume, Array_StdDevVol, Input_Length.GetInt()); if (Array_StdDevVol[sc.Index] != 0.0f) Array_RelVol[sc.Index] = (sc.Volume[sc.Index] - Array_AvgVol[sc.Index]) / Array_StdDevVol[sc.Index]; else Array_RelVol[sc.Index] = 0.0f; sc.Highest(Array_RelVol, Array_HighRelVol, Input_Length.GetInt()); float HighRelVol = Array_HighRelVol[sc.Index]; sc.Lowest(Array_RelVol, Array_LowRelVol, Input_Length.GetInt()); float LowRelVol = Array_LowRelVol[sc.Index]; if (HighRelVol - LowRelVol != 0.0f) Subgraph_NormRelVol[sc.Index] = 1.0f + 9.0f * (Array_RelVol[sc.Index] - LowRelVol) / (HighRelVol - LowRelVol); else Subgraph_NormRelVol[sc.Index] = 0.0f; // Compute Freedom of Movement if (Subgraph_NormMove[sc.Index] != 0.0f) Array_RelVolByMove[sc.Index] = Subgraph_NormRelVol[sc.Index] / Subgraph_NormMove[sc.Index]; else Array_RelVolByMove[sc.Index] = 0.0f; sc.MovingAverage(Array_RelVolByMove, Array_AvgRelVolByMove, Input_MovAvgType.GetMovAvgType(), Input_Length.GetInt()); sc.StdDeviation(Array_RelVolByMove, Array_SDRelVolByMove, Input_Length.GetInt()); if (Array_SDRelVolByMove[sc.Index] != 0.0f) Subgraph_FOM[sc.Index] = (Array_RelVolByMove[sc.Index] - Array_AvgRelVolByMove[sc.Index]) / Array_SDRelVolByMove[sc.Index]; else Subgraph_FOM[sc.Index] = 0.0f; if (Subgraph_FOM[sc.Index] > Input_NumStDevs.GetInt()) Subgraph_FOM.DataColor[sc.Index] = Subgraph_FOM.PrimaryColor; else Subgraph_FOM.DataColor[sc.Index] = Subgraph_FOM.SecondaryColor; }